This commit is contained in:
2026-02-07 16:07:54 +01:00
parent cd0c068b3f
commit 03c7f41457
12 changed files with 370 additions and 16 deletions

View File

@@ -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'