Skip to content

18.0 practice task agir #688

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: 18.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions custom_report/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
20 changes: 20 additions & 0 deletions custom_report/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
'name': 'Custom Picking Report',
'version': '1.0',
'summary': 'Add a custom report in sales module',
'description': """
Checking Product Quantity
==========================
In this module, add a custom report in which no sub kitt product will not print in report.

""",
'author': 'Raghav Agiwal',
'depends': ['sale_management', 'mrp', 'website'],
'data': [
'report/custom_report_mo_views.xml',
"report/custom_report_views.xml"
],
'installable': True,
'application': True,
'license': 'LGPL-3'
}
15 changes: 15 additions & 0 deletions custom_report/report/custom_report_mo_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record id="action_custom_report_mo_views" model="ir.actions.report">
<field name="name">Mo Delivery note</field>
<field name="model">stock.picking</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">custom_report.custom_report_mo_views</field>
<field name="report_file">custom_report.custom_report_mo_views</field>
<field name="print_report_name">'Mo Delivery Note -- %s - %s' % (object.partner_id.name or '', object.name)</field>
<field name="binding_model_id" ref="stock.model_stock_picking" />
<field name="binding_type">report</field>
</record>
</data>
</odoo>
13 changes: 13 additions & 0 deletions custom_report/report/custom_report_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_delivery_document" inherit_id="stock.report_delivery_document" primary="True">
<xpath expr="//table[@name='stock_move_table']/tbody/t" position="replace">
<t t-set="lines" t-value="o.move_ids.filtered(lambda x: x.product_uom_qty and (not x.bom_line_id or x.bom_line_id.bom_id.type != 'phantom'))" />
</xpath>
</template>
<template id="custom_report_mo_views">
<t t-foreach="docs" t-as="o">
<t t-call="custom_report.report_delivery_document" t-lang="o._get_report_lang()"/>
</t>
</template>
</odoo>
1 change: 1 addition & 0 deletions dev_zero_stock_blockage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
22 changes: 22 additions & 0 deletions dev_zero_stock_blockage/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
'name': 'Dev Zero Stock Blockage',
'version': '1.0',
'summary': 'Add zero stock blockage feature to sale order',
'description': """
Checking Product Quantity
==========================
This module stops Sales Orders from being confirmed if any product is out of stock, unless a Sales Manager gives approval.

Sales users can see the Zero Stock Approval field but cannot edit it.

It only checks stock for physical products, not services or combos.
""",
'author': 'Raghav Agiwal',
'depends': ['sale_management', 'stock'],
'data': [
'views/sale_order_views.xml',
],
'installable': True,
'application': True,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to make it an application.

Copy link
Author

@agir-odoo agir-odoo Apr 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok!!

'license': 'LGPL-3'
}
1 change: 1 addition & 0 deletions dev_zero_stock_blockage/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import sale_order
74 changes: 74 additions & 0 deletions dev_zero_stock_blockage/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from odoo import api, fields, models
from odoo.exceptions import UserError


class SaleOrder(models.Model):
_inherit = 'sale.order'

zero_stock_approval = fields.Boolean(
string="Approval",
copy=False,
)

@api.onchange('zero_stock_approval')
def _onchange_zero_stock_approval(self):
if self.zero_stock_approval and self.env.user.has_group('sales_team.group_sale_manager'):
warnings = []
for line in self.order_line:
if line.product_id.type == 'consu' and line.product_uom_qty > line.product_id.qty_available:
warnings.append(
f"Product '{line.product_id.display_name}' has demand {line.product_uom_qty} > available {line.product_id.qty_available}."
)
if warnings:
return {
'warning': {
'title': "Heads Up – Stock Alert ⚠️",
'message': (
"You're approving an order where some products have lower available stock than requested quantity:\n\n"
+ "\n".join(warnings) +
"\n\nIf you're sure about this decision, you can continue. Otherwise, consider adjusting the quantities or stock."
)
}
}

@api.model
def fields_get(self, allfields=None, attributes=None):
fields = super().fields_get(allfields=allfields, attributes=attributes)
if not self.env.user.has_group('sales_team.group_sale_manager'):
if "zero_stock_approval" in fields:
fields['zero_stock_approval']['readonly'] = True
return fields

def action_confirm(self):
for order in self:
stock_issues = []

for line in order.order_line:
demand_qty = line.product_uom_qty
available_qty = line.product_id.qty_available

