@dainamite/billing 0.20.0 → 0.22.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 +103 -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 +47 -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 +70 -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/de.json +880 -0
- package/dist/modules/billing/i18n/en.json +457 -21
- package/dist/modules/billing/i18n/es.json +880 -0
- package/dist/modules/billing/i18n/pl.json +458 -22
- 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 +133 -0
- package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
- package/dist/modules/billing/lib/invoiceLanguages.js +28 -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 +276 -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 +171 -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__/i18n/dictionaries.test.ts +64 -0
- 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 +206 -0
- package/src/modules/billing/__tests__/lib/invoiceLanguages.test.ts +49 -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 +269 -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 +197 -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 +59 -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 +80 -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 +656 -6
- 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/de.json +880 -0
- package/src/modules/billing/i18n/en.json +457 -21
- package/src/modules/billing/i18n/es.json +880 -0
- package/src/modules/billing/i18n/pl.json +458 -22
- 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 +196 -0
- package/src/modules/billing/lib/invoiceLanguages.ts +57 -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 +329 -0
- package/src/modules/billing/lib/pdf/invoicePdf.ts +220 -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,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { runCommandRoute } from "../../../lib/commandRoute.js";
|
|
3
|
+
const metadata = {
|
|
4
|
+
POST: { requireAuth: true, requireFeatures: ["billing.payment.manage"] }
|
|
5
|
+
};
|
|
6
|
+
const bodySchema = z.object({ allocationId: z.string().uuid() });
|
|
7
|
+
async function POST(req) {
|
|
8
|
+
return runCommandRoute(req, {
|
|
9
|
+
commandId: "billing.payments.unallocate",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.allocationId,
|
|
13
|
+
logLabel: "billing/payments/unallocate.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Remove an allocation",
|
|
21
|
+
description: "Un-allocates a payment or credit memo allocation (soft delete, history kept). The source's unallocated amount is restored and the invoice recomputed.",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 404, description: "Allocation not found" }
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
POST,
|
|
32
|
+
metadata,
|
|
33
|
+
openApi
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/payments/unallocate/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/unallocate` \u2014 remove an allocation (Spec C). */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.payment.manage'] },\n}\n\nconst bodySchema = z.object({ allocationId: z.string().uuid() })\n\nexport async function POST(req: Request) {\n return runCommandRoute(req, {\n commandId: 'billing.payments.unallocate',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.allocationId,\n logLabel: 'billing/payments/unallocate.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Remove an allocation',\n description: 'Un-allocates a payment or credit memo allocation (soft delete, history kept). The source\\'s unallocated amount is restored and the invoice recomputed.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 404, description: 'Allocation not found' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,uBAAuB;AAIzB,MAAM,WAAW;AAAA,EACtB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACzE;AAEA,MAAM,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE/D,eAAsB,KAAK,KAAc;AACvC,SAAO,gBAAgB,KAAK;AAAA,IAC1B,WAAW;AAAA,IACX;AAAA,IACA,cAAc;AAAA,IACd,YAAY,CAAC,SAAS,KAAK;AAAA,IAC3B,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,aAAa,EAAE,QAAQ,WAAW;AAAA,MAClC,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,wBAAwB,CAAC;AAAA,MACjE,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,uBAAuB;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { runCommandRoute } from "../../../lib/commandRoute.js";
|
|
3
|
+
const metadata = {
|
|
4
|
+
POST: { requireAuth: true, requireFeatures: ["billing.payment.manage"] }
|
|
5
|
+
};
|
|
6
|
+
const bodySchema = z.object({ paymentId: z.string().uuid() });
|
|
7
|
+
async function POST(req) {
|
|
8
|
+
return runCommandRoute(req, {
|
|
9
|
+
commandId: "billing.payments.unassign",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.paymentId,
|
|
13
|
+
logLabel: "billing/payments/unassign.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Unassign a payment",
|
|
21
|
+
description: "Reverses an assignment of a matched payment that has no allocations (status \u2192 unmatched).",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 409, description: "`billing.payment.has_allocations` \u2014 un-allocate first" }
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
POST,
|
|
32
|
+
metadata,
|
|
33
|
+
openApi
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/payments/unassign/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/unassign` \u2014 unassign a payment (Spec C). */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.payment.manage'] },\n}\n\nconst bodySchema = z.object({ paymentId: z.string().uuid() })\n\nexport async function POST(req: Request) {\n return runCommandRoute(req, {\n commandId: 'billing.payments.unassign',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.paymentId,\n logLabel: 'billing/payments/unassign.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Unassign a payment',\n description: 'Reverses an assignment of a matched payment that has no allocations (status \u2192 unmatched).',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 409, description: '`billing.payment.has_allocations` \u2014 un-allocate first' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,uBAAuB;AAIzB,MAAM,WAAW;AAAA,EACtB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACzE;AAEA,MAAM,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE5D,eAAsB,KAAK,KAAc;AACvC,SAAO,gBAAgB,KAAK;AAAA,IAC1B,WAAW;AAAA,IACX;AAAA,IACA,cAAc;AAAA,IACd,YAAY,CAAC,SAAS,KAAK;AAAA,IAC3B,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,aAAa,EAAE,QAAQ,WAAW;AAAA,MAClC,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,wBAAwB,CAAC;AAAA,MACjE,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,6DAAwD;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { SalesInvoice } from "@open-mercato/core/modules/sales/data/entities";
|
|
3
2
|
import { makeCrudRoute } from "@open-mercato/shared/lib/crud/factory";
|
|
4
|
-
import { BillingAccount, BillingRunOutcome } from "../../data/entities.js";
|
|
3
|
+
import { BillingAccount, BillingRun, BillingRunOutcome, BillingInvoice } from "../../data/entities.js";
|
|
4
|
+
import { toIsoDate } from "../../lib/dateOnly.js";
|
|
5
5
|
import { billingEntityIds } from "../../data/entityIds.js";
|
|
6
6
|
import {
|
|
7
7
|
BILL_RUN_OUTCOME_STATUSES
|
|
@@ -28,8 +28,28 @@ const billRunOutcomeListItemSchema = z.object({
|
|
|
28
28
|
errorMessage: z.string().nullable(),
|
|
29
29
|
warnings: z.record(z.string(), z.unknown()).nullable(),
|
|
30
30
|
draftInvoiceId: z.string().uuid().nullable(),
|
|
31
|
+
// Spec A: one entry per bill date processed for the account (catch-up).
|
|
32
|
+
cycles: z.array(
|
|
33
|
+
z.object({
|
|
34
|
+
bill_date: z.string(),
|
|
35
|
+
period_start: z.string().nullable(),
|
|
36
|
+
period_end: z.string().nullable(),
|
|
37
|
+
// Spec F: `charged` = prepaid charges debited from the balance.
|
|
38
|
+
status: z.enum(["invoiced", "charged", "previewed", "empty", "skipped_existing"]),
|
|
39
|
+
line_count: z.number(),
|
|
40
|
+
total_net: z.string(),
|
|
41
|
+
invoice_id: z.string().uuid().nullable(),
|
|
42
|
+
invoice_number: z.string().nullable(),
|
|
43
|
+
// Spec F (prepaid): what left the balance, and the period's statement.
|
|
44
|
+
total_debit: z.string().optional(),
|
|
45
|
+
statement_id: z.string().uuid().nullable().optional()
|
|
46
|
+
})
|
|
47
|
+
).nullable(),
|
|
31
48
|
bill_account_name: z.string().nullable(),
|
|
32
49
|
invoice_number: z.string().nullable(),
|
|
50
|
+
/** Spec F: mode and as-of date of the run this outcome belongs to. */
|
|
51
|
+
run_mode: z.enum(["real", "test", "dry"]).nullable(),
|
|
52
|
+
run_as_of_date: z.string().nullable(),
|
|
33
53
|
organizationId: z.string().uuid(),
|
|
34
54
|
tenantId: z.string().uuid(),
|
|
35
55
|
createdAt: z.string(),
|
|
@@ -55,6 +75,7 @@ const crud = makeCrudRoute({
|
|
|
55
75
|
"error_message",
|
|
56
76
|
"warnings",
|
|
57
77
|
"draft_invoice_id",
|
|
78
|
+
"cycles",
|
|
58
79
|
"organization_id",
|
|
59
80
|
"tenant_id",
|
|
60
81
|
"created_at",
|
|
@@ -85,24 +106,40 @@ const crud = makeCrudRoute({
|
|
|
85
106
|
items.map((row) => row.bill_account_id).filter((v) => typeof v === "string" && v.length > 0)
|
|
86
107
|
)
|
|
87
108
|
);
|
|
109
|
+
const cycleInvoiceIds = (row) => Array.isArray(row.cycles) ? row.cycles.map((cycle) => cycle?.invoice_id) : [];
|
|
88
110
|
const invoiceIds = Array.from(
|
|
89
111
|
new Set(
|
|
90
|
-
items.
|
|
112
|
+
items.flatMap((row) => [row.draft_invoice_id, ...cycleInvoiceIds(row)]).filter((v) => typeof v === "string" && v.length > 0)
|
|
91
113
|
)
|
|
92
114
|
);
|
|
93
|
-
const
|
|
115
|
+
const runIds = Array.from(
|
|
116
|
+
new Set(items.map((row) => row.bill_run_id).filter((v) => typeof v === "string" && v.length > 0))
|
|
117
|
+
);
|
|
118
|
+
const [accounts, invoices, runs] = await Promise.all([
|
|
94
119
|
accountIds.length ? em.find(BillingAccount, { id: { $in: accountIds } }) : [],
|
|
95
|
-
invoiceIds.length ? em.find(
|
|
120
|
+
invoiceIds.length ? em.find(BillingInvoice, { id: { $in: invoiceIds } }) : [],
|
|
121
|
+
// Spec F: the run's mode and as-of date (account Bill runs tab).
|
|
122
|
+
runIds.length ? em.find(BillingRun, { id: { $in: runIds } }) : []
|
|
96
123
|
]);
|
|
124
|
+
const runById = new Map(runs.map((run) => [String(run.id), run]));
|
|
97
125
|
const accountName = new Map(
|
|
98
126
|
accounts.map((a) => [String(a.id), a.name])
|
|
99
127
|
);
|
|
100
128
|
const invoiceNumber = new Map(
|
|
101
|
-
invoices.map((i) => [String(i.id), i.
|
|
129
|
+
invoices.map((i) => [String(i.id), i.number])
|
|
102
130
|
);
|
|
103
131
|
for (const row of items) {
|
|
104
132
|
row.bill_account_name = accountName.get(String(row.bill_account_id)) ?? null;
|
|
133
|
+
const run = runById.get(String(row.bill_run_id));
|
|
134
|
+
row.run_mode = run ? run.dryRun ? "dry" : run.testMode ? "test" : "real" : null;
|
|
135
|
+
row.run_as_of_date = run?.asOfDate ? toIsoDate(run.asOfDate) : null;
|
|
105
136
|
row.invoice_number = typeof row.draft_invoice_id === "string" ? invoiceNumber.get(row.draft_invoice_id) ?? null : null;
|
|
137
|
+
if (Array.isArray(row.cycles)) {
|
|
138
|
+
row.cycles = row.cycles.map((cycle) => ({
|
|
139
|
+
...cycle,
|
|
140
|
+
invoice_number: typeof cycle?.invoice_id === "string" ? invoiceNumber.get(cycle.invoice_id) ?? null : null
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
106
143
|
}
|
|
107
144
|
}
|
|
108
145
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/billing/api/run-outcomes/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AwilixContainer } from 'awilix'\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,SAAS;AAGlB,SAAS,
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AwilixContainer } from 'awilix'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { BillingAccount, BillingRun, BillingRunOutcome, BillingInvoice } from '../../data/entities'\nimport { toIsoDate } from '../../lib/dateOnly'\nimport { billingEntityIds } from '../../data/entityIds'\nimport {\n BILL_RUN_OUTCOME_STATUSES,\n} from '../../data/validators'\nimport { createBillingCrudOpenApi, createPagedListResponseSchema } from '../openapi'\n\n/**\n * `GET /api/billing/run-outcomes` \u2014 list per-account outcomes,\n * typically filtered by `billRunId` to populate the \"show me what\n * happened in this run\" detail panel.\n *\n * Read-only; outcomes are written by the engine itself, never by API\n * clients.\n */\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.run.view'] },\n}\n\nexport const metadata = routeMetadata\n\nconst listQuerySchema = z\n .object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(50),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n billRunId: z.string().uuid().optional(),\n billAccountId: z.string().uuid().optional(),\n status: z.enum(BILL_RUN_OUTCOME_STATUSES).optional(),\n })\n .passthrough()\n\nconst billRunOutcomeListItemSchema = z.object({\n id: z.string().uuid(),\n billRunId: z.string().uuid(),\n billAccountId: z.string().uuid(),\n status: z.string(),\n errorMessage: z.string().nullable(),\n warnings: z.record(z.string(), z.unknown()).nullable(),\n draftInvoiceId: z.string().uuid().nullable(),\n // Spec A: one entry per bill date processed for the account (catch-up).\n cycles: z\n .array(\n z.object({\n bill_date: z.string(),\n period_start: z.string().nullable(),\n period_end: z.string().nullable(),\n // Spec F: `charged` = prepaid charges debited from the balance.\n status: z.enum(['invoiced', 'charged', 'previewed', 'empty', 'skipped_existing']),\n line_count: z.number(),\n total_net: z.string(),\n invoice_id: z.string().uuid().nullable(),\n invoice_number: z.string().nullable(),\n // Spec F (prepaid): what left the balance, and the period's statement.\n total_debit: z.string().optional(),\n statement_id: z.string().uuid().nullable().optional(),\n }),\n )\n .nullable(),\n bill_account_name: z.string().nullable(),\n invoice_number: z.string().nullable(),\n /** Spec F: mode and as-of date of the run this outcome belongs to. */\n run_mode: z.enum(['real', 'test', 'dry']).nullable(),\n run_as_of_date: z.string().nullable(),\n organizationId: z.string().uuid(),\n tenantId: z.string().uuid(),\n createdAt: z.string(),\n updatedAt: z.string(),\n})\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: BillingRunOutcome,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n list: {\n schema: listQuerySchema,\n entityId: billingEntityIds.runOutcome,\n fields: [\n 'id',\n 'bill_run_id',\n 'bill_account_id',\n 'status',\n 'error_message',\n 'warnings',\n 'draft_invoice_id',\n 'cycles',\n 'organization_id',\n 'tenant_id',\n 'created_at',\n 'updated_at',\n ],\n sortFieldMap: {\n createdAt: 'created_at',\n },\n buildFilters: async (query) => {\n const filters: Record<string, unknown> = {}\n if (typeof query.billRunId === 'string') filters.bill_run_id = { $eq: query.billRunId }\n if (typeof query.billAccountId === 'string') {\n filters.bill_account_id = { $eq: query.billAccountId }\n }\n if (typeof query.status === 'string') filters.status = { $eq: query.status }\n return filters\n },\n },\n hooks: {\n // Outcomes reference account + draft invoice by FK id only. The\n // run detail UI wants names \u2014 resolve both in two bounded queries.\n afterList: async (payload: unknown, ctx: unknown) => {\n const items = ((payload as { items?: unknown[] } | null)?.items ?? []) as Array<\n Record<string, unknown>\n >\n if (items.length === 0) return\n const em = (ctx as { container: AwilixContainer }).container.resolve<EntityManager>('em')\n const accountIds = Array.from(\n new Set(\n items\n .map((row) => row.bill_account_id)\n .filter((v): v is string => typeof v === 'string' && v.length > 0),\n ),\n )\n const cycleInvoiceIds = (row: Record<string, unknown>): unknown[] =>\n Array.isArray(row.cycles)\n ? (row.cycles as Array<Record<string, unknown>>).map((cycle) => cycle?.invoice_id)\n : []\n const invoiceIds = Array.from(\n new Set(\n items\n .flatMap((row) => [row.draft_invoice_id, ...cycleInvoiceIds(row)])\n .filter((v): v is string => typeof v === 'string' && v.length > 0),\n ),\n )\n const runIds = Array.from(\n new Set(items.map((row) => row.bill_run_id).filter((v): v is string => typeof v === 'string' && v.length > 0)),\n )\n const [accounts, invoices, runs] = await Promise.all([\n accountIds.length\n ? em.find(BillingAccount, { id: { $in: accountIds } })\n : [],\n invoiceIds.length\n ? em.find(BillingInvoice, { id: { $in: invoiceIds } })\n : [],\n // Spec F: the run's mode and as-of date (account Bill runs tab).\n runIds.length ? em.find(BillingRun, { id: { $in: runIds } }) : [],\n ])\n const runById = new Map(runs.map((run) => [String(run.id), run] as const))\n const accountName = new Map(\n accounts.map((a) => [String(a.id), a.name] as [string, unknown]),\n )\n const invoiceNumber = new Map(\n invoices.map((i) => [String(i.id), i.number] as [string, unknown]),\n )\n for (const row of items) {\n row.bill_account_name = accountName.get(String(row.bill_account_id)) ?? null\n const run = runById.get(String(row.bill_run_id))\n row.run_mode = run ? (run.dryRun ? 'dry' : run.testMode ? 'test' : 'real') : null\n row.run_as_of_date = run?.asOfDate ? toIsoDate(run.asOfDate) : null\n row.invoice_number =\n typeof row.draft_invoice_id === 'string'\n ? invoiceNumber.get(row.draft_invoice_id) ?? null\n : null\n if (Array.isArray(row.cycles)) {\n row.cycles = (row.cycles as Array<Record<string, unknown>>).map((cycle) => ({\n ...cycle,\n invoice_number:\n typeof cycle?.invoice_id === 'string' ? invoiceNumber.get(cycle.invoice_id) ?? null : null,\n }))\n }\n }\n },\n },\n})\n\nexport const GET = crud.GET\n\nexport const openApi = createBillingCrudOpenApi({\n resourceName: 'BillRunOutcome',\n pluralName: 'BillRunOutcomes',\n querySchema: listQuerySchema,\n listResponseSchema: createPagedListResponseSchema(billRunOutcomeListItemSchema),\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readRequestBody, runCommandRoute } from "../../../../lib/commandRoute.js";
|
|
3
|
+
const metadata = {
|
|
4
|
+
POST: { requireAuth: true, requireFeatures: ["billing.invoice.post"] }
|
|
5
|
+
};
|
|
6
|
+
const paramsSchema = z.object({ id: z.string().uuid() });
|
|
7
|
+
const bodySchema = z.object({
|
|
8
|
+
afterInvoiceId: z.string().uuid().optional(),
|
|
9
|
+
limit: z.coerce.number().int().min(1).max(100).optional()
|
|
10
|
+
});
|
|
11
|
+
const responseSchema = z.object({
|
|
12
|
+
posted: z.number().int().nonnegative(),
|
|
13
|
+
failed: z.array(
|
|
14
|
+
z.object({ invoiceId: z.string().uuid(), number: z.string(), error: z.string(), code: z.string().nullable() })
|
|
15
|
+
),
|
|
16
|
+
nextCursor: z.string().uuid().nullable(),
|
|
17
|
+
remaining: z.number().int().nonnegative(),
|
|
18
|
+
stoppedReason: z.string().nullable()
|
|
19
|
+
});
|
|
20
|
+
async function POST(req, { params }) {
|
|
21
|
+
const parsedParams = paramsSchema.safeParse(await params);
|
|
22
|
+
if (!parsedParams.success) {
|
|
23
|
+
return Response.json({ error: "Invalid Bill Run id", code: "billing.request.invalid" }, { status: 400 });
|
|
24
|
+
}
|
|
25
|
+
const billRunId = parsedParams.data.id;
|
|
26
|
+
return runCommandRoute(
|
|
27
|
+
req,
|
|
28
|
+
{
|
|
29
|
+
commandId: "billing.runs.post_drafts",
|
|
30
|
+
bodySchema,
|
|
31
|
+
resourceKind: "billing.bill_run",
|
|
32
|
+
resourceId: () => billRunId,
|
|
33
|
+
toInput: (body, scope) => ({ ...body, ...scope, billRunId }),
|
|
34
|
+
logLabel: "billing/runs/[id]/post-drafts.POST"
|
|
35
|
+
},
|
|
36
|
+
await readRequestBody(req)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const openApi = {
|
|
40
|
+
methods: {
|
|
41
|
+
POST: {
|
|
42
|
+
tags: ["Billing"],
|
|
43
|
+
summary: "Post a real Bill Run's draft invoices (batched)",
|
|
44
|
+
description: "Posts up to `limit` (default 25, max 100) draft invoices of a real Bill Run, ascending by id. Pass `nextCursor` back as `afterInvoiceId` until `remaining` is 0. Per-invoice failures are listed in `failed`; incomplete seller settings stop the batch (`stoppedReason: billing.settings.incomplete`).",
|
|
45
|
+
pathParams: paramsSchema,
|
|
46
|
+
requestBody: { schema: bodySchema },
|
|
47
|
+
responses: [{ status: 200, description: "Batch result", schema: responseSchema }],
|
|
48
|
+
errors: [
|
|
49
|
+
{ status: 404, description: "`billing.run.not_found`" },
|
|
50
|
+
{ status: 409, description: "`billing.run.running`" },
|
|
51
|
+
{ status: 422, description: "`billing.run.not_real`" }
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export {
|
|
57
|
+
POST,
|
|
58
|
+
metadata,
|
|
59
|
+
openApi
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../src/modules/billing/api/runs/%5Bid%5D/post-drafts/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { readRequestBody, runCommandRoute } from '../../../../lib/commandRoute'\n\n/**\n * `POST /api/billing/runs/{id}/post-drafts` \u2014 post the draft invoices of a\n * REAL Bill Run, one bounded batch per call (ascending id). Call again with\n * `afterInvoiceId = nextCursor` until `remaining` is 0. Each invoice is posted\n * through `billing.invoices.post`; failures are reported per invoice and do\n * not stop the batch, except incomplete seller settings (`stoppedReason`).\n */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.invoice.post'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\nconst bodySchema = z.object({\n afterInvoiceId: z.string().uuid().optional(),\n limit: z.coerce.number().int().min(1).max(100).optional(),\n})\n\nconst responseSchema = z.object({\n posted: z.number().int().nonnegative(),\n failed: z.array(\n z.object({ invoiceId: z.string().uuid(), number: z.string(), error: z.string(), code: z.string().nullable() }),\n ),\n nextCursor: z.string().uuid().nullable(),\n remaining: z.number().int().nonnegative(),\n stoppedReason: z.string().nullable(),\n})\n\nexport async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {\n const parsedParams = paramsSchema.safeParse(await params)\n if (!parsedParams.success) {\n return Response.json({ error: 'Invalid Bill Run id', code: 'billing.request.invalid' }, { status: 400 })\n }\n const billRunId = parsedParams.data.id\n return runCommandRoute(\n req,\n {\n commandId: 'billing.runs.post_drafts',\n bodySchema,\n resourceKind: 'billing.bill_run',\n resourceId: () => billRunId,\n toInput: (body, scope) => ({ ...body, ...scope, billRunId }),\n logLabel: 'billing/runs/[id]/post-drafts.POST',\n },\n await readRequestBody(req),\n )\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: \"Post a real Bill Run's draft invoices (batched)\",\n description:\n 'Posts up to `limit` (default 25, max 100) draft invoices of a real Bill Run, ascending by id. ' +\n 'Pass `nextCursor` back as `afterInvoiceId` until `remaining` is 0. Per-invoice failures are listed in ' +\n '`failed`; incomplete seller settings stop the batch (`stoppedReason: billing.settings.incomplete`).',\n pathParams: paramsSchema,\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Batch result', schema: responseSchema }],\n errors: [\n { status: 404, description: '`billing.run.not_found`' },\n { status: 409, description: '`billing.run.running`' },\n { status: 422, description: '`billing.run.not_real`' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,iBAAiB,uBAAuB;AAU1C,MAAM,WAAW;AAAA,EACtB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,sBAAsB,EAAE;AACvE;AAEA,MAAM,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACvD,MAAM,aAAa,EAAE,OAAO;AAAA,EAC1B,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC3C,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAC1D,CAAC;AAED,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACrC,QAAQ,EAAE;AAAA,IACR,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,GAAG,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAAA,EAC/G;AAAA,EACA,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACvC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACxC,eAAe,EAAE,OAAO,EAAE,SAAS;AACrC,CAAC;AAED,eAAsB,KAAK,KAAc,EAAE,OAAO,GAAwC;AACxF,QAAM,eAAe,aAAa,UAAU,MAAM,MAAM;AACxD,MAAI,CAAC,aAAa,SAAS;AACzB,WAAO,SAAS,KAAK,EAAE,OAAO,uBAAuB,MAAM,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AACA,QAAM,YAAY,aAAa,KAAK;AACpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA,cAAc;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,SAAS,CAAC,MAAM,WAAW,EAAE,GAAG,MAAM,GAAG,OAAO,UAAU;AAAA,MAC1D,UAAU;AAAA,IACZ;AAAA,IACA,MAAM,gBAAgB,GAAG;AAAA,EAC3B;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aACE;AAAA,MAGF,YAAY;AAAA,MACZ,aAAa,EAAE,QAAQ,WAAW;AAAA,MAClC,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,gBAAgB,QAAQ,eAAe,CAAC;AAAA,MAChF,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,QACtD,EAAE,QAAQ,KAAK,aAAa,wBAAwB;AAAA,QACpD,EAAE,QAAQ,KAAK,aAAa,yBAAyB;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { runCommandRoute } from "../../../lib/commandRoute.js";
|
|
3
|
+
const metadata = {
|
|
4
|
+
DELETE: { requireAuth: true, requireFeatures: ["billing.run.delete"] }
|
|
5
|
+
};
|
|
6
|
+
const paramsSchema = z.object({ id: z.string().uuid() });
|
|
7
|
+
const emptyBodySchema = z.object({}).passthrough();
|
|
8
|
+
const deleteResponseSchema = z.object({
|
|
9
|
+
ok: z.literal(true),
|
|
10
|
+
invoicesRemoved: z.number().int().nonnegative()
|
|
11
|
+
});
|
|
12
|
+
async function DELETE(req, { params }) {
|
|
13
|
+
const parsedParams = paramsSchema.safeParse(await params);
|
|
14
|
+
if (!parsedParams.success) {
|
|
15
|
+
return Response.json({ error: "Invalid Bill Run id", code: "billing.request.invalid" }, { status: 400 });
|
|
16
|
+
}
|
|
17
|
+
const billRunId = parsedParams.data.id;
|
|
18
|
+
return runCommandRoute(
|
|
19
|
+
req,
|
|
20
|
+
{
|
|
21
|
+
commandId: "billing.runs.delete",
|
|
22
|
+
bodySchema: emptyBodySchema,
|
|
23
|
+
resourceKind: "billing.bill_run",
|
|
24
|
+
resourceId: () => billRunId,
|
|
25
|
+
operation: "delete",
|
|
26
|
+
toInput: (_body, scope) => ({ ...scope, billRunId }),
|
|
27
|
+
logLabel: "billing/runs/[id].DELETE"
|
|
28
|
+
},
|
|
29
|
+
{}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const openApi = {
|
|
33
|
+
methods: {
|
|
34
|
+
DELETE: {
|
|
35
|
+
tags: ["Billing"],
|
|
36
|
+
summary: "Delete a test or dry Bill Run",
|
|
37
|
+
description: "Hard-deletes a test or dry-run Bill Run, its outcomes and the test invoices it wrote (with lines and draft-edit audit rows). Retry runs that point at it keep existing with their parent link cleared. Real runs are never deleted.",
|
|
38
|
+
pathParams: paramsSchema,
|
|
39
|
+
responses: [{ status: 200, description: "Deleted", schema: deleteResponseSchema }],
|
|
40
|
+
errors: [
|
|
41
|
+
{ status: 404, description: "`billing.run.not_found`" },
|
|
42
|
+
{ status: 409, description: "`billing.run.running`" },
|
|
43
|
+
{ status: 422, description: "`billing.run.delete_real_forbidden`" }
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
DELETE,
|
|
50
|
+
metadata,
|
|
51
|
+
openApi
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/runs/%5Bid%5D/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/**\n * `DELETE /api/billing/runs/{id}` \u2014 delete a TEST or DRY Bill Run with its\n * test invoices and outcomes (Spec F, F-D1). Real runs are refused (422).\n */\n\nexport const metadata = {\n DELETE: { requireAuth: true, requireFeatures: ['billing.run.delete'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\nconst emptyBodySchema = z.object({}).passthrough()\n\nconst deleteResponseSchema = z.object({\n ok: z.literal(true),\n invoicesRemoved: z.number().int().nonnegative(),\n})\n\nexport async function DELETE(req: Request, { params }: { params: Promise<{ id: string }> }) {\n const parsedParams = paramsSchema.safeParse(await params)\n if (!parsedParams.success) {\n return Response.json({ error: 'Invalid Bill Run id', code: 'billing.request.invalid' }, { status: 400 })\n }\n const billRunId = parsedParams.data.id\n return runCommandRoute(\n req,\n {\n commandId: 'billing.runs.delete',\n bodySchema: emptyBodySchema,\n resourceKind: 'billing.bill_run',\n resourceId: () => billRunId,\n operation: 'delete',\n toInput: (_body, scope) => ({ ...scope, billRunId }),\n logLabel: 'billing/runs/[id].DELETE',\n },\n {},\n )\n}\n\nexport const openApi = {\n methods: {\n DELETE: {\n tags: ['Billing'],\n summary: 'Delete a test or dry Bill Run',\n description:\n 'Hard-deletes a test or dry-run Bill Run, its outcomes and the test invoices it wrote (with lines and draft-edit audit rows). ' +\n 'Retry runs that point at it keep existing with their parent link cleared. Real runs are never deleted.',\n pathParams: paramsSchema,\n responses: [{ status: 200, description: 'Deleted', schema: deleteResponseSchema }],\n errors: [\n { status: 404, description: '`billing.run.not_found`' },\n { status: 409, description: '`billing.run.running`' },\n { status: 422, description: '`billing.run.delete_real_forbidden`' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,uBAAuB;AAOzB,MAAM,WAAW;AAAA,EACtB,QAAQ,EAAE,aAAa,MAAM,iBAAiB,CAAC,oBAAoB,EAAE;AACvE;AAEA,MAAM,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACvD,MAAM,kBAAkB,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAEjD,MAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,IAAI,EAAE,QAAQ,IAAI;AAAA,EAClB,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAChD,CAAC;AAED,eAAsB,OAAO,KAAc,EAAE,OAAO,GAAwC;AAC1F,QAAM,eAAe,aAAa,UAAU,MAAM,MAAM;AACxD,MAAI,CAAC,aAAa,SAAS;AACzB,WAAO,SAAS,KAAK,EAAE,OAAO,uBAAuB,MAAM,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AACA,QAAM,YAAY,aAAa,KAAK;AACpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,WAAW;AAAA,MACX,SAAS,CAAC,OAAO,WAAW,EAAE,GAAG,OAAO,UAAU;AAAA,MAClD,UAAU;AAAA,IACZ;AAAA,IACA,CAAC;AAAA,EACH;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,QAAQ;AAAA,MACN,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aACE;AAAA,MAEF,YAAY;AAAA,MACZ,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,WAAW,QAAQ,qBAAqB,CAAC;AAAA,MACjF,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,QACtD,EAAE,QAAQ,KAAK,aAAa,wBAAwB;AAAA,QACpD,EAAE,QAAQ,KAAK,aAAa,sCAAsC;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -59,7 +59,7 @@ const openApi = createBillingCrudOpenApi({
|
|
|
59
59
|
create: {
|
|
60
60
|
schema: billingRunRetryFailedSchema,
|
|
61
61
|
responseSchema: retryResponseSchema,
|
|
62
|
-
description: "Re-runs the failed accounts of an earlier Bill Run. The new run inherits the parent run's `asOfDate` and
|
|
62
|
+
description: "Re-runs the failed accounts of an earlier Bill Run. The new run inherits the parent run's `asOfDate` (and, like every run, bills all due cycles up to it); its `parent_run_id` points back at the source. Returns 409 if there are no failed outcomes or if another run is in flight."
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/billing/api/runs/retry-failed/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { withScopedPayload } from '@open-mercato/shared/lib/api/scoped'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { BillingRun } from '../../../data/entities'\nimport { billingEntityIds } from '../../../data/entityIds'\nimport { billingRunRetryFailedSchema } from '../../../data/validators'\nimport { createBillingCrudOpenApi } from '../../openapi'\n\n/**\n * `POST /api/billing/runs/retry-failed`\n *\n * Creates a new Bill Run scoped to the failed-account ids from a parent\n * run, with `parent_run_id` set on the new run so the retry chain is\n * traceable. Returns the new run's id + status + outcomes count.\n *\n * Implemented as a \"create-only\" `makeCrudRoute` so the framework's\n * RBAC + OpenAPI + command-bus plumbing stays consistent with the rest\n * of the billing surface. The list/get half of the factory is never\n * exercised on this URL \u2014 only POST is exported.\n */\n\nconst routeMetadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.run.trigger'] },\n}\n\nexport const metadata = routeMetadata\n\nconst retryResponseSchema = z.object({\n billRunId: z.string().uuid(),\n status: z.string(),\n outcomesCount: z.number().int().nonnegative(),\n})\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: BillingRun,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n // No `list` \u2014 POST-only route. Keep a stub so the factory type-checks.\n list: {\n schema: z.object({}).passthrough(),\n entityId: billingEntityIds.run,\n fields: ['id'],\n buildFilters: async () => ({}),\n },\n actions: {\n create: {\n commandId: 'billing.runs.retry_failed',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n return billingRunRetryFailedSchema.parse(scoped)\n },\n response: ({ result }) => ({\n billRunId: result?.billRunId ?? null,\n status: result?.status ?? null,\n outcomesCount: result?.outcomesCount ?? 0,\n }),\n status: 201,\n },\n },\n})\n\nexport const POST = crud.POST\n\nexport const openApi = createBillingCrudOpenApi({\n resourceName: 'BillRunRetry',\n pluralName: 'BillRunRetries',\n querySchema: z.object({}).passthrough(),\n listResponseSchema: z.object({ items: z.array(z.unknown()) }),\n create: {\n schema: billingRunRetryFailedSchema,\n responseSchema: retryResponseSchema,\n description:\n 'Re-runs the failed accounts of an earlier Bill Run. The new run ' +\n 'inherits the parent run\\'s `asOfDate` and
|
|
5
|
-
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,SAAS,mCAAmC;AAC5C,SAAS,gCAAgC;AAezC,MAAM,gBAAgB;AAAA,EACpB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,qBAAqB,EAAE;AACtE;AAEO,MAAM,WAAW;AAExB,MAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,WAAW,EAAE,OAAO,EAAE,KAAK;AAAA,EAC3B,QAAQ,EAAE,OAAO;AAAA,EACjB,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAC9C,CAAC;AAED,MAAM,gBAAgB,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAE/C,MAAM,OAAO,cAAc;AAAA,EACzB,UAAU;AAAA,EACV,KAAK;AAAA,IACH,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA;AAAA,EAEA,MAAM;AAAA,IACJ,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAAA,IACjC,UAAU,iBAAiB;AAAA,IAC3B,QAAQ,CAAC,IAAI;AAAA,IACb,cAAc,aAAa,CAAC;AAAA,EAC9B;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,UAAU,OAAO,EAAE,KAAK,IAAI,MAAM;AAChC,cAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,cAAM,SAAS,kBAAkB,OAAO,CAAC,GAAG,KAAK,SAAS;AAC1D,eAAO,4BAA4B,MAAM,MAAM;AAAA,MACjD;AAAA,MACA,UAAU,CAAC,EAAE,OAAO,OAAO;AAAA,QACzB,WAAW,QAAQ,aAAa;AAAA,QAChC,QAAQ,QAAQ,UAAU;AAAA,QAC1B,eAAe,QAAQ,iBAAiB;AAAA,MAC1C;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AACF,CAAC;AAEM,MAAM,OAAO,KAAK;AAElB,MAAM,UAAU,yBAAyB;AAAA,EAC9C,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAAA,EACtC,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;AAAA,EAC5D,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,aACE;AAAA,
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { withScopedPayload } from '@open-mercato/shared/lib/api/scoped'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { BillingRun } from '../../../data/entities'\nimport { billingEntityIds } from '../../../data/entityIds'\nimport { billingRunRetryFailedSchema } from '../../../data/validators'\nimport { createBillingCrudOpenApi } from '../../openapi'\n\n/**\n * `POST /api/billing/runs/retry-failed`\n *\n * Creates a new Bill Run scoped to the failed-account ids from a parent\n * run, with `parent_run_id` set on the new run so the retry chain is\n * traceable. Returns the new run's id + status + outcomes count.\n *\n * Implemented as a \"create-only\" `makeCrudRoute` so the framework's\n * RBAC + OpenAPI + command-bus plumbing stays consistent with the rest\n * of the billing surface. The list/get half of the factory is never\n * exercised on this URL \u2014 only POST is exported.\n */\n\nconst routeMetadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.run.trigger'] },\n}\n\nexport const metadata = routeMetadata\n\nconst retryResponseSchema = z.object({\n billRunId: z.string().uuid(),\n status: z.string(),\n outcomesCount: z.number().int().nonnegative(),\n})\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: BillingRun,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n // No `list` \u2014 POST-only route. Keep a stub so the factory type-checks.\n list: {\n schema: z.object({}).passthrough(),\n entityId: billingEntityIds.run,\n fields: ['id'],\n buildFilters: async () => ({}),\n },\n actions: {\n create: {\n commandId: 'billing.runs.retry_failed',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n return billingRunRetryFailedSchema.parse(scoped)\n },\n response: ({ result }) => ({\n billRunId: result?.billRunId ?? null,\n status: result?.status ?? null,\n outcomesCount: result?.outcomesCount ?? 0,\n }),\n status: 201,\n },\n },\n})\n\nexport const POST = crud.POST\n\nexport const openApi = createBillingCrudOpenApi({\n resourceName: 'BillRunRetry',\n pluralName: 'BillRunRetries',\n querySchema: z.object({}).passthrough(),\n listResponseSchema: z.object({ items: z.array(z.unknown()) }),\n create: {\n schema: billingRunRetryFailedSchema,\n responseSchema: retryResponseSchema,\n description:\n 'Re-runs the failed accounts of an earlier Bill Run. The new run ' +\n 'inherits the parent run\\'s `asOfDate` (and, like every run, bills all due ' +\n 'cycles up to it); its ' +\n '`parent_run_id` points back at the source. Returns 409 if there ' +\n 'are no failed outcomes or if another run is in flight.',\n },\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,SAAS,mCAAmC;AAC5C,SAAS,gCAAgC;AAezC,MAAM,gBAAgB;AAAA,EACpB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,qBAAqB,EAAE;AACtE;AAEO,MAAM,WAAW;AAExB,MAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,WAAW,EAAE,OAAO,EAAE,KAAK;AAAA,EAC3B,QAAQ,EAAE,OAAO;AAAA,EACjB,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAC9C,CAAC;AAED,MAAM,gBAAgB,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAE/C,MAAM,OAAO,cAAc;AAAA,EACzB,UAAU;AAAA,EACV,KAAK;AAAA,IACH,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,aAAa;AAAA,IACb,iBAAiB;AAAA,EACnB;AAAA;AAAA,EAEA,MAAM;AAAA,IACJ,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAAA,IACjC,UAAU,iBAAiB;AAAA,IAC3B,QAAQ,CAAC,IAAI;AAAA,IACb,cAAc,aAAa,CAAC;AAAA,EAC9B;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,UAAU,OAAO,EAAE,KAAK,IAAI,MAAM;AAChC,cAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,cAAM,SAAS,kBAAkB,OAAO,CAAC,GAAG,KAAK,SAAS;AAC1D,eAAO,4BAA4B,MAAM,MAAM;AAAA,MACjD;AAAA,MACA,UAAU,CAAC,EAAE,OAAO,OAAO;AAAA,QACzB,WAAW,QAAQ,aAAa;AAAA,QAChC,QAAQ,QAAQ,UAAU;AAAA,QAC1B,eAAe,QAAQ,iBAAiB;AAAA,MAC1C;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AACF,CAAC;AAEM,MAAM,OAAO,KAAK;AAElB,MAAM,UAAU,yBAAyB;AAAA,EAC9C,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAAA,EACtC,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;AAAA,EAC5D,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,aACE;AAAA,EAKJ;AACF,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -20,7 +20,6 @@ const billRunListItemSchema = z.object({
|
|
|
20
20
|
parent_run_id: z.string().uuid().nullable(),
|
|
21
21
|
dry_run: z.boolean(),
|
|
22
22
|
test_mode: z.boolean(),
|
|
23
|
-
catch_up: z.boolean(),
|
|
24
23
|
scoped_account_ids: z.array(z.string().uuid()).nullable(),
|
|
25
24
|
as_of_date: z.string(),
|
|
26
25
|
started_at: z.string().nullable(),
|
|
@@ -56,7 +55,6 @@ const crud = makeCrudRoute({
|
|
|
56
55
|
"parent_run_id",
|
|
57
56
|
"dry_run",
|
|
58
57
|
"test_mode",
|
|
59
|
-
"catch_up",
|
|
60
58
|
"scoped_account_ids",
|
|
61
59
|
"as_of_date",
|
|
62
60
|
"started_at",
|
|
@@ -85,6 +83,14 @@ const crud = makeCrudRoute({
|
|
|
85
83
|
if (typeof query.status === "string") filters.status = { $eq: query.status };
|
|
86
84
|
if (typeof query.triggeredBy === "string") filters.triggered_by = { $eq: query.triggeredBy };
|
|
87
85
|
if (typeof query.parentRunId === "string") filters.parent_run_id = { $eq: query.parentRunId };
|
|
86
|
+
if (query.mode === "real") {
|
|
87
|
+
filters.dry_run = { $eq: false };
|
|
88
|
+
filters.test_mode = { $eq: false };
|
|
89
|
+
} else if (query.mode === "test") {
|
|
90
|
+
filters.test_mode = { $eq: true };
|
|
91
|
+
} else if (query.mode === "dry") {
|
|
92
|
+
filters.dry_run = { $eq: true };
|
|
93
|
+
}
|
|
88
94
|
if (query.asOfDateFrom instanceof Date) {
|
|
89
95
|
filters.as_of_date = Object.assign(
|
|
90
96
|
filters.as_of_date ?? {},
|
|
@@ -131,7 +137,7 @@ const openApi = createBillingCrudOpenApi({
|
|
|
131
137
|
create: {
|
|
132
138
|
schema: billingRunTriggerSchema,
|
|
133
139
|
responseSchema: triggerResponseSchema,
|
|
134
|
-
description: "Triggers a Bill Run. `mode=real` (default) persists drafts and advances state; `mode=test` persists test-flagged drafts without advancing state; `mode=dry`
|
|
140
|
+
description: "Triggers a Bill Run. Every run bills **all due cycles** up to `asOfDate` \u2014 one draft invoice per bill date (no catch-up flag; a legacy `catchUp` field is ignored). `mode=real` (default) persists drafts and advances state; `mode=test` persists test-flagged drafts for every cycle without advancing state; `mode=dry` simulates every cycle in memory and persists nothing. Per-cycle results are on each outcome's `cycles`. Returns HTTP 409 (`billing.run.lock_busy`) when another run is in flight for the same tenant."
|
|
135
141
|
}
|
|
136
142
|
});
|
|
137
143
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/billing/api/runs/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { withScopedPayload } from '@open-mercato/shared/lib/api/scoped'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { BillingRun } from '../../data/entities'\nimport { billingEntityIds } from '../../data/entityIds'\nimport {\n billingRunListQuerySchema,\n billingRunTriggerSchema,\n} from '../../data/validators'\nimport { createBillingCrudOpenApi, createPagedListResponseSchema } from '../openapi'\n\n/**\n * `/api/billing/runs` \u2014 GET (history list) + POST (manual trigger).\n *\n * The triggered-by enum gate:\n * - `trigger` feature is required for `real` mode (which mutates\n * production state).\n * - `dry_run` feature alone is enough for `mode=dry` (finance auditor\n * persona). The route-level RBAC check on POST requires `trigger`,\n * so dry-run callers must hold both `dry_run` AND `trigger` here \u2014\n * a deliberate tightening over what the spec persona table suggests.\n *\n * If we ever want auditors to drive dry-runs without holding `trigger`,\n * we split into two routes (POST `/runs` for real, POST `/runs/dry` for\n * dry). Postponed until an operator actually asks.\n */\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.run.view'] },\n POST: { requireAuth: true, requireFeatures: ['billing.run.trigger'] },\n}\n\nexport const metadata = routeMetadata\n\n// The list endpoint projects raw column names \u2014 snake_case.\nconst billRunListItemSchema = z.object({\n id: z.string().uuid(),\n triggered_by: z.string(),\n parent_run_id: z.string().uuid().nullable(),\n dry_run: z.boolean(),\n test_mode: z.boolean(),\n
|
|
5
|
-
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B,qCAAqC;AAkBxE,MAAM,gBAAgB;AAAA,EACpB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,kBAAkB,EAAE;AAAA,EAChE,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,qBAAqB,EAAE;AACtE;AAEO,MAAM,WAAW;AAGxB,MAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,cAAc,EAAE,OAAO;AAAA,EACvB,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC1C,SAAS,EAAE,QAAQ;AAAA,EACnB,WAAW,EAAE,QAAQ;AAAA,EACrB,
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { withScopedPayload } from '@open-mercato/shared/lib/api/scoped'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { BillingRun } from '../../data/entities'\nimport { billingEntityIds } from '../../data/entityIds'\nimport {\n billingRunListQuerySchema,\n billingRunTriggerSchema,\n} from '../../data/validators'\nimport { createBillingCrudOpenApi, createPagedListResponseSchema } from '../openapi'\n\n/**\n * `/api/billing/runs` \u2014 GET (history list) + POST (manual trigger).\n *\n * The triggered-by enum gate:\n * - `trigger` feature is required for `real` mode (which mutates\n * production state).\n * - `dry_run` feature alone is enough for `mode=dry` (finance auditor\n * persona). The route-level RBAC check on POST requires `trigger`,\n * so dry-run callers must hold both `dry_run` AND `trigger` here \u2014\n * a deliberate tightening over what the spec persona table suggests.\n *\n * If we ever want auditors to drive dry-runs without holding `trigger`,\n * we split into two routes (POST `/runs` for real, POST `/runs/dry` for\n * dry). Postponed until an operator actually asks.\n */\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.run.view'] },\n POST: { requireAuth: true, requireFeatures: ['billing.run.trigger'] },\n}\n\nexport const metadata = routeMetadata\n\n// The list endpoint projects raw column names \u2014 snake_case.\nconst billRunListItemSchema = z.object({\n id: z.string().uuid(),\n triggered_by: z.string(),\n parent_run_id: z.string().uuid().nullable(),\n dry_run: z.boolean(),\n test_mode: z.boolean(),\n scoped_account_ids: z.array(z.string().uuid()).nullable(),\n as_of_date: z.string(),\n started_at: z.string().nullable(),\n finished_at: z.string().nullable(),\n status: z.string(),\n summary: z.record(z.string(), z.unknown()).nullable(),\n organization_id: z.string().uuid(),\n tenant_id: z.string().uuid(),\n created_at: z.string(),\n updated_at: z.string(),\n})\n\nconst triggerResponseSchema = z.object({\n billRunId: z.string().uuid(),\n status: z.string(),\n outcomesCount: z.number().int().nonnegative(),\n})\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: BillingRun,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n list: {\n schema: billingRunListQuerySchema,\n entityId: billingEntityIds.run,\n fields: [\n 'id',\n 'triggered_by',\n 'parent_run_id',\n 'dry_run',\n 'test_mode',\n 'scoped_account_ids',\n 'as_of_date',\n 'started_at',\n 'finished_at',\n 'status',\n 'summary',\n 'organization_id',\n 'tenant_id',\n 'created_at',\n 'updated_at',\n ],\n sortFieldMap: {\n startedAt: 'started_at',\n finishedAt: 'finished_at',\n asOfDate: 'as_of_date',\n createdAt: 'created_at',\n },\n buildFilters: async (query) => {\n const filters: Record<string, unknown> = {}\n // `?id=<uuid>` narrows the list to one row \u2014 the detail page\n // reads a single Bill Run through this filter.\n if (typeof query.id === 'string' && query.id) {\n filters.id = { $eq: query.id }\n }\n // Run ids are UUIDs \u2014 search matches a pasted id exactly.\n if (typeof query.search === 'string' && /^[0-9a-fA-F-]{36}$/.test(query.search.trim())) {\n filters.id = { $eq: query.search.trim() }\n }\n if (typeof query.status === 'string') filters.status = { $eq: query.status }\n if (typeof query.triggeredBy === 'string') filters.triggered_by = { $eq: query.triggeredBy }\n if (typeof query.parentRunId === 'string') filters.parent_run_id = { $eq: query.parentRunId }\n if (query.mode === 'real') {\n filters.dry_run = { $eq: false }\n filters.test_mode = { $eq: false }\n } else if (query.mode === 'test') {\n filters.test_mode = { $eq: true }\n } else if (query.mode === 'dry') {\n filters.dry_run = { $eq: true }\n }\n if (query.asOfDateFrom instanceof Date) {\n filters.as_of_date = Object.assign(\n (filters.as_of_date as Record<string, unknown>) ?? {},\n { $gte: query.asOfDateFrom },\n )\n }\n if (query.asOfDateTo instanceof Date) {\n filters.as_of_date = Object.assign(\n (filters.as_of_date as Record<string, unknown>) ?? {},\n { $lte: query.asOfDateTo },\n )\n }\n return filters\n },\n },\n actions: {\n create: {\n commandId: 'billing.runs.trigger',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n return billingRunTriggerSchema.parse(scoped)\n },\n response: ({ result }) => ({\n billRunId: result?.billRunId ?? null,\n status: result?.status ?? null,\n outcomesCount: result?.outcomesCount ?? 0,\n }),\n status: 201,\n },\n // Runs are append-only \u2014 no update / delete on this surface. A\n // failed run is corrected by triggering a `retry-failed` (separate\n // route).\n },\n})\n\nconst { POST } = crud\nexport { POST }\nexport const GET = crud.GET\n\nexport const openApi = createBillingCrudOpenApi({\n resourceName: 'BillRun',\n pluralName: 'BillRuns',\n querySchema: billingRunListQuerySchema,\n listResponseSchema: createPagedListResponseSchema(billRunListItemSchema),\n create: {\n schema: billingRunTriggerSchema,\n responseSchema: triggerResponseSchema,\n description:\n 'Triggers a Bill Run. Every run bills **all due cycles** up to `asOfDate` \u2014 one ' +\n 'draft invoice per bill date (no catch-up flag; a legacy `catchUp` field is ignored). ' +\n '`mode=real` (default) persists drafts and advances state; `mode=test` persists ' +\n 'test-flagged drafts for every cycle without advancing state; `mode=dry` simulates ' +\n 'every cycle in memory and persists nothing. Per-cycle results are on each outcome\\'s ' +\n '`cycles`. Returns HTTP 409 (`billing.run.lock_busy`) when another run is in flight ' +\n 'for the same tenant.',\n },\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
4
|
+
import { DOCUMENT_SERIES, renderNumber, sequenceScopeKey, validateMask } from "../../../lib/numbering.js";
|
|
5
|
+
const metadata = {
|
|
6
|
+
GET: { requireAuth: true, requireFeatures: ["billing.settings.view"] }
|
|
7
|
+
};
|
|
8
|
+
const querySchema = z.object({ mask: z.string().max(200), series: z.enum(DOCUMENT_SERIES).optional() });
|
|
9
|
+
async function GET(req) {
|
|
10
|
+
const auth = await getAuthFromRequest(req);
|
|
11
|
+
if (!auth || !auth.tenantId) {
|
|
12
|
+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
13
|
+
}
|
|
14
|
+
const parsed = querySchema.safeParse(Object.fromEntries(new URL(req.url).searchParams.entries()));
|
|
15
|
+
if (!parsed.success) {
|
|
16
|
+
return NextResponse.json({ error: "Invalid query" }, { status: 400 });
|
|
17
|
+
}
|
|
18
|
+
const errors = validateMask(parsed.data.mask);
|
|
19
|
+
if (errors.length > 0) return NextResponse.json({ valid: false, errors });
|
|
20
|
+
const today = /* @__PURE__ */ new Date();
|
|
21
|
+
return NextResponse.json({
|
|
22
|
+
valid: true,
|
|
23
|
+
errors: [],
|
|
24
|
+
example: renderNumber(parsed.data.mask, { seq: 1, issueDate: today }),
|
|
25
|
+
scopeKey: sequenceScopeKey(parsed.data.mask, today)
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const openApi = {
|
|
29
|
+
methods: {
|
|
30
|
+
GET: {
|
|
31
|
+
tags: ["Billing"],
|
|
32
|
+
summary: "Preview a document number mask",
|
|
33
|
+
description: "Validates a number mask and returns an example number for today and its counter scope."
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
GET,
|
|
39
|
+
metadata,
|
|
40
|
+
openApi
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/settings/number-preview/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { DOCUMENT_SERIES, renderNumber, sequenceScopeKey, validateMask } from '../../../lib/numbering'\n\n/**\n * `GET /api/billing/settings/number-preview?mask=\u2026` \u2014 validates a number\n * mask and renders an example for today (sequence 1) plus the counter scope\n * it would use. Pure: no sequence is read or claimed.\n */\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.settings.view'] },\n}\n\nconst querySchema = z.object({ mask: z.string().max(200), series: z.enum(DOCUMENT_SERIES).optional() })\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.tenantId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const parsed = querySchema.safeParse(Object.fromEntries(new URL(req.url).searchParams.entries()))\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query' }, { status: 400 })\n }\n const errors = validateMask(parsed.data.mask)\n if (errors.length > 0) return NextResponse.json({ valid: false, errors })\n const today = new Date()\n return NextResponse.json({\n valid: true,\n errors: [],\n example: renderNumber(parsed.data.mask, { seq: 1, issueDate: today }),\n scopeKey: sequenceScopeKey(parsed.data.mask, today),\n })\n}\n\nexport const openApi = {\n methods: {\n GET: {\n tags: ['Billing'],\n summary: 'Preview a document number mask',\n description: 'Validates a number mask and returns an example number for today and its counter scope.',\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAClB,SAAS,0BAA0B;AACnC,SAAS,iBAAiB,cAAc,kBAAkB,oBAAoB;AAQvE,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,uBAAuB,EAAE;AACvE;AAEA,MAAM,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQ,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,CAAC;AAEtG,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,QAAQ,CAAC,KAAK,UAAU;AAC3B,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,SAAS,YAAY,UAAU,OAAO,YAAY,IAAI,IAAI,IAAI,GAAG,EAAE,aAAa,QAAQ,CAAC,CAAC;AAChG,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,gBAAgB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACtE;AACA,QAAM,SAAS,aAAa,OAAO,KAAK,IAAI;AAC5C,MAAI,OAAO,SAAS,EAAG,QAAO,aAAa,KAAK,EAAE,OAAO,OAAO,OAAO,CAAC;AACxE,QAAM,QAAQ,oBAAI,KAAK;AACvB,SAAO,aAAa,KAAK;AAAA,IACvB,OAAO;AAAA,IACP,QAAQ,CAAC;AAAA,IACT,SAAS,aAAa,OAAO,KAAK,MAAM,EAAE,KAAK,GAAG,WAAW,MAAM,CAAC;AAAA,IACpE,UAAU,iBAAiB,OAAO,KAAK,MAAM,KAAK;AAAA,EACpD,CAAC;AACH;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,KAAK;AAAA,MACH,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|