@dainamite/billing 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +90 -0
- package/dist/modules/billing/acl.js +13 -1
- package/dist/modules/billing/acl.js.map +2 -2
- package/dist/modules/billing/api/accounts/[id]/summary/route.js +52 -0
- package/dist/modules/billing/api/accounts/[id]/summary/route.js.map +7 -0
- package/dist/modules/billing/api/accounts/route.js +46 -4
- package/dist/modules/billing/api/accounts/route.js.map +2 -2
- package/dist/modules/billing/api/export/account/[id]/route.js +11 -7
- package/dist/modules/billing/api/export/account/[id]/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/[id]/memos/route.js +54 -0
- package/dist/modules/billing/api/invoices/[id]/memos/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/[id]/pdf/route.js +69 -0
- package/dist/modules/billing/api/invoices/[id]/pdf/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/[id]/route.js +44 -24
- package/dist/modules/billing/api/invoices/[id]/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/[id]/send/route.js +107 -0
- package/dist/modules/billing/api/invoices/[id]/send/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/add-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/add-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/delete-draft/route.js +33 -0
- package/dist/modules/billing/api/invoices/delete-draft/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/edit-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/edit-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/post/route.js +2 -2
- package/dist/modules/billing/api/invoices/post/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/remove-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/remove-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/route.js +45 -46
- package/dist/modules/billing/api/invoices/route.js.map +2 -2
- package/dist/modules/billing/api/items/bulk/route.js +1 -1
- package/dist/modules/billing/api/items/bulk/route.js.map +2 -2
- package/dist/modules/billing/api/items/change-price/route.js +44 -0
- package/dist/modules/billing/api/items/change-price/route.js.map +7 -0
- package/dist/modules/billing/api/items/route.js +19 -7
- package/dist/modules/billing/api/items/route.js.map +2 -2
- package/dist/modules/billing/api/payment-imports/[id]/route.js +49 -0
- package/dist/modules/billing/api/payment-imports/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/payment-imports/route.js +57 -0
- package/dist/modules/billing/api/payment-imports/route.js.map +7 -0
- package/dist/modules/billing/api/payments/[id]/route.js +60 -0
- package/dist/modules/billing/api/payments/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/payments/allocate/route.js +35 -0
- package/dist/modules/billing/api/payments/allocate/route.js.map +7 -0
- package/dist/modules/billing/api/payments/assign/route.js +36 -0
- package/dist/modules/billing/api/payments/assign/route.js.map +7 -0
- package/dist/modules/billing/api/payments/convert-to-topup/route.js +35 -0
- package/dist/modules/billing/api/payments/convert-to-topup/route.js.map +7 -0
- package/dist/modules/billing/api/payments/ignore/route.js +35 -0
- package/dist/modules/billing/api/payments/ignore/route.js.map +7 -0
- package/dist/modules/billing/api/payments/import/route.js +63 -0
- package/dist/modules/billing/api/payments/import/route.js.map +7 -0
- package/dist/modules/billing/api/payments/restore/route.js +35 -0
- package/dist/modules/billing/api/payments/restore/route.js.map +7 -0
- package/dist/modules/billing/api/payments/route.js +114 -0
- package/dist/modules/billing/api/payments/route.js.map +7 -0
- package/dist/modules/billing/api/payments/unallocate/route.js +35 -0
- package/dist/modules/billing/api/payments/unallocate/route.js.map +7 -0
- package/dist/modules/billing/api/payments/unassign/route.js +35 -0
- package/dist/modules/billing/api/payments/unassign/route.js.map +7 -0
- package/dist/modules/billing/api/run-outcomes/route.js +43 -6
- package/dist/modules/billing/api/run-outcomes/route.js.map +2 -2
- package/dist/modules/billing/api/runs/[id]/post-drafts/route.js +61 -0
- package/dist/modules/billing/api/runs/[id]/post-drafts/route.js.map +7 -0
- package/dist/modules/billing/api/runs/[id]/route.js +53 -0
- package/dist/modules/billing/api/runs/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/runs/retry-failed/route.js +1 -1
- package/dist/modules/billing/api/runs/retry-failed/route.js.map +2 -2
- package/dist/modules/billing/api/runs/route.js +9 -3
- package/dist/modules/billing/api/runs/route.js.map +2 -2
- package/dist/modules/billing/api/settings/number-preview/route.js +42 -0
- package/dist/modules/billing/api/settings/number-preview/route.js.map +7 -0
- package/dist/modules/billing/api/settings/route.js +92 -0
- package/dist/modules/billing/api/settings/route.js.map +7 -0
- package/dist/modules/billing/api/statements/route.js +3 -0
- package/dist/modules/billing/api/statements/route.js.map +2 -2
- package/dist/modules/billing/api/test-invoices/wipe/route.js +2 -2
- package/dist/modules/billing/api/test-invoices/wipe/route.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/[id]/page.js +121 -232
- package/dist/modules/billing/backend/billing/accounts/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/create/page.js +6 -0
- package/dist/modules/billing/backend/billing/accounts/create/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/page.js +63 -4
- package/dist/modules/billing/backend/billing/accounts/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/invoices/[id]/page.js +297 -65
- package/dist/modules/billing/backend/billing/invoices/[id]/page.js.map +3 -3
- package/dist/modules/billing/backend/billing/invoices/page.js +6 -172
- package/dist/modules/billing/backend/billing/invoices/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/[id]/page.js +51 -7
- package/dist/modules/billing/backend/billing/items/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/create/page.js +9 -6
- package/dist/modules/billing/backend/billing/items/create/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/page.js +8 -2
- package/dist/modules/billing/backend/billing/items/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/payments/[id]/page.js +297 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js +21 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js +74 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js +21 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/page.js +58 -0
- package/dist/modules/billing/backend/billing/payments/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/page.meta.js +18 -0
- package/dist/modules/billing/backend/billing/payments/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/runs/[id]/page.js +49 -14
- package/dist/modules/billing/backend/billing/runs/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/runs/page.js +58 -7
- package/dist/modules/billing/backend/billing/runs/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/statements/[id]/page.js +61 -6
- package/dist/modules/billing/backend/billing/statements/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/statements/page.js +1 -1
- package/dist/modules/billing/backend/billing/statements/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/topups/page.js +1 -1
- package/dist/modules/billing/backend/billing/topups/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/transactions/page.js +1 -1
- package/dist/modules/billing/backend/billing/transactions/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/usage/create/page.js +3 -2
- package/dist/modules/billing/backend/billing/usage/create/page.js.map +2 -2
- package/dist/modules/billing/backend/config/billing/page.js +472 -0
- package/dist/modules/billing/backend/config/billing/page.js.map +7 -0
- package/dist/modules/billing/backend/config/billing/page.meta.js +19 -0
- package/dist/modules/billing/backend/config/billing/page.meta.js.map +7 -0
- package/dist/modules/billing/cli.js +22 -1
- package/dist/modules/billing/cli.js.map +2 -2
- package/dist/modules/billing/commands/accounts.js +6 -0
- package/dist/modules/billing/commands/accounts.js.map +2 -2
- package/dist/modules/billing/commands/index.js +3 -0
- package/dist/modules/billing/commands/index.js.map +2 -2
- package/dist/modules/billing/commands/invoices.js +269 -167
- package/dist/modules/billing/commands/invoices.js.map +2 -2
- package/dist/modules/billing/commands/items.js +108 -0
- package/dist/modules/billing/commands/items.js.map +2 -2
- package/dist/modules/billing/commands/memos.js +179 -0
- package/dist/modules/billing/commands/memos.js.map +7 -0
- package/dist/modules/billing/commands/payments.js +379 -0
- package/dist/modules/billing/commands/payments.js.map +7 -0
- package/dist/modules/billing/commands/runs.js +151 -4
- package/dist/modules/billing/commands/runs.js.map +2 -2
- package/dist/modules/billing/commands/settings.js +59 -0
- package/dist/modules/billing/commands/settings.js.map +7 -0
- package/dist/modules/billing/commands/topups.js +9 -2
- package/dist/modules/billing/commands/topups.js.map +2 -2
- package/dist/modules/billing/commands/transactions.js +2 -2
- package/dist/modules/billing/commands/transactions.js.map +2 -2
- package/dist/modules/billing/components/AccountForm.js +149 -42
- package/dist/modules/billing/components/AccountForm.js.map +2 -2
- package/dist/modules/billing/components/AccountInvoicesSection.js +64 -0
- package/dist/modules/billing/components/AccountInvoicesSection.js.map +7 -0
- package/dist/modules/billing/components/AccountPaymentsSection.js +43 -0
- package/dist/modules/billing/components/AccountPaymentsSection.js.map +7 -0
- package/dist/modules/billing/components/AccountPicker.js +56 -0
- package/dist/modules/billing/components/AccountPicker.js.map +7 -0
- package/dist/modules/billing/components/AllocatePaymentDialog.js +134 -0
- package/dist/modules/billing/components/AllocatePaymentDialog.js.map +7 -0
- package/dist/modules/billing/components/BillingDataTable.js +21 -0
- package/dist/modules/billing/components/BillingDataTable.js.map +7 -0
- package/dist/modules/billing/components/BillingSettingsLink.js +19 -0
- package/dist/modules/billing/components/BillingSettingsLink.js.map +7 -0
- package/dist/modules/billing/components/ChangeItemPriceDialog.js +158 -0
- package/dist/modules/billing/components/ChangeItemPriceDialog.js.map +7 -0
- package/dist/modules/billing/components/CreateMemoDialog.js +200 -0
- package/dist/modules/billing/components/CreateMemoDialog.js.map +7 -0
- package/dist/modules/billing/components/CustomerLabel.js +33 -0
- package/dist/modules/billing/components/CustomerLabel.js.map +7 -0
- package/dist/modules/billing/components/InvoicesTable.js +270 -0
- package/dist/modules/billing/components/InvoicesTable.js.map +7 -0
- package/dist/modules/billing/components/ItemForm.js +176 -44
- package/dist/modules/billing/components/ItemForm.js.map +2 -2
- package/dist/modules/billing/components/ItemPriceField.js +46 -0
- package/dist/modules/billing/components/ItemPriceField.js.map +7 -0
- package/dist/modules/billing/components/LineFormDialog.js +25 -2
- package/dist/modules/billing/components/LineFormDialog.js.map +2 -2
- package/dist/modules/billing/components/ManualPaymentDialog.js +122 -0
- package/dist/modules/billing/components/ManualPaymentDialog.js.map +7 -0
- package/dist/modules/billing/components/MoneyInput.js +14 -0
- package/dist/modules/billing/components/MoneyInput.js.map +7 -0
- package/dist/modules/billing/components/PaymentUploadDialog.js +115 -0
- package/dist/modules/billing/components/PaymentUploadDialog.js.map +7 -0
- package/dist/modules/billing/components/PaymentsTable.js +171 -0
- package/dist/modules/billing/components/PaymentsTable.js.map +7 -0
- package/dist/modules/billing/components/PostRunDraftsButton.js +105 -0
- package/dist/modules/billing/components/PostRunDraftsButton.js.map +7 -0
- package/dist/modules/billing/components/PrepaidPanel.js +14 -4
- package/dist/modules/billing/components/PrepaidPanel.js.map +2 -2
- package/dist/modules/billing/components/RunCyclesSection.js +209 -0
- package/dist/modules/billing/components/RunCyclesSection.js.map +7 -0
- package/dist/modules/billing/components/TestRunActions.js +127 -0
- package/dist/modules/billing/components/TestRunActions.js.map +7 -0
- package/dist/modules/billing/components/account/AccountItemsTab.js +157 -0
- package/dist/modules/billing/components/account/AccountItemsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountRunBillingDialog.js +122 -0
- package/dist/modules/billing/components/account/AccountRunBillingDialog.js.map +7 -0
- package/dist/modules/billing/components/account/AccountRunsTab.js +152 -0
- package/dist/modules/billing/components/account/AccountRunsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountStatementsTab.js +98 -0
- package/dist/modules/billing/components/account/AccountStatementsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountSummaryCards.js +125 -0
- package/dist/modules/billing/components/account/AccountSummaryCards.js.map +7 -0
- package/dist/modules/billing/components/account/AccountUsageTab.js +91 -0
- package/dist/modules/billing/components/account/AccountUsageTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountView.js +73 -0
- package/dist/modules/billing/components/account/AccountView.js.map +7 -0
- package/dist/modules/billing/components/account/accountRow.js +39 -0
- package/dist/modules/billing/components/account/accountRow.js.map +7 -0
- package/dist/modules/billing/components/customerNames.js +42 -0
- package/dist/modules/billing/components/customerNames.js.map +7 -0
- package/dist/modules/billing/data/entities.js +560 -4
- package/dist/modules/billing/data/entities.js.map +2 -2
- package/dist/modules/billing/data/entityIds.js +10 -1
- package/dist/modules/billing/data/entityIds.js.map +2 -2
- package/dist/modules/billing/data/validators.js +269 -15
- package/dist/modules/billing/data/validators.js.map +2 -2
- package/dist/modules/billing/events.js +50 -0
- package/dist/modules/billing/events.js.map +2 -2
- package/dist/modules/billing/i18n/en.json +457 -21
- package/dist/modules/billing/i18n/pl.json +457 -21
- package/dist/modules/billing/index.js +6 -2
- package/dist/modules/billing/index.js.map +2 -2
- package/dist/modules/billing/lib/accountFinancials.js +58 -0
- package/dist/modules/billing/lib/accountFinancials.js.map +7 -0
- package/dist/modules/billing/lib/accountLock.js +14 -0
- package/dist/modules/billing/lib/accountLock.js.map +7 -0
- package/dist/modules/billing/lib/accountStatus.js +9 -7
- package/dist/modules/billing/lib/accountStatus.js.map +2 -2
- package/dist/modules/billing/lib/accountSummary.js +106 -0
- package/dist/modules/billing/lib/accountSummary.js.map +7 -0
- package/dist/modules/billing/lib/allocation.js +356 -0
- package/dist/modules/billing/lib/allocation.js.map +7 -0
- package/dist/modules/billing/lib/allocationEvents.js +22 -0
- package/dist/modules/billing/lib/allocationEvents.js.map +7 -0
- package/dist/modules/billing/lib/billPeriod.js +15 -1
- package/dist/modules/billing/lib/billPeriod.js.map +2 -2
- package/dist/modules/billing/lib/billRunEngine.js +237 -102
- package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
- package/dist/modules/billing/lib/billingSettings.js +116 -0
- package/dist/modules/billing/lib/billingSettings.js.map +7 -0
- package/dist/modules/billing/lib/commandRoute.js +81 -0
- package/dist/modules/billing/lib/commandRoute.js.map +7 -0
- package/dist/modules/billing/lib/customerLookup.js +97 -0
- package/dist/modules/billing/lib/customerLookup.js.map +7 -0
- package/dist/modules/billing/lib/dateOnly.js +13 -0
- package/dist/modules/billing/lib/dateOnly.js.map +7 -0
- package/dist/modules/billing/lib/documentParties.js +16 -0
- package/dist/modules/billing/lib/documentParties.js.map +7 -0
- package/dist/modules/billing/lib/documentTypes.js +27 -0
- package/dist/modules/billing/lib/documentTypes.js.map +7 -0
- package/dist/modules/billing/lib/dueDate.js +18 -0
- package/dist/modules/billing/lib/dueDate.js.map +7 -0
- package/dist/modules/billing/lib/iban.js +29 -0
- package/dist/modules/billing/lib/iban.js.map +7 -0
- package/dist/modules/billing/lib/invoiceDelivery.js +131 -0
- package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
- package/dist/modules/billing/lib/invoiceLanguages.js +16 -0
- package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
- package/dist/modules/billing/lib/invoiceWriter.js +107 -99
- package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
- package/dist/modules/billing/lib/itemBillingState.js +27 -0
- package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
- package/dist/modules/billing/lib/itemPriceChange.js +18 -0
- package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
- package/dist/modules/billing/lib/itemSelector.js.map +2 -2
- package/dist/modules/billing/lib/lineAmounts.js +32 -0
- package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
- package/dist/modules/billing/lib/memoGuards.js +25 -0
- package/dist/modules/billing/lib/memoGuards.js.map +7 -0
- package/dist/modules/billing/lib/navigation.js +48 -0
- package/dist/modules/billing/lib/navigation.js.map +7 -0
- package/dist/modules/billing/lib/numbering.js +120 -0
- package/dist/modules/billing/lib/numbering.js.map +7 -0
- package/dist/modules/billing/lib/overdue.js +36 -0
- package/dist/modules/billing/lib/overdue.js.map +7 -0
- package/dist/modules/billing/lib/paymentCsv.js +125 -0
- package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
- package/dist/modules/billing/lib/paymentGateway.js +15 -0
- package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
- package/dist/modules/billing/lib/paymentImport.js +164 -0
- package/dist/modules/billing/lib/paymentImport.js.map +7 -0
- package/dist/modules/billing/lib/paymentMatcher.js +36 -0
- package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
- package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
- package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
- package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
- package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
- package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
- package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoiceTemplate.js +274 -0
- package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
- package/dist/modules/billing/lib/prepaidConfig.js +17 -25
- package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
- package/dist/modules/billing/lib/prepaidConsume.js +26 -7
- package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
- package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
- package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
- package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
- package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
- package/dist/modules/billing/lib/seeds/demo.js +51 -3
- package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
- package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
- package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
- package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
- package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
- package/dist/modules/billing/lib/servicePeriods.js +121 -0
- package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
- package/dist/modules/billing/lib/testRunCleanup.js +24 -0
- package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
- package/dist/modules/billing/lib/topupCapture.js +2 -2
- package/dist/modules/billing/lib/topupCapture.js.map +2 -2
- package/dist/modules/billing/lib/topupReceipt.js +58 -79
- package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
- package/dist/modules/billing/lib/usageRater.js.map +1 -1
- package/dist/modules/billing/lib/usageRunner.js +14 -6
- package/dist/modules/billing/lib/usageRunner.js.map +2 -2
- package/dist/modules/billing/lib/vat.js +39 -0
- package/dist/modules/billing/lib/vat.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
- package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
- package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
- package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
- package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
- package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
- package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
- package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
- package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
- package/dist/modules/billing/setup.js +7 -184
- package/dist/modules/billing/setup.js.map +2 -2
- package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
- package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
- package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
- package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
- package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
- package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
- package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
- package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
- package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
- package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
- package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
- package/generated/entities/billing_account/index.ts +3 -0
- package/generated/entities/billing_allocation/index.ts +18 -0
- package/generated/entities/billing_document_sequence/index.ts +11 -0
- package/generated/entities/billing_invoice/index.ts +38 -0
- package/generated/entities/billing_invoice_line/index.ts +24 -0
- package/generated/entities/billing_item/index.ts +4 -0
- package/generated/entities/billing_payment/index.ts +25 -0
- package/generated/entities/billing_payment_import/index.ts +14 -0
- package/generated/entities/billing_run/index.ts +0 -1
- package/generated/entities/billing_run_outcome/index.ts +1 -0
- package/generated/entities/billing_settings/index.ts +26 -0
- package/generated/entities/billing_statement/index.ts +1 -0
- package/generated/entities.ids.generated.ts +7 -0
- package/package.json +5 -1
- package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +170 -0
- package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
- package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
- package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
- package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
- package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
- package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
- package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
- package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
- package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
- package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
- package/src/modules/billing/__tests__/commands/invoices.test.ts +436 -354
- package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
- package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
- package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
- package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
- package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
- package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
- package/src/modules/billing/__tests__/entityRegistry.test.ts +8 -1
- package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
- package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
- package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
- package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
- package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +228 -17
- package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
- package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
- package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
- package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
- package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +189 -0
- package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
- package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
- package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
- package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
- package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
- package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
- package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
- package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
- package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
- package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
- package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +199 -0
- package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
- package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
- package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
- package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
- package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
- package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
- package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
- package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
- package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
- package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
- package/src/modules/billing/__tests__/setup.test.ts +13 -4
- package/src/modules/billing/__tests__/validators.test.ts +193 -3
- package/src/modules/billing/acl.ts +12 -0
- package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
- package/src/modules/billing/api/accounts/route.ts +58 -4
- package/src/modules/billing/api/export/account/[id]/route.ts +13 -11
- package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
- package/src/modules/billing/api/invoices/[id]/pdf/route.ts +79 -0
- package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
- package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
- package/src/modules/billing/api/invoices/add-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
- package/src/modules/billing/api/invoices/edit-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/post/route.ts +7 -6
- package/src/modules/billing/api/invoices/remove-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/route.ts +81 -86
- package/src/modules/billing/api/items/bulk/route.ts +2 -1
- package/src/modules/billing/api/items/change-price/route.ts +54 -0
- package/src/modules/billing/api/items/route.ts +23 -7
- package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
- package/src/modules/billing/api/payment-imports/route.ts +57 -0
- package/src/modules/billing/api/payments/[id]/route.ts +63 -0
- package/src/modules/billing/api/payments/allocate/route.ts +35 -0
- package/src/modules/billing/api/payments/assign/route.ts +36 -0
- package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
- package/src/modules/billing/api/payments/ignore/route.ts +35 -0
- package/src/modules/billing/api/payments/import/route.ts +72 -0
- package/src/modules/billing/api/payments/restore/route.ts +35 -0
- package/src/modules/billing/api/payments/route.ts +147 -0
- package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
- package/src/modules/billing/api/payments/unassign/route.ts +35 -0
- package/src/modules/billing/api/run-outcomes/route.ts +49 -6
- package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
- package/src/modules/billing/api/runs/[id]/route.ts +59 -0
- package/src/modules/billing/api/runs/retry-failed/route.ts +2 -1
- package/src/modules/billing/api/runs/route.ts +15 -7
- package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
- package/src/modules/billing/api/settings/route.ts +116 -0
- package/src/modules/billing/api/statements/route.ts +5 -0
- package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
- package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
- package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
- package/src/modules/billing/backend/billing/accounts/page.tsx +70 -4
- package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +444 -95
- package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
- package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
- package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
- package/src/modules/billing/backend/billing/items/page.tsx +18 -2
- package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
- package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
- package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
- package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
- package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
- package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
- package/src/modules/billing/backend/billing/runs/[id]/page.tsx +49 -18
- package/src/modules/billing/backend/billing/runs/page.tsx +59 -8
- package/src/modules/billing/backend/billing/statements/[id]/page.tsx +86 -5
- package/src/modules/billing/backend/billing/statements/page.tsx +1 -1
- package/src/modules/billing/backend/billing/topups/page.tsx +1 -1
- package/src/modules/billing/backend/billing/transactions/page.tsx +1 -1
- package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
- package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
- package/src/modules/billing/backend/config/billing/page.tsx +549 -0
- package/src/modules/billing/cli.ts +31 -1
- package/src/modules/billing/commands/accounts.ts +6 -0
- package/src/modules/billing/commands/index.ts +3 -0
- package/src/modules/billing/commands/invoices.ts +364 -231
- package/src/modules/billing/commands/items.ts +143 -0
- package/src/modules/billing/commands/memos.ts +218 -0
- package/src/modules/billing/commands/payments.ts +428 -0
- package/src/modules/billing/commands/runs.ts +205 -3
- package/src/modules/billing/commands/settings.ts +77 -0
- package/src/modules/billing/commands/topups.ts +12 -3
- package/src/modules/billing/commands/transactions.ts +2 -2
- package/src/modules/billing/components/AccountForm.tsx +199 -53
- package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
- package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
- package/src/modules/billing/components/AccountPicker.tsx +70 -0
- package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
- package/src/modules/billing/components/BillingDataTable.tsx +34 -0
- package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
- package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
- package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
- package/src/modules/billing/components/CustomerLabel.tsx +53 -0
- package/src/modules/billing/components/InvoicesTable.tsx +344 -0
- package/src/modules/billing/components/ItemForm.tsx +233 -44
- package/src/modules/billing/components/ItemPriceField.tsx +81 -0
- package/src/modules/billing/components/LineFormDialog.tsx +25 -1
- package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
- package/src/modules/billing/components/MoneyInput.tsx +26 -0
- package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
- package/src/modules/billing/components/PaymentsTable.tsx +213 -0
- package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
- package/src/modules/billing/components/PrepaidPanel.tsx +19 -6
- package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
- package/src/modules/billing/components/TestRunActions.tsx +152 -0
- package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
- package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
- package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
- package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
- package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
- package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
- package/src/modules/billing/components/account/AccountView.tsx +101 -0
- package/src/modules/billing/components/account/accountRow.ts +70 -0
- package/src/modules/billing/components/customerNames.ts +62 -0
- package/src/modules/billing/data/entities.ts +654 -5
- package/src/modules/billing/data/entityIds.ts +9 -0
- package/src/modules/billing/data/validators.ts +388 -8
- package/src/modules/billing/events.ts +56 -3
- package/src/modules/billing/i18n/en.json +457 -21
- package/src/modules/billing/i18n/pl.json +457 -21
- package/src/modules/billing/index.ts +6 -2
- package/src/modules/billing/lib/accountFinancials.ts +84 -0
- package/src/modules/billing/lib/accountLock.ts +32 -0
- package/src/modules/billing/lib/accountStatus.ts +11 -9
- package/src/modules/billing/lib/accountSummary.ts +172 -0
- package/src/modules/billing/lib/allocation.ts +515 -0
- package/src/modules/billing/lib/allocationEvents.ts +26 -0
- package/src/modules/billing/lib/billPeriod.ts +19 -0
- package/src/modules/billing/lib/billRunEngine.ts +350 -150
- package/src/modules/billing/lib/billingSettings.ts +145 -0
- package/src/modules/billing/lib/commandRoute.ts +112 -0
- package/src/modules/billing/lib/customerLookup.ts +157 -0
- package/src/modules/billing/lib/dateOnly.ts +22 -0
- package/src/modules/billing/lib/documentParties.ts +23 -0
- package/src/modules/billing/lib/documentTypes.ts +37 -0
- package/src/modules/billing/lib/dueDate.ts +26 -0
- package/src/modules/billing/lib/iban.ts +36 -0
- package/src/modules/billing/lib/invoiceDelivery.ts +197 -0
- package/src/modules/billing/lib/invoiceLanguages.ts +34 -0
- package/src/modules/billing/lib/invoiceWriter.ts +162 -148
- package/src/modules/billing/lib/itemBillingState.ts +67 -0
- package/src/modules/billing/lib/itemPriceChange.ts +56 -0
- package/src/modules/billing/lib/itemSelector.ts +4 -1
- package/src/modules/billing/lib/lineAmounts.ts +61 -0
- package/src/modules/billing/lib/memoGuards.ts +41 -0
- package/src/modules/billing/lib/navigation.ts +64 -0
- package/src/modules/billing/lib/numbering.ts +174 -0
- package/src/modules/billing/lib/overdue.ts +60 -0
- package/src/modules/billing/lib/paymentCsv.ts +171 -0
- package/src/modules/billing/lib/paymentGateway.ts +52 -0
- package/src/modules/billing/lib/paymentImport.ts +228 -0
- package/src/modules/billing/lib/paymentMatcher.ts +88 -0
- package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
- package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
- package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
- package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
- package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
- package/src/modules/billing/lib/pdf/invoiceModel.ts +328 -0
- package/src/modules/billing/lib/pdf/invoicePdf.ts +216 -0
- package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
- package/src/modules/billing/lib/prepaidConfig.ts +27 -36
- package/src/modules/billing/lib/prepaidConsume.ts +29 -6
- package/src/modules/billing/lib/prepaidPeriodClose.ts +407 -239
- package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
- package/src/modules/billing/lib/seeds/demo.ts +79 -6
- package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
- package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
- package/src/modules/billing/lib/servicePeriods.ts +226 -0
- package/src/modules/billing/lib/testRunCleanup.ts +42 -0
- package/src/modules/billing/lib/topupCapture.ts +3 -4
- package/src/modules/billing/lib/topupReceipt.ts +70 -103
- package/src/modules/billing/lib/usageRater.ts +1 -1
- package/src/modules/billing/lib/usageRunner.ts +17 -5
- package/src/modules/billing/lib/vat.ts +56 -0
- package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
- package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
- package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
- package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
- package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
- package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
- package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
- package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
- package/src/modules/billing/setup.ts +11 -237
- package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
- package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
- package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
- package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
- package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
- package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
- package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
- package/dist/modules/billing/lib/invoiceStatus.js +0 -38
- package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
- package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
- package/src/modules/billing/lib/invoiceStatus.ts +0 -61
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test-run cleanup shared by the "wipe test invoices" and "delete run"
|
|
5
|
+
* commands (Spec F, P-D1).
|
|
6
|
+
*
|
|
7
|
+
* Hard-deletes test drafts (`test_run = true`, `document_type = 'invoice'`)
|
|
8
|
+
* together with their lines and their draft-edit audit rows. Scoped by
|
|
9
|
+
* tenant + organization, and optionally by one Bill Run. Must run inside the
|
|
10
|
+
* caller's transaction.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type TestRunCleanupScope = {
|
|
14
|
+
tenantId: string
|
|
15
|
+
organizationId: string
|
|
16
|
+
/** When set, only test invoices written by this Bill Run are removed. */
|
|
17
|
+
billRunId?: string | null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function deleteTestRunArtifacts(
|
|
21
|
+
em: EntityManager,
|
|
22
|
+
scope: TestRunCleanupScope,
|
|
23
|
+
): Promise<number> {
|
|
24
|
+
const params: unknown[] = [scope.tenantId, scope.organizationId]
|
|
25
|
+
let billRunClause = ''
|
|
26
|
+
if (scope.billRunId) {
|
|
27
|
+
billRunClause = ' AND bill_run_id = ?'
|
|
28
|
+
params.push(scope.billRunId)
|
|
29
|
+
}
|
|
30
|
+
const rows = (await em.execute(
|
|
31
|
+
`SELECT id FROM billing_invoices
|
|
32
|
+
WHERE tenant_id = ? AND organization_id = ? AND test_run = true AND document_type = 'invoice'${billRunClause}`,
|
|
33
|
+
params,
|
|
34
|
+
)) as unknown as Array<{ id: string }> | undefined
|
|
35
|
+
const ids = (rows ?? []).map((row) => row.id)
|
|
36
|
+
if (ids.length === 0) return 0
|
|
37
|
+
const placeholders = ids.map(() => '?').join(',')
|
|
38
|
+
await em.execute(`DELETE FROM billing_draft_invoice_edits WHERE invoice_id IN (${placeholders})`, ids)
|
|
39
|
+
await em.execute(`DELETE FROM billing_invoice_lines WHERE invoice_id IN (${placeholders})`, ids)
|
|
40
|
+
await em.execute(`DELETE FROM billing_invoices WHERE id IN (${placeholders})`, ids)
|
|
41
|
+
return ids.length
|
|
42
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
2
|
import { BillingTopup } from '../data/entities'
|
|
3
3
|
import { applyBalanceMovement } from './balanceLedger'
|
|
4
|
-
import { createTopupReceipt
|
|
4
|
+
import { createTopupReceipt } from './topupReceipt'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Idempotent top-up capture (SPEC-002 P2).
|
|
@@ -10,7 +10,7 @@ import { createTopupReceipt, type TopupReceiptDeps } from './topupReceipt'
|
|
|
10
10
|
* - credit the balance (atomic) + append a `type='topup'` transaction with a
|
|
11
11
|
* deterministic `source_ref = topup-{paymentId}` (so a re-fired capture can
|
|
12
12
|
* never double-credit),
|
|
13
|
-
* - create the
|
|
13
|
+
* - create the paid VAT receipt as a billing document (`document_type = 'receipt'`),
|
|
14
14
|
* - transition the BillingTopup → captured, backfilling `transaction_id` +
|
|
15
15
|
* `receipt_invoice_id`.
|
|
16
16
|
*
|
|
@@ -45,7 +45,6 @@ export type CaptureTopupResult = {
|
|
|
45
45
|
|
|
46
46
|
export async function captureTopup(
|
|
47
47
|
em: EntityManager,
|
|
48
|
-
deps: TopupReceiptDeps,
|
|
49
48
|
params: CaptureTopupParams,
|
|
50
49
|
): Promise<CaptureTopupResult> {
|
|
51
50
|
const { topup, account } = params
|
|
@@ -88,7 +87,7 @@ export async function captureTopup(
|
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
// 2. Fiscal VAT receipt (posted+paid).
|
|
91
|
-
const receipt = await createTopupReceipt(tem as EntityManager,
|
|
90
|
+
const receipt = await createTopupReceipt(tem as EntityManager, {
|
|
92
91
|
account,
|
|
93
92
|
topupId: topup.id,
|
|
94
93
|
paymentId: topup.paymentId,
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '
|
|
6
|
-
import type { SalesDocumentNumberGenerator } from '@open-mercato/core/modules/sales/services/salesDocumentNumberGenerator'
|
|
7
|
-
import type { TaxCalculationService } from '@open-mercato/core/modules/sales/services/taxCalculationService'
|
|
8
|
-
import { resolveInvoiceStatusEntryId } from './invoiceStatus'
|
|
2
|
+
import { BillingInvoice, BillingInvoiceLine } from '../data/entities'
|
|
3
|
+
import { getBillingSettings, numberMaskFor } from './billingSettings'
|
|
4
|
+
import { claimDocumentNumber } from './numbering'
|
|
5
|
+
import { lineAmountsFromGross, money4 } from './vat'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
|
-
* Creates the fiscal VAT receipt for a captured prepaid top-up (SPEC-002 P2
|
|
8
|
+
* Creates the fiscal VAT receipt for a captured prepaid top-up (SPEC-002 P2,
|
|
9
|
+
* Spec 0 E-D3).
|
|
12
10
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* receipt
|
|
16
|
-
*
|
|
17
|
-
* convention).
|
|
11
|
+
* The receipt is a billing-owned document (`billing_invoices` with
|
|
12
|
+
* `document_type = 'receipt'`, `status = 'paid'`), numbered from the
|
|
13
|
+
* `receipt` series (default mask `RC/{YYYY}/{MM}/{SEQUENCE_NUM_MONTH:4}`).
|
|
14
|
+
* Nothing is written to core `sales`.
|
|
18
15
|
*
|
|
19
|
-
*
|
|
20
|
-
* balance credited).
|
|
21
|
-
*
|
|
16
|
+
* VAT at top-up: the top-up `amount` is the GROSS the customer paid (= the
|
|
17
|
+
* balance credited); `vat.lineAmountsFromGross` splits it into net + tax with
|
|
18
|
+
* `net + tax = gross` exactly.
|
|
19
|
+
*
|
|
20
|
+
* MUST run inside the capture transaction (`captureTopup`) so the receipt
|
|
21
|
+
* number, the balance credit and the top-up transition commit together.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
export type TopupReceiptParams = {
|
|
@@ -36,11 +36,6 @@ export type TopupReceiptParams = {
|
|
|
36
36
|
taxRate: number
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export type TopupReceiptDeps = {
|
|
40
|
-
numberGenerator: Pick<SalesDocumentNumberGenerator, 'generate'>
|
|
41
|
-
taxService: TaxCalculationService
|
|
42
|
-
}
|
|
43
|
-
|
|
44
39
|
export type TopupReceipt = {
|
|
45
40
|
invoiceId: string
|
|
46
41
|
invoiceNumber: string
|
|
@@ -50,104 +45,76 @@ export type TopupReceipt = {
|
|
|
50
45
|
taxRate: number
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
function
|
|
54
|
-
|
|
48
|
+
function todayUtc(): Date {
|
|
49
|
+
const now = new Date()
|
|
50
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()))
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
export async function createTopupReceipt(
|
|
58
|
-
em: EntityManager,
|
|
59
|
-
deps: TopupReceiptDeps,
|
|
60
|
-
params: TopupReceiptParams,
|
|
61
|
-
): Promise<TopupReceipt> {
|
|
53
|
+
export async function createTopupReceipt(em: EntityManager, params: TopupReceiptParams): Promise<TopupReceipt> {
|
|
62
54
|
const { account } = params
|
|
55
|
+
const scope = { tenantId: account.tenantId, organizationId: account.organizationId }
|
|
56
|
+
const taxRate = Number.isFinite(params.taxRate) && params.taxRate > 0 ? params.taxRate : 0
|
|
57
|
+
const amounts = lineAmountsFromGross(Number.parseFloat(params.amount), taxRate)
|
|
58
|
+
const net = money4(amounts.net)
|
|
59
|
+
const tax = money4(amounts.tax)
|
|
60
|
+
const gross = money4(amounts.gross)
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
mode: 'gross',
|
|
68
|
-
organizationId: account.organizationId,
|
|
69
|
-
tenantId: account.tenantId,
|
|
70
|
-
taxRate: params.taxRate,
|
|
71
|
-
})
|
|
72
|
-
const net = fmt4(tax.netAmount)
|
|
73
|
-
const gross = fmt4(tax.grossAmount)
|
|
74
|
-
const taxAmount = fmt4(tax.taxAmount)
|
|
75
|
-
const effectiveRate = tax.taxRate ?? 0
|
|
76
|
-
|
|
77
|
-
const generated = await deps.numberGenerator.generate({
|
|
78
|
-
kind: 'invoice',
|
|
79
|
-
organizationId: account.organizationId,
|
|
80
|
-
tenantId: account.tenantId,
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
// Posted+paid in one shot — resolve the `paid` status entry directly.
|
|
84
|
-
const paidStatusEntryId = await resolveInvoiceStatusEntryId(
|
|
85
|
-
em,
|
|
86
|
-
account.tenantId,
|
|
87
|
-
account.organizationId,
|
|
88
|
-
'paid',
|
|
89
|
-
)
|
|
62
|
+
const settings = await getBillingSettings(em, scope)
|
|
63
|
+
const issueDate = todayUtc()
|
|
64
|
+
const claimed = await claimDocumentNumber(em, scope, 'receipt', numberMaskFor(settings, 'receipt'), issueDate)
|
|
90
65
|
|
|
91
66
|
const now = new Date()
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
67
|
+
const receipt = em.create(BillingInvoice, {
|
|
68
|
+
...scope,
|
|
69
|
+
billAccountId: account.id,
|
|
70
|
+
documentType: 'receipt',
|
|
71
|
+
number: claimed.number,
|
|
72
|
+
series: 'receipt',
|
|
97
73
|
status: 'paid',
|
|
98
|
-
|
|
74
|
+
testRun: false,
|
|
75
|
+
issueDate,
|
|
76
|
+
postedAt: now,
|
|
99
77
|
currencyCode: account.currencyCode,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
metadata: {
|
|
109
|
-
kind: 'prepaid_topup',
|
|
110
|
-
bill_account_id: account.id,
|
|
111
|
-
topup_id: params.topupId,
|
|
112
|
-
payment_id: params.paymentId,
|
|
113
|
-
},
|
|
78
|
+
subtotalNet: net,
|
|
79
|
+
taxTotal: tax,
|
|
80
|
+
totalGross: gross,
|
|
81
|
+
paidTotal: gross,
|
|
82
|
+
creditedTotal: '0',
|
|
83
|
+
outstanding: '0',
|
|
84
|
+
topupId: params.topupId,
|
|
85
|
+
metadata: { kind: 'prepaid_topup', payment_id: params.paymentId },
|
|
114
86
|
createdAt: now,
|
|
115
87
|
updatedAt: now,
|
|
116
88
|
})
|
|
117
|
-
em.persist(
|
|
89
|
+
em.persist(receipt)
|
|
90
|
+
await em.flush() // need the receipt id for the line
|
|
118
91
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
metadata: {
|
|
138
|
-
kind: 'prepaid_topup',
|
|
139
|
-
topup_id: params.topupId,
|
|
140
|
-
},
|
|
141
|
-
})
|
|
142
|
-
em.persist(line)
|
|
92
|
+
em.persist(
|
|
93
|
+
em.create(BillingInvoiceLine, {
|
|
94
|
+
...scope,
|
|
95
|
+
invoiceId: receipt.id,
|
|
96
|
+
lineNumber: 1,
|
|
97
|
+
billingType: 'receipt',
|
|
98
|
+
description: 'Account top-up',
|
|
99
|
+
quantity: '1.0000',
|
|
100
|
+
unitPriceNet: net,
|
|
101
|
+
taxRate: taxRate.toFixed(4),
|
|
102
|
+
netAmount: net,
|
|
103
|
+
taxAmount: tax,
|
|
104
|
+
grossAmount: gross,
|
|
105
|
+
metadata: { kind: 'prepaid_topup', topup_id: params.topupId },
|
|
106
|
+
createdAt: now,
|
|
107
|
+
updatedAt: now,
|
|
108
|
+
}),
|
|
109
|
+
)
|
|
143
110
|
await em.flush()
|
|
144
111
|
|
|
145
112
|
return {
|
|
146
|
-
invoiceId:
|
|
147
|
-
invoiceNumber:
|
|
113
|
+
invoiceId: receipt.id,
|
|
114
|
+
invoiceNumber: claimed.number,
|
|
148
115
|
netAmount: net,
|
|
149
|
-
taxAmount,
|
|
116
|
+
taxAmount: tax,
|
|
150
117
|
grossAmount: gross,
|
|
151
|
-
taxRate
|
|
118
|
+
taxRate,
|
|
152
119
|
}
|
|
153
120
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - `amount` — numeric string, rounded 2dp half-up, formatted to 4
|
|
12
12
|
* decimals to match the `core/sales` numeric(18,4) column shape.
|
|
13
13
|
* - `breakdown` — per-tier rated quantity / amount, persisted into
|
|
14
|
-
* `
|
|
14
|
+
* `billing_invoice_lines.metadata.usage_tier_breakdown` so operators
|
|
15
15
|
* can see how the line was built without re-running the math.
|
|
16
16
|
*/
|
|
17
17
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
2
|
import { type BillingAccount, type BillingItem } from '../data/entities'
|
|
3
3
|
import type { BillPeriod } from './billPeriod'
|
|
4
|
-
import type
|
|
4
|
+
import { itemTaxRate, type InvoiceLineDescriptor } from './invoiceWriter'
|
|
5
5
|
import { format4dp, formatUnitPrice, rateUsageForItem, type UsageRate } from './usageRater'
|
|
6
|
+
import { priceBasisOf } from './lineAmounts'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Per-account usage processing — Phase 3.
|
|
@@ -103,7 +104,13 @@ async function fetchUsageAggregate(
|
|
|
103
104
|
em: EntityManager,
|
|
104
105
|
account: BillingAccount,
|
|
105
106
|
period: BillPeriod,
|
|
107
|
+
after: Date | null,
|
|
106
108
|
): Promise<UsageAggregateRow[]> {
|
|
109
|
+
// `after` (Spec A): exclusive lower bound for multi-cycle test / dry runs,
|
|
110
|
+
// which never mark records as rated — without it every simulated cycle
|
|
111
|
+
// would re-count the usage an earlier simulated cycle already billed.
|
|
112
|
+
const params: unknown[] = [account.tenantId, account.organizationId, account.id, period.periodEnd]
|
|
113
|
+
if (after) params.push(after)
|
|
107
114
|
const rows = (await em.execute(
|
|
108
115
|
`SELECT uom_code,
|
|
109
116
|
SUM(quantity)::text AS total_quantity,
|
|
@@ -115,8 +122,9 @@ async function fetchUsageAggregate(
|
|
|
115
122
|
AND deleted_at IS NULL
|
|
116
123
|
AND rated_in_bill_run_id IS NULL
|
|
117
124
|
AND period_end <= ?
|
|
125
|
+
${after ? 'AND period_end > ?' : ''}
|
|
118
126
|
GROUP BY uom_code`,
|
|
119
|
-
|
|
127
|
+
params,
|
|
120
128
|
)) as unknown as UsageAggregateRow[] | undefined
|
|
121
129
|
return rows ?? []
|
|
122
130
|
}
|
|
@@ -126,8 +134,9 @@ export async function processUsageForAccount(
|
|
|
126
134
|
account: BillingAccount,
|
|
127
135
|
period: BillPeriod,
|
|
128
136
|
usageItems: readonly BillingItem[],
|
|
137
|
+
options: { after?: Date | null } = {},
|
|
129
138
|
): Promise<UsageRunResult> {
|
|
130
|
-
const aggregateRows = await fetchUsageAggregate(em, account, period)
|
|
139
|
+
const aggregateRows = await fetchUsageAggregate(em, account, period, options.after ?? null)
|
|
131
140
|
if (aggregateRows.length === 0) return EMPTY_RESULT
|
|
132
141
|
|
|
133
142
|
const itemByUom = nonNullUomItems(usageItems)
|
|
@@ -167,9 +176,12 @@ export async function processUsageForAccount(
|
|
|
167
176
|
billingItemId: item.id,
|
|
168
177
|
billingType: 'usage',
|
|
169
178
|
description: item.description,
|
|
170
|
-
unitPriceNet,
|
|
179
|
+
unitPrice: unitPriceNet,
|
|
171
180
|
quantity: format4dp(totalQuantity),
|
|
172
|
-
|
|
181
|
+
lineAmount: rated.amount,
|
|
182
|
+
// Tiered rates are always net (P-D4); a simple rate keeps the item basis.
|
|
183
|
+
priceBasis: isSimpleFlat ? priceBasisOf(item.priceBasis) : 'net',
|
|
184
|
+
taxRate: itemTaxRate(item),
|
|
173
185
|
metadataExtra: {
|
|
174
186
|
uom_code: uom,
|
|
175
187
|
usage_record_count: recordCount,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VAT arithmetic for billing documents (Spec 0 — replaces core
|
|
3
|
+
* `taxCalculationService`; billing no longer depends on core `sales`).
|
|
4
|
+
*
|
|
5
|
+
* Pure. Money is rounded half-up to 2 dp (fiscal documents) and the
|
|
6
|
+
* identity `net + tax = gross` always holds exactly:
|
|
7
|
+
* - from net: tax = round2(net × rate), gross = net + tax
|
|
8
|
+
* - from gross: net = round2(gross / (1 + rate)), tax = gross − net
|
|
9
|
+
* Per-line rounding; document totals are sums of rounded lines (both
|
|
10
|
+
* methods are permitted in PL/EU and this keeps documents internally
|
|
11
|
+
* consistent).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type VatAmounts = { net: number; tax: number; gross: number }
|
|
15
|
+
|
|
16
|
+
export function round2(value: number): number {
|
|
17
|
+
const sign = value < 0 ? -1 : 1
|
|
18
|
+
return (sign * Math.round((Math.abs(value) + Number.EPSILON) * 100)) / 100
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function fraction(ratePercent: number): number {
|
|
22
|
+
return Number.isFinite(ratePercent) && ratePercent > 0 ? ratePercent / 100 : 0
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Amounts for a net line value (sign preserved for credits). */
|
|
26
|
+
export function lineAmountsFromNet(net: number, ratePercent: number): VatAmounts {
|
|
27
|
+
const netRounded = round2(net)
|
|
28
|
+
const tax = round2(netRounded * fraction(ratePercent))
|
|
29
|
+
return { net: netRounded, tax, gross: round2(netRounded + tax) }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Split a gross amount (e.g. a top-up payment) into net + tax. */
|
|
33
|
+
export function lineAmountsFromGross(gross: number, ratePercent: number): VatAmounts {
|
|
34
|
+
const grossRounded = round2(gross)
|
|
35
|
+
const net = round2(grossRounded / (1 + fraction(ratePercent)))
|
|
36
|
+
return { net, tax: round2(grossRounded - net), gross: grossRounded }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Column format used by billing numeric(18,4) money columns. */
|
|
40
|
+
export function money4(value: number): string {
|
|
41
|
+
return (Number.isFinite(value) ? round2(value) : 0).toFixed(4)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type DocumentTotals = { subtotalNet: string; taxTotal: string; totalGross: string }
|
|
45
|
+
|
|
46
|
+
export function sumTotals(lines: ReadonlyArray<VatAmounts>): DocumentTotals {
|
|
47
|
+
let net = 0
|
|
48
|
+
let tax = 0
|
|
49
|
+
let gross = 0
|
|
50
|
+
for (const line of lines) {
|
|
51
|
+
net += line.net
|
|
52
|
+
tax += line.tax
|
|
53
|
+
gross += line.gross
|
|
54
|
+
}
|
|
55
|
+
return { subtotalNet: money4(net), taxTotal: money4(tax), totalGross: money4(gross) }
|
|
56
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* B2C billing accounts (Spec E, Phase 1).
|
|
5
|
+
*
|
|
6
|
+
* Adds `billing_accounts.customer_kind` ('company' | 'person'). Additive
|
|
7
|
+
* only: existing accounts default to 'company', which is what they were
|
|
8
|
+
* (the account form could only pick companies until now).
|
|
9
|
+
*
|
|
10
|
+
* Hand-written, like the package's earlier migrations: `yarn mercato db
|
|
11
|
+
* generate` only diffs `@app` modules, so it never reaches this package
|
|
12
|
+
* module. The column mirrors `data/entities.ts` 1:1 so a future generator
|
|
13
|
+
* run diffs clean.
|
|
14
|
+
*/
|
|
15
|
+
export class Migration20261114000000_billing_customer_kind extends Migration {
|
|
16
|
+
async up(): Promise<void> {
|
|
17
|
+
this.addSql(
|
|
18
|
+
`alter table "billing_accounts" add column if not exists "customer_kind" text not null default 'company';`,
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async down(): Promise<void> {
|
|
23
|
+
this.addSql(`alter table "billing_accounts" drop column if exists "customer_kind";`)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Billing cycle semantics (Spec A).
|
|
5
|
+
*
|
|
6
|
+
* - `billing_items.charge_timing` ('in_advance' | 'in_arrears', default
|
|
7
|
+
* 'in_advance') and `billing_items.prorate` (default true) — recurring
|
|
8
|
+
* items are billed in advance and partial periods are prorated.
|
|
9
|
+
* - `billing_run_outcomes.cycles` — per-bill-date breakdown of a run.
|
|
10
|
+
* - Drops `billing_runs.catch_up`: every run now catches up on all due
|
|
11
|
+
* cycles, so the flag has no meaning. Per the billing improvements
|
|
12
|
+
* decision D14 all instances are reseeded; no data is migrated.
|
|
13
|
+
*
|
|
14
|
+
* Hand-written like the package's earlier migrations: `yarn mercato db
|
|
15
|
+
* generate` only diffs `@app` modules. Columns mirror `data/entities.ts` 1:1.
|
|
16
|
+
*/
|
|
17
|
+
export class Migration20261114100000_billing_cycle_semantics extends Migration {
|
|
18
|
+
async up(): Promise<void> {
|
|
19
|
+
this.addSql(
|
|
20
|
+
`alter table "billing_items" add column if not exists "charge_timing" text not null default 'in_advance';`,
|
|
21
|
+
)
|
|
22
|
+
this.addSql(
|
|
23
|
+
`alter table "billing_items" add column if not exists "prorate" boolean not null default true;`,
|
|
24
|
+
)
|
|
25
|
+
this.addSql(`alter table "billing_run_outcomes" add column if not exists "cycles" jsonb null;`)
|
|
26
|
+
this.addSql(`alter table "billing_runs" drop column if exists "catch_up";`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async down(): Promise<void> {
|
|
30
|
+
this.addSql(
|
|
31
|
+
`alter table "billing_runs" add column if not exists "catch_up" boolean not null default false;`,
|
|
32
|
+
)
|
|
33
|
+
this.addSql(`alter table "billing_run_outcomes" drop column if exists "cycles";`)
|
|
34
|
+
this.addSql(`alter table "billing_items" drop column if exists "prorate";`)
|
|
35
|
+
this.addSql(`alter table "billing_items" drop column if exists "charge_timing";`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Standalone invoice ledger (Spec 0).
|
|
5
|
+
*
|
|
6
|
+
* Billing stops writing core `sales_invoices`: invoices, memos and top-up
|
|
7
|
+
* receipts move to `billing_invoices` / `billing_invoice_lines`, numbered by
|
|
8
|
+
* `billing_document_sequences`; prepaid settings move from core `configs`
|
|
9
|
+
* into per-organization `billing_settings`.
|
|
10
|
+
*
|
|
11
|
+
* No data migration (billing improvements decision D14 — instances are
|
|
12
|
+
* reseeded). Billing rows already in `sales_invoices` are left untouched.
|
|
13
|
+
*
|
|
14
|
+
* Hand-written: the partial unique indexes can't be expressed in entity
|
|
15
|
+
* decorators, and `yarn mercato db generate` only diffs `@app` modules.
|
|
16
|
+
*/
|
|
17
|
+
export class Migration20261115000000_billing_invoice_ledger extends Migration {
|
|
18
|
+
async up(): Promise<void> {
|
|
19
|
+
this.addSql(`create table if not exists "billing_invoices" (
|
|
20
|
+
"id" uuid not null default gen_random_uuid(),
|
|
21
|
+
"organization_id" uuid not null,
|
|
22
|
+
"tenant_id" uuid not null,
|
|
23
|
+
"bill_account_id" uuid not null,
|
|
24
|
+
"document_type" text not null default 'invoice',
|
|
25
|
+
"number" text not null,
|
|
26
|
+
"series" text null,
|
|
27
|
+
"status" text not null default 'draft',
|
|
28
|
+
"test_run" boolean not null default false,
|
|
29
|
+
"bill_run_id" uuid null,
|
|
30
|
+
"bill_date" date null,
|
|
31
|
+
"period_start" date null,
|
|
32
|
+
"period_end" date null,
|
|
33
|
+
"issue_date" date null,
|
|
34
|
+
"due_date" date null,
|
|
35
|
+
"currency_code" text not null,
|
|
36
|
+
"subtotal_net" numeric(18, 4) not null default 0,
|
|
37
|
+
"tax_total" numeric(18, 4) not null default 0,
|
|
38
|
+
"total_gross" numeric(18, 4) not null default 0,
|
|
39
|
+
"paid_total" numeric(18, 4) not null default 0,
|
|
40
|
+
"credited_total" numeric(18, 4) not null default 0,
|
|
41
|
+
"outstanding" numeric(18, 4) not null default 0,
|
|
42
|
+
"corrects_invoice_id" uuid null,
|
|
43
|
+
"correction_reason" text null,
|
|
44
|
+
"buyer_snapshot" jsonb null,
|
|
45
|
+
"seller_snapshot" jsonb null,
|
|
46
|
+
"pdf_attachment_id" uuid null,
|
|
47
|
+
"topup_id" uuid null,
|
|
48
|
+
"posted_at" timestamptz null,
|
|
49
|
+
"metadata" jsonb null,
|
|
50
|
+
"created_at" timestamptz not null,
|
|
51
|
+
"updated_at" timestamptz not null,
|
|
52
|
+
"deleted_at" timestamptz null,
|
|
53
|
+
constraint "billing_invoices_pkey" primary key ("id")
|
|
54
|
+
);`)
|
|
55
|
+
this.addSql(`create index if not exists "billing_invoices_status_idx" on "billing_invoices" ("tenant_id", "organization_id", "status");`)
|
|
56
|
+
this.addSql(`create index if not exists "billing_invoices_account_idx" on "billing_invoices" ("bill_account_id", "status", "due_date");`)
|
|
57
|
+
this.addSql(`create index if not exists "billing_invoices_run_idx" on "billing_invoices" ("bill_run_id");`)
|
|
58
|
+
this.addSql(`create index if not exists "billing_invoices_corrects_idx" on "billing_invoices" ("corrects_invoice_id");`)
|
|
59
|
+
this.addSql(`create index if not exists "billing_invoices_topup_idx" on "billing_invoices" ("topup_id");`)
|
|
60
|
+
// Spec A dedupe backstop: one invoice per (account, bill date, test flag).
|
|
61
|
+
this.addSql(`create unique index if not exists "billing_invoices_bill_date_uq" on "billing_invoices"
|
|
62
|
+
("tenant_id", "organization_id", "bill_account_id", "bill_date", "test_run")
|
|
63
|
+
where "document_type" = 'invoice' and "deleted_at" is null and "bill_date" is not null;`)
|
|
64
|
+
// A posted number is unique within the organization.
|
|
65
|
+
this.addSql(`create unique index if not exists "billing_invoices_number_uq" on "billing_invoices"
|
|
66
|
+
("tenant_id", "organization_id", "number") where "series" is not null;`)
|
|
67
|
+
|
|
68
|
+
this.addSql(`create table if not exists "billing_invoice_lines" (
|
|
69
|
+
"id" uuid not null default gen_random_uuid(),
|
|
70
|
+
"organization_id" uuid not null,
|
|
71
|
+
"tenant_id" uuid not null,
|
|
72
|
+
"invoice_id" uuid not null,
|
|
73
|
+
"line_number" int not null,
|
|
74
|
+
"billing_item_id" uuid null,
|
|
75
|
+
"billing_type" text not null,
|
|
76
|
+
"description" text not null,
|
|
77
|
+
"quantity" numeric(18, 4) not null,
|
|
78
|
+
"unit_price_net" numeric(18, 4) not null,
|
|
79
|
+
"tax_rate" numeric(7, 4) not null default 0,
|
|
80
|
+
"net_amount" numeric(18, 4) not null,
|
|
81
|
+
"tax_amount" numeric(18, 4) not null default 0,
|
|
82
|
+
"gross_amount" numeric(18, 4) not null,
|
|
83
|
+
"service_period_start" date null,
|
|
84
|
+
"service_period_end" date null,
|
|
85
|
+
"corrects_line_id" uuid null,
|
|
86
|
+
"metadata" jsonb null,
|
|
87
|
+
"created_at" timestamptz not null,
|
|
88
|
+
"updated_at" timestamptz not null,
|
|
89
|
+
"deleted_at" timestamptz null,
|
|
90
|
+
constraint "billing_invoice_lines_pkey" primary key ("id")
|
|
91
|
+
);`)
|
|
92
|
+
this.addSql(`create index if not exists "billing_invoice_lines_invoice_idx" on "billing_invoice_lines" ("invoice_id", "line_number");`)
|
|
93
|
+
|
|
94
|
+
this.addSql(`create table if not exists "billing_document_sequences" (
|
|
95
|
+
"id" uuid not null default gen_random_uuid(),
|
|
96
|
+
"organization_id" uuid not null,
|
|
97
|
+
"tenant_id" uuid not null,
|
|
98
|
+
"series" text not null,
|
|
99
|
+
"scope_key" text not null default '',
|
|
100
|
+
"next_value" bigint not null default 1,
|
|
101
|
+
"created_at" timestamptz not null,
|
|
102
|
+
"updated_at" timestamptz not null,
|
|
103
|
+
constraint "billing_document_sequences_pkey" primary key ("id"),
|
|
104
|
+
constraint "billing_document_sequences_scope_uq" unique ("tenant_id", "organization_id", "series", "scope_key")
|
|
105
|
+
);`)
|
|
106
|
+
|
|
107
|
+
this.addSql(`create table if not exists "billing_settings" (
|
|
108
|
+
"id" uuid not null default gen_random_uuid(),
|
|
109
|
+
"organization_id" uuid not null,
|
|
110
|
+
"tenant_id" uuid not null,
|
|
111
|
+
"low_balance_threshold_default" numeric(18, 4) not null default 0,
|
|
112
|
+
"near_limit_buffer_default" numeric(18, 4) not null default 0,
|
|
113
|
+
"statement_enabled" boolean not null default true,
|
|
114
|
+
"topup_tax_rate" numeric(7, 4) not null default 0,
|
|
115
|
+
"topup_provider" text not null default 'stripe',
|
|
116
|
+
"number_masks" jsonb null,
|
|
117
|
+
"created_at" timestamptz not null,
|
|
118
|
+
"updated_at" timestamptz not null,
|
|
119
|
+
"deleted_at" timestamptz null,
|
|
120
|
+
constraint "billing_settings_pkey" primary key ("id")
|
|
121
|
+
);`)
|
|
122
|
+
this.addSql(`create unique index if not exists "billing_settings_org_uq" on "billing_settings"
|
|
123
|
+
("tenant_id", "organization_id") where "deleted_at" is null;`)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async down(): Promise<void> {
|
|
127
|
+
this.addSql(`drop table if exists "billing_settings" cascade;`)
|
|
128
|
+
this.addSql(`drop table if exists "billing_document_sequences" cascade;`)
|
|
129
|
+
this.addSql(`drop table if exists "billing_invoice_lines" cascade;`)
|
|
130
|
+
this.addSql(`drop table if exists "billing_invoices" cascade;`)
|
|
131
|
+
}
|
|
132
|
+
}
|