diff --git a/modules/purchase_trade/__init__.py b/modules/purchase_trade/__init__.py index 0919bda..d3bae59 100755 --- a/modules/purchase_trade/__init__.py +++ b/modules/purchase_trade/__init__.py @@ -4,6 +4,7 @@ from trytond.pool import Pool from . import ( + account, purchase, sale, global_reporting, @@ -30,10 +31,10 @@ from . import ( valuation, dimension, weight_report, - backtoback, - service, - invoice, -) + backtoback, + service, + invoice, +) def register(): Pool.register( @@ -75,8 +76,8 @@ def register(): dashboard.Incoming, dashboard.BotAction, dashboard.News, - dashboard.Demos, - party.Party, + dashboard.Demos, + party.Party, party.PartyExecution, party.PartyExecutionSla, party.PartyExecutionPlace, @@ -178,16 +179,19 @@ def register(): purchase.PenaltyRule, purchase.PenaltyRuleTier, purchase.ConcentrateTerm, - backtoback.Backtoback, - dimension.AnalyticDimension, - dimension.AnalyticDimensionValue, - dimension.AnalyticDimensionAssignment, - weight_report.WeightReport, - module='purchase', type_='model') - Pool.register( - invoice.Invoice, - invoice.InvoiceLine, - module='account_invoice', type_='model') + backtoback.Backtoback, + dimension.AnalyticDimension, + dimension.AnalyticDimensionValue, + dimension.AnalyticDimensionAssignment, + weight_report.WeightReport, + module='purchase', type_='model') + Pool.register( + account.PhysicalTradeIFRS, + module='purchase_trade', type_='model') + Pool.register( + invoice.Invoice, + invoice.InvoiceLine, + module='account_invoice', type_='model') Pool.register( forex.Forex, forex.ForexCoverFees, diff --git a/modules/purchase_trade/account.py b/modules/purchase_trade/account.py new file mode 100644 index 0000000..b686fa6 --- /dev/null +++ b/modules/purchase_trade/account.py @@ -0,0 +1,30 @@ +# account.py +from trytond.model import ModelSQL, ModelView, fields +from trytond.pool import PoolMeta +from trytond.pyson import Eval + +__all__ = ['PhysicalTradeIFRS'] +__metaclass__ = PoolMeta + + +class PhysicalTradeIFRS(ModelSQL, ModelView): + 'Physical Trade - IFRS Adjustment' + __name__ = 'account.physical_trade_ifrs' + + date = fields.Date('Date', required=True) + comment = fields.Text('Comment', required=True) + currency = fields.Many2One('currency.currency', 'Currency', required=True) + currency_digits = fields.Function( + fields.Integer('Currency Digits'), + 'on_change_with_currency_digits') + amount = fields.Numeric( + 'Amount', + digits=(16, Eval('currency_digits', 2)), + depends=['currency_digits'], + required=True) + + @fields.depends('currency') + def on_change_with_currency_digits(self, name=None): + if self.currency: + return self.currency.digits + return 2 diff --git a/modules/purchase_trade/account.xml b/modules/purchase_trade/account.xml new file mode 100644 index 0000000..40efb3f --- /dev/null +++ b/modules/purchase_trade/account.xml @@ -0,0 +1,69 @@ + + + + + Physical Trade IFRS + + + Physical Trade IFRS Administration + + + + + + + + + + + + + account.physical_trade_ifrs + form + physical_trade_IFRS_form + + + account.physical_trade_ifrs + tree + physical_trade_IFRS_tree + + + + Physical Trade - IFRS Adjustment + account.physical_trade_ifrs + + + + + + + + + + + + + + + + account.physical_trade_ifrs + + + + + + + account.physical_trade_ifrs + + + + + + + + diff --git a/modules/purchase_trade/pricing.py b/modules/purchase_trade/pricing.py index b4031ea..6191627 100755 --- a/modules/purchase_trade/pricing.py +++ b/modules/purchase_trade/pricing.py @@ -113,11 +113,11 @@ class MtmStrategy(ModelSQL, ModelView): ) ) - elif comp.price_source_type == 'matrix' and comp.price_matrix: - value = self._get_matrix_price(comp, line, dt) - - if comp.ratio: - value *= Decimal(comp.ratio) + elif comp.price_source_type == 'matrix' and comp.price_matrix: + value = self._get_matrix_price(comp, line, dt) + + if comp.ratio: + value *= Decimal(comp.ratio) / Decimal(100) total += value * qty diff --git a/modules/purchase_trade/tests/__init__.py b/modules/purchase_trade/tests/__init__.py new file mode 100644 index 0000000..4effdfa --- /dev/null +++ b/modules/purchase_trade/tests/__init__.py @@ -0,0 +1,2 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py new file mode 100644 index 0000000..7d2b4c5 --- /dev/null +++ b/modules/purchase_trade/tests/test_module.py @@ -0,0 +1,74 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + +from decimal import Decimal +from unittest.mock import Mock, patch + +from trytond.pool import Pool +from trytond.tests.test_tryton import ModuleTestCase, with_transaction + + +class PurchaseTradeTestCase(ModuleTestCase): + 'Test purchase_trade module' + module = 'purchase_trade' + + @with_transaction() + def test_get_totals_without_rows(self): + 'get_totals returns zeros when the query has no row' + Valuation = Pool().get('valuation.valuation') + cursor = Mock() + cursor.fetchone.return_value = None + connection = Mock() + connection.cursor.return_value = cursor + + with patch( + 'trytond.modules.purchase_trade.valuation.Transaction' + ) as Transaction, patch.object( + Valuation, '__table__', return_value='valuation_valuation'): + Transaction.return_value.connection = connection + + self.assertEqual( + Valuation.get_totals(), (Decimal(0), Decimal(0))) + + @with_transaction() + def test_get_totals_without_previous_total(self): + 'get_totals converts null variation to zero' + Valuation = Pool().get('valuation.valuation') + cursor = Mock() + cursor.fetchone.return_value = (Decimal('42.50'), None) + connection = Mock() + connection.cursor.return_value = cursor + + with patch( + 'trytond.modules.purchase_trade.valuation.Transaction' + ) as Transaction, patch.object( + Valuation, '__table__', return_value='valuation_valuation'): + Transaction.return_value.connection = connection + + self.assertEqual( + Valuation.get_totals(), (Decimal('42.50'), Decimal(0))) + + @with_transaction() + def test_get_mtm_applies_component_ratio_as_percentage(self): + 'get_mtm treats component ratio as a percentage' + Strategy = Pool().get('mtm.strategy') + strategy = Strategy() + strategy.scenario = Mock( + valuation_date='2026-03-29', + use_last_price=True, + ) + strategy.currency = Mock() + strategy.components = [Mock( + price_source_type='curve', + price_index=Mock(get_price=Mock(return_value=Decimal('100'))), + price_matrix=None, + ratio=Decimal('25'), + )] + line = Mock(unit=Mock()) + + self.assertEqual( + strategy.get_mtm(line, Decimal('10')), + Decimal('250.00')) + + +del ModuleTestCase diff --git a/modules/purchase_trade/tryton.cfg b/modules/purchase_trade/tryton.cfg index e125de5..8f43cba 100755 --- a/modules/purchase_trade/tryton.cfg +++ b/modules/purchase_trade/tryton.cfg @@ -1,12 +1,12 @@ [tryton] version=7.2.7 -depends: - ir - purchase - sale - account_invoice - stock - res +depends: + ir + purchase + sale + account_invoice + stock + res lot document_incoming incoterm @@ -29,8 +29,9 @@ xml: party.xml forex.xml global_reporting.xml - derivative.xml - valuation.xml - weight_report.xml - dimension.xml - backtoback.xml + derivative.xml + valuation.xml + weight_report.xml + dimension.xml + backtoback.xml + account.xml diff --git a/modules/purchase_trade/valuation.py b/modules/purchase_trade/valuation.py index 3142d05..3dc7cf3 100644 --- a/modules/purchase_trade/valuation.py +++ b/modules/purchase_trade/valuation.py @@ -459,9 +459,13 @@ class Valuation(ValuationBase, ModelView): """ cursor.execute(sql) - last_total, last_variation = cursor.fetchone() + row = cursor.fetchone() + if not row: + return Decimal(0), Decimal(0) - return last_total, last_variation + last_total, last_variation = row + + return last_total or Decimal(0), last_variation or Decimal(0) class ValuationLine(ValuationBase, ModelView): "Last Valuation" diff --git a/modules/purchase_trade/view/physical_trade_IFRS_form.xml b/modules/purchase_trade/view/physical_trade_IFRS_form.xml new file mode 100644 index 0000000..19ca656 --- /dev/null +++ b/modules/purchase_trade/view/physical_trade_IFRS_form.xml @@ -0,0 +1,11 @@ +
+