Valuation/ark as finished
This commit is contained in:
@@ -147,41 +147,57 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
{'type': 'derivative', 'amount': Decimal('30')},
|
||||
])
|
||||
|
||||
def test_generate_skips_finished_purchase_line(self):
|
||||
'valuation generation keeps deleting old rows but skips finished purchase lines'
|
||||
def test_generate_keeps_finished_purchase_line_physical_pnl(self):
|
||||
'finished purchase lines still generate physical lot valuation'
|
||||
Valuation = Pool().get('valuation.valuation')
|
||||
line = Mock(finished=True)
|
||||
|
||||
with patch.object(Valuation, '_delete_existing') as delete_existing, patch.object(
|
||||
Valuation, 'create_pnl_fee_from_line') as create_fees, patch.object(
|
||||
Valuation, 'create_pnl_price_from_line') as create_prices, patch.object(
|
||||
Valuation, 'create_pnl_der_from_line') as create_derivatives, patch(
|
||||
Valuation, 'create_pnl_fee_from_line',
|
||||
return_value=[{'type': 'pur. fee'}]) as create_fees, patch.object(
|
||||
Valuation, 'create_pnl_price_from_line',
|
||||
return_value=[{'type': 'pur. priced'}]) as create_prices, patch.object(
|
||||
Valuation, 'create_pnl_der_from_line',
|
||||
return_value=[{'type': 'derivative'}]) as create_derivatives, patch(
|
||||
'trytond.modules.purchase_trade.valuation.Pool') as PoolMock:
|
||||
Valuation.generate(line)
|
||||
|
||||
delete_existing.assert_called_once_with(line, selected_types=None)
|
||||
create_fees.assert_not_called()
|
||||
create_prices.assert_not_called()
|
||||
create_derivatives.assert_not_called()
|
||||
PoolMock.return_value.get.assert_not_called()
|
||||
create_fees.assert_called_once_with(line)
|
||||
create_prices.assert_called_once_with(line)
|
||||
create_derivatives.assert_called_once_with(line)
|
||||
valuation_model = PoolMock.return_value.get.return_value
|
||||
valuation_model.create.assert_any_call([
|
||||
{'type': 'pur. fee'},
|
||||
{'type': 'pur. priced'},
|
||||
{'type': 'derivative'},
|
||||
])
|
||||
|
||||
def test_generate_skips_finished_sale_line(self):
|
||||
'sale valuation generation keeps deleting old rows but skips finished sale lines'
|
||||
def test_generate_keeps_finished_sale_line_physical_pnl(self):
|
||||
'finished sale lines still generate physical lot valuation'
|
||||
Valuation = Pool().get('valuation.valuation')
|
||||
sale_line = Mock(finished=True)
|
||||
|
||||
with patch.object(Valuation, '_delete_existing_sale_line') as delete_existing, patch.object(
|
||||
Valuation, 'create_pnl_fee_from_sale_line') as create_fees, patch.object(
|
||||
Valuation, 'create_pnl_price_from_sale_line') as create_prices, patch.object(
|
||||
Valuation, 'create_pnl_der_from_sale_line') as create_derivatives, patch(
|
||||
Valuation, 'create_pnl_fee_from_sale_line',
|
||||
return_value=[{'type': 'sale fee'}]) as create_fees, patch.object(
|
||||
Valuation, 'create_pnl_price_from_sale_line',
|
||||
return_value=[{'type': 'sale priced'}]) as create_prices, patch.object(
|
||||
Valuation, 'create_pnl_der_from_sale_line',
|
||||
return_value=[{'type': 'derivative'}]) as create_derivatives, patch(
|
||||
'trytond.modules.purchase_trade.valuation.Pool') as PoolMock:
|
||||
Valuation.generate_from_sale_line(sale_line)
|
||||
|
||||
delete_existing.assert_called_once_with(sale_line, selected_types=None)
|
||||
create_fees.assert_not_called()
|
||||
create_prices.assert_not_called()
|
||||
create_derivatives.assert_not_called()
|
||||
PoolMock.return_value.get.assert_not_called()
|
||||
create_fees.assert_called_once_with(sale_line)
|
||||
create_prices.assert_called_once_with(sale_line)
|
||||
create_derivatives.assert_called_once_with(sale_line)
|
||||
valuation_model = PoolMock.return_value.get.return_value
|
||||
valuation_model.create.assert_any_call([
|
||||
{'type': 'sale fee'},
|
||||
{'type': 'sale priced'},
|
||||
{'type': 'derivative'},
|
||||
])
|
||||
|
||||
def test_create_pnl_fee_from_line_accepts_missing_rate_amount(self):
|
||||
'purchase fee valuation treats an uncomputed rate amount as zero'
|
||||
@@ -257,16 +273,32 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
self.assertEqual(fee.get_amount(), Decimal('13.33'))
|
||||
|
||||
def test_create_pnl_price_from_line_ignores_finished_matched_sale_line(self):
|
||||
'purchase valuation does not add sale-side pnl when the matched sale line is finished'
|
||||
def test_create_pnl_price_from_line_keeps_finished_physical_sale_line(self):
|
||||
'purchase valuation keeps finished sale-side pnl on physical lots'
|
||||
Valuation = Pool().get('valuation.valuation')
|
||||
currency = Mock(id=1)
|
||||
company = Mock(currency=currency.id)
|
||||
unit = Mock(id=1)
|
||||
product = Mock(id=1)
|
||||
party = Mock(id=1)
|
||||
sale = Mock(id=2, currency=currency, company=company, party=party)
|
||||
finished_sale_line = Mock(
|
||||
finished=True,
|
||||
price_type='priced',
|
||||
mtm=[],
|
||||
sale=sale,
|
||||
unit=unit,
|
||||
product=product,
|
||||
)
|
||||
sale_lot = Mock(sale_line=finished_sale_line)
|
||||
sale_lot = Mock(
|
||||
id=3,
|
||||
sale_line=finished_sale_line,
|
||||
lot_price_sale=Decimal('20'),
|
||||
lot_type='physic',
|
||||
)
|
||||
sale_lot.get_current_quantity_converted.return_value = Decimal('2')
|
||||
purchase_lot = Mock(
|
||||
id=4,
|
||||
sale_line=None,
|
||||
lot_price=Decimal('10'),
|
||||
lot_type='physic',
|
||||
@@ -277,9 +309,9 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
lots=[purchase_lot],
|
||||
price_type='priced',
|
||||
mtm=[],
|
||||
purchase=Mock(id=1, currency=Mock(id=1), company=Mock(currency=Mock(id=1)), party=Mock(id=1)),
|
||||
unit=Mock(id=1),
|
||||
product=Mock(id=1),
|
||||
purchase=Mock(id=1, currency=currency, company=company, party=party),
|
||||
unit=unit,
|
||||
product=product,
|
||||
)
|
||||
|
||||
lot_qt_model = Mock()
|
||||
@@ -287,13 +319,20 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
with patch(
|
||||
'trytond.modules.purchase_trade.valuation.Pool') as PoolMock:
|
||||
PoolMock.return_value.get.return_value = lot_qt_model
|
||||
PoolMock.return_value.get.side_effect = lambda name: {
|
||||
'lot.qt': lot_qt_model,
|
||||
'currency.currency': Mock(),
|
||||
'ir.date': Mock(today=Mock(return_value=datetime.date(2026, 4, 29))),
|
||||
}[name]
|
||||
|
||||
values = Valuation.create_pnl_price_from_line(line)
|
||||
|
||||
self.assertEqual(len(values), 1)
|
||||
self.assertEqual(len(values), 2)
|
||||
self.assertEqual(values[0]['type'], 'pur. priced')
|
||||
self.assertNotIn('sale_line', values[0])
|
||||
self.assertEqual(values[1]['type'], 'sale priced')
|
||||
self.assertEqual(values[1]['sale_line'], finished_sale_line.id)
|
||||
self.assertEqual(values[1]['reference'], 'Sale/Physic')
|
||||
|
||||
def test_sale_report_crop_name_handles_missing_crop(self):
|
||||
'sale report crop name returns an empty string when crop is missing'
|
||||
|
||||
Reference in New Issue
Block a user