dev #8
@@ -4,6 +4,7 @@
|
|||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
|
account,
|
||||||
purchase,
|
purchase,
|
||||||
sale,
|
sale,
|
||||||
global_reporting,
|
global_reporting,
|
||||||
@@ -30,10 +31,10 @@ from . import (
|
|||||||
valuation,
|
valuation,
|
||||||
dimension,
|
dimension,
|
||||||
weight_report,
|
weight_report,
|
||||||
backtoback,
|
backtoback,
|
||||||
service,
|
service,
|
||||||
invoice,
|
invoice,
|
||||||
)
|
)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
Pool.register(
|
Pool.register(
|
||||||
@@ -75,8 +76,8 @@ def register():
|
|||||||
dashboard.Incoming,
|
dashboard.Incoming,
|
||||||
dashboard.BotAction,
|
dashboard.BotAction,
|
||||||
dashboard.News,
|
dashboard.News,
|
||||||
dashboard.Demos,
|
dashboard.Demos,
|
||||||
party.Party,
|
party.Party,
|
||||||
party.PartyExecution,
|
party.PartyExecution,
|
||||||
party.PartyExecutionSla,
|
party.PartyExecutionSla,
|
||||||
party.PartyExecutionPlace,
|
party.PartyExecutionPlace,
|
||||||
@@ -178,16 +179,19 @@ def register():
|
|||||||
purchase.PenaltyRule,
|
purchase.PenaltyRule,
|
||||||
purchase.PenaltyRuleTier,
|
purchase.PenaltyRuleTier,
|
||||||
purchase.ConcentrateTerm,
|
purchase.ConcentrateTerm,
|
||||||
backtoback.Backtoback,
|
backtoback.Backtoback,
|
||||||
dimension.AnalyticDimension,
|
dimension.AnalyticDimension,
|
||||||
dimension.AnalyticDimensionValue,
|
dimension.AnalyticDimensionValue,
|
||||||
dimension.AnalyticDimensionAssignment,
|
dimension.AnalyticDimensionAssignment,
|
||||||
weight_report.WeightReport,
|
weight_report.WeightReport,
|
||||||
module='purchase', type_='model')
|
module='purchase', type_='model')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
invoice.Invoice,
|
account.PhysicalTradeIFRS,
|
||||||
invoice.InvoiceLine,
|
module='purchase_trade', type_='model')
|
||||||
module='account_invoice', type_='model')
|
Pool.register(
|
||||||
|
invoice.Invoice,
|
||||||
|
invoice.InvoiceLine,
|
||||||
|
module='account_invoice', type_='model')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
forex.Forex,
|
forex.Forex,
|
||||||
forex.ForexCoverFees,
|
forex.ForexCoverFees,
|
||||||
|
|||||||
30
modules/purchase_trade/account.py
Normal file
30
modules/purchase_trade/account.py
Normal file
@@ -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
|
||||||
69
modules/purchase_trade/account.xml
Normal file
69
modules/purchase_trade/account.xml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<tryton>
|
||||||
|
<data>
|
||||||
|
<record model="res.group" id="group_physical_trade_ifrs">
|
||||||
|
<field name="name">Physical Trade IFRS</field>
|
||||||
|
</record>
|
||||||
|
<record model="res.group" id="group_physical_trade_ifrs_admin">
|
||||||
|
<field name="name">Physical Trade IFRS Administration</field>
|
||||||
|
<field name="parent" ref="group_physical_trade_ifrs"/>
|
||||||
|
</record>
|
||||||
|
<record model="res.user-res.group" id="user_admin_group_physical_trade_ifrs">
|
||||||
|
<field name="user" ref="res.user_admin"/>
|
||||||
|
<field name="group" ref="group_physical_trade_ifrs"/>
|
||||||
|
</record>
|
||||||
|
<record model="res.user-res.group" id="user_admin_group_physical_trade_ifrs_admin">
|
||||||
|
<field name="user" ref="res.user_admin"/>
|
||||||
|
<field name="group" ref="group_physical_trade_ifrs_admin"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="view_physical_trade_ifrs_form">
|
||||||
|
<field name="model">account.physical_trade_ifrs</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">physical_trade_IFRS_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="view_physical_trade_ifrs_tree">
|
||||||
|
<field name="model">account.physical_trade_ifrs</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="name">physical_trade_IFRS_tree</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.action.act_window" id="act_physical_trade_ifrs_form">
|
||||||
|
<field name="name">Physical Trade - IFRS Adjustment</field>
|
||||||
|
<field name="res_model">account.physical_trade_ifrs</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.act_window.view" id="act_physical_trade_ifrs_view_tree">
|
||||||
|
<field name="sequence" eval="10"/>
|
||||||
|
<field name="view" ref="view_physical_trade_ifrs_tree"/>
|
||||||
|
<field name="act_window" ref="act_physical_trade_ifrs_form"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.act_window.view" id="act_physical_trade_ifrs_view_form">
|
||||||
|
<field name="sequence" eval="20"/>
|
||||||
|
<field name="view" ref="view_physical_trade_ifrs_form"/>
|
||||||
|
<field name="act_window" ref="act_physical_trade_ifrs_form"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
name="Physical Trade - IFRS Adjustment"
|
||||||
|
parent="account.menu_processing"
|
||||||
|
action="act_physical_trade_ifrs_form"
|
||||||
|
sequence="30"
|
||||||
|
id="menu_physical_trade_ifrs"/>
|
||||||
|
|
||||||
|
<record model="ir.model.access" id="access_physical_trade_ifrs">
|
||||||
|
<field name="model">account.physical_trade_ifrs</field>
|
||||||
|
<field name="perm_read" eval="False"/>
|
||||||
|
<field name="perm_write" eval="False"/>
|
||||||
|
<field name="perm_create" eval="False"/>
|
||||||
|
<field name="perm_delete" eval="False"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.model.access" id="access_physical_trade_ifrs_group">
|
||||||
|
<field name="model">account.physical_trade_ifrs</field>
|
||||||
|
<field name="group" ref="group_physical_trade_ifrs"/>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="True"/>
|
||||||
|
<field name="perm_create" eval="True"/>
|
||||||
|
<field name="perm_delete" eval="True"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
@@ -113,11 +113,11 @@ class MtmStrategy(ModelSQL, ModelView):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
elif comp.price_source_type == 'matrix' and comp.price_matrix:
|
elif comp.price_source_type == 'matrix' and comp.price_matrix:
|
||||||
value = self._get_matrix_price(comp, line, dt)
|
value = self._get_matrix_price(comp, line, dt)
|
||||||
|
|
||||||
if comp.ratio:
|
if comp.ratio:
|
||||||
value *= Decimal(comp.ratio)
|
value *= Decimal(comp.ratio) / Decimal(100)
|
||||||
|
|
||||||
total += value * qty
|
total += value * qty
|
||||||
|
|
||||||
|
|||||||
2
modules/purchase_trade/tests/__init__.py
Normal file
2
modules/purchase_trade/tests/__init__.py
Normal file
@@ -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.
|
||||||
74
modules/purchase_trade/tests/test_module.py
Normal file
74
modules/purchase_trade/tests/test_module.py
Normal file
@@ -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
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
[tryton]
|
[tryton]
|
||||||
version=7.2.7
|
version=7.2.7
|
||||||
depends:
|
depends:
|
||||||
ir
|
ir
|
||||||
purchase
|
purchase
|
||||||
sale
|
sale
|
||||||
account_invoice
|
account_invoice
|
||||||
stock
|
stock
|
||||||
res
|
res
|
||||||
lot
|
lot
|
||||||
document_incoming
|
document_incoming
|
||||||
incoterm
|
incoterm
|
||||||
@@ -29,8 +29,9 @@ xml:
|
|||||||
party.xml
|
party.xml
|
||||||
forex.xml
|
forex.xml
|
||||||
global_reporting.xml
|
global_reporting.xml
|
||||||
derivative.xml
|
derivative.xml
|
||||||
valuation.xml
|
valuation.xml
|
||||||
weight_report.xml
|
weight_report.xml
|
||||||
dimension.xml
|
dimension.xml
|
||||||
backtoback.xml
|
backtoback.xml
|
||||||
|
account.xml
|
||||||
|
|||||||
@@ -459,9 +459,13 @@ class Valuation(ValuationBase, ModelView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
cursor.execute(sql)
|
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):
|
class ValuationLine(ValuationBase, ModelView):
|
||||||
"Last Valuation"
|
"Last Valuation"
|
||||||
|
|||||||
11
modules/purchase_trade/view/physical_trade_IFRS_form.xml
Normal file
11
modules/purchase_trade/view/physical_trade_IFRS_form.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<form col="4">
|
||||||
|
<label name="date"/>
|
||||||
|
<field name="date"/>
|
||||||
|
<label name="currency"/>
|
||||||
|
<field name="currency"/>
|
||||||
|
<label name="amount"/>
|
||||||
|
<field name="amount"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="comment"/>
|
||||||
|
<field name="comment" colspan="4"/>
|
||||||
|
</form>
|
||||||
6
modules/purchase_trade/view/physical_trade_IFRS_tree.xml
Normal file
6
modules/purchase_trade/view/physical_trade_IFRS_tree.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<tree>
|
||||||
|
<field name="date"/>
|
||||||
|
<field name="currency"/>
|
||||||
|
<field name="amount"/>
|
||||||
|
<field name="comment"/>
|
||||||
|
</tree>
|
||||||
Reference in New Issue
Block a user