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

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))