ICT bulk
This commit is contained in:
@@ -184,6 +184,20 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
self.assertEqual(
|
||||
PurchaseLine.default_pricing_rule(), 'Default pricing rule')
|
||||
|
||||
def test_sale_and_purchase_trader_operator_domains_use_explicit_categories(self):
|
||||
'sale and purchase trader/operator fields are filtered by TRADER/OPERATOR categories'
|
||||
Sale = Pool().get('sale.sale')
|
||||
Purchase = Pool().get('purchase.purchase')
|
||||
|
||||
self.assertEqual(
|
||||
Sale.trader.domain, [('categories.name', '=', 'TRADER')])
|
||||
self.assertEqual(
|
||||
Sale.operator.domain, [('categories.name', '=', 'OPERATOR')])
|
||||
self.assertEqual(
|
||||
Purchase.trader.domain, [('categories.name', '=', 'TRADER')])
|
||||
self.assertEqual(
|
||||
Purchase.operator.domain, [('categories.name', '=', 'OPERATOR')])
|
||||
|
||||
def test_sale_line_write_updates_virtual_lot_when_theorical_qty_increases(self):
|
||||
'sale line write increases virtual lot and open lot.qt when contractual qty grows'
|
||||
SaleLine = Pool().get('sale.line')
|
||||
@@ -841,15 +855,86 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
'USC 8.3000 PER POUND (EIGHT USC AND THIRTY CENTS) ON ICE Cotton #2 MARCH 2026',
|
||||
)])
|
||||
|
||||
def test_invoice_report_note_title_uses_total_amount_sign(self):
|
||||
'final invoice title switches between credit and debit note'
|
||||
def test_sale_report_uses_single_virtual_lot_hist_when_no_physical(self):
|
||||
'sale report uses the unique virtual lot hist when no physical lot exists'
|
||||
Sale = Pool().get('sale.sale')
|
||||
|
||||
virtual = Mock(lot_type='virtual', lot_unit_line=Mock(rec_name='LBS'))
|
||||
virtual.get_hist_quantity.return_value = (
|
||||
Decimal('930'),
|
||||
Decimal('0'),
|
||||
)
|
||||
line = Mock(type='line', quantity=Decimal('1000'))
|
||||
line.lots = [virtual]
|
||||
line.unit = Mock(rec_name='MT')
|
||||
line.del_period = Mock(description='MARCH 2026')
|
||||
|
||||
sale = Sale()
|
||||
sale.lines = [line]
|
||||
|
||||
self.assertEqual(sale.report_net, Decimal('930'))
|
||||
self.assertEqual(sale.report_gross, Decimal('930'))
|
||||
self.assertEqual(sale.report_total_quantity, '930.0')
|
||||
self.assertEqual(sale.report_quantity_unit_upper, 'LBS')
|
||||
self.assertEqual(
|
||||
sale.report_quantity_lines,
|
||||
'930.0 LBS (NINE HUNDRED AND THIRTY POUNDS) - MARCH 2026')
|
||||
|
||||
def test_sale_report_prefers_physical_lot_hist_over_virtual(self):
|
||||
'sale report prioritizes physical lot hist values over virtual ones'
|
||||
Sale = Pool().get('sale.sale')
|
||||
|
||||
virtual = Mock(lot_type='virtual', lot_unit_line=Mock(rec_name='LBS'))
|
||||
virtual.get_hist_quantity.return_value = (
|
||||
Decimal('930'),
|
||||
Decimal('940'),
|
||||
)
|
||||
physical = Mock(lot_type='physic', lot_unit_line=Mock(rec_name='LBS'))
|
||||
physical.get_hist_quantity.return_value = (
|
||||
Decimal('950'),
|
||||
Decimal('980'),
|
||||
)
|
||||
line = Mock(type='line', quantity=Decimal('1000'))
|
||||
line.lots = [virtual, physical]
|
||||
line.unit = Mock(rec_name='MT')
|
||||
line.del_period = Mock(description='MARCH 2026')
|
||||
|
||||
sale = Sale()
|
||||
sale.lines = [line]
|
||||
|
||||
self.assertEqual(sale.report_net, Decimal('950'))
|
||||
self.assertEqual(sale.report_gross, Decimal('980'))
|
||||
self.assertEqual(sale.report_total_quantity, '950.0')
|
||||
self.assertEqual(sale.report_quantity_unit_upper, 'LBS')
|
||||
self.assertEqual(
|
||||
sale.report_quantity_lines,
|
||||
'950.0 LBS (NINE HUNDRED AND FIFTY POUNDS) - MARCH 2026')
|
||||
|
||||
def test_invoice_report_note_title_uses_sale_direction(self):
|
||||
'sale final note title is inverted from the raw amount sign'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
debit = Invoice()
|
||||
debit.type = 'out'
|
||||
debit.total_amount = Decimal('10')
|
||||
self.assertEqual(debit.report_note_title, 'Debit Note')
|
||||
|
||||
credit = Invoice()
|
||||
credit.type = 'out'
|
||||
credit.total_amount = Decimal('-10')
|
||||
self.assertEqual(credit.report_note_title, 'Credit Note')
|
||||
|
||||
def test_invoice_report_note_title_keeps_inverse_for_purchase(self):
|
||||
'purchase final note title keeps the opposite mapping'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
credit = Invoice()
|
||||
credit.type = 'in'
|
||||
credit.total_amount = Decimal('10')
|
||||
self.assertEqual(credit.report_note_title, 'Credit Note')
|
||||
|
||||
debit = Invoice()
|
||||
debit.type = 'in'
|
||||
debit.total_amount = Decimal('-10')
|
||||
self.assertEqual(debit.report_note_title, 'Debit Note')
|
||||
|
||||
@@ -864,6 +949,187 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
self.assertEqual(invoice.report_net, Decimal('800'))
|
||||
|
||||
def test_invoice_report_weights_use_current_lot_hist_values(self):
|
||||
'invoice net and gross weights come from the current lot hist entry'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
unit = Mock(rec_name='LBS')
|
||||
lot = Mock(lot_unit_line=unit)
|
||||
lot.get_hist_quantity.return_value = (
|
||||
Decimal('950'),
|
||||
Decimal('980'),
|
||||
)
|
||||
line = Mock(type='line', quantity=Decimal('1000'), lot=lot, unit=Mock(rec_name='MT'))
|
||||
invoice = Invoice()
|
||||
invoice.lines = [line]
|
||||
|
||||
self.assertEqual(invoice.report_net, Decimal('950'))
|
||||
self.assertEqual(invoice.report_gross, Decimal('980'))
|
||||
self.assertEqual(invoice.report_weight_unit_upper, 'LBS')
|
||||
self.assertEqual(
|
||||
invoice.report_quantity_lines,
|
||||
'950.0 LBS (2094389.00 LBS)')
|
||||
|
||||
def test_invoice_report_weights_keep_line_sign_with_lot_hist_values(self):
|
||||
'invoice lot hist values keep the invoice line sign for final notes'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
positive_lot = Mock(lot_unit_line=Mock(rec_name='LBS'))
|
||||
positive_lot.get_hist_quantity.return_value = (
|
||||
Decimal('950'),
|
||||
Decimal('980'),
|
||||
)
|
||||
negative_lot = Mock(lot_unit_line=Mock(rec_name='LBS'))
|
||||
negative_lot.get_hist_quantity.return_value = (
|
||||
Decimal('150'),
|
||||
Decimal('160'),
|
||||
)
|
||||
positive = Mock(type='line', quantity=Decimal('1000'), lot=positive_lot)
|
||||
negative = Mock(type='line', quantity=Decimal('-200'), lot=negative_lot)
|
||||
invoice = Invoice()
|
||||
invoice.lines = [positive, negative]
|
||||
|
||||
self.assertEqual(invoice.report_net, Decimal('800'))
|
||||
self.assertEqual(invoice.report_gross, Decimal('820'))
|
||||
|
||||
def test_invoice_report_weights_use_single_virtual_lot_when_no_physical(self):
|
||||
'invoice uses the unique virtual lot hist when no physical lot exists'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
virtual = Mock(id=1, lot_type='virtual', lot_unit_line=Mock(rec_name='LBS'))
|
||||
virtual.get_hist_quantity.return_value = (
|
||||
Decimal('930'),
|
||||
Decimal('0'),
|
||||
)
|
||||
origin = Mock(lots=[virtual])
|
||||
line = Mock(
|
||||
type='line',
|
||||
quantity=Decimal('1000'),
|
||||
lot=None,
|
||||
origin=origin,
|
||||
unit=Mock(rec_name='MT'),
|
||||
)
|
||||
invoice = Invoice()
|
||||
invoice.lines = [line]
|
||||
|
||||
self.assertEqual(invoice.report_net, Decimal('930'))
|
||||
self.assertEqual(invoice.report_gross, Decimal('930'))
|
||||
self.assertEqual(invoice.report_weight_unit_upper, 'LBS')
|
||||
|
||||
def test_invoice_report_weights_prefer_physical_lots_over_virtual(self):
|
||||
'invoice uses physical lot hist values whenever physical lots exist'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
virtual = Mock(id=1, lot_type='virtual', lot_unit_line=Mock(rec_name='LBS'))
|
||||
virtual.get_hist_quantity.return_value = (
|
||||
Decimal('930'),
|
||||
Decimal('940'),
|
||||
)
|
||||
physical = Mock(id=2, lot_type='physic', lot_unit_line=Mock(rec_name='LBS'))
|
||||
physical.get_hist_quantity.return_value = (
|
||||
Decimal('950'),
|
||||
Decimal('980'),
|
||||
)
|
||||
origin = Mock(lots=[virtual, physical])
|
||||
line = Mock(
|
||||
type='line',
|
||||
quantity=Decimal('1000'),
|
||||
lot=virtual,
|
||||
origin=origin,
|
||||
unit=Mock(rec_name='MT'),
|
||||
)
|
||||
invoice = Invoice()
|
||||
invoice.lines = [line]
|
||||
|
||||
self.assertEqual(invoice.report_net, Decimal('950'))
|
||||
self.assertEqual(invoice.report_gross, Decimal('980'))
|
||||
self.assertEqual(invoice.report_weight_unit_upper, 'LBS')
|
||||
|
||||
def test_invoice_report_shipment_uses_invoice_line_lot_not_first_trade_line(self):
|
||||
'invoice shipment info comes from the lots linked to the invoiced line'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
shipment_a = Mock(
|
||||
id=1,
|
||||
bl_date='2026-04-01',
|
||||
bl_number='BL-A',
|
||||
vessel=Mock(vessel_name='VESSEL A'),
|
||||
from_location=Mock(rec_name='LOADING A'),
|
||||
to_location=Mock(rec_name='DISCHARGE A'),
|
||||
controller=Mock(rec_name='CTRL A'),
|
||||
number='SI-A',
|
||||
)
|
||||
shipment_b = Mock(
|
||||
id=2,
|
||||
bl_date='2026-04-05',
|
||||
bl_number='BL-B',
|
||||
vessel=Mock(vessel_name='VESSEL B'),
|
||||
from_location=Mock(rec_name='LOADING B'),
|
||||
to_location=Mock(rec_name='DISCHARGE B'),
|
||||
controller=Mock(rec_name='CTRL B'),
|
||||
number='SI-B',
|
||||
)
|
||||
lot_a = Mock(id=10, lot_type='physic', lot_shipment_in=shipment_a)
|
||||
lot_b = Mock(id=20, lot_type='physic', lot_shipment_in=shipment_b)
|
||||
line_a = Mock(lots=[lot_a])
|
||||
line_b = Mock(lots=[lot_b])
|
||||
purchase = Mock(lines=[line_a, line_b])
|
||||
|
||||
invoice_line = Mock(type='line', lot=lot_b, origin=line_b)
|
||||
invoice = Invoice()
|
||||
invoice.purchases = [purchase]
|
||||
invoice.lines = [invoice_line]
|
||||
|
||||
self.assertEqual(invoice.report_bl_nb, 'BL-B')
|
||||
self.assertEqual(invoice.report_bl_date, '2026-04-05')
|
||||
self.assertEqual(invoice.report_vessel, 'VESSEL B')
|
||||
self.assertEqual(invoice.report_loading_port, 'LOADING B')
|
||||
self.assertEqual(invoice.report_discharge_port, 'DISCHARGE B')
|
||||
self.assertEqual(invoice.report_controller_name, 'CTRL B')
|
||||
self.assertEqual(invoice.report_si_number, 'SI-B')
|
||||
self.assertEqual(invoice.report_si_reference, 'REF-B')
|
||||
|
||||
def test_invoice_report_shipment_is_blank_if_invoice_mixes_shipments(self):
|
||||
'invoice shipment fields stay empty when multiple shipments are invoiced together'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
shipment_a = Mock(
|
||||
id=1,
|
||||
bl_date='2026-04-01',
|
||||
bl_number='BL-A',
|
||||
vessel=Mock(vessel_name='VESSEL A'),
|
||||
from_location=Mock(rec_name='LOADING A'),
|
||||
to_location=Mock(rec_name='DISCHARGE A'),
|
||||
controller=Mock(rec_name='CTRL A'),
|
||||
number='SI-A',
|
||||
)
|
||||
shipment_b = Mock(
|
||||
id=2,
|
||||
bl_date='2026-04-05',
|
||||
bl_number='BL-B',
|
||||
reference='REF-B',
|
||||
vessel=Mock(vessel_name='VESSEL B'),
|
||||
from_location=Mock(rec_name='LOADING B'),
|
||||
to_location=Mock(rec_name='DISCHARGE B'),
|
||||
controller=Mock(rec_name='CTRL B'),
|
||||
number='SI-B',
|
||||
)
|
||||
lot_a = Mock(id=10, lot_type='physic', lot_shipment_in=shipment_a)
|
||||
lot_b = Mock(id=20, lot_type='physic', lot_shipment_in=shipment_b)
|
||||
line_a = Mock(type='line', lot=lot_a, origin=Mock(lots=[lot_a]))
|
||||
line_b = Mock(type='line', lot=lot_b, origin=Mock(lots=[lot_b]))
|
||||
invoice = Invoice()
|
||||
invoice.lines = [line_a, line_b]
|
||||
|
||||
self.assertIsNone(invoice.report_bl_nb)
|
||||
self.assertIsNone(invoice.report_bl_date)
|
||||
self.assertEqual(invoice.report_vessel, None)
|
||||
self.assertEqual(invoice.report_loading_port, '')
|
||||
self.assertEqual(invoice.report_discharge_port, '')
|
||||
self.assertEqual(invoice.report_controller_name, '')
|
||||
self.assertEqual(invoice.report_si_number, '')
|
||||
self.assertEqual(invoice.report_si_reference, '')
|
||||
|
||||
def test_invoice_report_nb_bale_sums_signed_line_lot_quantities(self):
|
||||
'invoice reports packaging from the signed sum of line lot_qt values'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
@@ -876,6 +1142,18 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
self.assertEqual(invoice.report_nb_bale, 'NB BALES: 0')
|
||||
|
||||
def test_invoice_report_cndn_nb_bale_displays_unchanged_for_zero(self):
|
||||
'CN/DN bale label displays Unchanged when the signed balance is zero'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
lot = Mock(lot_qt=Decimal('350'), lot_unit=Mock(symbol='bale'))
|
||||
negative = Mock(type='line', quantity=Decimal('-1000'), lot=lot)
|
||||
positive = Mock(type='line', quantity=Decimal('1000'), lot=lot)
|
||||
invoice = Invoice()
|
||||
invoice.lines = [negative, positive]
|
||||
|
||||
self.assertEqual(invoice.report_cndn_nb_bale, 'Unchanged')
|
||||
|
||||
def test_invoice_report_positive_rate_lines_keep_positive_components(self):
|
||||
'invoice final note pricing section keeps only positive component lines'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
Reference in New Issue
Block a user