Files
tradon/modules/purchase_trade/ctrm_reporting.py
2026-05-24 18:05:31 +02:00

311 lines
12 KiB
Python

from sql import Literal
from sql.aggregate import Max, Min, Sum
from sql.conditionals import Case, Coalesce
from sql.functions import CurrentTimestamp
from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.transaction import Transaction
PHYSICAL_VALUATION_TYPES = [
'priced',
'pur. priced',
'pur. efp',
'sale priced',
'sale efp',
'line fee',
'pur. fee',
'sale fee',
'shipment fee',
'market',
]
DERIVATIVE_VALUATION_TYPES = ['derivative']
class CTRMValuationContextMixin:
date = fields.Date("Valuation Date")
product = fields.Many2One('product.product', "Product")
counterparty = fields.Many2One('party.party', "Counterparty")
currency = fields.Many2One('currency.currency', "Currency")
purchase = fields.Many2One('purchase.purchase', "Purchase")
sale = fields.Many2One('sale.sale', "Sale")
strategy = fields.Many2One('mtm.strategy', "Strategy")
state = fields.Char("State")
@classmethod
def default_date(cls):
Date = Pool().get('ir.date')
return Date.today()
class CTRMPhysicalPositionContext(
CTRMValuationContextMixin, ModelView):
"CTRM Physical Position Context"
__name__ = 'ctrm.reporting.position.physical.context'
class CTRMPhysicalPosition(ModelSQL, ModelView):
"CTRM Physical Position"
__name__ = 'ctrm.reporting.position.physical'
valuation_date = fields.Date("Valuation Date")
lot = fields.Many2One('lot.lot', "Lot")
purchase = fields.Many2One('purchase.purchase', "Purchase")
purchase_line = fields.Many2One('purchase.line', "Purchase Line")
sale = fields.Many2One('sale.sale', "Sale")
sale_line = fields.Many2One('sale.line', "Sale Line")
type = fields.Selection([
('priced', 'Price'),
('pur. priced', 'Pur. price'),
('pur. efp', 'Pur. efp'),
('sale priced', 'Sale price'),
('sale efp', 'Sale efp'),
('line fee', 'Line fee'),
('pur. fee', 'Pur. fee'),
('sale fee', 'Sale fee'),
('shipment fee', 'Shipment fee'),
('market', 'Market'),
], "Type")
reference = fields.Char("Reference")
counterparty = fields.Many2One('party.party', "Counterparty")
product = fields.Many2One('product.product', "Product")
state = fields.Char("State")
price = fields.Numeric("Price", digits=(16, 4))
currency = fields.Many2One('currency.currency', "Currency")
quantity = fields.Numeric("Quantity", digits=(16, 5))
unit = fields.Many2One('product.uom', "Unit")
amount = fields.Numeric("Amount", digits=(16, 2))
base_amount = fields.Numeric("Base Amount", digits=(16, 2))
mtm_price = fields.Numeric("MTM Price", digits=(16, 4))
mtm = fields.Numeric("MTM", digits=(16, 2))
strategy = fields.Many2One('mtm.strategy', "Strategy")
@classmethod
def table_query(cls):
ValuationLine = Pool().get('valuation.valuation.line')
val = ValuationLine.__table__()
context = Transaction().context
where = val.type.in_(PHYSICAL_VALUATION_TYPES)
if context.get('date'):
where &= val.date == context['date']
if context.get('product'):
where &= val.product == context['product']
if context.get('counterparty'):
where &= val.counterparty == context['counterparty']
if context.get('currency'):
where &= val.currency == context['currency']
if context.get('purchase'):
where &= val.purchase == context['purchase']
if context.get('sale'):
where &= val.sale == context['sale']
if context.get('strategy'):
where &= val.strategy == context['strategy']
if context.get('state'):
where &= val.state == context['state']
return val.select(
Literal(0).as_('create_uid'),
CurrentTimestamp().as_('create_date'),
Literal(None).as_('write_uid'),
Literal(None).as_('write_date'),
val.id.as_('id'),
val.date.as_('valuation_date'),
val.lot.as_('lot'),
val.purchase.as_('purchase'),
val.line.as_('purchase_line'),
val.sale.as_('sale'),
val.sale_line.as_('sale_line'),
val.type.as_('type'),
val.reference.as_('reference'),
val.counterparty.as_('counterparty'),
val.product.as_('product'),
val.state.as_('state'),
val.price.as_('price'),
val.currency.as_('currency'),
val.quantity.as_('quantity'),
val.unit.as_('unit'),
val.amount.as_('amount'),
val.base_amount.as_('base_amount'),
val.mtm_price.as_('mtm_price'),
val.mtm.as_('mtm'),
val.strategy.as_('strategy'),
where=where)
class CTRMFinancialPositionContext(
CTRMValuationContextMixin, ModelView):
"CTRM Financial Position Context"
__name__ = 'ctrm.reporting.position.financial.context'
class CTRMFinancialPosition(ModelSQL, ModelView):
"CTRM Financial Position"
__name__ = 'ctrm.reporting.position.financial'
valuation_date = fields.Date("Valuation Date")
purchase = fields.Many2One('purchase.purchase', "Purchase")
purchase_line = fields.Many2One('purchase.line', "Purchase Line")
sale = fields.Many2One('sale.sale', "Sale")
sale_line = fields.Many2One('sale.line', "Sale Line")
reference = fields.Char("Reference")
counterparty = fields.Many2One('party.party', "Counterparty")
product = fields.Many2One('product.product', "Product")
state = fields.Char("State")
price = fields.Numeric("Price", digits=(16, 4))
currency = fields.Many2One('currency.currency', "Currency")
quantity = fields.Numeric("Quantity", digits=(16, 5))
unit = fields.Many2One('product.uom', "Unit")
amount = fields.Numeric("Amount", digits=(16, 2))
base_amount = fields.Numeric("Base Amount", digits=(16, 2))
mtm_price = fields.Numeric("MTM Price", digits=(16, 4))
mtm = fields.Numeric("MTM", digits=(16, 2))
strategy = fields.Many2One('mtm.strategy', "Strategy")
@classmethod
def table_query(cls):
ValuationLine = Pool().get('valuation.valuation.line')
val = ValuationLine.__table__()
context = Transaction().context
where = val.type.in_(DERIVATIVE_VALUATION_TYPES)
if context.get('date'):
where &= val.date == context['date']
if context.get('product'):
where &= val.product == context['product']
if context.get('counterparty'):
where &= val.counterparty == context['counterparty']
if context.get('currency'):
where &= val.currency == context['currency']
if context.get('purchase'):
where &= val.purchase == context['purchase']
if context.get('sale'):
where &= val.sale == context['sale']
if context.get('strategy'):
where &= val.strategy == context['strategy']
if context.get('state'):
where &= val.state == context['state']
return val.select(
Literal(0).as_('create_uid'),
CurrentTimestamp().as_('create_date'),
Literal(None).as_('write_uid'),
Literal(None).as_('write_date'),
val.id.as_('id'),
val.date.as_('valuation_date'),
val.purchase.as_('purchase'),
val.line.as_('purchase_line'),
val.sale.as_('sale'),
val.sale_line.as_('sale_line'),
val.reference.as_('reference'),
val.counterparty.as_('counterparty'),
val.product.as_('product'),
val.state.as_('state'),
val.price.as_('price'),
val.currency.as_('currency'),
val.quantity.as_('quantity'),
val.unit.as_('unit'),
val.amount.as_('amount'),
val.base_amount.as_('base_amount'),
val.mtm_price.as_('mtm_price'),
val.mtm.as_('mtm'),
val.strategy.as_('strategy'),
where=where)
class CTRMNetPositionContext(
CTRMValuationContextMixin, ModelView):
"CTRM Net Position Context"
__name__ = 'ctrm.reporting.position.net.context'
class CTRMNetPosition(ModelSQL, ModelView):
"CTRM Net Position"
__name__ = 'ctrm.reporting.position.net'
valuation_date = fields.Date("Valuation Date")
product = fields.Many2One('product.product', "Product")
counterparty = fields.Many2One('party.party', "Counterparty")
currency = fields.Many2One('currency.currency', "Currency")
unit = fields.Many2One('product.uom', "Unit")
state = fields.Char("State")
strategy = fields.Many2One('mtm.strategy', "Strategy")
physical_quantity = fields.Numeric(
"Physical Quantity", digits=(16, 5))
derivative_quantity = fields.Numeric(
"Derivative Quantity", digits=(16, 5))
net_quantity = fields.Numeric("Net Quantity", digits=(16, 5))
physical_amount = fields.Numeric("Physical Amount", digits=(16, 2))
derivative_amount = fields.Numeric("Derivative Amount", digits=(16, 2))
net_amount = fields.Numeric("Net Amount", digits=(16, 2))
mtm = fields.Numeric("MTM", digits=(16, 2))
@classmethod
def table_query(cls):
ValuationLine = Pool().get('valuation.valuation.line')
val = ValuationLine.__table__()
context = Transaction().context
where = val.type.in_(
PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES)
if context.get('date'):
where &= val.date == context['date']
if context.get('product'):
where &= val.product == context['product']
if context.get('counterparty'):
where &= val.counterparty == context['counterparty']
if context.get('currency'):
where &= val.currency == context['currency']
if context.get('purchase'):
where &= val.purchase == context['purchase']
if context.get('sale'):
where &= val.sale == context['sale']
if context.get('strategy'):
where &= val.strategy == context['strategy']
if context.get('state'):
where &= val.state == context['state']
is_derivative = val.type.in_(DERIVATIVE_VALUATION_TYPES)
physical_quantity = Case(
(is_derivative, 0), else_=Coalesce(val.quantity, 0))
derivative_quantity = Case(
(is_derivative, Coalesce(val.quantity, 0)), else_=0)
physical_amount = Case(
(is_derivative, 0), else_=Coalesce(val.amount, 0))
derivative_amount = Case(
(is_derivative, Coalesce(val.amount, 0)), else_=0)
group_by = [
val.date,
val.product,
val.counterparty,
val.currency,
val.unit,
val.state,
val.strategy,
]
return val.select(
Literal(0).as_('create_uid'),
CurrentTimestamp().as_('create_date'),
Literal(None).as_('write_uid'),
Literal(None).as_('write_date'),
Min(val.id).as_('id'),
val.date.as_('valuation_date'),
val.product.as_('product'),
val.counterparty.as_('counterparty'),
val.currency.as_('currency'),
val.unit.as_('unit'),
val.state.as_('state'),
val.strategy.as_('strategy'),
Sum(physical_quantity).as_('physical_quantity'),
Sum(derivative_quantity).as_('derivative_quantity'),
Sum(Coalesce(val.quantity, 0)).as_('net_quantity'),
Sum(physical_amount).as_('physical_amount'),
Sum(derivative_amount).as_('derivative_amount'),
Sum(Coalesce(val.amount, 0)).as_('net_amount'),
Sum(Coalesce(val.mtm, 0)).as_('mtm'),
where=where,
group_by=group_by)