278 lines
9.7 KiB
Python
278 lines
9.7 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
|
|
|
|
|
|
class CTRMPhysicalPositionContext(ModelView):
|
|
"CTRM Physical Position Context"
|
|
__name__ = 'ctrm.reporting.position.physical.context'
|
|
|
|
as_of = fields.Date("As of")
|
|
product = fields.Many2One('product.product', "Product")
|
|
supplier = fields.Many2One('party.party', "Supplier")
|
|
client = fields.Many2One('party.party', "Client")
|
|
currency = fields.Many2One('currency.currency', "Currency")
|
|
position_type = fields.Selection([
|
|
(None, ""),
|
|
('open', 'Open'),
|
|
('physic', 'Physic'),
|
|
('shipped', 'Shipped'),
|
|
], "Position Type")
|
|
|
|
@classmethod
|
|
def default_as_of(cls):
|
|
Date = Pool().get('ir.date')
|
|
return Date.today()
|
|
|
|
|
|
class CTRMPhysicalPosition(ModelSQL, ModelView):
|
|
"CTRM Physical Position"
|
|
__name__ = 'ctrm.reporting.position.physical'
|
|
|
|
product = fields.Many2One('product.product', "Product")
|
|
supplier = fields.Many2One('party.party', "Supplier")
|
|
client = fields.Many2One('party.party', "Client")
|
|
currency = fields.Many2One('currency.currency', "Currency")
|
|
uom = fields.Many2One('product.uom', "Unit")
|
|
position_type = fields.Selection([
|
|
('open', 'Open'),
|
|
('physic', 'Physic'),
|
|
('shipped', 'Shipped'),
|
|
], "Position Type")
|
|
physical_qty = fields.Numeric("Physical Quantity", digits=(16, 5))
|
|
hedged_qty = fields.Numeric("Hedged Quantity", digits=(16, 5))
|
|
net_exposure = fields.Numeric("Net Exposure", digits=(16, 5))
|
|
amount = fields.Numeric("Amount", digits=(16, 2))
|
|
mtm = fields.Numeric("MTM", digits=(16, 2))
|
|
pnl = fields.Numeric("P&L", digits=(16, 2))
|
|
period_start = fields.Date("Period Start")
|
|
period_end = fields.Date("Period End")
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
LotReport = Pool().get('lot.report')
|
|
PurchaseLine = Pool().get('purchase.line')
|
|
Purchase = Pool().get('purchase.purchase')
|
|
SaleLine = Pool().get('sale.line')
|
|
Sale = Pool().get('sale.sale')
|
|
|
|
context = Transaction().context
|
|
as_of = context.get('as_of')
|
|
product = context.get('product')
|
|
supplier = context.get('supplier')
|
|
client = context.get('client')
|
|
currency = context.get('currency')
|
|
position_type = context.get('position_type')
|
|
|
|
lot_context = {
|
|
'purchase': None,
|
|
'sale': None,
|
|
'shipment': None,
|
|
'type': 'all',
|
|
'state': 'all',
|
|
'wh': 'all',
|
|
'group': 'by_physic',
|
|
'origin': 'all',
|
|
'ps': 'all',
|
|
'shipping_status': 'all',
|
|
}
|
|
if as_of:
|
|
lot_context['todate'] = as_of
|
|
if product:
|
|
lot_context['product'] = product
|
|
if supplier:
|
|
lot_context['supplier'] = supplier
|
|
if client:
|
|
lot_context['client'] = client
|
|
|
|
lr = LotReport.table_query(lot_context)
|
|
pl = PurchaseLine.__table__()
|
|
pu = Purchase.__table__()
|
|
sl = SaleLine.__table__()
|
|
sa = Sale.__table__()
|
|
|
|
position_type_expr = Case(
|
|
(lr.r_lot_type == 'virtual', 'open'),
|
|
(lr.r_shipping_status.in_(['scheduled', 'shipped', 'received']),
|
|
'shipped'),
|
|
else_='physic')
|
|
currency_expr = Coalesce(sa.currency, pu.currency)
|
|
price_expr = Coalesce(sl.unit_price, pl.unit_price, 0)
|
|
|
|
where = Literal(True)
|
|
if currency:
|
|
where &= currency_expr == currency
|
|
if position_type:
|
|
where &= position_type_expr == position_type
|
|
|
|
group_by = [
|
|
lr.r_lot_product,
|
|
lr.r_supplier,
|
|
lr.r_client,
|
|
currency_expr,
|
|
lr.r_lot_unit,
|
|
position_type_expr,
|
|
]
|
|
|
|
return (
|
|
lr
|
|
.join(pl, 'LEFT', condition=pl.id == lr.r_line)
|
|
.join(pu, 'LEFT', condition=pu.id == lr.r_purchase)
|
|
.join(sl, 'LEFT', condition=sl.id == lr.r_sale_line)
|
|
.join(sa, 'LEFT', condition=sa.id == lr.r_sale)
|
|
.select(
|
|
Literal(0).as_('create_uid'),
|
|
CurrentTimestamp().as_('create_date'),
|
|
Literal(None).as_('write_uid'),
|
|
Literal(None).as_('write_date'),
|
|
Min(lr.id).as_('id'),
|
|
lr.r_lot_product.as_('product'),
|
|
lr.r_supplier.as_('supplier'),
|
|
lr.r_client.as_('client'),
|
|
currency_expr.as_('currency'),
|
|
lr.r_lot_unit.as_('uom'),
|
|
position_type_expr.as_('position_type'),
|
|
Sum(lr.r_lot_quantity).as_('physical_qty'),
|
|
Literal(0).as_('hedged_qty'),
|
|
Sum(lr.r_lot_quantity).as_('net_exposure'),
|
|
Sum(lr.r_lot_quantity * price_expr).as_('amount'),
|
|
Literal(None).as_('mtm'),
|
|
Literal(None).as_('pnl'),
|
|
Literal(None).as_('period_start'),
|
|
Literal(None).as_('period_end'),
|
|
where=where,
|
|
group_by=group_by))
|
|
|
|
|
|
class CTRMFinancialPositionContext(ModelView):
|
|
"CTRM Financial Position Context"
|
|
__name__ = 'ctrm.reporting.position.financial.context'
|
|
|
|
trade_from = fields.Date("Trade Date From")
|
|
trade_to = fields.Date("Trade Date To")
|
|
maturity_from = fields.Date("Maturity From")
|
|
maturity_to = fields.Date("Maturity To")
|
|
product = fields.Many2One('product.product', "Product")
|
|
party = fields.Many2One('party.party', "Counterparty")
|
|
purchase = fields.Many2One('purchase.purchase', "Purchase")
|
|
sale = fields.Many2One('sale.sale', "Sale")
|
|
direction = fields.Selection([
|
|
(None, ''),
|
|
('long', 'Long'),
|
|
('short', 'Short'),
|
|
], 'Direction')
|
|
state = fields.Selection([
|
|
(None, ''),
|
|
('open', 'Open'),
|
|
('closed', 'Closed'),
|
|
], 'State')
|
|
open_only = fields.Boolean("Open Positions Only")
|
|
|
|
@classmethod
|
|
def default_trade_to(cls):
|
|
Date = Pool().get('ir.date')
|
|
return Date.today()
|
|
|
|
@classmethod
|
|
def default_open_only(cls):
|
|
return True
|
|
|
|
|
|
class CTRMFinancialPosition(ModelSQL, ModelView):
|
|
"CTRM Financial Position"
|
|
__name__ = 'ctrm.reporting.position.financial'
|
|
|
|
derivative = fields.Many2One('derivative.derivative', "Derivative")
|
|
trade_date = fields.Date("Trade Date")
|
|
maturity_date = fields.Date("Maturity")
|
|
product = fields.Many2One('product.product', "Product")
|
|
party = fields.Many2One('party.party', "Counterparty")
|
|
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")
|
|
price_index = fields.Many2One('price.price', "Curve")
|
|
direction = fields.Selection([
|
|
('long', 'Long'),
|
|
('short', 'Short'),
|
|
], 'Direction')
|
|
state = fields.Selection([
|
|
('open', 'Open'),
|
|
('closed', 'Closed'),
|
|
], 'State')
|
|
contract_count = fields.Integer("Nb ct")
|
|
open_qty = fields.Numeric("Open Quantity", digits='unit')
|
|
entry_price = fields.Numeric("Entry Price", digits='currency')
|
|
exit_price = fields.Numeric("Exit Price", digits='currency')
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
Derivative = Pool().get('derivative.derivative')
|
|
d = Derivative.__table__()
|
|
|
|
context = Transaction().context
|
|
trade_from = context.get('trade_from')
|
|
trade_to = context.get('trade_to')
|
|
maturity_from = context.get('maturity_from')
|
|
maturity_to = context.get('maturity_to')
|
|
product = context.get('product')
|
|
party = context.get('party')
|
|
purchase = context.get('purchase')
|
|
sale = context.get('sale')
|
|
direction = context.get('direction')
|
|
state = context.get('state')
|
|
open_only = context.get('open_only')
|
|
|
|
where = Literal(True)
|
|
if trade_from:
|
|
where &= d.trade_date >= trade_from
|
|
if trade_to:
|
|
where &= d.trade_date <= trade_to
|
|
if maturity_from:
|
|
where &= d.maturity_date >= maturity_from
|
|
if maturity_to:
|
|
where &= d.maturity_date <= maturity_to
|
|
if product:
|
|
where &= d.product == product
|
|
if party:
|
|
where &= d.party == party
|
|
if purchase:
|
|
where &= d.purchase == purchase
|
|
if sale:
|
|
where &= d.sale == sale
|
|
if direction:
|
|
where &= d.direction == direction
|
|
if state:
|
|
where &= d.state == state
|
|
if open_only:
|
|
where &= d.open_qty > 0
|
|
|
|
return d.select(
|
|
Literal(0).as_('create_uid'),
|
|
CurrentTimestamp().as_('create_date'),
|
|
Literal(None).as_('write_uid'),
|
|
Literal(None).as_('write_date'),
|
|
d.id.as_('id'),
|
|
d.id.as_('derivative'),
|
|
d.trade_date.as_('trade_date'),
|
|
d.maturity_date.as_('maturity_date'),
|
|
d.product.as_('product'),
|
|
d.party.as_('party'),
|
|
d.purchase.as_('purchase'),
|
|
d.line.as_('purchase_line'),
|
|
d.sale.as_('sale'),
|
|
d.sale_line.as_('sale_line'),
|
|
d.price_index.as_('price_index'),
|
|
d.direction.as_('direction'),
|
|
d.state.as_('state'),
|
|
d.nb_ct.as_('contract_count'),
|
|
d.open_qty.as_('open_qty'),
|
|
d.price.as_('entry_price'),
|
|
d.exit_price.as_('exit_price'),
|
|
where=where)
|