feat(billing): post + reconcile only PAID invoices, keeping original dates
_post_and_reconcile_paid: for invoices NexaCloud marks paid, set the ledger entry's invoice_date AND accounting date to the original NexaCloud date, post, then reconcile the Stripe payment dated to the actual paid_at. Unpaid invoices stay draft. Per-invoice isolated. 76 tests green on odoo-trial.
This commit is contained in:
@@ -120,6 +120,24 @@ class TestLedgerIngest(TransactionCase):
|
||||
self.assertAlmostEqual(mv.amount_untaxed, 200.0, places=2) # captured via reconciling line
|
||||
self.assertTrue(any('base/unitemized' in (l.name or '') for l in mv.invoice_line_ids))
|
||||
|
||||
def test_post_and_reconcile_paid_only(self):
|
||||
base = _inv_fixture()[0]
|
||||
paid = dict(base, id='inv-paid', invoice_number='NEX-PAID',
|
||||
status='paid', amount_paid=113.0, paid_at='2026-05-02',
|
||||
invoice_date='2026-05-01')
|
||||
unpaid = dict(base, id='inv-unpaid', invoice_number='NEX-UNPAID',
|
||||
status='open', amount_paid=0.0, invoice_date='2026-04-01')
|
||||
self.W._ingest_invoices([paid, unpaid], post=False)
|
||||
summary = self.W._post_and_reconcile_paid([paid, unpaid])
|
||||
pm = self.Move.search([('x_fc_nexacloud_invoice_id', '=', 'inv-paid')])
|
||||
um = self.Move.search([('x_fc_nexacloud_invoice_id', '=', 'inv-unpaid')])
|
||||
self.assertEqual(pm.state, 'posted')
|
||||
self.assertIn(pm.payment_state, ('paid', 'in_payment'))
|
||||
self.assertEqual(str(pm.invoice_date), '2026-05-01') # original invoice date kept
|
||||
self.assertEqual(um.state, 'draft') # unpaid stays draft
|
||||
self.assertEqual(summary['posted'], 1)
|
||||
self.assertEqual(summary['skipped_unpaid'], 1)
|
||||
|
||||
def test_partner_named_by_company_not_person(self):
|
||||
data = _inv_fixture()
|
||||
data[0]['partner_company'] = 'Acme Holdings Inc' # full_name is "Acme"; company wins
|
||||
|
||||
Reference in New Issue
Block a user