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