diff --git a/modules/account_invoice/invoice_melya.fodt b/modules/account_invoice/invoice_melya.fodt index 4874d7b..5d1e1a5 100644 --- a/modules/account_invoice/invoice_melya.fodt +++ b/modules/account_invoice/invoice_melya.fodt @@ -1662,10 +1662,10 @@ - <pc['label']> + <pc['label']> - <format_currency(pc['amount'], invoice.party.lang, invoice.currency) if pc['amount'] is not None else ''> + <format_number(pc['amount'], invoice.party.lang) if pc['amount'] is not None else ''> diff --git a/modules/purchase_trade/sale.py b/modules/purchase_trade/sale.py index 3bf21e9..ba1fb5c 100755 --- a/modules/purchase_trade/sale.py +++ b/modules/purchase_trade/sale.py @@ -859,11 +859,27 @@ class Sale(metaclass=PoolMeta): currency_name = ( currency.rec_name.upper() if currency and currency.rec_name else '') - for composition in getattr(line, 'price_composition', []) or []: + compositions = list(getattr(line, 'price_composition', []) or []) + missing = [ + composition for composition in compositions + if getattr(composition, 'price', None) in (None, '')] + known_total = sum( + Decimal(str(getattr(composition, 'price', 0) or 0)) + for composition in compositions + if getattr(composition, 'price', None) not in (None, '')) + residual = None + if len(missing) == 1: + residual = ( + self._get_report_price_composition_line_amount(line) + - known_total) + for composition in compositions: component = getattr(composition, 'component', '') or '' price = getattr(composition, 'price', None) if price in (None, ''): - continue + if composition is missing[0] and residual is not None: + price = residual + else: + continue label = ' '.join( part for part in [ component, @@ -877,6 +893,18 @@ class Sale(metaclass=PoolMeta): }) return lines + @staticmethod + def _get_report_price_composition_line_amount(line): + amount = getattr(line, 'amount', None) + if amount not in (None, ''): + return Decimal(str(amount or 0)) + quantity = Decimal(str(getattr(line, 'quantity', 0) or 0)) + unit_price = Decimal(str(getattr(line, 'unit_price', 0) or 0)) + premium_getter = getattr(line, '_get_premium_price', None) + premium = premium_getter() if premium_getter else getattr( + line, 'premium', 0) + return quantity * (unit_price + Decimal(str(premium or 0))) + @property def report_trade_blocks(self): lines = self._get_report_lines() diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index 2b4f649..893ec1f 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -2600,9 +2600,10 @@ class PurchaseTradeTestCase(ModuleTestCase): line.linked_unit = None line.unit = Mock(rec_name='MT') line.unit_price = Decimal('2525') + line.amount = Decimal('62493.75') line.price_composition = [ Mock(component='FOB', price=Decimal('2500')), - Mock(component='FREIGHT', price=Decimal('25')), + Mock(component='FREIGHT', price=None), ] sale = Sale() @@ -2619,7 +2620,10 @@ class PurchaseTradeTestCase(ModuleTestCase): sale.report_price_composition_rows, [ {'label': 'FOB value in EUR', 'amount': Decimal('2500')}, - {'label': 'FREIGHT value in EUR', 'amount': Decimal('25')}, + { + 'label': 'FREIGHT value in EUR', + 'amount': Decimal('59993.75'), + }, ]) def test_invoice_report_rate_lines_prefers_sale_price_composition(self):