Skip to main content

Invoice Delivery

Phases 3-4

Phase 3 (PlanFact + R2) is implemented. Phase 4 (Didox + email) is planned.

After approval, invoices are delivered to clients and synced with external systems.

Delivery Flow​

Cloudflare R2 Storage (Phase 3) ✅​

PDFs are uploaded to Cloudflare R2 on invoice approval (best-effort, before transaction).

SettingValue
Bucketproxima-invoices
Domaininvoices.prxm.uz
Key formatinvoices/{year}/{application_key}/Act_{display_number}.pdf
SDKAWS SDK v2 (S3-compatible)
Packageinternal/services/r2/

After upload, the r2_storage_key and r2_public_url fields on the invoice are populated. If upload fails, approval proceeds normally and the PDF remains available from the database.

Frontend shows "Open PDF" link in the Integrations card when r2_public_url is set, or "Not uploaded" otherwise.

PlanFact Sync (Phase 3) ✅​

Approved invoices are synced to PlanFact (accounting system) as shipments via an async goroutine (30s timeout):

PlanFact configuration:

  • Company ID: 146673 (default)
  • API Key: Stored in INVOICE_PLANFACT_API_KEY env var
  • Product IDs: b78ac753-... (hourly), d9c144af-... (support) — seeded in migration 000007

Manual retry: POST /api/v1/invoices/:id/sync-planfact for approved/sent invoices. Frontend shows "Retry" button in the Integrations card when sync has not completed.

Didox.uz (Phase 4)​

Local (UZS) invoices are sent via the Didox.uz e-invoicing platform, required for B2B invoicing in Uzbekistan.

FieldValue
Seller TIN309630523 (ProximaOps)
Document typeService act (Акт выполненных работ)

After submission, the didox_document_id and didox_status fields are populated.

Email Delivery (Phase 4)​

International invoices are delivered as PDF email attachments:

  • To: Client contact email from ClickHouse (cdm.jira_contacts)
  • Subject: Invoice <display_number> — <period>
  • Attachment: PDF from R2 storage
  • Template: Professional email with payment instructions

Status Updates​

ActionStatus Transition
Send via Didoxapproved → sent
Send via emailapproved → sent
Client accepts (Didox callback)sent → accepted
Client rejects (Didox callback)sent → rejected
Manual acceptancesent → accepted
Payment receivedaccepted → paid