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')