From baf64e03bc374009a4eafaa9d6ba1db4fd690dc4 Mon Sep 17 00:00:00 2001 From: qni Date: Tue, 20 Aug 2019 13:40:40 +0000 Subject: [PATCH] [IMP] sale: reflect down payment changes in the SO Allow users to modify a down payment invoice's properly by reflecting the change done to the invoice (e.g. taxes, amount) on the initial downpayment SO line when the invoice is posted. This support several nice flows, such a allowing (partial and full) refunds of downpayments while preserving still a meaningful 'last invoice with deducted down payments' amount that sums up to the total of the order. Note that this does not apply to locked orders (by definition of the term 'locked'). closes odoo/odoo#35982 Signed-off-by: Damien Bouvy (dbo) --- addons/sale/models/account_move.py | 19 +++++++++++++++++++ addons/sale/models/sale.py | 9 ++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/addons/sale/models/account_move.py b/addons/sale/models/account_move.py index ce4a1d411ef..0e20b8f4c82 100644 --- a/addons/sale/models/account_move.py +++ b/addons/sale/models/account_move.py @@ -6,6 +6,25 @@ from odoo.exceptions import UserError from odoo.tools import float_compare, float_is_zero +class AccountMove(models.Model): + _inherit = 'account.move' + + def action_post(self): + #inherit of the function from account.move to validate a new tax and the priceunit of a downpayment + res = super(AccountMove, self).action_post() + line_ids = self.mapped('line_ids').filtered(lambda line: line.sale_line_ids.is_downpayment) + for line in line_ids: + try: + line.sale_line_ids.tax_id = line.tax_ids + #To keep positive amount on the sale order and to have the right price for the invoice + #We need the - before our untaxed_amount_to_invoice + line.sale_line_ids.price_unit = -line.sale_line_ids.untaxed_amount_to_invoice + except UserError: + # a UserError here means the SO was locked, which prevents changing the taxes + # just ignore the error - this is a nice to have feature and should not be blocking + pass + return res + class AccountMoveLine(models.Model): _inherit = 'account.move.line' diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index a5b2988202c..d47d9f8f732 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -983,6 +983,8 @@ class SaleOrderLine(models.Model): for line in self: if line.state not in ('sale', 'done'): line.invoice_status = 'no' + elif line.is_downpayment and line.untaxed_amount_to_invoice == 0: + line.invoice_status = 'invoiced' elif not float_is_zero(line.qty_to_invoice, precision_digits=precision): line.invoice_status = 'to invoice' elif line.state == 'sale' and line.product_id.invoice_policy == 'order' and\ @@ -1030,7 +1032,7 @@ class SaleOrderLine(models.Model): else: line.qty_to_invoice = 0 - @api.depends('invoice_lines.move_id.state', 'invoice_lines.quantity') + @api.depends('invoice_lines.move_id.state', 'invoice_lines.quantity', 'untaxed_amount_to_invoice') def _get_invoice_qty(self): """ Compute the quantity invoiced. If case of a refund, the quantity invoiced is decreased. Note @@ -1044,8 +1046,9 @@ class SaleOrderLine(models.Model): if invoice_line.move_id.state != 'cancel': if invoice_line.move_id.type == 'out_invoice': qty_invoiced += invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, line.product_uom) - elif invoice_line.move_id.type == 'out_refund': - qty_invoiced -= invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, line.product_uom) + elif invoice_line.move_id.type == 'out_refund' : + if not line.is_downpayment or line.untaxed_amount_to_invoice == 0 : + qty_invoiced -= invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, line.product_uom) line.qty_invoiced = qty_invoiced @api.depends('price_unit', 'discount')