From 96879015169bc7f355202d1657f4cdf7f17dca52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 28 Sep 2024 18:06:42 +0200 Subject: [PATCH] Link stock moves with invoice lines only for the same quantity sign as the order line When invoice lines are created to correct invoices quantity, it should not be linked to stock moves because it comes from a stock move being cancelled. Closes #12972 (grafted from 20c538f39c871bacc0486b8506957229268f59cd) --HG-- branch : 6.0 --- modules/purchase/purchase.py | 14 +++++++++++--- modules/sale/sale.py | 11 +++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/modules/purchase/purchase.py b/modules/purchase/purchase.py index b9f1c5f337..be4462e1d5 100644 --- a/modules/purchase/purchase.py +++ b/modules/purchase/purchase.py @@ -1,6 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import datetime +import math from itertools import chain from decimal import Decimal @@ -32,6 +33,10 @@ from trytond.modules.product import price_digits, round_price from .exceptions import PurchaseQuotationError, PartyLocationError +def samesign(a, b): + return math.copysign(a, b) == a + + def get_shipments_returns(model_name): "Computes the returns or shipments" def method(self, name): @@ -1585,7 +1590,8 @@ class Line(sequence_ordered(), ModelSQL, ModelView): gettext('purchase' '.msg_purchase_missing_account_expense', purchase=self.purchase.rec_name)) - invoice_line.stock_moves = self._get_invoice_line_moves() + if samesign(self.quantity, invoice_line.quantity): + invoice_line.stock_moves = self._get_invoice_line_moves() return [invoice_line] def _get_invoice_not_line(self): @@ -1713,9 +1719,11 @@ class Line(sequence_ordered(), ModelSQL, ModelView): def _get_move_invoice_lines(self, move_type): 'Return the invoice lines that should be shipped' if self.purchase.invoice_method == 'order': - return [l for l in self.invoice_lines] + lines = self.invoice_lines else: - return [l for l in self.invoice_lines if not l.stock_moves] + lines = filter(lambda l: not l.stock_moves, self.invoice_lines) + return list(filter( + lambda l: samesign(self.quantity, l.quantity), lines)) def set_actual_quantity(self): pool = Pool() diff --git a/modules/sale/sale.py b/modules/sale/sale.py index a774c93166..e3750d0997 100644 --- a/modules/sale/sale.py +++ b/modules/sale/sale.py @@ -1,6 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import datetime +import math from decimal import Decimal from itertools import groupby, chain from functools import partial @@ -29,6 +30,10 @@ from .exceptions import ( SaleValidationError, SaleQuotationError, PartyLocationError) +def samesign(a, b): + return math.copysign(a, b) == a + + def get_shipments_returns(model_name): "Computes the returns or shipments" def method(self, name): @@ -1533,7 +1538,8 @@ class SaleLine(TaxableMixin, sequence_ordered(), ModelSQL, ModelView): raise AccountError( gettext('sale.msg_sale_missing_account_revenue', sale=self.sale.rec_name)) - invoice_line.stock_moves = self._get_invoice_line_moves() + if samesign(self.quantity, invoice_line.quantity): + invoice_line.stock_moves = self._get_invoice_line_moves() return [invoice_line] def _get_invoice_not_line(self): @@ -1685,7 +1691,8 @@ class SaleLine(TaxableMixin, sequence_ordered(), ModelSQL, ModelView): and invoice_line.invoice.state == 'paid'): if invoice_line.moved_quantity < invoice_line.quantity: invoice_lines.append(invoice_line) - return invoice_lines + return list(filter( + lambda l: samesign(self.quantity, l.quantity), invoice_lines)) def set_actual_quantity(self): pool = Pool()