# if demand_qty <= 0:
# raise UserError(
# f"You cannot confirm this Sale Order.\n"
# f"Product '{line.product_id.display_name}' has a quantity of {demand_qty}.\n"
# f"Quantity must be greater than zero."
# )
Comment on lines +50 to +55

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this code because I thought if the quantity is less than or equal to zero, it could cause a problem, like wrong stock numbers. But the task did not say anything about checking for negative quantities, so I was not sure if I should add it. That's why I commented it out. waiting for your confirmation if I should keep it or not.


if (
line.product_id.type == 'consu'
and demand_qty > available_qty
and not self.env.user.has_group('sales_team.group_sale_manager')
and not order.zero_stock_approval
):
stock_issues.append(
f"- {line.product_id.display_name}: Requested {demand_qty}, Available {available_qty}"
)

if stock_issues:
raise UserError(
"Cannot confirm this Sale Order due to insufficient stock:\n\n" +
"\n".join(stock_issues) +
"\n\nPlease get approval or adjust the quantities."
)

return super().action_confirm()
13 changes: 13 additions & 0 deletions dev_zero_stock_blockage/views/sale_order_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_sale_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='payment_term_id']" position="after">
<field name="zero_stock_approval"/>
</xpath>
</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions event_limit_reg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
14 changes: 14 additions & 0 deletions event_limit_reg/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
'name': 'Event limit registration',
'version': '1.0',
'summary': 'Event limit registration',
'author': 'Raghav Agiwal',
'depends': ['website_event', 'website'],
'data': [
'views/event_ticket_view.xml',
'views/event_registration_website_view.xml',
],
'installable': True,
'auto_install': True,
'license': 'LGPL-3'
}
1 change: 1 addition & 0 deletions event_limit_reg/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .import event_ticket
10 changes: 10 additions & 0 deletions event_limit_reg/models/event_ticket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from odoo import fields, models


class EventTicket(models.Model):
_inherit = "event.event.ticket"

max_registration_per_user_limit = fields.Integer(
string="Tickets limit per user",
help="maximum number of tickets that a single user can book for this event",
)
20 changes: 20 additions & 0 deletions event_limit_reg/views/event_registration_website_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="modal_ticket_registration" name="modal_ticket_registration" inherit_id="website_event.modal_ticket_registration">
<xpath expr="//t[@t-set='seats_max']" position="before">
<t t-set="seats_max_registration" t-value="(ticket.max_registration_per_user_limit or 9) + 1"/>
</xpath>

<xpath expr="//t[@t-set='seats_max']" position="attributes">
<attribute name="t-value">min(seats_max_ticket, seats_max_event,seats_max_registration)</attribute>
</xpath>

<xpath expr="//div[hasclass('o_wevent_registration_single_select')]//t[@t-set='seats_max']" position="before">
<t t-set="seats_max_registration" t-value="(tickets.max_registration_per_user_limit or 9) + 1"/>
</xpath>

<xpath expr="//div[hasclass('o_wevent_registration_single_select')]//t[@t-set='seats_max']" position="attributes">
<attribute name="t-value">min(seats_max_ticket, seats_max_event,seats_max_registration)</attribute>
</xpath>
</template>
</odoo>
15 changes: 15 additions & 0 deletions event_limit_reg/views/event_ticket_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="view_event_event_ticket_form_custom" model="ir.ui.view">
<field name="name">event.event.ticket.form.inherit.custom</field>
<field name="model">event.event.ticket</field>
<field name = "inherit_id" ref = "event.event_event_ticket_view_tree_from_event"/>
<field name = "arch" type = "xml">
<xpath expr="//list" position="inside">
<field name="max_registration_per_user_limit"/>
</xpath>
</field>
</record>

</odoo>
2 changes: 2 additions & 0 deletions new_product_type_kit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
22 changes: 22 additions & 0 deletions new_product_type_kit/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
'name': 'Dev Zero Stock Blockage',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name?

'version': '1.0',
'summary': 'Add a new prodcut type kit',
'description': """
Add kit-type products with configurable sub-products and conditional report visibility
""",
Comment on lines +5 to +7

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check indentation in codebase!

'author': 'Raghav Agiwal',
'depends': ['sale_management', 'stock', 'product'],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need stock here? Also only sale_management will work fine.

