Practitionist / Practitionist/elluminar_web
🏢 B2B tax invoices for enterprise license contracts
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 17h 2m
- Merged PRs (30d)
- 18
Description
Context
Enterprise/university licenses are purchased sales-led: a platform admin records the contract payment via recordLicensePayment (src/actions/license.ts), which creates a MANUAL-provider Payment + PLATFORM ADJUSTMENT ledger entry and flips the OrgLicense DRAFT → ACTIVE.
Gap: no Invoice is generated for B2B contracts, even though:
Invoice/InvoiceSeriesmodels exist (prisma/models/commerce.prisma) with partial unique indexesTenant.gstinis captured on the org tenant but never used- Retail checkout already writes TAX_INVOICE JSON snapshots (src/lib/commerce/fulfillment.ts)
- Indian GST rules require a tax invoice for B2B supplies; enterprises will demand GST invoices with their own GSTIN as bill-to before paying contracts
Proposed implementation
- Bill-to resolution — invoice
dataJSON gains an org bill-to block: legal entity name, billing address, GSTIN (from Tenant), PO/reference number (addOrgLicense.poNumber String?if approved — additive). - Series — reuse the existing row-locked
InvoiceSeriescounter; decide whether B2B contract invoices share seriesCN/default or get their own series (recommend shared TAX_INVOICE numbering per GST practice — one sequential series). - Action — extend
recordLicensePaymentto create the Invoice in the same transaction as the Payment + ledger entry; amount =contractValueMinor, GST split per configured rate or reverse-charge flag for B2B (input credit model — line items show base + IGST 18% unless tenant config overrides). - PDF + email — coordinate with issue #24 (compliance pack): once PDF generation lands, contract invoices render through the same pipeline; until then the numbered DB row + /org license page display is acceptable internally.
- Placeholders gate — seller entity details come from
src/lib/brand.tsplaceholders (#37); must be filled before real contracts are invoiced.
Acceptance
- Recording a license payment produces a numbered TAX_INVOICE carrying buyer GSTIN + PO ref
- Invoice appears on /org licenses page and /admin queues
- No schema restructuring — additive only (schema freeze, #43)
Advances #24, #38. Part of epic #42.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with recordLicensePayment in src/actions/license.ts, then inspect Invoice and InvoiceSeries in prisma/models/commerce.prisma and the TAX_INVOICE snapshot flow in src/lib/commerce/fulfillment.ts. Review the related constraints from issues #24, #37, #42 and #43 before resolving the series, GST, and PO-number decisions. Done means a transactional, numbered TAX_INVOICE appears with buyer GSTIN and PO reference on the organization licenses page and admin queues.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, payments
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100