Mtm new
This commit is contained in:
@@ -21,7 +21,10 @@ PHYSICAL_VALUATION_TYPES = [
|
||||
'market',
|
||||
]
|
||||
DERIVATIVE_VALUATION_TYPES = ['derivative']
|
||||
ALL_VALUATION_TYPES = PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES
|
||||
MTM_VALUATION_TYPES = ['mtm']
|
||||
ALL_VALUATION_TYPES = (
|
||||
PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES
|
||||
+ MTM_VALUATION_TYPES)
|
||||
|
||||
|
||||
class CTRMValuationContextMixin:
|
||||
@@ -249,7 +252,8 @@ class CTRMNetPosition(ModelSQL, ModelView):
|
||||
|
||||
context = Transaction().context
|
||||
where = val.type.in_(
|
||||
PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES)
|
||||
PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES
|
||||
+ MTM_VALUATION_TYPES)
|
||||
if context.get('date'):
|
||||
where &= val.date == context['date']
|
||||
if context.get('product'):
|
||||
@@ -268,14 +272,17 @@ class CTRMNetPosition(ModelSQL, ModelView):
|
||||
where &= val.state == context['state']
|
||||
|
||||
is_derivative = val.type.in_(DERIVATIVE_VALUATION_TYPES)
|
||||
is_mtm = val.type.in_(MTM_VALUATION_TYPES)
|
||||
physical_quantity = Case(
|
||||
(is_derivative, 0), else_=Coalesce(val.quantity, 0))
|
||||
(is_derivative | is_mtm, 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))
|
||||
(is_derivative | is_mtm, 0), else_=Coalesce(val.amount, 0))
|
||||
derivative_amount = Case(
|
||||
(is_derivative, Coalesce(val.amount, 0)), else_=0)
|
||||
net_quantity = Case(
|
||||
(is_mtm, 0), else_=Coalesce(val.quantity, 0))
|
||||
|
||||
group_by = [
|
||||
val.date,
|
||||
@@ -302,7 +309,7 @@ class CTRMNetPosition(ModelSQL, ModelView):
|
||||
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(net_quantity).as_('net_quantity'),
|
||||
Sum(physical_amount).as_('physical_amount'),
|
||||
Sum(derivative_amount).as_('derivative_amount'),
|
||||
Sum(Coalesce(val.amount, 0)).as_('net_amount'),
|
||||
@@ -396,7 +403,8 @@ class CTRMRealizedPnl(ModelSQL, ModelView):
|
||||
context = Transaction().context
|
||||
realization = context.get(
|
||||
'realization', 'purchase_and_sale_invoiced')
|
||||
where = val.type.in_(ALL_VALUATION_TYPES)
|
||||
where = val.type.in_(
|
||||
PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES)
|
||||
if context.get('date'):
|
||||
where &= val.date == context['date']
|
||||
if context.get('product'):
|
||||
@@ -487,6 +495,7 @@ class CTRMMtmPnl(ModelSQL, ModelView):
|
||||
('sale fee', 'Sale fee'),
|
||||
('shipment fee', 'Shipment fee'),
|
||||
('market', 'Market'),
|
||||
('mtm', 'Mtm'),
|
||||
('derivative', 'Derivative'),
|
||||
], "Type")
|
||||
reference = fields.Char("Reference")
|
||||
@@ -610,8 +619,10 @@ class CTRMPnlExplain(ModelSQL, ModelView):
|
||||
'shipment fee',
|
||||
])
|
||||
is_derivative = val.type.in_(DERIVATIVE_VALUATION_TYPES)
|
||||
is_mtm = val.type.in_(MTM_VALUATION_TYPES)
|
||||
physical_pnl = Case(
|
||||
(is_fee | is_derivative, 0), else_=Coalesce(val.amount, 0))
|
||||
(is_fee | is_derivative | is_mtm, 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)
|
||||
@@ -737,7 +748,9 @@ class CTRMPnlDimension(ModelSQL, ModelView):
|
||||
val.unit.as_('unit'),
|
||||
val.state.as_('state'),
|
||||
val.strategy.as_('strategy'),
|
||||
Sum(Coalesce(val.quantity, 0)).as_('quantity'),
|
||||
Sum(Case(
|
||||
(val.type.in_(MTM_VALUATION_TYPES), 0),
|
||||
else_=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_(
|
||||
@@ -1613,7 +1626,8 @@ class CTRMAccruals(ModelSQL, ModelView):
|
||||
else_='physical')
|
||||
context = Transaction().context
|
||||
where = (
|
||||
val.type.in_(ALL_VALUATION_TYPES)
|
||||
val.type.in_(
|
||||
PHYSICAL_VALUATION_TYPES + DERIVATIVE_VALUATION_TYPES)
|
||||
& ((val.lot == Null)
|
||||
| ((lot.invoice_line == Null)
|
||||
& (lot.sale_invoice_line == Null))))
|
||||
|
||||
@@ -1022,11 +1022,11 @@ class Lot(metaclass=PoolMeta):
|
||||
return True
|
||||
return False
|
||||
|
||||
def createMove(self,r,qt,sh):
|
||||
Move = Pool().get('stock.move')
|
||||
nm = Move()
|
||||
nm.from_location = r.lot_p.line.purchase.from_location
|
||||
nm.to_location = r.lot_p.line.purchase.to_location
|
||||
def createMove(self,r,qt,sh):
|
||||
Move = Pool().get('stock.move')
|
||||
nm = Move()
|
||||
nm.from_location = r.lot_p.line.purchase.from_location
|
||||
nm.to_location = r.lot_p.line.purchase.to_location
|
||||
nm.product = r.lot_p.lot_product
|
||||
nm.unit = r.lot_unit
|
||||
nm.quantity = qt
|
||||
@@ -1034,11 +1034,32 @@ class Lot(metaclass=PoolMeta):
|
||||
nm.shipment = sh
|
||||
nm.currency = r.lot_p.line.currency
|
||||
nm.unit_price = r.lot_p.line.unit_price
|
||||
Move.save([nm])
|
||||
return nm.id
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
Move.save([nm])
|
||||
return nm.id
|
||||
|
||||
def create_shipment_move(self, shipment_origin):
|
||||
Move = Pool().get('stock.move')
|
||||
line = self.line
|
||||
if not line or not getattr(line, 'purchase', None):
|
||||
return
|
||||
unit = self.lot_unit or self.lot_unit_line or line.unit
|
||||
quantity = self.get_current_quantity_converted(0, unit)
|
||||
move = Move()
|
||||
move.from_location = line.purchase.from_location
|
||||
move.to_location = line.purchase.to_location
|
||||
move.product = self.lot_product
|
||||
move.unit = unit
|
||||
move.quantity = quantity
|
||||
move.origin = line
|
||||
move.shipment = shipment_origin
|
||||
move.currency = line.currency
|
||||
move.unit_price = line.unit_price
|
||||
move.lot = self
|
||||
Move.save([move])
|
||||
return move
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
vlist = [x.copy() for x in vlist]
|
||||
L = Pool().get('lot.lot')
|
||||
Uom = Pool().get('product.uom')
|
||||
@@ -3095,10 +3116,16 @@ class LotShipping(Wizard):
|
||||
elif self.ship.shipment == 'int':
|
||||
l.lot_shipment_internal = self.ship.shipment_internal
|
||||
logger.info("IN_SHIPPING2:%s",l.move)
|
||||
move = None
|
||||
if not l.move:
|
||||
continue
|
||||
move = l.create_shipment_move(shipment_origin)
|
||||
if not move:
|
||||
raise UserError(
|
||||
"Cannot create shipment move for lot %s."
|
||||
% l)
|
||||
logger.info("IN_SHIPPING3:%s",r)
|
||||
move = Move(l.move)
|
||||
if not move:
|
||||
move = Move(l.move)
|
||||
move.shipment = shipment_origin
|
||||
Move.save([move])
|
||||
linked_transit_move = move.get_linked_transit_move()
|
||||
|
||||
@@ -440,6 +440,60 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
with self.assertRaises(UserError):
|
||||
wizard.transition_shipping()
|
||||
|
||||
def test_lot_shipping_physical_without_move_creates_shipment_move(self):
|
||||
'linking a physical lot to shipment creates the missing stock move'
|
||||
wizard = lot_module.LotShipping()
|
||||
shipment = Mock(id=40)
|
||||
wizard.ship = Mock(
|
||||
shipment='in',
|
||||
shipment_in=shipment,
|
||||
shipment_out=None,
|
||||
shipment_internal=None,
|
||||
create_new_shipment=False,
|
||||
quantity=None,
|
||||
)
|
||||
record = Mock(
|
||||
id=2014,
|
||||
r_lot_type='physic',
|
||||
)
|
||||
wizard.records = [record]
|
||||
move = Mock()
|
||||
move.get_linked_transit_move.return_value = None
|
||||
lot = Mock(
|
||||
id=2014,
|
||||
move=None,
|
||||
line=Mock(),
|
||||
sale_line=None,
|
||||
)
|
||||
lot.get_current_quantity_converted.return_value = Decimal('22')
|
||||
lot.getVlot_p.return_value = Mock()
|
||||
lot.getVlot_s.return_value = None
|
||||
lot.create_shipment_move.return_value = move
|
||||
Lot = Mock()
|
||||
Lot.return_value = lot
|
||||
Lot.skip_quantity_consistency.return_value.__enter__ = Mock()
|
||||
Lot.skip_quantity_consistency.return_value.__exit__ = Mock()
|
||||
LotQt = Mock()
|
||||
Move = Mock()
|
||||
|
||||
pool = Mock()
|
||||
pool.get.side_effect = [Lot, LotQt, Move]
|
||||
with patch('trytond.modules.purchase_trade.lot.Pool',
|
||||
return_value=pool):
|
||||
state = wizard.transition_shipping()
|
||||
|
||||
self.assertEqual(state, 'end')
|
||||
self.assertEqual(lot.lot_shipment_in, shipment)
|
||||
lot.create_shipment_move.assert_called_once_with(
|
||||
'stock.shipment.in,40')
|
||||
self.assertEqual(move.shipment, 'stock.shipment.in,40')
|
||||
Move.save.assert_called_once_with([move])
|
||||
lot.updateVirtualPart.assert_called_once_with(
|
||||
Decimal('-22'), 'stock.shipment.in,40', None)
|
||||
Lot.save.assert_called()
|
||||
Lot.assert_lines_quantity_consistency.assert_called_once_with([
|
||||
lot.line])
|
||||
|
||||
def test_lot_shipping_scheduled_lotqt_keeps_planned_locations(self):
|
||||
'scheduled lot.qt keeps the planned from and to locations'
|
||||
wizard = lot_module.LotShipping()
|
||||
@@ -556,8 +610,8 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
Decimal('-349167.53'))
|
||||
|
||||
@with_transaction()
|
||||
def test_strategy_mtm_lines_split_by_curve_with_previous_price(self):
|
||||
'strategy MTM creates one valuation line per curve with previous price'
|
||||
def test_strategy_mtm_lines_are_separate_from_realized_price(self):
|
||||
'strategy MTM creates separate curve lines and preserves realized line'
|
||||
Valuation = Pool().get('valuation.valuation')
|
||||
valuation_date = datetime.date(2026, 6, 5)
|
||||
previous_date = datetime.date(2026, 6, 4)
|
||||
@@ -583,6 +637,7 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
price_index=curve_b,
|
||||
ratio=Decimal('40')),
|
||||
])
|
||||
line.mtm = [strategy]
|
||||
values = {
|
||||
'type': 'pur. priced',
|
||||
'price': Decimal('10'),
|
||||
@@ -596,22 +651,28 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
with patch('trytond.modules.purchase_trade.valuation.Pool') as PoolMock:
|
||||
PoolMock.return_value.get.return_value = price_value
|
||||
Valuation._append_strategy_mtm_lines(
|
||||
target, values, strategy, line)
|
||||
Valuation._append_pnl_values(target, values, line)
|
||||
|
||||
self.assertEqual(len(target), 2)
|
||||
self.assertEqual(target[0]['mtm_curve'], curve_a.id)
|
||||
self.assertEqual(target[0]['amount'], Decimal('-60.00'))
|
||||
self.assertEqual(target[0]['mtm_price'], Decimal('60.0000'))
|
||||
self.assertEqual(target[0]['mtm_price_prev'], Decimal('54.0000'))
|
||||
self.assertEqual(target[0]['amount_prev'], Decimal('-540.00'))
|
||||
self.assertEqual(target[0]['mtm'], Decimal('-600.00'))
|
||||
self.assertEqual(target[1]['mtm_curve'], curve_b.id)
|
||||
self.assertEqual(target[1]['amount'], Decimal('-40.00'))
|
||||
self.assertEqual(target[1]['mtm_price'], Decimal('20.0000'))
|
||||
self.assertEqual(target[1]['mtm_price_prev'], Decimal('18.0000'))
|
||||
self.assertEqual(target[1]['amount_prev'], Decimal('-180.00'))
|
||||
self.assertEqual(target[1]['mtm'], Decimal('-200.00'))
|
||||
self.assertEqual(len(target), 3)
|
||||
self.assertEqual(target[0], values)
|
||||
self.assertEqual(target[1]['type'], 'mtm')
|
||||
self.assertEqual(target[1]['mtm_curve'], curve_a.id)
|
||||
self.assertEqual(target[1]['price'], None)
|
||||
self.assertEqual(target[1]['amount'], Decimal('0'))
|
||||
self.assertEqual(target[1]['quantity'], Decimal('10'))
|
||||
self.assertEqual(target[1]['mtm_price'], Decimal('100.0000'))
|
||||
self.assertEqual(target[1]['mtm_price_prev'], Decimal('90.0000'))
|
||||
self.assertEqual(target[1]['amount_prev'], Decimal('-540.00'))
|
||||
self.assertEqual(target[1]['mtm'], Decimal('-600.00'))
|
||||
self.assertEqual(target[2]['type'], 'mtm')
|
||||
self.assertEqual(target[2]['mtm_curve'], curve_b.id)
|
||||
self.assertEqual(target[2]['price'], None)
|
||||
self.assertEqual(target[2]['amount'], Decimal('0'))
|
||||
self.assertEqual(target[2]['quantity'], Decimal('10'))
|
||||
self.assertEqual(target[2]['mtm_price'], Decimal('50.0000'))
|
||||
self.assertEqual(target[2]['mtm_price_prev'], Decimal('45.0000'))
|
||||
self.assertEqual(target[2]['amount_prev'], Decimal('-180.00'))
|
||||
self.assertEqual(target[2]['mtm'], Decimal('-200.00'))
|
||||
|
||||
def test_purchase_pnl_uses_partial_lotqt_match_quantity(self):
|
||||
'open matched purchase and sale pnl use the matched lot.qt quantity'
|
||||
@@ -1095,6 +1156,7 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
Valuation._get_generate_types('derivatives'),
|
||||
{'derivative'})
|
||||
self.assertIn('pur. priced', Valuation._get_generate_types('goods'))
|
||||
self.assertIn('mtm', Valuation._get_generate_types('goods'))
|
||||
|
||||
def test_filter_values_by_types_keeps_matching_entries_only(self):
|
||||
'type filtering keeps only the requested valuation entries'
|
||||
|
||||
@@ -32,6 +32,7 @@ VALTYPE = [
|
||||
('sale fee', 'Sale fee'),
|
||||
('shipment fee', 'Shipment fee'),
|
||||
('market', 'Market'),
|
||||
('mtm', 'Mtm'),
|
||||
('derivative', 'Derivative'),
|
||||
]
|
||||
|
||||
@@ -75,7 +76,7 @@ class ValuationBase(ModelSQL):
|
||||
'fees': {'line fee', 'pur. fee', 'sale fee', 'shipment fee'},
|
||||
'goods': {
|
||||
'priced', 'pur. priced', 'pur. efp',
|
||||
'sale priced', 'sale efp', 'market',
|
||||
'sale priced', 'sale efp', 'market', 'mtm',
|
||||
},
|
||||
'derivatives': {'derivative'},
|
||||
}
|
||||
@@ -573,11 +574,6 @@ class ValuationBase(ModelSQL):
|
||||
scenario.valuation_date,
|
||||
line.unit,
|
||||
strategy.currency)
|
||||
if component.ratio:
|
||||
ratio = Decimal(component.ratio) / Decimal(100)
|
||||
value *= ratio
|
||||
if previous is not None:
|
||||
previous *= ratio
|
||||
return round(value, 4), (
|
||||
round(previous, 4) if previous is not None else None)
|
||||
|
||||
@@ -587,6 +583,34 @@ class ValuationBase(ModelSQL):
|
||||
return value
|
||||
return round(Decimal(value) * share, digits)
|
||||
|
||||
@classmethod
|
||||
def _mtm_sign(cls, values):
|
||||
amount = values.get('amount')
|
||||
if amount and amount < 0:
|
||||
return Decimal(-1)
|
||||
if not amount and values.get('type') in {'pur. priced', 'pur. efp'}:
|
||||
return Decimal(-1)
|
||||
return Decimal(1)
|
||||
|
||||
@classmethod
|
||||
def _mtm_line_values(cls, values, strategy, mtm_price, mtm_amount,
|
||||
mtm_curve=None, mtm_price_prev=None, mtm_amount_prev=None):
|
||||
line_values = dict(values)
|
||||
line_values.update({
|
||||
'type': 'mtm',
|
||||
'reference': 'MTM/%s' % (values.get('reference') or ''),
|
||||
'price': None,
|
||||
'amount': Decimal(0),
|
||||
'base_amount': Decimal(0),
|
||||
'mtm_price': mtm_price,
|
||||
'mtm_price_prev': mtm_price_prev,
|
||||
'mtm_curve': mtm_curve,
|
||||
'amount_prev': mtm_amount_prev,
|
||||
'mtm': mtm_amount,
|
||||
'strategy': strategy,
|
||||
})
|
||||
return line_values
|
||||
|
||||
@classmethod
|
||||
def _append_strategy_mtm_lines(cls, target, values, strategy, line):
|
||||
components = list(strategy.components or [])
|
||||
@@ -595,76 +619,53 @@ class ValuationBase(ModelSQL):
|
||||
if component.price_source_type == 'curve'
|
||||
and component.price_index]
|
||||
if not curve_components:
|
||||
line_values = dict(values)
|
||||
line_values['mtm_price'] = cls._get_strategy_mtm_price(
|
||||
strategy, line)
|
||||
line_values['amount_prev'] = None
|
||||
line_values['mtm'] = cls._signed_strategy_mtm(
|
||||
values, strategy, line)
|
||||
line_values['strategy'] = strategy
|
||||
target.append(line_values)
|
||||
target.append(cls._mtm_line_values(
|
||||
values,
|
||||
strategy,
|
||||
cls._get_strategy_mtm_price(strategy, line),
|
||||
cls._signed_strategy_mtm(values, strategy, line)))
|
||||
return
|
||||
|
||||
curve_component_ids = {id(component) for component in curve_components}
|
||||
total_weight = sum(
|
||||
cls._component_weight(component)
|
||||
for component in components) or Decimal(100)
|
||||
total_mtm_price = cls._get_strategy_mtm_price(strategy, line)
|
||||
curve_mtm_price = Decimal(0)
|
||||
signed_factor = Decimal(1)
|
||||
amount = values.get('amount')
|
||||
if amount and amount < 0:
|
||||
signed_factor = Decimal(-1)
|
||||
elif not amount and values.get('type') in {'pur. priced', 'pur. efp'}:
|
||||
signed_factor = Decimal(-1)
|
||||
signed_factor = cls._mtm_sign(values)
|
||||
|
||||
for component in curve_components:
|
||||
share = cls._component_weight(component) / total_weight
|
||||
ratio = cls._component_weight(component) / Decimal(100)
|
||||
mtm_price, mtm_price_prev = cls._curve_component_price(
|
||||
component, line, strategy)
|
||||
curve_mtm_price += mtm_price
|
||||
line_values = dict(values)
|
||||
line_values['price'] = cls._split_value(
|
||||
values.get('price'), share, digits=4)
|
||||
line_values['amount'] = cls._split_value(
|
||||
values.get('amount'), share)
|
||||
line_values['base_amount'] = cls._split_value(
|
||||
values.get('base_amount'), share)
|
||||
line_values['mtm_price'] = mtm_price
|
||||
line_values['mtm_price_prev'] = mtm_price_prev
|
||||
line_values['mtm_curve'] = component.price_index.id
|
||||
line_values['amount_prev'] = (
|
||||
weighted_mtm_price = mtm_price * ratio
|
||||
curve_mtm_price += weighted_mtm_price
|
||||
mtm_amount_prev = (
|
||||
round(
|
||||
mtm_price_prev * Decimal(values['quantity'])
|
||||
mtm_price_prev * ratio * Decimal(values['quantity'])
|
||||
* signed_factor, 2)
|
||||
if mtm_price_prev is not None else None)
|
||||
line_values['mtm'] = round(
|
||||
mtm_price * Decimal(values['quantity']) * signed_factor, 2)
|
||||
line_values['strategy'] = strategy
|
||||
target.append(line_values)
|
||||
target.append(cls._mtm_line_values(
|
||||
values,
|
||||
strategy,
|
||||
mtm_price,
|
||||
round(
|
||||
mtm_price * ratio * Decimal(values['quantity'])
|
||||
* signed_factor, 2),
|
||||
mtm_curve=component.price_index.id,
|
||||
mtm_price_prev=mtm_price_prev,
|
||||
mtm_amount_prev=mtm_amount_prev))
|
||||
|
||||
residual_weight = sum(
|
||||
cls._component_weight(component)
|
||||
for component in components
|
||||
if id(component) not in curve_component_ids)
|
||||
if residual_weight:
|
||||
share = residual_weight / total_weight
|
||||
mtm_price = round(total_mtm_price - curve_mtm_price, 4)
|
||||
line_values = dict(values)
|
||||
line_values['price'] = cls._split_value(
|
||||
values.get('price'), share, digits=4)
|
||||
line_values['amount'] = cls._split_value(
|
||||
values.get('amount'), share)
|
||||
line_values['base_amount'] = cls._split_value(
|
||||
values.get('base_amount'), share)
|
||||
line_values['mtm_price'] = mtm_price
|
||||
line_values['mtm_price_prev'] = None
|
||||
line_values['mtm_curve'] = None
|
||||
line_values['amount_prev'] = None
|
||||
line_values['mtm'] = round(
|
||||
mtm_price * Decimal(values['quantity']) * signed_factor, 2)
|
||||
line_values['strategy'] = strategy
|
||||
target.append(line_values)
|
||||
target.append(cls._mtm_line_values(
|
||||
values,
|
||||
strategy,
|
||||
mtm_price,
|
||||
round(
|
||||
mtm_price * Decimal(values['quantity']) * signed_factor,
|
||||
2)))
|
||||
|
||||
@staticmethod
|
||||
def _get_basis_component_total(record):
|
||||
@@ -813,6 +814,7 @@ class ValuationBase(ModelSQL):
|
||||
def _append_pnl_values(cls, price_lines, values, mtm_source):
|
||||
if (values and getattr(mtm_source, 'mtm', None)
|
||||
and cls._supports_strategy_mtm(values)):
|
||||
price_lines.append(values)
|
||||
for strat in mtm_source.mtm:
|
||||
cls._append_strategy_mtm_lines(
|
||||
price_lines, values, strat, mtm_source)
|
||||
@@ -1014,26 +1016,14 @@ class ValuationBase(ModelSQL):
|
||||
state='unfixed',
|
||||
pnl_type='sale priced'
|
||||
)
|
||||
if sale_line.mtm and cls._supports_strategy_mtm(values):
|
||||
for strat in sale_line.mtm:
|
||||
cls._append_strategy_mtm_lines(
|
||||
price_lines, values, strat, sale_line)
|
||||
else:
|
||||
if values:
|
||||
price_lines.append(values)
|
||||
cls._append_pnl_values(price_lines, values, sale_line)
|
||||
continue
|
||||
|
||||
for pc in summaries:
|
||||
values = cls._build_basis_pnl_from_sale_line(
|
||||
sale_line=sale_line, lot=lot, pc=pc,
|
||||
extra_price=premium_delta)
|
||||
if sale_line.mtm and cls._supports_strategy_mtm(values):
|
||||
for strat in sale_line.mtm:
|
||||
cls._append_strategy_mtm_lines(
|
||||
price_lines, values, strat, sale_line)
|
||||
else:
|
||||
if values:
|
||||
price_lines.append(values)
|
||||
cls._append_pnl_values(price_lines, values, sale_line)
|
||||
|
||||
elif sale_line.price_type in ('priced', 'efp'):
|
||||
price = cls._get_sale_lot_price(sale_line, lot)
|
||||
@@ -1046,13 +1036,7 @@ class ValuationBase(ModelSQL):
|
||||
state='fixed' if sale_line.price_type == 'priced' else 'not fixed',
|
||||
pnl_type=f'sale {sale_line.price_type}'
|
||||
)
|
||||
if sale_line.mtm and cls._supports_strategy_mtm(values):
|
||||
for strat in sale_line.mtm:
|
||||
cls._append_strategy_mtm_lines(
|
||||
price_lines, values, strat, sale_line)
|
||||
else:
|
||||
if values:
|
||||
price_lines.append(values)
|
||||
cls._append_pnl_values(price_lines, values, sale_line)
|
||||
|
||||
return price_lines
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<field name="fee" optional="1"/>
|
||||
<field name="type"
|
||||
widget="badge"
|
||||
badge_colors="priced:#2563eb,Price:#2563eb,pur. priced:#1d4ed8,Pur. price:#1d4ed8,pur. efp:#38bdf8,Pur. efp:#38bdf8,sale priced:#16a34a,Sale price:#16a34a,sale efp:#86efac,Sale efp:#86efac,market:#64748b,Market:#64748b,line fee:#d97706,Line fee:#d97706,pur. fee:#f59e0b,Pur. fee:#f59e0b,sale fee:#fb923c,Sale fee:#fb923c,shipment fee:#0f766e,Shipment fee:#0f766e,derivative:#8b5cf6,Derivative:#8b5cf6,*:#94a3b8"/>
|
||||
badge_colors="priced:#2563eb,Price:#2563eb,pur. priced:#1d4ed8,Pur. price:#1d4ed8,pur. efp:#38bdf8,Pur. efp:#38bdf8,sale priced:#16a34a,Sale price:#16a34a,sale efp:#86efac,Sale efp:#86efac,market:#64748b,Market:#64748b,line fee:#d97706,Line fee:#d97706,pur. fee:#f59e0b,Pur. fee:#f59e0b,sale fee:#fb923c,Sale fee:#fb923c,shipment fee:#0f766e,Shipment fee:#0f766e,mtm:#9f1239,Mtm:#9f1239,derivative:#8b5cf6,Derivative:#8b5cf6,*:#94a3b8"/>
|
||||
<field name="reference"/>
|
||||
<field name="counterparty"/>
|
||||
<field name="state"/>
|
||||
|
||||
@@ -7,7 +7,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="fee" optional="1"/>
|
||||
<field name="type"
|
||||
widget="badge"
|
||||
badge_colors="priced:#2563eb,Price:#2563eb,pur. priced:#1d4ed8,Pur. price:#1d4ed8,pur. efp:#38bdf8,Pur. efp:#38bdf8,sale priced:#16a34a,Sale price:#16a34a,sale efp:#86efac,Sale efp:#86efac,market:#64748b,Market:#64748b,line fee:#d97706,Line fee:#d97706,pur. fee:#f59e0b,Pur. fee:#f59e0b,sale fee:#fb923c,Sale fee:#fb923c,shipment fee:#0f766e,Shipment fee:#0f766e,derivative:#8b5cf6,Derivative:#8b5cf6,*:#94a3b8"/>
|
||||
badge_colors="priced:#2563eb,Price:#2563eb,pur. priced:#1d4ed8,Pur. price:#1d4ed8,pur. efp:#38bdf8,Pur. efp:#38bdf8,sale priced:#16a34a,Sale price:#16a34a,sale efp:#86efac,Sale efp:#86efac,market:#64748b,Market:#64748b,line fee:#d97706,Line fee:#d97706,pur. fee:#f59e0b,Pur. fee:#f59e0b,sale fee:#fb923c,Sale fee:#fb923c,shipment fee:#0f766e,Shipment fee:#0f766e,mtm:#9f1239,Mtm:#9f1239,derivative:#8b5cf6,Derivative:#8b5cf6,*:#94a3b8"/>
|
||||
<field name="reference"/>
|
||||
<field name="counterparty"/>
|
||||
<field name="state"/>
|
||||
|
||||
Reference in New Issue
Block a user