feat(billing): Stripe/Lago-verified go-forward sync + activate daily cron
The NexaCloud->Odoo ledger now verifies every new invoice against its
SOURCE billing system before posting, instead of trusting NexaCloud's
unreliable created_at/status/paid_at:
- _fc_verify routes by stripe_invoice_id prefix (in_ -> Stripe REST,
lago: -> Lago REST) and returns source-truth
{invoice_date, void, draft, paid, paid_at, amount_paid}, or None when it
can't be determined/reached (left for the next run).
- _ingest_invoices(post=True, verified=...) uses the source invoice date
(and accounting date), and reconciles a payment ONLY when the source
confirms paid.
- _cron_sync_verified posts only finalized invoices; skips void + draft,
logs unverified for retry. Replaces the old _cron_ingest_recent.
Cron cron_fc_invoice_ledger is enabled daily on nexamain. First live run:
23 already-posted, 1 void + 2 Stripe drafts + 5 zero-amount all skipped,
0 new posted, ledger intact at $3,403.46.
Tests: routing/guards (no network), verified date+reconcile, and the cron's
void/draft/unverified filtering (sources patched). FCB_EXIT=0 on odoo-trial.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -134,8 +134,25 @@ Income-account codes come from the COA (`nexa_coa_setup`); confirm/create at imp
|
||||
`payment_status=succeeded` via the Lago API (`billing.nexasystems.ca/api/api/v1`, key in
|
||||
Fusion-Chat; Lago host 192.168.1.117, double-hop ssh via supabase-prod).
|
||||
Partner names came from the NexaCloud `company` field (not the user's full_name).
|
||||
- **GO-FORWARD CAVEAT — do NOT enable the daily cron yet.** `_ingest_invoices` /
|
||||
`_post_and_reconcile_paid` still date + gauge payment from NexaCloud's own fields, which
|
||||
are unreliable for new invoices too. Before automating, the ledger must verify each new
|
||||
invoice's date + paid status against Stripe (and Lago, until decommissioned) — i.e. fold
|
||||
the verification used in this backfill into the ingest path.
|
||||
- **GO-FORWARD: verified sync is LIVE (2026-05-27).** The verification used in the backfill
|
||||
is now folded into the ingest path, and the daily cron is enabled:
|
||||
- `_fc_verify(inv)` routes each invoice to its source by `stripe_invoice_id` prefix
|
||||
(`in_` → Stripe REST `GET /v1/invoices/{id}`; `lago:` → Lago REST) and returns
|
||||
`{invoice_date, void, draft, paid, paid_at, amount_paid}` taken from the SOURCE — or
|
||||
`None` if it can't be determined/reached. Credentials live in `ir.config_parameter`:
|
||||
`fusion_billing.stripe_api_key` (set, live), `fusion_billing.lago_api_url` /
|
||||
`fusion_billing.lago_api_key` (optional; unset — no new Lago invoices expected).
|
||||
- `_cron_sync_verified()` reads all NexaCloud invoices, skips ones already posted, then
|
||||
for the rest: skips **void** and **draft** (not finalized at source), logs **unverified**
|
||||
for retry next run, and ingests the rest with `_ingest_invoices(post=True, verified=…)`
|
||||
so the move uses the source invoice_date (accounting date too) and a payment is
|
||||
reconciled ONLY when the source confirms paid. Never acts on NexaCloud's raw fields.
|
||||
- Cron `cron_fc_invoice_ledger` on nexamain: **active**, daily at 06:00 UTC. (A stale
|
||||
pre-existing copy of this record still called the removed `_cron_ingest_recent`; because
|
||||
the data file is `noupdate="1"` the upgrade didn't rewrite it, so its server-action code
|
||||
+ name were corrected once via SQL. Fresh installs get the right definition from the XML.)
|
||||
- First live run (2026-05-27): 23 already-posted, 1 void + 2 Stripe drafts + 5 genuine
|
||||
$0 invoices all correctly skipped, **0 new posted**, ledger intact at $3,403.46.
|
||||
- Verification helpers are unit-tested without network (routing short-circuits when no
|
||||
credentials are set; the cron is exercised with `_read_nexacloud_invoices` / `_fc_verify`
|
||||
patched). Full suite green on odoo-trial (`FCB_EXIT=0`).
|
||||
|
||||
Reference in New Issue
Block a user