753 lines
29 KiB
Python
753 lines
29 KiB
Python
from sql import Literal, Null
|
|
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']
|
|
ALL_VALUATION_TYPES = PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES
|
|
|
|
|
|
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)
|
|
|
|
|
|
class CTRMPnlContextMixin:
|
|
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 CTRMRealizedPnlContext(CTRMPnlContextMixin, ModelView):
|
|
"CTRM Realized P&L Context"
|
|
__name__ = 'ctrm.reporting.pnl.realized.context'
|
|
|
|
realization = fields.Selection([
|
|
('purchase_and_sale_invoiced', 'Purchase and Sale Invoiced'),
|
|
('sale_invoiced', 'Sale Invoiced'),
|
|
('purchase_invoiced', 'Purchase Invoiced'),
|
|
('all_valued', 'All Valued Lines'),
|
|
], "Realization")
|
|
|
|
@classmethod
|
|
def default_realization(cls):
|
|
return 'purchase_and_sale_invoiced'
|
|
|
|
|
|
class CTRMRealizedPnl(ModelSQL, ModelView):
|
|
"CTRM Realized P&L"
|
|
__name__ = 'ctrm.reporting.pnl.realized'
|
|
|
|
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")
|
|
purchase_invoice = fields.Many2One('account.invoice', "Purchase Invoice")
|
|
sale = fields.Many2One('sale.sale', "Sale")
|
|
sale_line = fields.Many2One('sale.line', "Sale Line")
|
|
sale_invoice = fields.Many2One('account.invoice', "Sale Invoice")
|
|
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'),
|
|
('derivative', 'Derivative'),
|
|
], "Type")
|
|
reference = fields.Char("Reference")
|
|
counterparty = fields.Many2One('party.party', "Counterparty")
|
|
product = fields.Many2One('product.product', "Product")
|
|
state = fields.Char("State")
|
|
quantity = fields.Numeric("Quantity", digits=(16, 5))
|
|
unit = fields.Many2One('product.uom', "Unit")
|
|
currency = fields.Many2One('currency.currency', "Currency")
|
|
amount = fields.Numeric("Amount", digits=(16, 2))
|
|
base_amount = fields.Numeric("Base Amount", digits=(16, 2))
|
|
strategy = fields.Many2One('mtm.strategy', "Strategy")
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
ValuationLine = Pool().get('valuation.valuation.line')
|
|
Lot = Pool().get('lot.lot')
|
|
InvoiceLine = Pool().get('account.invoice.line')
|
|
Invoice = Pool().get('account.invoice')
|
|
|
|
val = ValuationLine.__table__()
|
|
lot = Lot.__table__()
|
|
purchase_invoice_line = InvoiceLine.__table__()
|
|
purchase_invoice = Invoice.__table__()
|
|
sale_invoice_line = InvoiceLine.__table__()
|
|
sale_invoice = Invoice.__table__()
|
|
|
|
context = Transaction().context
|
|
realization = context.get(
|
|
'realization', 'purchase_and_sale_invoiced')
|
|
where = val.type.in_(ALL_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']
|
|
|
|
if realization == 'purchase_and_sale_invoiced':
|
|
where &= lot.invoice_line != Null
|
|
where &= lot.sale_invoice_line != Null
|
|
elif realization == 'sale_invoiced':
|
|
where &= lot.sale_invoice_line != Null
|
|
elif realization == 'purchase_invoiced':
|
|
where &= lot.invoice_line != Null
|
|
|
|
return (
|
|
val
|
|
.join(lot, 'LEFT', condition=lot.id == val.lot)
|
|
.join(purchase_invoice_line, 'LEFT',
|
|
condition=purchase_invoice_line.id == lot.invoice_line)
|
|
.join(purchase_invoice, 'LEFT',
|
|
condition=purchase_invoice.id == purchase_invoice_line.invoice)
|
|
.join(sale_invoice_line, 'LEFT',
|
|
condition=sale_invoice_line.id == lot.sale_invoice_line)
|
|
.join(sale_invoice, 'LEFT',
|
|
condition=sale_invoice.id == sale_invoice_line.invoice)
|
|
.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'),
|
|
purchase_invoice.id.as_('purchase_invoice'),
|
|
val.sale.as_('sale'),
|
|
val.sale_line.as_('sale_line'),
|
|
sale_invoice.id.as_('sale_invoice'),
|
|
val.type.as_('type'),
|
|
val.reference.as_('reference'),
|
|
val.counterparty.as_('counterparty'),
|
|
val.product.as_('product'),
|
|
val.state.as_('state'),
|
|
val.quantity.as_('quantity'),
|
|
val.unit.as_('unit'),
|
|
val.currency.as_('currency'),
|
|
val.amount.as_('amount'),
|
|
val.base_amount.as_('base_amount'),
|
|
val.strategy.as_('strategy'),
|
|
where=where))
|
|
|
|
|
|
class CTRMMtmPnlContext(CTRMPnlContextMixin, ModelView):
|
|
"CTRM Mark-to-Market Context"
|
|
__name__ = 'ctrm.reporting.pnl.mtm.context'
|
|
|
|
|
|
class CTRMMtmPnl(ModelSQL, ModelView):
|
|
"CTRM Mark-to-Market"
|
|
__name__ = 'ctrm.reporting.pnl.mtm'
|
|
|
|
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'),
|
|
('derivative', 'Derivative'),
|
|
], "Type")
|
|
reference = fields.Char("Reference")
|
|
counterparty = fields.Many2One('party.party', "Counterparty")
|
|
product = fields.Many2One('product.product', "Product")
|
|
state = fields.Char("State")
|
|
quantity = fields.Numeric("Quantity", digits=(16, 5))
|
|
unit = fields.Many2One('product.uom', "Unit")
|
|
price = fields.Numeric("Price", digits=(16, 4))
|
|
mtm_price = fields.Numeric("MTM Price", digits=(16, 4))
|
|
currency = fields.Many2One('currency.currency', "Currency")
|
|
amount = fields.Numeric("Amount", digits=(16, 2))
|
|
mtm = fields.Numeric("MTM", digits=(16, 2))
|
|
mtm_delta = fields.Numeric("MTM Delta", 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_(ALL_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.quantity.as_('quantity'),
|
|
val.unit.as_('unit'),
|
|
val.price.as_('price'),
|
|
val.mtm_price.as_('mtm_price'),
|
|
val.currency.as_('currency'),
|
|
val.amount.as_('amount'),
|
|
val.mtm.as_('mtm'),
|
|
(Coalesce(val.mtm, 0) - Coalesce(val.amount, 0)).as_(
|
|
'mtm_delta'),
|
|
val.strategy.as_('strategy'),
|
|
where=where)
|
|
|
|
|
|
class CTRMPnlExplainContext(CTRMPnlContextMixin, ModelView):
|
|
"CTRM P&L Explain Context"
|
|
__name__ = 'ctrm.reporting.pnl.explain.context'
|
|
|
|
|
|
class CTRMPnlExplain(ModelSQL, ModelView):
|
|
"CTRM P&L Explain"
|
|
__name__ = 'ctrm.reporting.pnl.explain'
|
|
|
|
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_pnl = fields.Numeric("Physical P&L", digits=(16, 2))
|
|
fee_pnl = fields.Numeric("Fee P&L", digits=(16, 2))
|
|
derivative_pnl = fields.Numeric("Derivative P&L", digits=(16, 2))
|
|
mtm_delta = fields.Numeric("MTM Delta", digits=(16, 2))
|
|
total_pnl = fields.Numeric("Total P&L", digits=(16, 2))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
ValuationLine = Pool().get('valuation.valuation.line')
|
|
val = ValuationLine.__table__()
|
|
|
|
context = Transaction().context
|
|
where = val.type.in_(ALL_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_fee = val.type.in_([
|
|
'line fee',
|
|
'pur. fee',
|
|
'sale fee',
|
|
'shipment fee',
|
|
])
|
|
is_derivative = val.type.in_(DERIVATIVE_VALUATION_TYPES)
|
|
physical_pnl = Case(
|
|
(is_fee | is_derivative, 0), else_=Coalesce(val.amount, 0))
|
|
fee_pnl = Case((is_fee, Coalesce(val.amount, 0)), else_=0)
|
|
derivative_pnl = Case(
|
|
(is_derivative, Coalesce(val.amount, 0)), else_=0)
|
|
mtm_delta = Coalesce(val.mtm, 0) - Coalesce(val.amount, 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_pnl).as_('physical_pnl'),
|
|
Sum(fee_pnl).as_('fee_pnl'),
|
|
Sum(derivative_pnl).as_('derivative_pnl'),
|
|
Sum(mtm_delta).as_('mtm_delta'),
|
|
Sum(Coalesce(val.amount, 0)).as_('total_pnl'),
|
|
where=where,
|
|
group_by=group_by)
|
|
|
|
|
|
class CTRMPnlDimensionContext(CTRMPnlContextMixin, ModelView):
|
|
"CTRM P&L by Dimension Context"
|
|
__name__ = 'ctrm.reporting.pnl.dimension.context'
|
|
|
|
dimension = fields.Many2One('analytic.dimension', "Dimension")
|
|
value = fields.Many2One('analytic.dimension.value', "Value")
|
|
|
|
|
|
class CTRMPnlDimension(ModelSQL, ModelView):
|
|
"CTRM P&L by Dimension"
|
|
__name__ = 'ctrm.reporting.pnl.dimension'
|
|
|
|
valuation_date = fields.Date("Valuation Date")
|
|
dimension = fields.Many2One('analytic.dimension', "Dimension")
|
|
value = fields.Many2One('analytic.dimension.value', "Value")
|
|
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")
|
|
quantity = fields.Numeric("Quantity", digits=(16, 5))
|
|
amount = fields.Numeric("Amount", digits=(16, 2))
|
|
mtm = fields.Numeric("MTM", digits=(16, 2))
|
|
mtm_delta = fields.Numeric("MTM Delta", digits=(16, 2))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
ValuationLine = Pool().get('valuation.valuation.line')
|
|
Assignment = Pool().get('analytic.dimension.assignment')
|
|
val = ValuationLine.__table__()
|
|
purchase_assignment = Assignment.__table__()
|
|
sale_assignment = Assignment.__table__()
|
|
|
|
context = Transaction().context
|
|
dimension_expr = Coalesce(
|
|
sale_assignment.dimension, purchase_assignment.dimension)
|
|
value_expr = Coalesce(sale_assignment.value, purchase_assignment.value)
|
|
|
|
where = val.type.in_(ALL_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']
|
|
if context.get('dimension'):
|
|
where &= dimension_expr == context['dimension']
|
|
if context.get('value'):
|
|
where &= value_expr == context['value']
|
|
|
|
group_by = [
|
|
val.date,
|
|
dimension_expr,
|
|
value_expr,
|
|
val.product,
|
|
val.counterparty,
|
|
val.currency,
|
|
val.unit,
|
|
val.state,
|
|
val.strategy,
|
|
]
|
|
|
|
return (
|
|
val
|
|
.join(purchase_assignment, 'LEFT',
|
|
condition=purchase_assignment.purchase == val.purchase)
|
|
.join(sale_assignment, 'LEFT',
|
|
condition=sale_assignment.sale == val.sale)
|
|
.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'),
|
|
dimension_expr.as_('dimension'),
|
|
value_expr.as_('value'),
|
|
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(Coalesce(val.quantity, 0)).as_('quantity'),
|
|
Sum(Coalesce(val.amount, 0)).as_('amount'),
|
|
Sum(Coalesce(val.mtm, 0)).as_('mtm'),
|
|
Sum(Coalesce(val.mtm, 0) - Coalesce(val.amount, 0)).as_(
|
|
'mtm_delta'),
|
|
where=where,
|
|
group_by=group_by))
|