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, ] row_id = ( Coalesce(Max(dimension_expr), 0) * 1000000 + Coalesce(Max(value_expr), 0)) 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'), row_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))