Lot invoicing + Fee invoicing

This commit is contained in:
2026-06-22 17:44:55 +02:00
parent 703868001b
commit ed818c2287
6 changed files with 224 additions and 54 deletions

View File

@@ -5897,7 +5897,7 @@ class PurchaseTradeTestCase(ModuleTestCase):
self.assertEqual(FeeReport._invoice_payment_status([unpaid]), 'not')
def test_fee_report_payment_status_includes_fee_dn_cn(self):
'fee payment status consolidates the invoice and its DN/CN'
'fee payment status distinguishes invoice and DN/CN payments'
FeeReport = Pool().get('fee.report')
report = FeeReport()
report.id = 10
@@ -5916,10 +5916,28 @@ class PurchaseTradeTestCase(ModuleTestCase):
self.assertEqual(
report.get_fee_payment_status('r_fee_payment_status'),
'partial')
'invoice_paid')
fee.get_invoice.assert_called_once_with('inv')
unpaid_dn_cn.payment_lines = [SimpleNamespace()]
unpaid_dn_cn.amount_to_pay = Decimal('0')
with patch('trytond.modules.purchase_trade.fee.Pool') as PoolMock:
PoolMock.return_value.get.return_value = fee_model
self.assertEqual(
report.get_fee_payment_status('r_fee_payment_status'),
'all_paid')
unpaid = SimpleNamespace(
state='posted', payment_lines=[],
amount_to_pay=Decimal('5'))
self.assertEqual(
FeeReport._fee_payment_status(unpaid, unpaid), 'not_paid')
self.assertEqual(
FeeReport._fee_payment_status(unpaid, unpaid_dn_cn),
'dn_cn_paid')
def test_sale_report_converts_mixed_units_for_total_and_words(self):
'sale report totals prefer the virtual lot unit as common unit'
Sale = Pool().get('sale.sale')
@@ -8315,6 +8333,68 @@ class PurchaseTradeTestCase(ModuleTestCase):
lot_module.LotInvoice._split_sale_padding(Decimal('1000'), lots),
{1: Decimal('500'), 2: Decimal('500')})
def test_lot_invoice_fee_action_follows_lot_invoice_stage(self):
'fee action is standard in provisional and DN/CN in final'
not_invoiced = Mock()
not_invoiced.get_invoice.return_value = None
invoiced = Mock()
invoiced.get_invoice.return_value = Mock()
self.assertEqual(
lot_module._fee_invoice_action(not_invoiced, 'prov'),
'standard')
self.assertEqual(
lot_module._fee_invoice_action(invoiced, 'prov'),
'already_invoiced')
self.assertEqual(
lot_module._fee_invoice_action(not_invoiced, 'final'),
'standard')
self.assertEqual(
lot_module._fee_invoice_action(invoiced, 'final'),
'dn_cn')
def test_lot_invoice_only_invoices_checked_fees_for_selected_side(self):
'lot invoice invoices only checked fees from purchase or sale side'
purchase_fee = Mock(id=1)
purchase_fee.get_invoice.return_value = None
ignored_purchase_fee = Mock(id=2)
ignored_purchase_fee.get_invoice.return_value = None
sale_fee = Mock(id=3)
sale_fee.get_invoice.return_value = None
wizard = SimpleNamespace(inv=SimpleNamespace(
type='purchase', action='prov',
fee_pur=[
SimpleNamespace(fee=purchase_fee, to_invoice=True),
SimpleNamespace(fee=ignored_purchase_fee, to_invoice=False),
],
fee_sale=[SimpleNamespace(fee=sale_fee, to_invoice=True)],
))
fee_model = Mock()
with patch('trytond.modules.purchase_trade.lot.Pool') as PoolMock:
PoolMock.return_value.get.return_value = fee_model
lot_module.LotInvoice._invoice_selected_fees(wizard)
fee_model.invoice.assert_called_once_with([purchase_fee])
def test_lot_invoice_final_invoices_checked_existing_fee_as_dn_cn(self):
'final lot invoice sends an already invoiced checked fee to Fee.invoice'
fee = Mock(id=1)
fee.get_invoice.return_value = Mock()
wizard = SimpleNamespace(inv=SimpleNamespace(
type='sale', action='final', fee_pur=[],
fee_sale=[SimpleNamespace(fee=fee, to_invoice=True)],
))
fee_model = Mock()
with patch('trytond.modules.purchase_trade.lot.Pool') as PoolMock:
PoolMock.return_value.get.return_value = fee_model
lot_module.LotInvoice._invoice_selected_fees(wizard)
fee_model.invoice.assert_called_once_with([fee])
@with_transaction()
def test_invoice_line_included_padding_reads_sale_lot_padding(self):
'invoice line exposes the sale provisional padding stored on the lot'