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)