[IMP]pms: improvement autoupdate invoice from folio sale lines

This commit is contained in:
Darío Lodeiros
2023-01-22 12:22:38 +01:00
parent 3b524e1bfa
commit dd03dce28e

View File

@@ -11,6 +11,7 @@ from odoo import _, api, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.osv import expression from odoo.osv import expression
from odoo.tools import float_compare from odoo.tools import float_compare
from odoo.tools.float_utils import float_round
from odoo.tools.misc import get_lang from odoo.tools.misc import get_lang
@@ -947,7 +948,7 @@ class FolioSaleLine(models.Model):
""" """
return new or old return new or old
def _update_line_quantity(self, values): def _mens_update_line_quantity(self, values):
folios = self.mapped("folio_id") folios = self.mapped("folio_id")
for order in folios: for order in folios:
order_lines = self.filtered(lambda x: x.folio_id == order) order_lines = self.filtered(lambda x: x.folio_id == order)
@@ -977,27 +978,46 @@ class FolioSaleLine(models.Model):
fields_modified = self.env["ir.model.fields"].search( fields_modified = self.env["ir.model.fields"].search(
[("name", "in", protected_fields_modified_list), ("model", "=", self._name)] [("name", "in", protected_fields_modified_list), ("model", "=", self._name)]
) )
if fields_modified: if fields_modified or "product_uom_qty" in values:
if self.filtered( # If value is float, we need to round it to compare with the original value
lambda l: any( for field in fields_modified:
values.get(field.name) != getattr(l, field.name) if field.ttype in ["float", "monetary"] and field.name in values:
for field in fields_modified values[field.name] = float_round(
) values[field.name], precision_digits=2
) and (
"done" in self.mapped("folio_id.state")
or self.invoice_lines.filtered(
lambda l: l.move_id.state == "posted"
and l.move_id.move_type == "out_invoice"
and l.move_id.payment_state != "reversed"
)
):
raise UserError(
_(
"""It is forbidden to modify the following fields
in a locked folio (fields already invoiced):\n%s"""
) )
% "\n".join(fields_modified.mapped("field_description")) has_locked_folio = "done" in self.mapped(
) "folio_id.state"
) or self.invoice_lines.filtered(
lambda l: l.move_id.state == "posted"
and l.move_id.move_type == "out_invoice"
and l.move_id.payment_state != "reversed"
)
if has_locked_folio:
# We check that dont reduced the invoiced quantity in locked folios
if "product_uom_qty" in values and any(
line.qty_invoiced > values["product_uom_qty"] for line in self
):
raise UserError(
_(
"""You cannot reduce the invoiced quantity below
the quantity already invoiced."""
)
)
# We check that dont modified the protected fields in locked folios
if self.filtered(
lambda l: any(
values.get(field.name) != getattr(l, field.name)
for field in fields_modified
)
):
raise UserError(
_(
"""It is forbidden to modify the following fields
in a locked folio (fields already invoiced):\n%s"""
)
% "\n".join(fields_modified.mapped("field_description"))
)
# If has draft invoices, we need to update the invoice lines
if "draft" in self.mapped("invoice_lines.move_id.state"): if "draft" in self.mapped("invoice_lines.move_id.state"):
if "product_uom_qty" in values: if "product_uom_qty" in values:
for line in self: for line in self:
@@ -1009,8 +1029,6 @@ class FolioSaleLine(models.Model):
) )
) )
for line in self.filtered(lambda l: not l.display_type): for line in self.filtered(lambda l: not l.display_type):
if "product_uom_qty" in values:
line._update_line_quantity(values)
mapped_fields = self._get_mapped_move_line_fields() mapped_fields = self._get_mapped_move_line_fields()
move_line_vals = [ move_line_vals = [
( (
@@ -1022,9 +1040,15 @@ class FolioSaleLine(models.Model):
}, },
) )
] ]
# Add invoice line name in values to avoid
# overwriting the name by _move_autocomplete_invoice_lines_values
if not move_line_vals[0][2].get("name"):
move_line_vals[0][2]["name"] = line.name
line[0].invoice_lines.move_id.write( line[0].invoice_lines.move_id.write(
{"invoice_line_ids": move_line_vals} {"invoice_line_ids": move_line_vals}
) )
if "product_uom_qty" in values:
line._mens_update_line_quantity(values)
result = super(FolioSaleLine, self).write(values) result = super(FolioSaleLine, self).write(values)
return result return result
@@ -1067,28 +1091,15 @@ class FolioSaleLine(models.Model):
res["account_id"] = False res["account_id"] = False
return res return res
def _check_line_unlink(self): def unlink(self):
""" if self.invoice_lines:
Check wether a line can be deleted or not. raise UserError(
_(
Lines cannot be deleted if the folio is confirmed; downpayment "You cannot delete a sale order line once a "
lines who have not yet been invoiced bypass that exception. "invoice has been created from it."
:rtype: recordset folio.sale.line )
:returns: set of lines that cannot be deleted )
""" return super(FolioSaleLine, self).unlink()
return self.filtered(
lambda line: line.state not in ("draft")
and (line.invoice_lines or not line.is_downpayment)
)
# def unlink(self):
# if self._check_line_unlink():
# raise UserError(
# _("""You can not remove an sale line once the sales
# folio is confirmed.\n
# You should rather set the quantity to 0.""")
# )
# return super(FolioSaleLine, self).unlink()
def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id): def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id):
"""Retrieve the price before applying the pricelist """Retrieve the price before applying the pricelist