Skip to content
Open
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
83 changes: 53 additions & 30 deletions purchase_work_acceptance/models/account_move.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Copyright 2019 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from collections import defaultdict

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare


class AccountMove(models.Model):
Expand All @@ -29,38 +32,52 @@ def _compute_require_wa(self):
)
rec.require_wa = self.wa_id and enforce_wa

def _aggregate_qty_by_product(self, lines, qty_field, uom_field):
"""Aggregate quantities by product, converted to the product's base UoM."""
result = defaultdict(float)
for line in lines:
uom = getattr(line, uom_field)
qty = uom._compute_quantity(
getattr(line, qty_field), line.product_id.uom_id
)
if qty > 0.0:
result[line.product_id.id] += qty
return dict(result)

def _check_quantity_wa(self):
self.ensure_one()
precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
wa_qty = self._aggregate_qty_by_product(
self.wa_id.wa_line_ids, "product_qty", "product_uom"
)
invoice_qty = self._aggregate_qty_by_product(
self.invoice_line_ids.filtered(lambda line: line.control_wa),
"quantity",
"product_uom_id",
)
all_products = set(wa_qty.keys()) | set(invoice_qty.keys())
for product_id in all_products:
wa = wa_qty.get(product_id, 0.0)
inv = invoice_qty.get(product_id, 0.0)
if float_compare(wa, inv, precision_digits=precision) != 0:
product = self.env["product.product"].browse(product_id)
raise ValidationError(
_(
"Quantity mismatch for product '%(product)s': "
"WA quantity = %(wa_qty)s, Invoice quantity = %(inv_qty)s",
product=product.display_name,
wa_qty=wa,
inv_qty=inv,
)
)

def action_post(self):
for rec in self:
if rec.wa_id:
wa_line = {}
for line in rec.wa_id.wa_line_ids:
qty = line.product_uom._compute_quantity(
line.product_qty, line.product_id.uom_id
)
if qty > 0.0:
if line.product_id.id in wa_line.keys():
qty_old = wa_line[line.product_id.id]
wa_line[line.product_id.id] = qty_old + qty
else:
wa_line[line.product_id.id] = qty
invoice_line = {}
for line in rec.invoice_line_ids:
qty = line.product_uom_id._compute_quantity(
line.quantity, line.product_id.uom_id
)
if qty > 0.0:
if line.product_id.id in invoice_line.keys():
qty_old = invoice_line[line.product_id.id]
invoice_line[line.product_id.id] = qty_old + qty
else:
invoice_line[line.product_id.id] = qty
if wa_line != invoice_line:
raise ValidationError(
_(
"You cannot validate a bill if Quantity not equal "
"accepted quantity"
)
)
if not rec.wa_id:
continue
rec._check_quantity_wa()
return super().action_post()

@api.model
Expand All @@ -71,3 +88,9 @@ def create(self, vals):
lines = filter(lambda l: len(l) == 3 and l[2].get("quantity") != 0, lines)
vals["invoice_line_ids"] = list(lines)
return super().create(vals)


class AccountMoveLine(models.Model):
_inherit = "account.move.line"

control_wa = fields.Boolean(default=True, copy=False)
21 changes: 21 additions & 0 deletions purchase_work_acceptance/views/account_move_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@
attrs="{'required': [('require_wa','=', True)], 'invisible': [('wa_id', '=', False)]}"
/>
</group>
<xpath expr="//field[@name='invoice_line_ids']/tree" position="inside">
<field name="control_wa" optional="hide" />
</xpath>
<xpath
expr="//field[@name='invoice_line_ids']/form/sheet/group"
position="inside"
>
<field name="control_wa" />
</xpath>
<xpath
expr="//page/field[@name='line_ids']/tree/field[@name='tax_ids']"
position="after"
>
<field name="control_wa" optional="hide" />
</xpath>
<xpath
expr="//page/field[@name='line_ids']/form//field[@name='tax_ids']"
position="after"
>
<field name="control_wa" />
</xpath>
</field>
</record>
</odoo>
Loading