From a4a655b05ea1526a310cbc9e93cf6f29fb297011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 30 May 2025 21:35:55 +0200 Subject: [PATCH] Use explicit key when computing taxes and object instead of dict This defines explicitly the available attribute and unify the use the values as tax line instead of the keys. --- modules/account/tax.py | 94 ++++++++++--------- modules/account/tests/test_module.py | 80 ++++++++-------- modules/account/view/tax_test_result_list.xml | 2 - modules/account_invoice/invoice.py | 58 +++++++----- modules/account_tax_non_deductible/account.py | 6 +- modules/purchase/purchase.py | 3 +- modules/sale/sale.py | 3 +- modules/sale_point/sale.py | 37 ++++---- modules/sale_shipment_cost/sale.py | 4 +- modules/web_shop_vue_storefront/sale.py | 3 +- 10 files changed, 147 insertions(+), 143 deletions(-) diff --git a/modules/account/tax.py b/modules/account/tax.py index a7f8ab6b40..f016eed00c 100644 --- a/modules/account/tax.py +++ b/modules/account/tax.py @@ -1,5 +1,6 @@ # 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 copy import datetime from collections import defaultdict, namedtuple from decimal import Decimal @@ -1173,21 +1174,37 @@ class Tax(sequence_ordered(), ModelSQL, ModelView, DeactivableMixin): cls.save(to_save) -class _TaxKey(dict): +class _TaxLine: + __slots__ = ('base', 'amount', 'tax', 'account') def __init__(self, **kwargs): - self.update(kwargs) + for k, v in kwargs.items(): + setattr(self, k, v) + def values(self): + for k in self.__slots__: + yield k, getattr(self, k) + + @property def _key(self): - return (self['account'], self['tax'], self['base'] >= 0) + return (self.account, self.tax, self.base >= 0) - def __eq__(self, other): - if isinstance(other, _TaxKey): - return self._key() == other._key() - return self._key() == other + def __add__(self, other): + if (not isinstance(other, _TaxLine) + or self._key != other._key): + return NotImplemented + new = copy.copy(self) + for key in ['base', 'amount']: + setattr(new, key, getattr(self, key) + getattr(other, key)) + return new - def __hash__(self): - return hash(self._key()) + def __iadd__(self, other): + if (not isinstance(other, _TaxLine) + or self._key != other._key): + return NotImplemented + for key in ['base', 'amount']: + setattr(self, key, getattr(self, key) + getattr(other, key)) + return self class _TaxableLine(namedtuple( @@ -1223,23 +1240,21 @@ class TaxableMixin(object): def _get_tax_context(self): return {} - @staticmethod - def _compute_tax_line(amount, base, tax): + def _compute_tax_line(self, amount, base, tax): if base >= 0: type_ = 'invoice' else: type_ = 'credit_note' - - line = {} - line['manual'] = False - line['description'] = tax.description - line['legal_notice'] = tax.legal_notice - line['base'] = base - line['amount'] = amount - line['tax'] = tax.id - line['account'] = getattr(tax, '%s_account' % type_).id - - return _TaxKey(**line) + # Base must always be rounded per line as there will be + # one tax line per taxable_lines + if self.currency: + base = self.currency.round(base) + return _TaxLine( + base=base, + amount=amount, + tax=tax, + account=getattr(tax, '%s_account' % type_), + ) def _round_taxes(self, taxes): if not self.currency: @@ -1247,9 +1262,9 @@ class TaxableMixin(object): remainder = 0 for taxline in taxes.values(): - rounded_amount = self.currency.round(taxline['amount']) - remainder += rounded_amount - taxline['amount'] - taxline['amount'] = rounded_amount + rounded_amount = self.currency.round(taxline.amount) + remainder += rounded_amount - taxline.amount + taxline.amount = rounded_amount # We need to compensate the rounding we did remainder = self.currency.round(remainder, opposite=True) @@ -1257,8 +1272,8 @@ class TaxableMixin(object): offset_amount = self.currency.rounding.copy_sign(remainder) for tax in cycle(taxes.values()): - if tax['amount']: - tax['amount'] -= offset_amount + if tax.amount: + tax.amount -= offset_amount remainder -= offset_amount if abs(remainder) < self.currency.rounding: break @@ -1291,33 +1306,25 @@ class TaxableMixin(object): current_taxes = {} for tax in l_taxes: taxline = self._compute_tax_line(**tax) - # Base must always be rounded per line as there will be - # one tax line per taxable_lines - if self.currency: - taxline['base'] = self.currency.round( - taxline['base']) + key = taxline._key if taxline not in current_taxes: - current_taxes[taxline] = taxline + current_taxes[key] = taxline else: - current_taxes[taxline]['base'] += taxline['base'] - current_taxes[taxline]['amount'] += ( - taxline['amount']) + current_taxes[key] += taxline if tax_rounding == 'line': self._round_taxes(current_taxes) for key, taxline in current_taxes.items(): if key not in taxes: taxes[key] = taxline else: - taxes[key]['base'] += taxline['base'] - taxes[key]['amount'] += taxline['amount'] + taxes[key] += taxline if tax_rounding == 'document': self._round_taxes(taxes) for key, taxline in taxes.items(): if key not in all_taxes: all_taxes[key] = taxline else: - all_taxes[key]['base'] += taxline['base'] - all_taxes[key]['amount'] += taxline['amount'] + all_taxes[key] += taxline return all_taxes @@ -1919,17 +1926,14 @@ class TestTaxView(ModelView, TaxableMixin): Result = pool.get('account.tax.test.result') result = [] if all([self.tax_date, self.unit_price, self.quantity, self.currency]): - for taxline in self._get_taxes(): - del taxline['manual'] - result.append(Result(**taxline)) + for taxline in self._get_taxes().values(): + result.append(Result(**dict(taxline.values()))) return result class TestTaxViewResult(ModelView): __name__ = 'account.tax.test.result' tax = fields.Many2One('account.tax', "Tax") - description = fields.Char("Description") - legal_notice = fields.Char("Legal Notice") account = fields.Many2One('account.account', "Account") base = fields.Numeric("Base") amount = fields.Numeric("Amount") diff --git a/modules/account/tests/test_module.py b/modules/account/tests/test_module.py index d76b394866..a6c194e251 100644 --- a/modules/account/tests/test_module.py +++ b/modules/account/tests/test_module.py @@ -1257,11 +1257,11 @@ class AccountTestCase( ] * 100, company=company) - taxes = taxable._get_taxes() + taxes = taxable._get_taxes().values() tax, = taxes - self.assertEqual(tax['base'], Decimal('100.00')) - self.assertEqual(tax['amount'], Decimal('20.00')) + self.assertEqual(tax.base, Decimal('100.00')) + self.assertEqual(tax.amount, Decimal('20.00')) @with_transaction() def test_taxable_mixin_line2(self): @@ -1289,11 +1289,11 @@ class AccountTestCase( ], company=company) - taxes = taxable._get_taxes() + taxes = taxable._get_taxes().values() tax, = taxes - self.assertEqual(tax['base'], Decimal('2.07')) - self.assertEqual(tax['amount'], Decimal('2.07')) + self.assertEqual(tax.base, Decimal('2.07')) + self.assertEqual(tax.amount, Decimal('2.07')) @with_transaction() def test_taxable_mixin_document(self): @@ -1318,11 +1318,11 @@ class AccountTestCase( ] * 100, company=company) - taxes = taxable._get_taxes() + taxes = taxable._get_taxes().values() tax, = taxes - self.assertEqual(tax['base'], Decimal('100.00')) - self.assertEqual(tax['amount'], Decimal('20.02')) + self.assertEqual(tax.base, Decimal('100.00')) + self.assertEqual(tax.amount, Decimal('20.02')) @with_transaction() def test_taxable_mixin_many_taxable_lines(self): @@ -1345,15 +1345,15 @@ class AccountTestCase( ], company=company) - taxes = taxable._get_taxes() + taxes = taxable._get_taxes().values() self.assertEqual(len(taxes), 2) - tax_line1, = [t for t in taxes if t['tax'] == tax1.id] - tax_line2, = [t for t in taxes if t['tax'] == tax2.id] - self.assertEqual(tax_line1['base'], Decimal('30.00')) - self.assertEqual(tax_line1['amount'], Decimal('3.00')) - self.assertEqual(tax_line2['base'], Decimal('20.00')) - self.assertEqual(tax_line2['amount'], Decimal('4.00')) + tax_line1, = [t for t in taxes if t.tax == tax1] + tax_line2, = [t for t in taxes if t.tax == tax2] + self.assertEqual(tax_line1.base, Decimal('30.00')) + self.assertEqual(tax_line1.amount, Decimal('3.00')) + self.assertEqual(tax_line2.base, Decimal('20.00')) + self.assertEqual(tax_line2.amount, Decimal('4.00')) @with_transaction() def test_taxable_mixin_tax_residual_rounding(self): @@ -1398,11 +1398,11 @@ class AccountTestCase( ], company=company) - taxline_1, taxline_2 = taxable._get_taxes() - self.assertEqual(taxline_1['base'], Decimal('1.04')) - self.assertEqual(taxline_1['amount'], Decimal('.11')) - self.assertEqual(taxline_2['base'], Decimal('1.04')) - self.assertEqual(taxline_2['amount'], Decimal('.10')) + taxline_1, taxline_2 = taxable._get_taxes().values() + self.assertEqual(taxline_1.base, Decimal('1.04')) + self.assertEqual(taxline_1.amount, Decimal('.11')) + self.assertEqual(taxline_2.base, Decimal('1.04')) + self.assertEqual(taxline_2.amount, Decimal('.10')) @with_transaction() def test_taxable_mixin_tax_residual_rounding_with_0(self): @@ -1454,13 +1454,13 @@ class AccountTestCase( ], company=company) - taxline_0, taxline_1, taxline_2 = taxable._get_taxes() - self.assertEqual(taxline_0['base'], Decimal('1.04')) - self.assertEqual(taxline_0['amount'], Decimal('0')) - self.assertEqual(taxline_1['base'], Decimal('1.04')) - self.assertEqual(taxline_1['amount'], Decimal('.11')) - self.assertEqual(taxline_2['base'], Decimal('1.04')) - self.assertEqual(taxline_2['amount'], Decimal('.10')) + taxline_0, taxline_1, taxline_2 = taxable._get_taxes().values() + self.assertEqual(taxline_0.base, Decimal('1.04')) + self.assertEqual(taxline_0.amount, Decimal('0')) + self.assertEqual(taxline_1.base, Decimal('1.04')) + self.assertEqual(taxline_1.amount, Decimal('.11')) + self.assertEqual(taxline_2.base, Decimal('1.04')) + self.assertEqual(taxline_2.amount, Decimal('.10')) @with_transaction() def test_taxable_mixin_tax_residual_rounding_negative_residual(self): @@ -1507,13 +1507,13 @@ class AccountTestCase( ], company=company) - taxline_1, taxline_2, taxline_3 = taxable._get_taxes() - self.assertEqual(taxline_1['base'], Decimal('30.00')) - self.assertEqual(taxline_1['amount'], Decimal('3.00')) - self.assertEqual(taxline_2['base'], Decimal('-2.95')) - self.assertEqual(taxline_2['amount'], Decimal('-0.29')) - self.assertEqual(taxline_3['base'], Decimal('-2.95')) - self.assertEqual(taxline_3['amount'], Decimal('-0.30')) + taxline_1, taxline_2, taxline_3 = taxable._get_taxes().values() + self.assertEqual(taxline_1.base, Decimal('30.00')) + self.assertEqual(taxline_1.amount, Decimal('3.00')) + self.assertEqual(taxline_2.base, Decimal('-2.95')) + self.assertEqual(taxline_2.amount, Decimal('-0.29')) + self.assertEqual(taxline_3.base, Decimal('-2.95')) + self.assertEqual(taxline_3.amount, Decimal('-0.30')) @with_transaction() def test_taxable_mixin_tax_residual_rounding_per_same_taxes(self): @@ -1553,11 +1553,11 @@ class AccountTestCase( ], company=company) - taxline_1, taxline_2 = taxable._get_taxes() - self.assertEqual(taxline_1['base'], Decimal('11.72')) - self.assertEqual(taxline_1['amount'], Decimal('0.7')) - self.assertEqual(taxline_2['base'], Decimal('-0.45')) - self.assertEqual(taxline_2['amount'], Decimal('-0.03')) + taxline_1, taxline_2 = taxable._get_taxes().values() + self.assertEqual(taxline_1.base, Decimal('11.72')) + self.assertEqual(taxline_1.amount, Decimal('0.7')) + self.assertEqual(taxline_2.base, Decimal('-0.45')) + self.assertEqual(taxline_2.amount, Decimal('-0.03')) @with_transaction() def test_tax_compute_with_children_update_unit_price(self): diff --git a/modules/account/view/tax_test_result_list.xml b/modules/account/view/tax_test_result_list.xml index dd4c524480..d4108c2e46 100644 --- a/modules/account/view/tax_test_result_list.xml +++ b/modules/account/view/tax_test_result_list.xml @@ -6,6 +6,4 @@ this repository contains the full copyright notices and license terms. --> - - diff --git a/modules/account_invoice/invoice.py b/modules/account_invoice/invoice.py index 185d74acb3..f4f549e7d3 100644 --- a/modules/account_invoice/invoice.py +++ b/modules/account_invoice/invoice.py @@ -649,13 +649,14 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): self.untaxed_amount = Decimal(0) self.tax_amount = Decimal(0) self.total_amount = Decimal(0) - computed_taxes = {} if self.lines: for line in self.lines: if getattr(line, 'type', '') == 'line': self.untaxed_amount += getattr(line, 'amount', 0) or 0 computed_taxes = self._get_taxes() + else: + computed_taxes = {} def is_zero(amount): if self.currency: @@ -663,7 +664,7 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): else: return amount == Decimal(0) - tax_keys = [] + tax_keys = set() taxes = list(self.taxes or []) for tax in (self.taxes or []): if tax.manual: @@ -673,20 +674,24 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): if (key not in computed_taxes) or (key in tax_keys): taxes.remove(tax) continue - tax_keys.append(key) - if not is_zero(computed_taxes[key]['base'] - - (tax.base or Decimal(0))): - self.tax_amount += computed_taxes[key]['amount'] - tax.amount = computed_taxes[key]['amount'] - tax.base = computed_taxes[key]['base'] + tax_keys.add(key) + if not is_zero( + computed_taxes[key].base - (tax.base or Decimal(0))): + self.tax_amount += computed_taxes[key].amount + tax.amount = computed_taxes[key].amount + tax.base = computed_taxes[key].base else: self.tax_amount += tax.amount or Decimal(0) for key in computed_taxes: if key not in tax_keys: - self.tax_amount += computed_taxes[key]['amount'] + tax = computed_taxes[key].tax + self.tax_amount += computed_taxes[key].amount value = InvoiceTax.default_get( list(InvoiceTax._fields.keys()), with_rec_name=False) - value.update(computed_taxes[key]) + value.update(computed_taxes[key].values()) + value['manual'] = False + value['description'] = tax.description + value['legal_notice'] = tax.legal_notice invoice_tax = InvoiceTax(**value) if invoice_tax.tax: invoice_tax.sequence = invoice_tax.tax.sequence @@ -1080,10 +1085,13 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): return context def _compute_taxes(self): - taxes = self._get_taxes() - for tax in taxes.values(): - tax['invoice'] = self.id - return taxes + for key, tax_line in self._get_taxes().items(): + value = dict(tax_line.values()) + value['invoice'] = self.id + value['manual'] = False + value['description'] = tax_line.tax.description + value['legal_notice'] = tax_line.tax.legal_notice + yield key, value @dualmethod def update_taxes(cls, invoices, exception=False): @@ -1094,11 +1102,11 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): for invoice in invoices: if invoice.state in ('posted', 'paid', 'cancelled'): continue - computed_taxes = invoice._compute_taxes() + computed_taxes = dict(invoice._compute_taxes()) if not invoice.taxes: to_create.extend(computed_taxes.values()) else: - tax_keys = [] + tax_keys = set() for tax in invoice.taxes: if tax.manual: continue @@ -1106,7 +1114,7 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): if (key not in computed_taxes) or (key in tax_keys): to_delete.append(tax) continue - tax_keys.append(key) + tax_keys.add(key) if not invoice.currency.is_zero( computed_taxes[key]['base'] - tax.base): to_write.extend(([tax], computed_taxes[key])) @@ -1114,6 +1122,7 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): if key not in tax_keys: to_create.append(computed_taxes[key]) if exception and (to_create or to_delete or to_write): + raise Exception(invoice.taxes, to_create, to_delete, to_write) raise InvoiceTaxValidationError( gettext('account_invoice.msg_invoice_tax_invalid', invoice=invoice.rec_name)) @@ -2520,7 +2529,7 @@ class InvoiceLine(sequence_ordered(), ModelSQL, ModelView, TaxableMixin): and self.taxes_deductible_rate != 1): with Transaction().set_context(_deductible_rate=1): tax_amount = sum( - t['amount'] for t in self._get_taxes().values()) + t.amount for t in self._get_taxes().values()) non_deductible_amount = ( tax_amount * (1 - self.taxes_deductible_rate)) amount += non_deductible_amount @@ -2603,7 +2612,7 @@ class InvoiceLine(sequence_ordered(), ModelSQL, ModelView, TaxableMixin): def get_invoice_taxes(self, name): if not self.invoice: return - taxes_keys = list(self._get_taxes().keys()) + taxes_keys = self._get_taxes().keys() taxes = [] for tax in self.invoice.taxes: if tax.manual: @@ -2831,7 +2840,7 @@ class InvoiceLine(sequence_ordered(), ModelSQL, ModelView, TaxableMixin): return tax_lines taxes = self._get_taxes().values() for tax in taxes: - amount = tax['base'] + amount = tax.base with Transaction().set_context( date=self.invoice.currency_date): amount = Currency.compute( @@ -2840,7 +2849,7 @@ class InvoiceLine(sequence_ordered(), ModelSQL, ModelView, TaxableMixin): tax_line = TaxLine() tax_line.amount = amount tax_line.type = 'base' - tax_line.tax = tax['tax'] + tax_line.tax = tax.tax tax_lines.append(tax_line) return tax_lines @@ -3093,11 +3102,8 @@ class InvoiceTax(sequence_ordered(), ModelSQL, ModelView): @property def _key(self): - # Same as _TaxKey - tax_id = self.tax.id if getattr(self, 'tax', None) else -1 - account_id = ( - self.account.id if getattr(self, 'account', None) else None) - return (account_id, tax_id, (getattr(self, 'base', 0) or 0) >= 0) + # Same as _TaxLine + return (self.account, self.tax, (getattr(self, 'base', 0) or 0) >= 0) @classmethod def check_modification(cls, mode, taxes, values=None, external=False): diff --git a/modules/account_tax_non_deductible/account.py b/modules/account_tax_non_deductible/account.py index 376514ac50..e25f4217eb 100644 --- a/modules/account_tax_non_deductible/account.py +++ b/modules/account_tax_non_deductible/account.py @@ -48,7 +48,7 @@ class InvoiceLine(metaclass=PoolMeta): with Transaction().set_context( _non_deductible=True, _deductible_rate=1): tax_amount = sum( - t['amount'] for t in self._get_taxes().values()) + t.amount for t in self._get_taxes().values()) amount += tax_amount return amount @@ -87,7 +87,7 @@ class InvoiceLine(metaclass=PoolMeta): taxes = self._get_taxes().values() for tax in taxes: for type_, amount in [('base', 'base'), ('tax', 'amount')]: - amount = tax[amount] + amount = getattr(tax, amount) with Transaction().set_context( date=self.invoice.currency_date): amount = Currency.compute( @@ -96,6 +96,6 @@ class InvoiceLine(metaclass=PoolMeta): tax_line = TaxLine() tax_line.amount = amount tax_line.type = type_ - tax_line.tax = tax['tax'] + tax_line.tax = tax.tax tax_lines.append(tax_line) return tax_lines diff --git a/modules/purchase/purchase.py b/modules/purchase/purchase.py index 2fdabd99b0..0d4889daa8 100644 --- a/modules/purchase/purchase.py +++ b/modules/purchase/purchase.py @@ -527,8 +527,7 @@ class Purchase( @fields.depends(methods=['_get_taxes']) def get_tax_amount(self): - taxes = iter(self._get_taxes().values()) - return sum((tax['amount'] for tax in taxes), Decimal(0)) + return sum((t.amount for t in self._get_taxes().values()), Decimal(0)) @classmethod def get_amount(cls, purchases, names): diff --git a/modules/sale/sale.py b/modules/sale/sale.py index d59961cbf0..780c1f14bb 100644 --- a/modules/sale/sale.py +++ b/modules/sale/sale.py @@ -647,8 +647,7 @@ class Sale( @fields.depends(methods=['_get_taxes']) def get_tax_amount(self): - return sum( - (v['amount'] for v in self._get_taxes().values()), Decimal(0)) + return sum((t.amount for t in self._get_taxes().values()), Decimal(0)) @classmethod def get_amount(cls, sales, names): diff --git a/modules/sale_point/sale.py b/modules/sale_point/sale.py index 14be9265e8..93a9486c9e 100644 --- a/modules/sale_point/sale.py +++ b/modules/sale_point/sale.py @@ -399,46 +399,45 @@ class POSSale(Workflow, ModelSQL, ModelView, TaxableMixin): TaxLine = pool.get('account.tax.line') lines = [] - taxes = self._get_taxes() + taxes = self._get_taxes().values() # Distribute rounding error from tax computation - tax_amount = sum(t['amount'] for t in taxes) + tax_amount = sum(t.amount for t in taxes) difference = self.total_tax - tax_amount if difference: remaining = difference for tax in taxes: - if tax['amount']: + if tax.amount: if tax_amount: - ratio = tax['amount'] / tax_amount + ratio = tax.amount / tax_amount else: ratio = 1 / len(taxes) value = self.currency.round(difference * ratio) - tax['amount'] += value + tax.amount += value remaining -= value # Add remaining rounding error to the first tax if remaining: for tax in taxes: - if tax['amount']: - tax['amount'] += remaining + if tax.amount: + tax.amount += remaining break for tax in taxes: - amount = tax['amount'] + amount = tax.amount if not amount: continue line = Line() - line.description = tax['description'] + line.description = tax.tax.description if amount >= 0: line.debit, line.credit = Decimal(0), amount else: line.debit, line.credit = -amount, 0 - line.account = tax['account'] - if tax['tax']: - tax_line = TaxLine() - tax_line.amount = amount - tax_line.type = 'tax' - tax_line.tax = tax['tax'] - line.tax_lines = [tax_line] + line.account = tax.account + tax_line = TaxLine() + tax_line.amount = amount + tax_line.type = 'tax' + tax_line.tax = tax.tax + line.tax_lines = [tax_line] lines.append(line) return lines @@ -691,11 +690,11 @@ class POSSaleLine(ModelSQL, ModelView, TaxableMixin): line.origin = self tax_lines = [] - for tax in self._get_taxes(): + for tax in self._get_taxes().values(): tax_line = TaxLine() - tax_line.amount = tax['base'] + tax_line.amount = tax.base tax_line.type = 'base' - tax_line.tax = tax['tax'] + tax_line.tax = tax.tax tax_lines.append(tax_line) line.tax_lines = tax_lines return [line] diff --git a/modules/sale_shipment_cost/sale.py b/modules/sale_shipment_cost/sale.py index 17db34e95d..c064acbe4b 100644 --- a/modules/sale_shipment_cost/sale.py +++ b/modules/sale_shipment_cost/sale.py @@ -517,7 +517,7 @@ class Promotion(metaclass=PoolMeta): l.amount for l in sale.lines if l.shipment_cost is not None) if not self.untaxed_amount: amount -= sum( - v['amount'] + t.amount for l in sale.lines if l.shipment_cost is not None - for v in l._get_taxes().values()) + for t in l._get_taxes().values()) return amount diff --git a/modules/web_shop_vue_storefront/sale.py b/modules/web_shop_vue_storefront/sale.py index 75240bc987..227e5ba962 100644 --- a/modules/web_shop_vue_storefront/sale.py +++ b/modules/web_shop_vue_storefront/sale.py @@ -179,8 +179,7 @@ class Line(metaclass=PoolMeta): @property def vsf_tax_amount(self): - return sum( - (v['amount'] for v in self._get_taxes().values()), Decimal(0)) + return sum((t.amount for t in self._get_taxes().values()), Decimal(0)) def get_vsf_user_order_history(self): amount_incl_tax = self.amount + self.vsf_tax_amount