07.02.26
This commit is contained in:
@@ -172,6 +172,11 @@ def register():
|
||||
forex.ForexCategory,
|
||||
pricing.Component,
|
||||
pricing.Mtm,
|
||||
pricing.MtmStrategy,
|
||||
pricing.MtmScenario,
|
||||
pricing.MtmSnapshot,
|
||||
pricing.PriceMatrix,
|
||||
pricing.PriceMatrixLine,
|
||||
pricing.Estimated,
|
||||
pricing.Pricing,
|
||||
pricing.Period,
|
||||
|
||||
13
modules/purchase_trade/icons/tradon-mtm.svg
Normal file
13
modules/purchase_trade/icons/tradon-mtm.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" d="M0 0h24v24H0z"/>
|
||||
<path d="
|
||||
M4 18 V6
|
||||
H7 L12 13 L17 6
|
||||
H20 V18
|
||||
H17 V10.5
|
||||
L12 16
|
||||
L7 10.5
|
||||
V18
|
||||
Z
|
||||
" fill="#267F82"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 259 B |
@@ -50,8 +50,6 @@ DAYS = [
|
||||
('sunday', 'Sunday'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
class Estimated(ModelSQL, ModelView):
|
||||
"Estimated date"
|
||||
__name__ = 'pricing.estimated'
|
||||
@@ -59,21 +57,212 @@ class Estimated(ModelSQL, ModelView):
|
||||
trigger = fields.Selection(TRIGGERS,"Trigger")
|
||||
estimated_date = fields.Date("Estimated date")
|
||||
|
||||
class MtmScenario(ModelSQL, ModelView):
|
||||
"MtM Scenario"
|
||||
__name__ = 'mtm.scenario'
|
||||
|
||||
name = fields.Char("Scenario", required=True)
|
||||
valuation_date = fields.Date("Valuation Date", required=True)
|
||||
use_last_price = fields.Boolean("Use Last Available Price")
|
||||
calendar = fields.Many2One(
|
||||
'price.calendar', "Calendar"
|
||||
)
|
||||
|
||||
class MtmStrategy(ModelSQL, ModelView):
|
||||
"Mark to Market Strategy"
|
||||
__name__ = 'mtm.strategy'
|
||||
|
||||
name = fields.Char("Name", required=True)
|
||||
active = fields.Boolean("Active", select=True)
|
||||
|
||||
scenario = fields.Many2One(
|
||||
'mtm.scenario', "Scenario", required=True
|
||||
)
|
||||
|
||||
currency = fields.Many2One(
|
||||
'currency.currency', "Valuation Currency"
|
||||
)
|
||||
|
||||
components = fields.One2Many(
|
||||
'mtm.component', 'strategy', "Components"
|
||||
)
|
||||
|
||||
def compute_mtm(self):
|
||||
pool = Pool()
|
||||
Currency = pool.get('currency.currency')
|
||||
total = Decimal(0)
|
||||
|
||||
scenario = self.scenario
|
||||
dt = scenario.valuation_date
|
||||
|
||||
for comp in self.components:
|
||||
value = Decimal(0)
|
||||
|
||||
if comp.price_source_type == 'curve' and comp.price_curve:
|
||||
value = Decimal(
|
||||
comp.price_curve.get_price(
|
||||
dt,
|
||||
self.purchase_line.unit,
|
||||
self.currency,
|
||||
last=scenario.use_last_price
|
||||
)
|
||||
)
|
||||
|
||||
elif comp.price_source_type == 'matrix' and comp.price_matrix:
|
||||
value = self._get_matrix_price(comp, dt)
|
||||
|
||||
if comp.ratio:
|
||||
value *= Decimal(comp.ratio)
|
||||
|
||||
total += value
|
||||
|
||||
return total
|
||||
|
||||
def _get_matrix_price(self, comp, dt):
|
||||
MatrixLine = Pool().get('price.matrix.line')
|
||||
|
||||
domain = [
|
||||
('matrix', '=', comp.price_matrix.id),
|
||||
]
|
||||
|
||||
if self.purchase_line:
|
||||
domain += [
|
||||
('origin', '=', self.purchase_line.from_location),
|
||||
('destination', '=', self.purchase_line.to_location),
|
||||
]
|
||||
|
||||
lines = MatrixLine.search(domain)
|
||||
if lines:
|
||||
return Decimal(lines[0].price_value)
|
||||
|
||||
return Decimal(0)
|
||||
|
||||
def run_daily_mtm():
|
||||
Strategy = Pool().get('mtm.strategy')
|
||||
Snapshot = Pool().get('mtm.snapshot')
|
||||
|
||||
for strat in Strategy.search([('active', '=', True)]):
|
||||
amount = strat.compute_mtm()
|
||||
Snapshot.create([{
|
||||
'strategy': strat.id,
|
||||
'valuation_date': strat.scenario.valuation_date,
|
||||
'amount': amount,
|
||||
'currency': strat.currency.id,
|
||||
}])
|
||||
|
||||
class Mtm(ModelSQL, ModelView):
|
||||
"Mtm"
|
||||
"MtM Component"
|
||||
__name__ = 'mtm.component'
|
||||
|
||||
fix_type = fields.Many2One('price.fixtype',"Fixation type")
|
||||
ratio = fields.Numeric("%")
|
||||
price_index = fields.Many2One('price.price',"Curve")
|
||||
currency = fields.Function(fields.Many2One('currency.currency',"Curr."),'get_cur')
|
||||
strategy = fields.Many2One(
|
||||
'mtm.strategy', "Strategy",
|
||||
required=True, ondelete='CASCADE'
|
||||
)
|
||||
|
||||
def get_cur(self,name):
|
||||
name = fields.Char("Component", required=True)
|
||||
|
||||
component_type = fields.Selection([
|
||||
('commodity', 'Commodity'),
|
||||
('freight', 'Freight'),
|
||||
('quality', 'Quality'),
|
||||
('fx', 'FX'),
|
||||
('storage', 'Storage'),
|
||||
('other', 'Other'),
|
||||
], "Type", required=True)
|
||||
|
||||
fix_type = fields.Many2One('price.fixtype', "Fixation Type")
|
||||
|
||||
price_source_type = fields.Selection([
|
||||
('curve', 'Curve'),
|
||||
('matrix', 'Matrix'),
|
||||
('manual', 'Manual'),
|
||||
], "Price Source", required=True)
|
||||
|
||||
price_index = fields.Many2One('price.price', "Price Curve")
|
||||
price_matrix = fields.Many2One('price.matrix', "Price Matrix")
|
||||
|
||||
ratio = fields.Numeric("Ratio / %", digits=(16, 6))
|
||||
|
||||
manual_price = fields.Numeric(
|
||||
"Manual Price",
|
||||
digits=(16, 6),
|
||||
help="Price set manually if price_source_type is 'manual'"
|
||||
)
|
||||
|
||||
currency = fields.Many2One('currency.currency', "Currency")
|
||||
|
||||
def get_cur(self, name=None):
|
||||
if self.price_index:
|
||||
PI = Pool().get('price.price')
|
||||
pi = PI(self.price_index)
|
||||
return pi.price_currency
|
||||
|
||||
return self.price_index.price_currency
|
||||
if self.price_matrix:
|
||||
return self.price_matrix.currency
|
||||
return None
|
||||
|
||||
@fields.depends('price_index','price_matrix')
|
||||
def on_change_with_currency(self):
|
||||
return self.get_cur()
|
||||
|
||||
class PriceMatrix(ModelSQL, ModelView):
|
||||
"Price Matrix"
|
||||
__name__ = 'price.matrix'
|
||||
|
||||
name = fields.Char("Name", required=True)
|
||||
|
||||
matrix_type = fields.Selection([
|
||||
('freight', 'Freight'),
|
||||
('location', 'Location Spread'),
|
||||
('quality', 'Quality'),
|
||||
('storage', 'Storage'),
|
||||
('other', 'Other'),
|
||||
], "Matrix Type", required=True)
|
||||
|
||||
unit = fields.Many2One('product.uom', "Unit")
|
||||
currency = fields.Many2One('currency.currency', "Currency")
|
||||
|
||||
calendar = fields.Many2One(
|
||||
'price.calendar', "Calendar"
|
||||
)
|
||||
|
||||
valid_from = fields.Date("Valid From")
|
||||
valid_to = fields.Date("Valid To")
|
||||
|
||||
lines = fields.One2Many(
|
||||
'price.matrix.line', 'matrix', "Lines"
|
||||
)
|
||||
|
||||
class PriceMatrixLine(ModelSQL, ModelView):
|
||||
"Price Matrix Line"
|
||||
__name__ = 'price.matrix.line'
|
||||
|
||||
matrix = fields.Many2One(
|
||||
'price.matrix', "Matrix",
|
||||
required=True, ondelete='CASCADE'
|
||||
)
|
||||
|
||||
origin = fields.Many2One('stock.location', "Origin")
|
||||
destination = fields.Many2One('stock.location', "Destination")
|
||||
|
||||
product = fields.Many2One('product.product', "Product")
|
||||
quality = fields.Many2One('product.quality', "Quality")
|
||||
|
||||
price_value = fields.Numeric("Price", digits=(16, 6))
|
||||
|
||||
class MtmSnapshot(ModelSQL, ModelView):
|
||||
"MtM Snapshot"
|
||||
__name__ = 'mtm.snapshot'
|
||||
|
||||
strategy = fields.Many2One(
|
||||
'mtm.strategy', "Strategy",
|
||||
required=True, ondelete='CASCADE'
|
||||
)
|
||||
|
||||
valuation_date = fields.Date("Valuation Date", required=True)
|
||||
|
||||
amount = fields.Numeric("MtM Amount", digits=(16, 6))
|
||||
currency = fields.Many2One('currency.currency', "Currency")
|
||||
|
||||
created_at = fields.DateTime("Created At")
|
||||
|
||||
class Component(ModelSQL, ModelView):
|
||||
"Component"
|
||||
__name__ = 'pricing.component'
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.icon" id="mtm_icon">
|
||||
<field name="name">tradon-mtm</field>
|
||||
<field name="path">icons/tradon-mtm.svg</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="summary_view_tree_sequence">
|
||||
<field name="model">sale.pricing.summary</field>
|
||||
<field name="type">tree</field>
|
||||
@@ -104,5 +109,84 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="type">form</field>
|
||||
<field name="name">period_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="mtm_scenario_view_form">
|
||||
<field name="model">mtm.scenario</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">mtm_scenario_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mtm_scenario_view_list">
|
||||
<field name="model">mtm.scenario</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">mtm_scenario_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mtm_strategy_view_form">
|
||||
<field name="model">mtm.strategy</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">mtm_strategy_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mtm_strategy_view_list">
|
||||
<field name="model">mtm.strategy</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">mtm_strategy_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="price_matrix_view_form">
|
||||
<field name="model">price.matrix</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">price_matrix_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="price_matrix_view_list">
|
||||
<field name="model">price.matrix</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">price_matrix_tree</field>
|
||||
</record>
|
||||
<!-- <record model="ir.ui.view" id="price_matrix_line_view_form">
|
||||
<field name="model">price.matrix.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">price_matrix_line_form</field>
|
||||
</record> -->
|
||||
<!-- <record model="ir.ui.view" id="price_matrix_view_list">
|
||||
<field name="model">price.matrix.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">price_matrix_line_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mtm_snapshot_view_form">
|
||||
<field name="model">mtm.snapshot</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">mtm_snapshot_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mtm_snapshot_view_list">
|
||||
<field name="model">mtm.snapshot</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">mtm_snapshot_tree</field>
|
||||
</record> -->
|
||||
|
||||
<record model="ir.action.act_window" id="act_strategy_form">
|
||||
<field name="name">Strategy</field>
|
||||
<field name="res_model">mtm.strategy</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_mtm_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="mtm_strategy_view_list"/>
|
||||
<field name="act_window" ref="act_mtm_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_mtm_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="mtm_strategy_view_form"/>
|
||||
<field name="act_window" ref="act_mtm_form"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Mtm"
|
||||
sequence="99"
|
||||
id="menu_mtm"
|
||||
icon="tradon-mtm" />
|
||||
<menuitem
|
||||
name="Strategy"
|
||||
action="act_strategy_form"
|
||||
parent="menu_mtm"
|
||||
sequence="10"
|
||||
id="menu_strategy" />
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
@@ -64,7 +64,7 @@ class DocTypeTemplate(ModelSQL):
|
||||
class Mtm(metaclass=PoolMeta):
|
||||
"Mtm"
|
||||
__name__ = 'mtm.component'
|
||||
line = fields.Many2One('purchase.line')
|
||||
line = fields.Many2One('purchase.line',"Line",ondelete='CASCADE')
|
||||
|
||||
class Estimated(metaclass=PoolMeta):
|
||||
"Estimated date"
|
||||
@@ -422,7 +422,11 @@ class Line(metaclass=PoolMeta):
|
||||
purchase_line = fields.Many2One('purchase.line',"Lines")
|
||||
fees = fields.One2Many('fee.fee', 'line', 'Fees')#, filter=[('product.type', '=', 'service')])
|
||||
derivatives = fields.One2Many('derivative.derivative','line',"Derivatives")
|
||||
mtm = fields.One2Many('mtm.component','line',"Mtm")
|
||||
# mtm = fields.One2Many('mtm.component','line',"Mtm")
|
||||
mtm = fields.One2Many(
|
||||
'mtm.strategy', 'line',
|
||||
"MtM Strategies"
|
||||
)
|
||||
tol_min = fields.Numeric("Tol - in %",states={
|
||||
'readonly': (Eval('inherit_tol')),
|
||||
})
|
||||
|
||||
@@ -55,7 +55,7 @@ class OpenPosition(metaclass=PoolMeta):
|
||||
class Mtm(metaclass=PoolMeta):
|
||||
"Mtm"
|
||||
__name__ = 'mtm.component'
|
||||
sale_line = fields.Many2One('sale.line',"Line")
|
||||
sale_line = fields.Many2One('sale.line',"Line",ondelete='CASCADE')
|
||||
|
||||
class Component(metaclass=PoolMeta):
|
||||
"Component"
|
||||
@@ -363,7 +363,11 @@ class SaleLine(metaclass=PoolMeta):
|
||||
from_del = fields.Date("From")
|
||||
to_del = fields.Date("To")
|
||||
price_components = fields.One2Many('pricing.component','sale_line',"Components")
|
||||
mtm = fields.One2Many('mtm.component','sale_line',"Mtm")
|
||||
# mtm = fields.One2Many('mtm.component','sale_line',"Mtm")
|
||||
mtm = fields.One2Many(
|
||||
'mtm.strategy', 'sale_line',
|
||||
"MtM Strategies"
|
||||
)
|
||||
derivatives = fields.One2Many('derivative.derivative','sale_line',"Derivatives")
|
||||
price_pricing = fields.One2Many('pricing.pricing','sale_line',"Pricing")
|
||||
price_summary = fields.One2Many('sale.pricing.summary','sale_line',"Summary")
|
||||
|
||||
6
modules/purchase_trade/view/mtm_scenario_tree.xml
Normal file
6
modules/purchase_trade/view/mtm_scenario_tree.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="valuation_date"/>
|
||||
<field name="use_last_price"/>
|
||||
<field name="calendar"/>
|
||||
</tree>
|
||||
10
modules/purchase_trade/view/mtm_strategy_form.xml
Normal file
10
modules/purchase_trade/view/mtm_strategy_form.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<form col="4">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="scenario"/>
|
||||
<field name="scenario"/>
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<newline/>
|
||||
<field name="components" colspan="4"/>
|
||||
</form>
|
||||
5
modules/purchase_trade/view/mtm_strategy_tree.xml
Normal file
5
modules/purchase_trade/view/mtm_strategy_tree.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="scenario"/>
|
||||
<field name="currency"/>
|
||||
</tree>
|
||||
18
modules/purchase_trade/view/price_matrix_form.xml
Normal file
18
modules/purchase_trade/view/price_matrix_form.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<form col="4">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="matrix_type"/>
|
||||
<field name="matrix_type"/>
|
||||
<label name="unit"/>
|
||||
<field name="unit"/>
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<label name="calendar"/>
|
||||
<field name="calendar"/>
|
||||
<label name="valid_from"/>
|
||||
<field name="valid_from"/>
|
||||
<label name="valid_to"/>
|
||||
<field name="valid_to"/>
|
||||
<newline/>
|
||||
<field name="lines" colspan="4"/>
|
||||
</form>
|
||||
7
modules/purchase_trade/view/price_matrix_line_tree.xml
Normal file
7
modules/purchase_trade/view/price_matrix_line_tree.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<tree>
|
||||
<field name="origin"/>
|
||||
<field name="destination"/>
|
||||
<field name="product"/>
|
||||
<field name="quality"/>
|
||||
<field name="price_value"/>
|
||||
</tree>
|
||||
9
modules/purchase_trade/view/price_matrix_tree.xml
Normal file
9
modules/purchase_trade/view/price_matrix_tree.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="matrix_type"/>
|
||||
<field name="unit"/>
|
||||
<field name="currency"/>
|
||||
<field name="calendar"/>
|
||||
<field name="valid_from"/>
|
||||
<field name="valid_to"/>
|
||||
</tree>
|
||||
Reference in New Issue
Block a user