'data': [
'security/ir.model.access.csv',
'views/product_template_view.xml',
'views/sale_order_line_view.xml',
'views/kit_wizard_views.xml',
'views/portal_saleorder_templates.xml',
'report/report_saleorder_templates.xml',
'report/report_invoice_templates.xml',
],
'installable': True,
'application': True,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this module as an application!

'license': 'LGPL-3'
}
3 changes: 3 additions & 0 deletions new_product_type_kit/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import product_template
from . import sale_order
from . import sale_order_line
12 changes: 12 additions & 0 deletions new_product_type_kit/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import fields, models


class ProductTemplate(models.Model):
_inherit = 'product.template'

is_kit = fields.Boolean(string="Is Kit")
sub_product_ids = fields.Many2many(
'product.product',
string="Sub Products",
required=True,
)
10 changes: 10 additions & 0 deletions new_product_type_kit/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from odoo import fields, models


class SaleOrder(models.Model):
_inherit = 'sale.order'

print_in_report = fields.Boolean(
string="Print in report?",
default=False

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be False by default. This is used if we are going other way.

)
42 changes: 42 additions & 0 deletions new_product_type_kit/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from odoo import _, fields, models


class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'

is_kit = fields.Boolean(related="product_template_id.is_kit")
is_kit_component = fields.Boolean(string="Is Subproduct")
kit_parent_line_id = fields.Many2one('sale.order.line', string="Kit Parent Line", ondelete="cascade")
kit_unit_cost = fields.Float(string="Unit Price (Wizard)", default=0.0)

def action_open_kit_wizard(self):
return {
'name': 'Kit Components',
'type': 'ir.actions.act_window',
'res_model': 'kit.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
"active_id": self.order_id.id,
'default_product_id': self.product_id.id,
'default_sale_order_line_id': self.id,
}
}

def unlink(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is letting user delete sub products. Check functional flow.

# Identify sub-product lines
sub_products = self.filtered(lambda line: line.is_kit_component)

if sub_products and not self.env.context.get('allow_sub_product_deletion'):
if self == sub_products:
raise models.UserError(_("You cannot delete kit sub-products directly. Delete the main kit line instead."))
return (self - sub_products).unlink()

child_lines = self.env['sale.order.line'].search([
('kit_parent_line_id', 'in', self.ids)
])

if child_lines:
child_lines.with_context(allow_sub_product_deletion=True).unlink()

return super().unlink()
12 changes: 12 additions & 0 deletions new_product_type_kit/report/report_invoice_templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="report_invoice_document_inherit_kit" inherit_id="account.report_invoice_document">
<xpath expr="//table[@name='invoice_line_table']/tbody/t/tr" position="attributes">
<attribute name="t-if">
not any(line.sale_line_ids.mapped('kit_parent_line_id')) or
any(line.sale_line_ids.mapped('kit_parent_line_id') and
line.sale_line_ids.mapped('order_id.print_in_report'))
</attribute>
</xpath>
</template>
</odoo>
10 changes: 10 additions & 0 deletions new_product_type_kit/report/report_saleorder_templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="report_saleorder_document_inherit_kit" inherit_id="sale.report_saleorder_document">
<xpath expr="//tbody/t/tr" position="attributes">
<attribute name="t-if">
(not line.kit_parent_line_id) or (doc.print_in_report and line.kit_parent_line_id)
</attribute>
</xpath>
</template>
</odoo>
3 changes: 3 additions & 0 deletions new_product_type_kit/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_kit_wizard,access.kit.wizard,model_kit_wizard,,1,1,1,1
access_kit_wizard_line,access.kit.wizard.line,model_kit_wizard_line,,1,1,1,1
29 changes: 29 additions & 0 deletions new_product_type_kit/views/kit_wizard_views.xml

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be inside wizard folder.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_kit_wizard_form" model="ir.ui.view">
<field name="name">kit.wizard.form</field>
<field name="model">kit.wizard</field>
<field name="arch" type="xml">
<form string="Configure Kit" create="0">
<group>
<field name="product_id" readonly="1"/>
</group>

<group string="Sub Products">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use <sheet> instead of <group> here.

<field name="kit_line_ids" nolabel="1">
<list editable="bottom" create="0">
<field name="product_id" readonly="1" force_save="1"/>
<field name="quantity"/>
<field name="price"/>
</list>
</field>
</group>

<footer>
<button string="Confirm" type="object" name="action_confirm" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>
Loading