diff --git a/addons/sale_stock/models/stock.py b/addons/sale_stock/models/stock.py index 3fd60679493..c4a8e7487ea 100644 --- a/addons/sale_stock/models/stock.py +++ b/addons/sale_stock/models/stock.py @@ -76,7 +76,7 @@ class StockRule(models.Model): def _get_custom_move_fields(self): fields = super(StockRule, self)._get_custom_move_fields() - fields += ['sale_line_id', 'partner_id', 'sequence'] + fields += ['sale_line_id', 'partner_id', 'sequence', 'to_refund'] return fields diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index cc367019650..6a20a91314c 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -6,6 +6,7 @@ from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_c from odoo.addons.sale.tests.common import TestSaleCommon from odoo.exceptions import UserError from odoo.tests import Form, tagged +from odoo import Command @tagged('post_install', '-at_install') @@ -1720,3 +1721,32 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): self.assertEqual(out1.move_line_ids.quantity, 3) self.assertEqual(out2.state, 'assigned') self.assertEqual(out2.move_line_ids.quantity, 1) + + def test_delivery_on_negative_delivered_qty(self): + """ + Tests that returns created from SO lines with negative quantities update the delivered + quantities negatively so that they appear on the corresponding invoice. + """ + product = self.env['product.product'].create({ + 'name': 'Super product', + 'uom_id': self.env.ref('uom.product_uom_unit').id, + 'lst_price': 100.0, + 'detailed_type': 'product', + 'invoice_policy': 'delivery', + }) + sale_order = self.env['sale.order'].create({ + 'partner_id': self.partner_a.id, + 'state': 'draft', + 'order_line':[Command.create({ + 'product_id': product.id, + 'product_uom_qty': -1, + })], + }) + sale_order.action_confirm() + self.assertEqual(sale_order.order_line.qty_delivered, 0.0) + self.assertEqual(sale_order.order_line.qty_to_invoice, 0.0) + picking = self.env['stock.move'].browse(self.env['stock.move'].search([('sale_line_id', '=', sale_order.order_line.id)]).id).picking_id + picking.action_confirm() + picking.button_validate() + self.assertEqual(sale_order.order_line.qty_delivered, -1.0) + self.assertEqual(sale_order.order_line.qty_to_invoice, -1.0) diff --git a/addons/stock/models/stock_rule.py b/addons/stock/models/stock_rule.py index 27ce620f9b5..0d5f58c0ad0 100644 --- a/addons/stock/models/stock_rule.py +++ b/addons/stock/models/stock_rule.py @@ -322,6 +322,10 @@ class StockRule(models.Model): partner = partners move_dest.partner_id = self.location_src_id.warehouse_id.partner_id or self.company_id.partner_id + # If the quantity is negative the move should be considered as a refund + if float_compare(product_qty, 0.0, precision_rounding=product_uom.rounding) < 0: + values['to_refund'] = True + move_values = { 'name': name[:2000], 'company_id': self.company_id.id or self.location_src_id.company_id.id or self.location_dest_id.company_id.id or company_id.id,