@dainamite/billing 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +90 -0
- package/dist/modules/billing/acl.js +13 -1
- package/dist/modules/billing/acl.js.map +2 -2
- package/dist/modules/billing/api/accounts/[id]/summary/route.js +52 -0
- package/dist/modules/billing/api/accounts/[id]/summary/route.js.map +7 -0
- package/dist/modules/billing/api/accounts/route.js +46 -4
- package/dist/modules/billing/api/accounts/route.js.map +2 -2
- package/dist/modules/billing/api/export/account/[id]/route.js +11 -7
- package/dist/modules/billing/api/export/account/[id]/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/[id]/memos/route.js +54 -0
- package/dist/modules/billing/api/invoices/[id]/memos/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/[id]/pdf/route.js +69 -0
- package/dist/modules/billing/api/invoices/[id]/pdf/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/[id]/route.js +44 -24
- package/dist/modules/billing/api/invoices/[id]/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/[id]/send/route.js +107 -0
- package/dist/modules/billing/api/invoices/[id]/send/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/add-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/add-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/delete-draft/route.js +33 -0
- package/dist/modules/billing/api/invoices/delete-draft/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/edit-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/edit-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/post/route.js +2 -2
- package/dist/modules/billing/api/invoices/post/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/remove-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/remove-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/route.js +45 -46
- package/dist/modules/billing/api/invoices/route.js.map +2 -2
- package/dist/modules/billing/api/items/bulk/route.js +1 -1
- package/dist/modules/billing/api/items/bulk/route.js.map +2 -2
- package/dist/modules/billing/api/items/change-price/route.js +44 -0
- package/dist/modules/billing/api/items/change-price/route.js.map +7 -0
- package/dist/modules/billing/api/items/route.js +19 -7
- package/dist/modules/billing/api/items/route.js.map +2 -2
- package/dist/modules/billing/api/payment-imports/[id]/route.js +49 -0
- package/dist/modules/billing/api/payment-imports/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/payment-imports/route.js +57 -0
- package/dist/modules/billing/api/payment-imports/route.js.map +7 -0
- package/dist/modules/billing/api/payments/[id]/route.js +60 -0
- package/dist/modules/billing/api/payments/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/payments/allocate/route.js +35 -0
- package/dist/modules/billing/api/payments/allocate/route.js.map +7 -0
- package/dist/modules/billing/api/payments/assign/route.js +36 -0
- package/dist/modules/billing/api/payments/assign/route.js.map +7 -0
- package/dist/modules/billing/api/payments/convert-to-topup/route.js +35 -0
- package/dist/modules/billing/api/payments/convert-to-topup/route.js.map +7 -0
- package/dist/modules/billing/api/payments/ignore/route.js +35 -0
- package/dist/modules/billing/api/payments/ignore/route.js.map +7 -0
- package/dist/modules/billing/api/payments/import/route.js +63 -0
- package/dist/modules/billing/api/payments/import/route.js.map +7 -0
- package/dist/modules/billing/api/payments/restore/route.js +35 -0
- package/dist/modules/billing/api/payments/restore/route.js.map +7 -0
- package/dist/modules/billing/api/payments/route.js +114 -0
- package/dist/modules/billing/api/payments/route.js.map +7 -0
- package/dist/modules/billing/api/payments/unallocate/route.js +35 -0
- package/dist/modules/billing/api/payments/unallocate/route.js.map +7 -0
- package/dist/modules/billing/api/payments/unassign/route.js +35 -0
- package/dist/modules/billing/api/payments/unassign/route.js.map +7 -0
- package/dist/modules/billing/api/run-outcomes/route.js +43 -6
- package/dist/modules/billing/api/run-outcomes/route.js.map +2 -2
- package/dist/modules/billing/api/runs/[id]/post-drafts/route.js +61 -0
- package/dist/modules/billing/api/runs/[id]/post-drafts/route.js.map +7 -0
- package/dist/modules/billing/api/runs/[id]/route.js +53 -0
- package/dist/modules/billing/api/runs/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/runs/retry-failed/route.js +1 -1
- package/dist/modules/billing/api/runs/retry-failed/route.js.map +2 -2
- package/dist/modules/billing/api/runs/route.js +9 -3
- package/dist/modules/billing/api/runs/route.js.map +2 -2
- package/dist/modules/billing/api/settings/number-preview/route.js +42 -0
- package/dist/modules/billing/api/settings/number-preview/route.js.map +7 -0
- package/dist/modules/billing/api/settings/route.js +92 -0
- package/dist/modules/billing/api/settings/route.js.map +7 -0
- package/dist/modules/billing/api/statements/route.js +3 -0
- package/dist/modules/billing/api/statements/route.js.map +2 -2
- package/dist/modules/billing/api/test-invoices/wipe/route.js +2 -2
- package/dist/modules/billing/api/test-invoices/wipe/route.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/[id]/page.js +121 -232
- package/dist/modules/billing/backend/billing/accounts/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/create/page.js +6 -0
- package/dist/modules/billing/backend/billing/accounts/create/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/page.js +63 -4
- package/dist/modules/billing/backend/billing/accounts/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/invoices/[id]/page.js +297 -65
- package/dist/modules/billing/backend/billing/invoices/[id]/page.js.map +3 -3
- package/dist/modules/billing/backend/billing/invoices/page.js +6 -172
- package/dist/modules/billing/backend/billing/invoices/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/[id]/page.js +51 -7
- package/dist/modules/billing/backend/billing/items/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/create/page.js +9 -6
- package/dist/modules/billing/backend/billing/items/create/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/page.js +8 -2
- package/dist/modules/billing/backend/billing/items/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/payments/[id]/page.js +297 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js +21 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js +74 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js +21 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/page.js +58 -0
- package/dist/modules/billing/backend/billing/payments/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/page.meta.js +18 -0
- package/dist/modules/billing/backend/billing/payments/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/runs/[id]/page.js +49 -14
- package/dist/modules/billing/backend/billing/runs/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/runs/page.js +58 -7
- package/dist/modules/billing/backend/billing/runs/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/statements/[id]/page.js +61 -6
- package/dist/modules/billing/backend/billing/statements/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/statements/page.js +1 -1
- package/dist/modules/billing/backend/billing/statements/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/topups/page.js +1 -1
- package/dist/modules/billing/backend/billing/topups/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/transactions/page.js +1 -1
- package/dist/modules/billing/backend/billing/transactions/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/usage/create/page.js +3 -2
- package/dist/modules/billing/backend/billing/usage/create/page.js.map +2 -2
- package/dist/modules/billing/backend/config/billing/page.js +472 -0
- package/dist/modules/billing/backend/config/billing/page.js.map +7 -0
- package/dist/modules/billing/backend/config/billing/page.meta.js +19 -0
- package/dist/modules/billing/backend/config/billing/page.meta.js.map +7 -0
- package/dist/modules/billing/cli.js +22 -1
- package/dist/modules/billing/cli.js.map +2 -2
- package/dist/modules/billing/commands/accounts.js +6 -0
- package/dist/modules/billing/commands/accounts.js.map +2 -2
- package/dist/modules/billing/commands/index.js +3 -0
- package/dist/modules/billing/commands/index.js.map +2 -2
- package/dist/modules/billing/commands/invoices.js +269 -167
- package/dist/modules/billing/commands/invoices.js.map +2 -2
- package/dist/modules/billing/commands/items.js +108 -0
- package/dist/modules/billing/commands/items.js.map +2 -2
- package/dist/modules/billing/commands/memos.js +179 -0
- package/dist/modules/billing/commands/memos.js.map +7 -0
- package/dist/modules/billing/commands/payments.js +379 -0
- package/dist/modules/billing/commands/payments.js.map +7 -0
- package/dist/modules/billing/commands/runs.js +151 -4
- package/dist/modules/billing/commands/runs.js.map +2 -2
- package/dist/modules/billing/commands/settings.js +59 -0
- package/dist/modules/billing/commands/settings.js.map +7 -0
- package/dist/modules/billing/commands/topups.js +9 -2
- package/dist/modules/billing/commands/topups.js.map +2 -2
- package/dist/modules/billing/commands/transactions.js +2 -2
- package/dist/modules/billing/commands/transactions.js.map +2 -2
- package/dist/modules/billing/components/AccountForm.js +149 -42
- package/dist/modules/billing/components/AccountForm.js.map +2 -2
- package/dist/modules/billing/components/AccountInvoicesSection.js +64 -0
- package/dist/modules/billing/components/AccountInvoicesSection.js.map +7 -0
- package/dist/modules/billing/components/AccountPaymentsSection.js +43 -0
- package/dist/modules/billing/components/AccountPaymentsSection.js.map +7 -0
- package/dist/modules/billing/components/AccountPicker.js +56 -0
- package/dist/modules/billing/components/AccountPicker.js.map +7 -0
- package/dist/modules/billing/components/AllocatePaymentDialog.js +134 -0
- package/dist/modules/billing/components/AllocatePaymentDialog.js.map +7 -0
- package/dist/modules/billing/components/BillingDataTable.js +21 -0
- package/dist/modules/billing/components/BillingDataTable.js.map +7 -0
- package/dist/modules/billing/components/BillingSettingsLink.js +19 -0
- package/dist/modules/billing/components/BillingSettingsLink.js.map +7 -0
- package/dist/modules/billing/components/ChangeItemPriceDialog.js +158 -0
- package/dist/modules/billing/components/ChangeItemPriceDialog.js.map +7 -0
- package/dist/modules/billing/components/CreateMemoDialog.js +200 -0
- package/dist/modules/billing/components/CreateMemoDialog.js.map +7 -0
- package/dist/modules/billing/components/CustomerLabel.js +33 -0
- package/dist/modules/billing/components/CustomerLabel.js.map +7 -0
- package/dist/modules/billing/components/InvoicesTable.js +270 -0
- package/dist/modules/billing/components/InvoicesTable.js.map +7 -0
- package/dist/modules/billing/components/ItemForm.js +176 -44
- package/dist/modules/billing/components/ItemForm.js.map +2 -2
- package/dist/modules/billing/components/ItemPriceField.js +46 -0
- package/dist/modules/billing/components/ItemPriceField.js.map +7 -0
- package/dist/modules/billing/components/LineFormDialog.js +25 -2
- package/dist/modules/billing/components/LineFormDialog.js.map +2 -2
- package/dist/modules/billing/components/ManualPaymentDialog.js +122 -0
- package/dist/modules/billing/components/ManualPaymentDialog.js.map +7 -0
- package/dist/modules/billing/components/MoneyInput.js +14 -0
- package/dist/modules/billing/components/MoneyInput.js.map +7 -0
- package/dist/modules/billing/components/PaymentUploadDialog.js +115 -0
- package/dist/modules/billing/components/PaymentUploadDialog.js.map +7 -0
- package/dist/modules/billing/components/PaymentsTable.js +171 -0
- package/dist/modules/billing/components/PaymentsTable.js.map +7 -0
- package/dist/modules/billing/components/PostRunDraftsButton.js +105 -0
- package/dist/modules/billing/components/PostRunDraftsButton.js.map +7 -0
- package/dist/modules/billing/components/PrepaidPanel.js +14 -4
- package/dist/modules/billing/components/PrepaidPanel.js.map +2 -2
- package/dist/modules/billing/components/RunCyclesSection.js +209 -0
- package/dist/modules/billing/components/RunCyclesSection.js.map +7 -0
- package/dist/modules/billing/components/TestRunActions.js +127 -0
- package/dist/modules/billing/components/TestRunActions.js.map +7 -0
- package/dist/modules/billing/components/account/AccountItemsTab.js +157 -0
- package/dist/modules/billing/components/account/AccountItemsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountRunBillingDialog.js +122 -0
- package/dist/modules/billing/components/account/AccountRunBillingDialog.js.map +7 -0
- package/dist/modules/billing/components/account/AccountRunsTab.js +152 -0
- package/dist/modules/billing/components/account/AccountRunsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountStatementsTab.js +98 -0
- package/dist/modules/billing/components/account/AccountStatementsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountSummaryCards.js +125 -0
- package/dist/modules/billing/components/account/AccountSummaryCards.js.map +7 -0
- package/dist/modules/billing/components/account/AccountUsageTab.js +91 -0
- package/dist/modules/billing/components/account/AccountUsageTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountView.js +73 -0
- package/dist/modules/billing/components/account/AccountView.js.map +7 -0
- package/dist/modules/billing/components/account/accountRow.js +39 -0
- package/dist/modules/billing/components/account/accountRow.js.map +7 -0
- package/dist/modules/billing/components/customerNames.js +42 -0
- package/dist/modules/billing/components/customerNames.js.map +7 -0
- package/dist/modules/billing/data/entities.js +560 -4
- package/dist/modules/billing/data/entities.js.map +2 -2
- package/dist/modules/billing/data/entityIds.js +10 -1
- package/dist/modules/billing/data/entityIds.js.map +2 -2
- package/dist/modules/billing/data/validators.js +269 -15
- package/dist/modules/billing/data/validators.js.map +2 -2
- package/dist/modules/billing/events.js +50 -0
- package/dist/modules/billing/events.js.map +2 -2
- package/dist/modules/billing/i18n/en.json +457 -21
- package/dist/modules/billing/i18n/pl.json +457 -21
- package/dist/modules/billing/index.js +6 -2
- package/dist/modules/billing/index.js.map +2 -2
- package/dist/modules/billing/lib/accountFinancials.js +58 -0
- package/dist/modules/billing/lib/accountFinancials.js.map +7 -0
- package/dist/modules/billing/lib/accountLock.js +14 -0
- package/dist/modules/billing/lib/accountLock.js.map +7 -0
- package/dist/modules/billing/lib/accountStatus.js +9 -7
- package/dist/modules/billing/lib/accountStatus.js.map +2 -2
- package/dist/modules/billing/lib/accountSummary.js +106 -0
- package/dist/modules/billing/lib/accountSummary.js.map +7 -0
- package/dist/modules/billing/lib/allocation.js +356 -0
- package/dist/modules/billing/lib/allocation.js.map +7 -0
- package/dist/modules/billing/lib/allocationEvents.js +22 -0
- package/dist/modules/billing/lib/allocationEvents.js.map +7 -0
- package/dist/modules/billing/lib/billPeriod.js +15 -1
- package/dist/modules/billing/lib/billPeriod.js.map +2 -2
- package/dist/modules/billing/lib/billRunEngine.js +237 -102
- package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
- package/dist/modules/billing/lib/billingSettings.js +116 -0
- package/dist/modules/billing/lib/billingSettings.js.map +7 -0
- package/dist/modules/billing/lib/commandRoute.js +81 -0
- package/dist/modules/billing/lib/commandRoute.js.map +7 -0
- package/dist/modules/billing/lib/customerLookup.js +97 -0
- package/dist/modules/billing/lib/customerLookup.js.map +7 -0
- package/dist/modules/billing/lib/dateOnly.js +13 -0
- package/dist/modules/billing/lib/dateOnly.js.map +7 -0
- package/dist/modules/billing/lib/documentParties.js +16 -0
- package/dist/modules/billing/lib/documentParties.js.map +7 -0
- package/dist/modules/billing/lib/documentTypes.js +27 -0
- package/dist/modules/billing/lib/documentTypes.js.map +7 -0
- package/dist/modules/billing/lib/dueDate.js +18 -0
- package/dist/modules/billing/lib/dueDate.js.map +7 -0
- package/dist/modules/billing/lib/iban.js +29 -0
- package/dist/modules/billing/lib/iban.js.map +7 -0
- package/dist/modules/billing/lib/invoiceDelivery.js +131 -0
- package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
- package/dist/modules/billing/lib/invoiceLanguages.js +16 -0
- package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
- package/dist/modules/billing/lib/invoiceWriter.js +107 -99
- package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
- package/dist/modules/billing/lib/itemBillingState.js +27 -0
- package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
- package/dist/modules/billing/lib/itemPriceChange.js +18 -0
- package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
- package/dist/modules/billing/lib/itemSelector.js.map +2 -2
- package/dist/modules/billing/lib/lineAmounts.js +32 -0
- package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
- package/dist/modules/billing/lib/memoGuards.js +25 -0
- package/dist/modules/billing/lib/memoGuards.js.map +7 -0
- package/dist/modules/billing/lib/navigation.js +48 -0
- package/dist/modules/billing/lib/navigation.js.map +7 -0
- package/dist/modules/billing/lib/numbering.js +120 -0
- package/dist/modules/billing/lib/numbering.js.map +7 -0
- package/dist/modules/billing/lib/overdue.js +36 -0
- package/dist/modules/billing/lib/overdue.js.map +7 -0
- package/dist/modules/billing/lib/paymentCsv.js +125 -0
- package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
- package/dist/modules/billing/lib/paymentGateway.js +15 -0
- package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
- package/dist/modules/billing/lib/paymentImport.js +164 -0
- package/dist/modules/billing/lib/paymentImport.js.map +7 -0
- package/dist/modules/billing/lib/paymentMatcher.js +36 -0
- package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
- package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
- package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
- package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
- package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
- package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
- package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoiceTemplate.js +274 -0
- package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
- package/dist/modules/billing/lib/prepaidConfig.js +17 -25
- package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
- package/dist/modules/billing/lib/prepaidConsume.js +26 -7
- package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
- package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
- package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
- package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
- package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
- package/dist/modules/billing/lib/seeds/demo.js +51 -3
- package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
- package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
- package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
- package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
- package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
- package/dist/modules/billing/lib/servicePeriods.js +121 -0
- package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
- package/dist/modules/billing/lib/testRunCleanup.js +24 -0
- package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
- package/dist/modules/billing/lib/topupCapture.js +2 -2
- package/dist/modules/billing/lib/topupCapture.js.map +2 -2
- package/dist/modules/billing/lib/topupReceipt.js +58 -79
- package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
- package/dist/modules/billing/lib/usageRater.js.map +1 -1
- package/dist/modules/billing/lib/usageRunner.js +14 -6
- package/dist/modules/billing/lib/usageRunner.js.map +2 -2
- package/dist/modules/billing/lib/vat.js +39 -0
- package/dist/modules/billing/lib/vat.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
- package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
- package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
- package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
- package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
- package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
- package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
- package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
- package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
- package/dist/modules/billing/setup.js +7 -184
- package/dist/modules/billing/setup.js.map +2 -2
- package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
- package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
- package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
- package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
- package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
- package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
- package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
- package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
- package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
- package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
- package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
- package/generated/entities/billing_account/index.ts +3 -0
- package/generated/entities/billing_allocation/index.ts +18 -0
- package/generated/entities/billing_document_sequence/index.ts +11 -0
- package/generated/entities/billing_invoice/index.ts +38 -0
- package/generated/entities/billing_invoice_line/index.ts +24 -0
- package/generated/entities/billing_item/index.ts +4 -0
- package/generated/entities/billing_payment/index.ts +25 -0
- package/generated/entities/billing_payment_import/index.ts +14 -0
- package/generated/entities/billing_run/index.ts +0 -1
- package/generated/entities/billing_run_outcome/index.ts +1 -0
- package/generated/entities/billing_settings/index.ts +26 -0
- package/generated/entities/billing_statement/index.ts +1 -0
- package/generated/entities.ids.generated.ts +7 -0
- package/package.json +5 -1
- package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +170 -0
- package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
- package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
- package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
- package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
- package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
- package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
- package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
- package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
- package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
- package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
- package/src/modules/billing/__tests__/commands/invoices.test.ts +436 -354
- package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
- package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
- package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
- package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
- package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
- package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
- package/src/modules/billing/__tests__/entityRegistry.test.ts +8 -1
- package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
- package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
- package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
- package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
- package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +228 -17
- package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
- package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
- package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
- package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
- package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +189 -0
- package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
- package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
- package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
- package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
- package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
- package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
- package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
- package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
- package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
- package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
- package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +199 -0
- package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
- package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
- package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
- package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
- package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
- package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
- package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
- package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
- package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
- package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
- package/src/modules/billing/__tests__/setup.test.ts +13 -4
- package/src/modules/billing/__tests__/validators.test.ts +193 -3
- package/src/modules/billing/acl.ts +12 -0
- package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
- package/src/modules/billing/api/accounts/route.ts +58 -4
- package/src/modules/billing/api/export/account/[id]/route.ts +13 -11
- package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
- package/src/modules/billing/api/invoices/[id]/pdf/route.ts +79 -0
- package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
- package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
- package/src/modules/billing/api/invoices/add-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
- package/src/modules/billing/api/invoices/edit-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/post/route.ts +7 -6
- package/src/modules/billing/api/invoices/remove-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/route.ts +81 -86
- package/src/modules/billing/api/items/bulk/route.ts +2 -1
- package/src/modules/billing/api/items/change-price/route.ts +54 -0
- package/src/modules/billing/api/items/route.ts +23 -7
- package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
- package/src/modules/billing/api/payment-imports/route.ts +57 -0
- package/src/modules/billing/api/payments/[id]/route.ts +63 -0
- package/src/modules/billing/api/payments/allocate/route.ts +35 -0
- package/src/modules/billing/api/payments/assign/route.ts +36 -0
- package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
- package/src/modules/billing/api/payments/ignore/route.ts +35 -0
- package/src/modules/billing/api/payments/import/route.ts +72 -0
- package/src/modules/billing/api/payments/restore/route.ts +35 -0
- package/src/modules/billing/api/payments/route.ts +147 -0
- package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
- package/src/modules/billing/api/payments/unassign/route.ts +35 -0
- package/src/modules/billing/api/run-outcomes/route.ts +49 -6
- package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
- package/src/modules/billing/api/runs/[id]/route.ts +59 -0
- package/src/modules/billing/api/runs/retry-failed/route.ts +2 -1
- package/src/modules/billing/api/runs/route.ts +15 -7
- package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
- package/src/modules/billing/api/settings/route.ts +116 -0
- package/src/modules/billing/api/statements/route.ts +5 -0
- package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
- package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
- package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
- package/src/modules/billing/backend/billing/accounts/page.tsx +70 -4
- package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +444 -95
- package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
- package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
- package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
- package/src/modules/billing/backend/billing/items/page.tsx +18 -2
- package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
- package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
- package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
- package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
- package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
- package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
- package/src/modules/billing/backend/billing/runs/[id]/page.tsx +49 -18
- package/src/modules/billing/backend/billing/runs/page.tsx +59 -8
- package/src/modules/billing/backend/billing/statements/[id]/page.tsx +86 -5
- package/src/modules/billing/backend/billing/statements/page.tsx +1 -1
- package/src/modules/billing/backend/billing/topups/page.tsx +1 -1
- package/src/modules/billing/backend/billing/transactions/page.tsx +1 -1
- package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
- package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
- package/src/modules/billing/backend/config/billing/page.tsx +549 -0
- package/src/modules/billing/cli.ts +31 -1
- package/src/modules/billing/commands/accounts.ts +6 -0
- package/src/modules/billing/commands/index.ts +3 -0
- package/src/modules/billing/commands/invoices.ts +364 -231
- package/src/modules/billing/commands/items.ts +143 -0
- package/src/modules/billing/commands/memos.ts +218 -0
- package/src/modules/billing/commands/payments.ts +428 -0
- package/src/modules/billing/commands/runs.ts +205 -3
- package/src/modules/billing/commands/settings.ts +77 -0
- package/src/modules/billing/commands/topups.ts +12 -3
- package/src/modules/billing/commands/transactions.ts +2 -2
- package/src/modules/billing/components/AccountForm.tsx +199 -53
- package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
- package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
- package/src/modules/billing/components/AccountPicker.tsx +70 -0
- package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
- package/src/modules/billing/components/BillingDataTable.tsx +34 -0
- package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
- package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
- package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
- package/src/modules/billing/components/CustomerLabel.tsx +53 -0
- package/src/modules/billing/components/InvoicesTable.tsx +344 -0
- package/src/modules/billing/components/ItemForm.tsx +233 -44
- package/src/modules/billing/components/ItemPriceField.tsx +81 -0
- package/src/modules/billing/components/LineFormDialog.tsx +25 -1
- package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
- package/src/modules/billing/components/MoneyInput.tsx +26 -0
- package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
- package/src/modules/billing/components/PaymentsTable.tsx +213 -0
- package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
- package/src/modules/billing/components/PrepaidPanel.tsx +19 -6
- package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
- package/src/modules/billing/components/TestRunActions.tsx +152 -0
- package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
- package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
- package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
- package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
- package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
- package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
- package/src/modules/billing/components/account/AccountView.tsx +101 -0
- package/src/modules/billing/components/account/accountRow.ts +70 -0
- package/src/modules/billing/components/customerNames.ts +62 -0
- package/src/modules/billing/data/entities.ts +654 -5
- package/src/modules/billing/data/entityIds.ts +9 -0
- package/src/modules/billing/data/validators.ts +388 -8
- package/src/modules/billing/events.ts +56 -3
- package/src/modules/billing/i18n/en.json +457 -21
- package/src/modules/billing/i18n/pl.json +457 -21
- package/src/modules/billing/index.ts +6 -2
- package/src/modules/billing/lib/accountFinancials.ts +84 -0
- package/src/modules/billing/lib/accountLock.ts +32 -0
- package/src/modules/billing/lib/accountStatus.ts +11 -9
- package/src/modules/billing/lib/accountSummary.ts +172 -0
- package/src/modules/billing/lib/allocation.ts +515 -0
- package/src/modules/billing/lib/allocationEvents.ts +26 -0
- package/src/modules/billing/lib/billPeriod.ts +19 -0
- package/src/modules/billing/lib/billRunEngine.ts +350 -150
- package/src/modules/billing/lib/billingSettings.ts +145 -0
- package/src/modules/billing/lib/commandRoute.ts +112 -0
- package/src/modules/billing/lib/customerLookup.ts +157 -0
- package/src/modules/billing/lib/dateOnly.ts +22 -0
- package/src/modules/billing/lib/documentParties.ts +23 -0
- package/src/modules/billing/lib/documentTypes.ts +37 -0
- package/src/modules/billing/lib/dueDate.ts +26 -0
- package/src/modules/billing/lib/iban.ts +36 -0
- package/src/modules/billing/lib/invoiceDelivery.ts +197 -0
- package/src/modules/billing/lib/invoiceLanguages.ts +34 -0
- package/src/modules/billing/lib/invoiceWriter.ts +162 -148
- package/src/modules/billing/lib/itemBillingState.ts +67 -0
- package/src/modules/billing/lib/itemPriceChange.ts +56 -0
- package/src/modules/billing/lib/itemSelector.ts +4 -1
- package/src/modules/billing/lib/lineAmounts.ts +61 -0
- package/src/modules/billing/lib/memoGuards.ts +41 -0
- package/src/modules/billing/lib/navigation.ts +64 -0
- package/src/modules/billing/lib/numbering.ts +174 -0
- package/src/modules/billing/lib/overdue.ts +60 -0
- package/src/modules/billing/lib/paymentCsv.ts +171 -0
- package/src/modules/billing/lib/paymentGateway.ts +52 -0
- package/src/modules/billing/lib/paymentImport.ts +228 -0
- package/src/modules/billing/lib/paymentMatcher.ts +88 -0
- package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
- package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
- package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
- package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
- package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
- package/src/modules/billing/lib/pdf/invoiceModel.ts +328 -0
- package/src/modules/billing/lib/pdf/invoicePdf.ts +216 -0
- package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
- package/src/modules/billing/lib/prepaidConfig.ts +27 -36
- package/src/modules/billing/lib/prepaidConsume.ts +29 -6
- package/src/modules/billing/lib/prepaidPeriodClose.ts +407 -239
- package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
- package/src/modules/billing/lib/seeds/demo.ts +79 -6
- package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
- package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
- package/src/modules/billing/lib/servicePeriods.ts +226 -0
- package/src/modules/billing/lib/testRunCleanup.ts +42 -0
- package/src/modules/billing/lib/topupCapture.ts +3 -4
- package/src/modules/billing/lib/topupReceipt.ts +70 -103
- package/src/modules/billing/lib/usageRater.ts +1 -1
- package/src/modules/billing/lib/usageRunner.ts +17 -5
- package/src/modules/billing/lib/vat.ts +56 -0
- package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
- package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
- package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
- package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
- package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
- package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
- package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
- package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
- package/src/modules/billing/setup.ts +11 -237
- package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
- package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
- package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
- package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
- package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
- package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
- package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
- package/dist/modules/billing/lib/invoiceStatus.js +0 -38
- package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
- package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
- package/src/modules/billing/lib/invoiceStatus.ts +0 -61
|
@@ -3,10 +3,14 @@ const metadata = {
|
|
|
3
3
|
name: "billing",
|
|
4
4
|
title: "Billing",
|
|
5
5
|
version: "0.1.0",
|
|
6
|
-
description: "Lightweight recurring-billing engine \u2014 collects one-time / recurring / usage items, runs Bill Runs
|
|
6
|
+
description: "Lightweight recurring-billing engine \u2014 collects one-time / recurring / usage items, runs Bill Runs and issues its own invoices, memos and top-up receipts (no core sales dependency).",
|
|
7
7
|
author: "Dainamite",
|
|
8
8
|
license: "MIT",
|
|
9
|
-
|
|
9
|
+
// Spec 0: billing owns its documents. `payment_gateways` is optional
|
|
10
|
+
// (online top-ups only, resolved at runtime); no sales / configs /
|
|
11
|
+
// dictionaries dependency. Spec B: `attachments` (platform module) stores
|
|
12
|
+
// frozen invoice PDFs and the document logo.
|
|
13
|
+
requires: ["auth", "directory", "attachments"],
|
|
10
14
|
ejectable: false
|
|
11
15
|
};
|
|
12
16
|
import { features } from "./acl.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/modules/billing/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ModuleInfo } from '@open-mercato/shared/modules/registry'\n\n// Side-effect import \u2014 registers every CRUD command in the global\n// command bus at module load time. The makeCrudRoute factory looks up\n// `actions.<verb>.commandId` against this registry at request time, so\n// without this import every billing write returns \"command not found\".\n// Pattern mirrors `@open-mercato/core/src/modules/customers/index.ts`.\nimport './commands'\n\nexport const metadata: ModuleInfo = {\n name: 'billing',\n title: 'Billing',\n version: '0.1.0',\n description:\n 'Lightweight recurring-billing engine \u2014 collects one-time / recurring / usage items, runs Bill Runs
|
|
5
|
-
"mappings": "AAOA,OAAO;AAEA,MAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,aACE;AAAA,EACF,QAAQ;AAAA,EACR,SAAS;AAAA,
|
|
4
|
+
"sourcesContent": ["import type { ModuleInfo } from '@open-mercato/shared/modules/registry'\n\n// Side-effect import \u2014 registers every CRUD command in the global\n// command bus at module load time. The makeCrudRoute factory looks up\n// `actions.<verb>.commandId` against this registry at request time, so\n// without this import every billing write returns \"command not found\".\n// Pattern mirrors `@open-mercato/core/src/modules/customers/index.ts`.\nimport './commands'\n\nexport const metadata: ModuleInfo = {\n name: 'billing',\n title: 'Billing',\n version: '0.1.0',\n description:\n 'Lightweight recurring-billing engine \u2014 collects one-time / recurring / usage items, runs Bill Runs and issues its own invoices, memos and top-up receipts (no core sales dependency).',\n author: 'Dainamite',\n license: 'MIT',\n // Spec 0: billing owns its documents. `payment_gateways` is optional\n // (online top-ups only, resolved at runtime); no sales / configs /\n // dictionaries dependency. Spec B: `attachments` (platform module) stores\n // frozen invoice PDFs and the document logo.\n requires: ['auth', 'directory', 'attachments'],\n ejectable: false,\n}\n\nexport { features } from './acl'\n"],
|
|
5
|
+
"mappings": "AAOA,OAAO;AAEA,MAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,aACE;AAAA,EACF,QAAQ;AAAA,EACR,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT,UAAU,CAAC,QAAQ,aAAa,aAAa;AAAA,EAC7C,WAAW;AACb;AAEA,SAAS,gBAAgB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { isoDay, overdueSql } from "./overdue.js";
|
|
2
|
+
const ACCOUNT_FINANCIALS_SQL = `SELECT
|
|
3
|
+
i.bill_account_id,
|
|
4
|
+
COALESCE(SUM(i.outstanding), 0) AS balance_due,
|
|
5
|
+
COALESCE(SUM(i.outstanding) FILTER (WHERE ${overdueSql("i")}), 0) AS overdue_amount
|
|
6
|
+
FROM billing_invoices i
|
|
7
|
+
WHERE i.tenant_id = ? AND i.organization_id = ? AND i.bill_account_id = ANY(?::uuid[])
|
|
8
|
+
AND i.deleted_at IS NULL AND i.test_run = false
|
|
9
|
+
AND i.status IN ('posted', 'partially_paid')
|
|
10
|
+
AND i.document_type IN ('invoice', 'debit_memo')
|
|
11
|
+
GROUP BY i.bill_account_id`;
|
|
12
|
+
const OVERDUE_ACCOUNT_IDS_SQL = `SELECT DISTINCT i.bill_account_id
|
|
13
|
+
FROM billing_invoices i
|
|
14
|
+
WHERE i.tenant_id = ? AND i.organization_id = ANY(?::uuid[])
|
|
15
|
+
AND i.deleted_at IS NULL AND i.test_run = false
|
|
16
|
+
AND ${overdueSql("i")}`;
|
|
17
|
+
const ZERO = "0.0000";
|
|
18
|
+
function money(value) {
|
|
19
|
+
const n = typeof value === "number" ? value : Number.parseFloat(value ?? "0");
|
|
20
|
+
return (Number.isFinite(n) ? n : 0).toFixed(4);
|
|
21
|
+
}
|
|
22
|
+
function uuidArray(ids) {
|
|
23
|
+
return `{${ids.join(",")}}`;
|
|
24
|
+
}
|
|
25
|
+
async function fetchAccountFinancials(em, scope, accountIds, today = /* @__PURE__ */ new Date()) {
|
|
26
|
+
const out = /* @__PURE__ */ new Map();
|
|
27
|
+
if (accountIds.length === 0) return out;
|
|
28
|
+
const rows = await em.execute(ACCOUNT_FINANCIALS_SQL, [
|
|
29
|
+
isoDay(today),
|
|
30
|
+
scope.tenantId,
|
|
31
|
+
scope.organizationId,
|
|
32
|
+
uuidArray(accountIds)
|
|
33
|
+
]);
|
|
34
|
+
for (const row of rows ?? []) {
|
|
35
|
+
out.set(String(row.bill_account_id), { balance_due: money(row.balance_due), overdue_amount: money(row.overdue_amount) });
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
async function fetchOverdueAccountIds(em, scope, today = /* @__PURE__ */ new Date()) {
|
|
40
|
+
if (scope.organizationIds.length === 0) return [];
|
|
41
|
+
const rows = await em.execute(OVERDUE_ACCOUNT_IDS_SQL, [
|
|
42
|
+
scope.tenantId,
|
|
43
|
+
uuidArray(scope.organizationIds),
|
|
44
|
+
isoDay(today)
|
|
45
|
+
]);
|
|
46
|
+
return (rows ?? []).map((row) => String(row.bill_account_id));
|
|
47
|
+
}
|
|
48
|
+
function financialsOrZero(map, accountId) {
|
|
49
|
+
return map.get(accountId) ?? { balance_due: ZERO, overdue_amount: ZERO };
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
ACCOUNT_FINANCIALS_SQL,
|
|
53
|
+
OVERDUE_ACCOUNT_IDS_SQL,
|
|
54
|
+
fetchAccountFinancials,
|
|
55
|
+
fetchOverdueAccountIds,
|
|
56
|
+
financialsOrZero
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=accountFinancials.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/billing/lib/accountFinancials.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { isoDay, overdueSql } from './overdue'\n\n/**\n * Account-list financials (Spec E \u00A74 / Spec F, F8, P-D15).\n *\n * One aggregate over `billing_invoices` per list page \u2014 `GROUP BY\n * bill_account_id` for the page's account ids, never a per-row fetch:\n * - balance_due \u03A3 outstanding of posted / partially paid receivables\n * - overdue_amount \u03A3 outstanding of the overdue subset\n * Test-run documents never count. Same overdue rule as the invoice list and\n * the account summary (`overdueSql`).\n */\n\nexport type AccountFinancials = { balance_due: string; overdue_amount: string }\n\nexport type FinancialsScope = { tenantId: string; organizationId: string }\n\nexport const ACCOUNT_FINANCIALS_SQL = `SELECT\n i.bill_account_id,\n COALESCE(SUM(i.outstanding), 0) AS balance_due,\n COALESCE(SUM(i.outstanding) FILTER (WHERE ${overdueSql('i')}), 0) AS overdue_amount\n FROM billing_invoices i\n WHERE i.tenant_id = ? AND i.organization_id = ? AND i.bill_account_id = ANY(?::uuid[])\n AND i.deleted_at IS NULL AND i.test_run = false\n AND i.status IN ('posted', 'partially_paid')\n AND i.document_type IN ('invoice', 'debit_memo')\n GROUP BY i.bill_account_id`\n\nexport const OVERDUE_ACCOUNT_IDS_SQL = `SELECT DISTINCT i.bill_account_id\n FROM billing_invoices i\n WHERE i.tenant_id = ? AND i.organization_id = ANY(?::uuid[])\n AND i.deleted_at IS NULL AND i.test_run = false\n AND ${overdueSql('i')}`\n\nconst ZERO = '0.0000'\n\nfunction money(value: string | number | null | undefined): string {\n const n = typeof value === 'number' ? value : Number.parseFloat(value ?? '0')\n return (Number.isFinite(n) ? n : 0).toFixed(4)\n}\n\nfunction uuidArray(ids: readonly string[]): string {\n return `{${ids.join(',')}}`\n}\n\nexport async function fetchAccountFinancials(\n em: EntityManager,\n scope: FinancialsScope,\n accountIds: readonly string[],\n today: Date = new Date(),\n): Promise<Map<string, AccountFinancials>> {\n const out = new Map<string, AccountFinancials>()\n if (accountIds.length === 0) return out\n const rows = (await em.execute(ACCOUNT_FINANCIALS_SQL, [\n isoDay(today),\n scope.tenantId,\n scope.organizationId,\n uuidArray(accountIds),\n ])) as unknown as Array<{ bill_account_id: string; balance_due: string; overdue_amount: string }>\n for (const row of rows ?? []) {\n out.set(String(row.bill_account_id), { balance_due: money(row.balance_due), overdue_amount: money(row.overdue_amount) })\n }\n return out\n}\n\n/** Ids of accounts with at least one overdue receivable (the `hasOverdue` filter). */\nexport async function fetchOverdueAccountIds(\n em: EntityManager,\n scope: { tenantId: string; organizationIds: readonly string[] },\n today: Date = new Date(),\n): Promise<string[]> {\n if (scope.organizationIds.length === 0) return []\n const rows = (await em.execute(OVERDUE_ACCOUNT_IDS_SQL, [\n scope.tenantId,\n uuidArray(scope.organizationIds),\n isoDay(today),\n ])) as unknown as Array<{ bill_account_id: string }>\n return (rows ?? []).map((row) => String(row.bill_account_id))\n}\n\nexport function financialsOrZero(map: Map<string, AccountFinancials>, accountId: string): AccountFinancials {\n return map.get(accountId) ?? { balance_due: ZERO, overdue_amount: ZERO }\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,QAAQ,kBAAkB;AAiB5B,MAAM,yBAAyB;AAAA;AAAA;AAAA,gDAGU,WAAW,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQxD,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA,UAI7B,WAAW,GAAG,CAAC;AAEzB,MAAM,OAAO;AAEb,SAAS,MAAM,OAAmD;AAChE,QAAM,IAAI,OAAO,UAAU,WAAW,QAAQ,OAAO,WAAW,SAAS,GAAG;AAC5E,UAAQ,OAAO,SAAS,CAAC,IAAI,IAAI,GAAG,QAAQ,CAAC;AAC/C;AAEA,SAAS,UAAU,KAAgC;AACjD,SAAO,IAAI,IAAI,KAAK,GAAG,CAAC;AAC1B;AAEA,eAAsB,uBACpB,IACA,OACA,YACA,QAAc,oBAAI,KAAK,GACkB;AACzC,QAAM,MAAM,oBAAI,IAA+B;AAC/C,MAAI,WAAW,WAAW,EAAG,QAAO;AACpC,QAAM,OAAQ,MAAM,GAAG,QAAQ,wBAAwB;AAAA,IACrD,OAAO,KAAK;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,UAAU;AAAA,EACtB,CAAC;AACD,aAAW,OAAO,QAAQ,CAAC,GAAG;AAC5B,QAAI,IAAI,OAAO,IAAI,eAAe,GAAG,EAAE,aAAa,MAAM,IAAI,WAAW,GAAG,gBAAgB,MAAM,IAAI,cAAc,EAAE,CAAC;AAAA,EACzH;AACA,SAAO;AACT;AAGA,eAAsB,uBACpB,IACA,OACA,QAAc,oBAAI,KAAK,GACJ;AACnB,MAAI,MAAM,gBAAgB,WAAW,EAAG,QAAO,CAAC;AAChD,QAAM,OAAQ,MAAM,GAAG,QAAQ,yBAAyB;AAAA,IACtD,MAAM;AAAA,IACN,UAAU,MAAM,eAAe;AAAA,IAC/B,OAAO,KAAK;AAAA,EACd,CAAC;AACD,UAAQ,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,OAAO,IAAI,eAAe,CAAC;AAC9D;AAEO,SAAS,iBAAiB,KAAqC,WAAsC;AAC1G,SAAO,IAAI,IAAI,SAAS,KAAK,EAAE,aAAa,MAAM,gBAAgB,KAAK;AACzE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function accountLockKey(scope) {
|
|
2
|
+
return `billing-ar:${scope.tenantId}:${scope.billAccountId}`;
|
|
3
|
+
}
|
|
4
|
+
async function withAccountLock(em, scope, fn) {
|
|
5
|
+
return em.transactional(async (tem) => {
|
|
6
|
+
await tem.execute("SELECT pg_advisory_xact_lock(hashtextextended(?, 0))", [accountLockKey(scope)]);
|
|
7
|
+
return fn(tem);
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
accountLockKey,
|
|
12
|
+
withAccountLock
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=accountLock.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/billing/lib/accountLock.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\n\n/**\n * Per-billing-account transaction-scoped advisory lock (Spec C, P-D3).\n *\n * Every change to an account's receivables \u2014 CSV import allocations, manual\n * allocate / un-allocate, credit auto-apply on post, gateway captures and\n * (Spec D) credit memo posts \u2014 runs inside this lock, so two of them can\n * never spend the same credit or over-allocate the same invoice.\n *\n * Unlike `tenantLock` (a non-blocking try-lock for bill runs), this one\n * BLOCKS: operations on one account simply queue up. The lock is released\n * when the transaction ends (commit, rollback or process death). Keep the\n * callback short \u2014 it holds a database transaction.\n */\n\nexport type AccountLockScope = { tenantId: string; billAccountId: string }\n\nexport function accountLockKey(scope: AccountLockScope): string {\n return `billing-ar:${scope.tenantId}:${scope.billAccountId}`\n}\n\nexport async function withAccountLock<T>(\n em: EntityManager,\n scope: AccountLockScope,\n fn: (tem: EntityManager) => Promise<T>,\n): Promise<T> {\n return em.transactional(async (tem) => {\n await (tem as EntityManager).execute('SELECT pg_advisory_xact_lock(hashtextextended(?, 0))', [accountLockKey(scope)])\n return fn(tem as EntityManager)\n })\n}\n"],
|
|
5
|
+
"mappings": "AAkBO,SAAS,eAAe,OAAiC;AAC9D,SAAO,cAAc,MAAM,QAAQ,IAAI,MAAM,aAAa;AAC5D;AAEA,eAAsB,gBACpB,IACA,OACA,IACY;AACZ,SAAO,GAAG,cAAc,OAAO,QAAQ;AACrC,UAAO,IAAsB,QAAQ,wDAAwD,CAAC,eAAe,KAAK,CAAC,CAAC;AACpH,WAAO,GAAG,GAAoB;AAAA,EAChC,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -20,7 +20,7 @@ async function getBalanceSnapshot(em, account) {
|
|
|
20
20
|
const balance = row?.balance ?? "0.0000";
|
|
21
21
|
const threshold = resolveLowBalanceThreshold(
|
|
22
22
|
row?.lowBalanceThreshold ?? null,
|
|
23
|
-
await getLowBalanceThresholdDefault(em)
|
|
23
|
+
await getLowBalanceThresholdDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId })
|
|
24
24
|
);
|
|
25
25
|
return {
|
|
26
26
|
billAccountId: account.id,
|
|
@@ -33,20 +33,22 @@ async function getBalanceSnapshot(em, account) {
|
|
|
33
33
|
}
|
|
34
34
|
async function getPostpaidOutstanding(em, account) {
|
|
35
35
|
const rows = await em.execute(
|
|
36
|
-
`SELECT COALESCE(SUM(
|
|
37
|
-
FROM
|
|
36
|
+
`SELECT COALESCE(SUM(outstanding), 0) AS total
|
|
37
|
+
FROM billing_invoices
|
|
38
38
|
WHERE tenant_id = ?
|
|
39
39
|
AND organization_id = ?
|
|
40
40
|
AND deleted_at IS NULL
|
|
41
|
-
AND
|
|
42
|
-
AND
|
|
41
|
+
AND test_run = false
|
|
42
|
+
AND status IN ('posted', 'partially_paid')
|
|
43
|
+
AND document_type IN ('invoice', 'debit_memo')
|
|
44
|
+
AND bill_account_id = ?`,
|
|
43
45
|
[account.tenantId, account.organizationId, account.id]
|
|
44
46
|
);
|
|
45
47
|
return formatMoney(rows?.[0]?.total ?? 0);
|
|
46
48
|
}
|
|
47
49
|
async function getCreditSnapshot(em, account) {
|
|
48
50
|
const mode = account.billingMode ?? "postpaid";
|
|
49
|
-
const nearLimitBuffer = await getNearLimitBufferDefault(em);
|
|
51
|
+
const nearLimitBuffer = await getNearLimitBufferDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId });
|
|
50
52
|
let balance = null;
|
|
51
53
|
let outstanding = null;
|
|
52
54
|
if (mode === "prepaid") {
|
|
@@ -71,7 +73,7 @@ async function buildPostpaidCreditCrossingEvents(em, account, justPostedOutstand
|
|
|
71
73
|
if (account.billingMode !== "postpaid") return [];
|
|
72
74
|
const creditLimit = account.creditLimit ?? "0";
|
|
73
75
|
if (toUnits(creditLimit) <= 0) return [];
|
|
74
|
-
const nearLimitBuffer = await getNearLimitBufferDefault(em);
|
|
76
|
+
const nearLimitBuffer = await getNearLimitBufferDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId });
|
|
75
77
|
const usedAfter = await getPostpaidOutstanding(em, account);
|
|
76
78
|
const usedBefore = subMoney(usedAfter, justPostedOutstanding);
|
|
77
79
|
const crossing = detectCreditCrossing({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/billing/lib/accountStatus.ts"],
|
|
4
|
-
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { BillingAccount, BillingAccountBalance } from '../data/entities'\nimport type { BalanceStatus, BillingMode } from '../data/validators'\nimport {\n computeBalanceStatus,\n resolveLowBalanceThreshold,\n} from './balanceStatus'\nimport {\n computeCreditSnapshot,\n detectCreditCrossing,\n type CreditSnapshot,\n} from './creditStatus'\nimport type { DomainEvent } from './balanceEvents'\nimport { formatMoney, subMoney, toUnits } from './money'\nimport {\n getLowBalanceThresholdDefault,\n getNearLimitBufferDefault,\n} from './prepaidConfig'\n\n/**\n * Read-model helpers for an account's prepaid balance + credit status\n * (SPEC-002). Shared by `GET \u2026/balance`, `GET \u2026/credit-status`, and the\n * admin Prepaid panel so the math lives in exactly one place.\n */\n\nexport type BalanceSnapshot = {\n billAccountId: string\n currencyCode: string\n balance: string\n balanceStatus: BalanceStatus\n /** The resolved threshold (account row \u2192 tenant config default). */\n lowBalanceThreshold: string\n lastMovementAt: string | null\n}\n\nexport async function getBalanceSnapshot(\n em: EntityManager,\n account: BillingAccount,\n): Promise<BalanceSnapshot> {\n const row = await em.findOne(BillingAccountBalance, {\n tenantId: account.tenantId,\n billAccountId: account.id,\n })\n const balance = row?.balance ?? '0.0000'\n const threshold = resolveLowBalanceThreshold(\n row?.lowBalanceThreshold ?? null,\n await getLowBalanceThresholdDefault(em),\n )\n return {\n billAccountId: account.id,\n currencyCode: account.currencyCode,\n balance: formatMoney(balance),\n balanceStatus: computeBalanceStatus(balance, threshold),\n lowBalanceThreshold: formatMoney(threshold),\n lastMovementAt: row?.lastMovementAt ? row.lastMovementAt.toISOString() : null,\n }\n}\n\n/**\n * \u03A3 outstanding of
|
|
5
|
-
"mappings": "AACA,SAAyB,6BAA6B;AAEtD;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,aAAa,UAAU,eAAe;AAC/C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAkBP,eAAsB,mBACpB,IACA,SAC0B;AAC1B,QAAM,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAClD,UAAU,QAAQ;AAAA,IAClB,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,YAAY;AAAA,IAChB,KAAK,uBAAuB;AAAA,IAC5B,MAAM,8BAA8B,EAAE;AAAA,
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { BillingAccount, BillingAccountBalance } from '../data/entities'\nimport type { BalanceStatus, BillingMode } from '../data/validators'\nimport {\n computeBalanceStatus,\n resolveLowBalanceThreshold,\n} from './balanceStatus'\nimport {\n computeCreditSnapshot,\n detectCreditCrossing,\n type CreditSnapshot,\n} from './creditStatus'\nimport type { DomainEvent } from './balanceEvents'\nimport { formatMoney, subMoney, toUnits } from './money'\nimport {\n getLowBalanceThresholdDefault,\n getNearLimitBufferDefault,\n} from './prepaidConfig'\n\n/**\n * Read-model helpers for an account's prepaid balance + credit status\n * (SPEC-002). Shared by `GET \u2026/balance`, `GET \u2026/credit-status`, and the\n * admin Prepaid panel so the math lives in exactly one place.\n */\n\nexport type BalanceSnapshot = {\n billAccountId: string\n currencyCode: string\n balance: string\n balanceStatus: BalanceStatus\n /** The resolved threshold (account row \u2192 tenant config default). */\n lowBalanceThreshold: string\n lastMovementAt: string | null\n}\n\nexport async function getBalanceSnapshot(\n em: EntityManager,\n account: BillingAccount,\n): Promise<BalanceSnapshot> {\n const row = await em.findOne(BillingAccountBalance, {\n tenantId: account.tenantId,\n billAccountId: account.id,\n })\n const balance = row?.balance ?? '0.0000'\n const threshold = resolveLowBalanceThreshold(\n row?.lowBalanceThreshold ?? null,\n await getLowBalanceThresholdDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId }),\n )\n return {\n billAccountId: account.id,\n currencyCode: account.currencyCode,\n balance: formatMoney(balance),\n balanceStatus: computeBalanceStatus(balance, threshold),\n lowBalanceThreshold: formatMoney(threshold),\n lastMovementAt: row?.lastMovementAt ? row.lastMovementAt.toISOString() : null,\n }\n}\n\n/**\n * \u03A3 outstanding of posted / partially paid billing invoices and debit memos\n * of this account (Spec 0: billing-owned `billing_invoices`) \u2014 the postpaid `credit_used` (v1; mid-period\n * accrued usage is not counted, see SPEC-002 Open Question #5). Top-up\n * receipts are `paid`, so they never count here.\n */\nexport async function getPostpaidOutstanding(\n em: EntityManager,\n account: BillingAccount,\n): Promise<string> {\n const rows = (await em.execute(\n `SELECT COALESCE(SUM(outstanding), 0) AS total\n FROM billing_invoices\n WHERE tenant_id = ?\n AND organization_id = ?\n AND deleted_at IS NULL\n AND test_run = false\n AND status IN ('posted', 'partially_paid')\n AND document_type IN ('invoice', 'debit_memo')\n AND bill_account_id = ?`,\n [account.tenantId, account.organizationId, account.id],\n )) as unknown as Array<{ total: string }>\n return formatMoney(rows?.[0]?.total ?? 0)\n}\n\nexport type CreditSnapshotResult = CreditSnapshot & { currencyCode: string }\n\nexport async function getCreditSnapshot(\n em: EntityManager,\n account: BillingAccount,\n): Promise<CreditSnapshotResult> {\n const mode = (account.billingMode as BillingMode) ?? 'postpaid'\n const nearLimitBuffer = await getNearLimitBufferDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId })\n\n let balance: string | null = null\n let outstanding: string | null = null\n if (mode === 'prepaid') {\n const row = await em.findOne(BillingAccountBalance, {\n tenantId: account.tenantId,\n billAccountId: account.id,\n })\n balance = row?.balance ?? '0.0000'\n } else {\n outstanding = await getPostpaidOutstanding(em, account)\n }\n\n const snapshot = computeCreditSnapshot({\n mode,\n creditLimit: account.creditLimit ?? '0',\n nearLimitBuffer,\n balance,\n outstanding,\n })\n return { ...snapshot, currencyCode: account.currencyCode }\n}\n\n/**\n * Credit-crossing events for a postpaid account when a draft invoice is posted\n * (SPEC-002 P6). `billing.credit.over_limit` fires once on the upward crossing\n * of `credit_used` (\u03A3 posted-unpaid outstanding) past `credit_limit`. The\n * just-posted invoice's `outstanding` is already included in the current total,\n * so the prior total is `current \u2212 justPostedOutstanding`.\n */\nexport async function buildPostpaidCreditCrossingEvents(\n em: EntityManager,\n account: BillingAccount,\n justPostedOutstanding: string,\n): Promise<DomainEvent[]> {\n if ((account.billingMode as BillingMode) !== 'postpaid') return []\n const creditLimit = account.creditLimit ?? '0'\n if (toUnits(creditLimit) <= 0) return []\n\n const nearLimitBuffer = await getNearLimitBufferDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId })\n const usedAfter = await getPostpaidOutstanding(em, account)\n const usedBefore = subMoney(usedAfter, justPostedOutstanding)\n const crossing = detectCreditCrossing({\n creditLimit,\n nearLimitBuffer,\n usedBefore,\n usedAfter,\n })\n\n const events: DomainEvent[] = []\n const base = {\n billAccountId: account.id,\n tenantId: account.tenantId,\n organizationId: account.organizationId,\n currencyCode: account.currencyCode,\n creditLimit,\n creditUsed: usedAfter,\n }\n if (crossing.overLimitCrossedUp) {\n events.push({ id: 'billing.credit.over_limit', payload: { ...base } })\n }\n if (crossing.nearLimitCrossedUp) {\n events.push({ id: 'billing.credit.near_limit', payload: { ...base } })\n }\n return events\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAyB,6BAA6B;AAEtD;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,aAAa,UAAU,eAAe;AAC/C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAkBP,eAAsB,mBACpB,IACA,SAC0B;AAC1B,QAAM,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAClD,UAAU,QAAQ;AAAA,IAClB,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,YAAY;AAAA,IAChB,KAAK,uBAAuB;AAAA,IAC5B,MAAM,8BAA8B,IAAI,EAAE,UAAU,QAAQ,UAAU,gBAAgB,QAAQ,eAAe,CAAC;AAAA,EAChH;AACA,SAAO;AAAA,IACL,eAAe,QAAQ;AAAA,IACvB,cAAc,QAAQ;AAAA,IACtB,SAAS,YAAY,OAAO;AAAA,IAC5B,eAAe,qBAAqB,SAAS,SAAS;AAAA,IACtD,qBAAqB,YAAY,SAAS;AAAA,IAC1C,gBAAgB,KAAK,iBAAiB,IAAI,eAAe,YAAY,IAAI;AAAA,EAC3E;AACF;AAQA,eAAsB,uBACpB,IACA,SACiB;AACjB,QAAM,OAAQ,MAAM,GAAG;AAAA,IACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,CAAC,QAAQ,UAAU,QAAQ,gBAAgB,QAAQ,EAAE;AAAA,EACvD;AACA,SAAO,YAAY,OAAO,CAAC,GAAG,SAAS,CAAC;AAC1C;AAIA,eAAsB,kBACpB,IACA,SAC+B;AAC/B,QAAM,OAAQ,QAAQ,eAA+B;AACrD,QAAM,kBAAkB,MAAM,0BAA0B,IAAI,EAAE,UAAU,QAAQ,UAAU,gBAAgB,QAAQ,eAAe,CAAC;AAElI,MAAI,UAAyB;AAC7B,MAAI,cAA6B;AACjC,MAAI,SAAS,WAAW;AACtB,UAAM,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,MAClD,UAAU,QAAQ;AAAA,MAClB,eAAe,QAAQ;AAAA,IACzB,CAAC;AACD,cAAU,KAAK,WAAW;AAAA,EAC5B,OAAO;AACL,kBAAc,MAAM,uBAAuB,IAAI,OAAO;AAAA,EACxD;AAEA,QAAM,WAAW,sBAAsB;AAAA,IACrC;AAAA,IACA,aAAa,QAAQ,eAAe;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO,EAAE,GAAG,UAAU,cAAc,QAAQ,aAAa;AAC3D;AASA,eAAsB,kCACpB,IACA,SACA,uBACwB;AACxB,MAAK,QAAQ,gBAAgC,WAAY,QAAO,CAAC;AACjE,QAAM,cAAc,QAAQ,eAAe;AAC3C,MAAI,QAAQ,WAAW,KAAK,EAAG,QAAO,CAAC;AAEvC,QAAM,kBAAkB,MAAM,0BAA0B,IAAI,EAAE,UAAU,QAAQ,UAAU,gBAAgB,QAAQ,eAAe,CAAC;AAClI,QAAM,YAAY,MAAM,uBAAuB,IAAI,OAAO;AAC1D,QAAM,aAAa,SAAS,WAAW,qBAAqB;AAC5D,QAAM,WAAW,qBAAqB;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,SAAwB,CAAC;AAC/B,QAAM,OAAO;AAAA,IACX,eAAe,QAAQ;AAAA,IACvB,UAAU,QAAQ;AAAA,IAClB,gBAAgB,QAAQ;AAAA,IACxB,cAAc,QAAQ;AAAA,IACtB;AAAA,IACA,YAAY;AAAA,EACd;AACA,MAAI,SAAS,oBAAoB;AAC/B,WAAO,KAAK,EAAE,IAAI,6BAA6B,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;AAAA,EACvE;AACA,MAAI,SAAS,oBAAoB;AAC/B,WAAO,KAAK,EAAE,IAAI,6BAA6B,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;AAAA,EACvE;AACA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { isoDay, overdueSql } from "./overdue.js";
|
|
2
|
+
import { getAccountCredit } from "./allocation.js";
|
|
3
|
+
import { computeBalanceStatus, resolveLowBalanceThreshold } from "./balanceStatus.js";
|
|
4
|
+
import { getLowBalanceThresholdDefault } from "./prepaidConfig.js";
|
|
5
|
+
import { toIsoDate } from "./dateOnly.js";
|
|
6
|
+
const ACCOUNT_SUMMARY_SQL = `SELECT
|
|
7
|
+
COALESCE(SUM(i.outstanding), 0) AS open_amount,
|
|
8
|
+
COALESCE(SUM(i.outstanding) FILTER (WHERE ${overdueSql("i")}), 0) AS overdue_amount,
|
|
9
|
+
COUNT(*) FILTER (WHERE ${overdueSql("i")})::int AS overdue_count
|
|
10
|
+
FROM billing_invoices i
|
|
11
|
+
WHERE i.tenant_id = ? AND i.organization_id = ? AND i.bill_account_id = ?
|
|
12
|
+
AND i.deleted_at IS NULL AND i.test_run = false
|
|
13
|
+
AND i.status IN ('posted', 'partially_paid')
|
|
14
|
+
AND i.document_type IN ('invoice', 'debit_memo')`;
|
|
15
|
+
function money(value) {
|
|
16
|
+
const n = typeof value === "number" ? value : Number.parseFloat(value ?? "0");
|
|
17
|
+
return (Number.isFinite(n) ? n : 0).toFixed(4);
|
|
18
|
+
}
|
|
19
|
+
async function getAccountArSummary(em, account, today = /* @__PURE__ */ new Date()) {
|
|
20
|
+
const day = isoDay(today);
|
|
21
|
+
const rows = await em.execute(ACCOUNT_SUMMARY_SQL, [
|
|
22
|
+
day,
|
|
23
|
+
day,
|
|
24
|
+
account.tenantId,
|
|
25
|
+
account.organizationId,
|
|
26
|
+
account.id
|
|
27
|
+
]);
|
|
28
|
+
const row = rows?.[0];
|
|
29
|
+
return {
|
|
30
|
+
bill_account_id: account.id,
|
|
31
|
+
currency_code: account.currencyCode,
|
|
32
|
+
open_amount: money(row?.open_amount),
|
|
33
|
+
overdue_amount: money(row?.overdue_amount),
|
|
34
|
+
overdue_count: Number(row?.overdue_count ?? 0) || 0,
|
|
35
|
+
credit_amount: await getAccountCredit(
|
|
36
|
+
em,
|
|
37
|
+
{ tenantId: account.tenantId, organizationId: account.organizationId },
|
|
38
|
+
{ id: account.id, currencyCode: account.currencyCode }
|
|
39
|
+
)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const LAST_INVOICE_SQL = `SELECT id, number, issue_date, total_gross
|
|
43
|
+
FROM billing_invoices
|
|
44
|
+
WHERE tenant_id = ? AND organization_id = ? AND bill_account_id = ?
|
|
45
|
+
AND deleted_at IS NULL AND test_run = false
|
|
46
|
+
AND document_type IN ('invoice', 'debit_memo')
|
|
47
|
+
AND status NOT IN ('draft')
|
|
48
|
+
ORDER BY issue_date DESC NULLS LAST, created_at DESC
|
|
49
|
+
LIMIT 1`;
|
|
50
|
+
const BALANCE_SQL = `SELECT balance, low_balance_threshold
|
|
51
|
+
FROM billing_account_balances
|
|
52
|
+
WHERE tenant_id = ? AND bill_account_id = ?
|
|
53
|
+
LIMIT 1`;
|
|
54
|
+
const LAST_STATEMENT_SQL = `SELECT id, period_start, period_end, closing_balance
|
|
55
|
+
FROM billing_statements
|
|
56
|
+
WHERE tenant_id = ? AND organization_id = ? AND bill_account_id = ?
|
|
57
|
+
ORDER BY period_end DESC
|
|
58
|
+
LIMIT 1`;
|
|
59
|
+
async function getAccountWorkspaceSummary(em, account, today = /* @__PURE__ */ new Date()) {
|
|
60
|
+
const ar = await getAccountArSummary(em, account, today);
|
|
61
|
+
const scopeParams = [account.tenantId, account.organizationId, account.id];
|
|
62
|
+
const lastInvoice = (await em.execute(LAST_INVOICE_SQL, scopeParams))?.[0];
|
|
63
|
+
let prepaid = null;
|
|
64
|
+
if (account.billingMode === "prepaid") {
|
|
65
|
+
const balanceRow = (await em.execute(BALANCE_SQL, [account.tenantId, account.id]))?.[0];
|
|
66
|
+
const statement = (await em.execute(LAST_STATEMENT_SQL, scopeParams))?.[0];
|
|
67
|
+
const balance = money(balanceRow?.balance);
|
|
68
|
+
const threshold = resolveLowBalanceThreshold(
|
|
69
|
+
balanceRow?.low_balance_threshold ?? null,
|
|
70
|
+
await getLowBalanceThresholdDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId })
|
|
71
|
+
);
|
|
72
|
+
prepaid = {
|
|
73
|
+
balance,
|
|
74
|
+
balance_status: computeBalanceStatus(balance, threshold),
|
|
75
|
+
credit_limit: money(account.creditLimit),
|
|
76
|
+
last_statement: statement ? {
|
|
77
|
+
id: statement.id,
|
|
78
|
+
period_start: toIsoDate(statement.period_start),
|
|
79
|
+
period_end: toIsoDate(statement.period_end),
|
|
80
|
+
closing_balance: money(statement.closing_balance)
|
|
81
|
+
} : null
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
...ar,
|
|
86
|
+
billing_mode: account.billingMode === "prepaid" ? "prepaid" : "postpaid",
|
|
87
|
+
bill_cycle: account.billCycle,
|
|
88
|
+
next_bill_date: account.nextBillDate ? toIsoDate(account.nextBillDate) : null,
|
|
89
|
+
last_invoice: lastInvoice ? {
|
|
90
|
+
id: lastInvoice.id,
|
|
91
|
+
number: lastInvoice.number,
|
|
92
|
+
issue_date: lastInvoice.issue_date ? toIsoDate(lastInvoice.issue_date) : null,
|
|
93
|
+
total_gross: money(lastInvoice.total_gross)
|
|
94
|
+
} : null,
|
|
95
|
+
prepaid
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
ACCOUNT_SUMMARY_SQL,
|
|
100
|
+
BALANCE_SQL,
|
|
101
|
+
LAST_INVOICE_SQL,
|
|
102
|
+
LAST_STATEMENT_SQL,
|
|
103
|
+
getAccountArSummary,
|
|
104
|
+
getAccountWorkspaceSummary
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=accountSummary.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/billing/lib/accountSummary.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { BillingAccount } from '../data/entities'\nimport { isoDay, overdueSql } from './overdue'\nimport { getAccountCredit } from './allocation'\nimport { computeBalanceStatus, resolveLowBalanceThreshold } from './balanceStatus'\nimport { getLowBalanceThresholdDefault } from './prepaidConfig'\nimport { toIsoDate } from './dateOnly'\n\n/**\n * Accounts-receivable summary of one billing account (Spec B; the endpoint\n * is Spec E's `GET /api/billing/accounts/{id}/summary`, which later adds the\n * prepaid balance and next bill date to the same response).\n *\n * One aggregate query over `billing_invoices` (indexed on\n * `bill_account_id, status, due_date`), no ORM hydration:\n * - open_amount \u03A3 outstanding of posted / partially paid receivables\n * - overdue_amount \u03A3 outstanding of the overdue subset (B-D6)\n * - overdue_count number of overdue documents\n * - credit_amount unapplied credit (Spec C): unallocated payments + open\n * credit memos of the account\n * Test-run documents never count.\n */\n\nexport type AccountArSummary = {\n bill_account_id: string\n currency_code: string\n open_amount: string\n overdue_amount: string\n overdue_count: number\n credit_amount: string\n}\n\ntype SummaryRow = { open_amount: string | null; overdue_amount: string | null; overdue_count: number | string | null }\n\nexport const ACCOUNT_SUMMARY_SQL = `SELECT\n COALESCE(SUM(i.outstanding), 0) AS open_amount,\n COALESCE(SUM(i.outstanding) FILTER (WHERE ${overdueSql('i')}), 0) AS overdue_amount,\n COUNT(*) FILTER (WHERE ${overdueSql('i')})::int AS overdue_count\n FROM billing_invoices i\n WHERE i.tenant_id = ? AND i.organization_id = ? AND i.bill_account_id = ?\n AND i.deleted_at IS NULL AND i.test_run = false\n AND i.status IN ('posted', 'partially_paid')\n AND i.document_type IN ('invoice', 'debit_memo')`\n\nfunction money(value: string | number | null | undefined): string {\n const n = typeof value === 'number' ? value : Number.parseFloat(value ?? '0')\n return (Number.isFinite(n) ? n : 0).toFixed(4)\n}\n\nexport async function getAccountArSummary(\n em: EntityManager,\n account: Pick<BillingAccount, 'id' | 'tenantId' | 'organizationId' | 'currencyCode'>,\n today: Date = new Date(),\n): Promise<AccountArSummary> {\n const day = isoDay(today)\n const rows = (await em.execute(ACCOUNT_SUMMARY_SQL, [\n day,\n day,\n account.tenantId,\n account.organizationId,\n account.id,\n ])) as unknown as SummaryRow[]\n const row = rows?.[0]\n return {\n bill_account_id: account.id,\n currency_code: account.currencyCode,\n open_amount: money(row?.open_amount),\n overdue_amount: money(row?.overdue_amount),\n overdue_count: Number(row?.overdue_count ?? 0) || 0,\n credit_amount: await getAccountCredit(\n em,\n { tenantId: account.tenantId, organizationId: account.organizationId },\n { id: account.id, currencyCode: account.currencyCode },\n ),\n }\n}\n\n// \u2500\u2500\u2500 Spec E / Spec F (F8): the account workspace header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type AccountWorkspaceSummary = AccountArSummary & {\n billing_mode: 'postpaid' | 'prepaid'\n bill_cycle: string\n next_bill_date: string | null\n last_invoice: { id: string; number: string; issue_date: string | null; total_gross: string } | null\n prepaid: {\n balance: string\n balance_status: 'ok' | 'low' | 'exhausted'\n credit_limit: string\n last_statement: { id: string; period_start: string; period_end: string; closing_balance: string } | null\n } | null\n}\n\ntype LastInvoiceRow = { id: string; number: string; issue_date: string | Date | null; total_gross: string }\ntype BalanceRow = { balance: string | null; low_balance_threshold: string | null }\ntype StatementRow = { id: string; period_start: string | Date; period_end: string | Date; closing_balance: string }\n\nexport const LAST_INVOICE_SQL = `SELECT id, number, issue_date, total_gross\n FROM billing_invoices\n WHERE tenant_id = ? AND organization_id = ? AND bill_account_id = ?\n AND deleted_at IS NULL AND test_run = false\n AND document_type IN ('invoice', 'debit_memo')\n AND status NOT IN ('draft')\n ORDER BY issue_date DESC NULLS LAST, created_at DESC\n LIMIT 1`\n\nexport const BALANCE_SQL = `SELECT balance, low_balance_threshold\n FROM billing_account_balances\n WHERE tenant_id = ? AND bill_account_id = ?\n LIMIT 1`\n\nexport const LAST_STATEMENT_SQL = `SELECT id, period_start, period_end, closing_balance\n FROM billing_statements\n WHERE tenant_id = ? AND organization_id = ? AND bill_account_id = ?\n ORDER BY period_end DESC\n LIMIT 1`\n\n/**\n * Everything the account header shows, in a fixed number of small indexed\n * queries (no ORM hydration, no per-document fetch): the AR summary, cycle\n * state, the last posted invoice and \u2014 for prepaid accounts \u2014 the balance\n * with its status, the credit limit and the last statement.\n */\nexport async function getAccountWorkspaceSummary(\n em: EntityManager,\n account: Pick<\n BillingAccount,\n 'id' | 'tenantId' | 'organizationId' | 'currencyCode' | 'billingMode' | 'billCycle' | 'nextBillDate' | 'creditLimit'\n >,\n today: Date = new Date(),\n): Promise<AccountWorkspaceSummary> {\n const ar = await getAccountArSummary(em, account, today)\n const scopeParams = [account.tenantId, account.organizationId, account.id]\n const lastInvoice = ((await em.execute(LAST_INVOICE_SQL, scopeParams)) as unknown as LastInvoiceRow[])?.[0]\n let prepaid: AccountWorkspaceSummary['prepaid'] = null\n if (account.billingMode === 'prepaid') {\n const balanceRow = ((await em.execute(BALANCE_SQL, [account.tenantId, account.id])) as unknown as BalanceRow[])?.[0]\n const statement = ((await em.execute(LAST_STATEMENT_SQL, scopeParams)) as unknown as StatementRow[])?.[0]\n const balance = money(balanceRow?.balance)\n const threshold = resolveLowBalanceThreshold(\n balanceRow?.low_balance_threshold ?? null,\n await getLowBalanceThresholdDefault(em, { tenantId: account.tenantId, organizationId: account.organizationId }),\n )\n prepaid = {\n balance,\n balance_status: computeBalanceStatus(balance, threshold),\n credit_limit: money(account.creditLimit),\n last_statement: statement\n ? {\n id: statement.id,\n period_start: toIsoDate(statement.period_start),\n period_end: toIsoDate(statement.period_end),\n closing_balance: money(statement.closing_balance),\n }\n : null,\n }\n }\n return {\n ...ar,\n billing_mode: account.billingMode === 'prepaid' ? 'prepaid' : 'postpaid',\n bill_cycle: account.billCycle,\n next_bill_date: account.nextBillDate ? toIsoDate(account.nextBillDate) : null,\n last_invoice: lastInvoice\n ? {\n id: lastInvoice.id,\n number: lastInvoice.number,\n issue_date: lastInvoice.issue_date ? toIsoDate(lastInvoice.issue_date) : null,\n total_gross: money(lastInvoice.total_gross),\n }\n : null,\n prepaid,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,QAAQ,kBAAkB;AACnC,SAAS,wBAAwB;AACjC,SAAS,sBAAsB,kCAAkC;AACjE,SAAS,qCAAqC;AAC9C,SAAS,iBAAiB;AA4BnB,MAAM,sBAAsB;AAAA;AAAA,gDAEa,WAAW,GAAG,CAAC;AAAA,6BAClC,WAAW,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAO5C,SAAS,MAAM,OAAmD;AAChE,QAAM,IAAI,OAAO,UAAU,WAAW,QAAQ,OAAO,WAAW,SAAS,GAAG;AAC5E,UAAQ,OAAO,SAAS,CAAC,IAAI,IAAI,GAAG,QAAQ,CAAC;AAC/C;AAEA,eAAsB,oBACpB,IACA,SACA,QAAc,oBAAI,KAAK,GACI;AAC3B,QAAM,MAAM,OAAO,KAAK;AACxB,QAAM,OAAQ,MAAM,GAAG,QAAQ,qBAAqB;AAAA,IAClD;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,MAAM,OAAO,CAAC;AACpB,SAAO;AAAA,IACL,iBAAiB,QAAQ;AAAA,IACzB,eAAe,QAAQ;AAAA,IACvB,aAAa,MAAM,KAAK,WAAW;AAAA,IACnC,gBAAgB,MAAM,KAAK,cAAc;AAAA,IACzC,eAAe,OAAO,KAAK,iBAAiB,CAAC,KAAK;AAAA,IAClD,eAAe,MAAM;AAAA,MACnB;AAAA,MACA,EAAE,UAAU,QAAQ,UAAU,gBAAgB,QAAQ,eAAe;AAAA,MACrE,EAAE,IAAI,QAAQ,IAAI,cAAc,QAAQ,aAAa;AAAA,IACvD;AAAA,EACF;AACF;AAqBO,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASzB,MAAM,cAAc;AAAA;AAAA;AAAA;AAKpB,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAYlC,eAAsB,2BACpB,IACA,SAIA,QAAc,oBAAI,KAAK,GACW;AAClC,QAAM,KAAK,MAAM,oBAAoB,IAAI,SAAS,KAAK;AACvD,QAAM,cAAc,CAAC,QAAQ,UAAU,QAAQ,gBAAgB,QAAQ,EAAE;AACzE,QAAM,eAAgB,MAAM,GAAG,QAAQ,kBAAkB,WAAW,KAAqC,CAAC;AAC1G,MAAI,UAA8C;AAClD,MAAI,QAAQ,gBAAgB,WAAW;AACrC,UAAM,cAAe,MAAM,GAAG,QAAQ,aAAa,CAAC,QAAQ,UAAU,QAAQ,EAAE,CAAC,KAAiC,CAAC;AACnH,UAAM,aAAc,MAAM,GAAG,QAAQ,oBAAoB,WAAW,KAAmC,CAAC;AACxG,UAAM,UAAU,MAAM,YAAY,OAAO;AACzC,UAAM,YAAY;AAAA,MAChB,YAAY,yBAAyB;AAAA,MACrC,MAAM,8BAA8B,IAAI,EAAE,UAAU,QAAQ,UAAU,gBAAgB,QAAQ,eAAe,CAAC;AAAA,IAChH;AACA,cAAU;AAAA,MACR;AAAA,MACA,gBAAgB,qBAAqB,SAAS,SAAS;AAAA,MACvD,cAAc,MAAM,QAAQ,WAAW;AAAA,MACvC,gBAAgB,YACZ;AAAA,QACE,IAAI,UAAU;AAAA,QACd,cAAc,UAAU,UAAU,YAAY;AAAA,QAC9C,YAAY,UAAU,UAAU,UAAU;AAAA,QAC1C,iBAAiB,MAAM,UAAU,eAAe;AAAA,MAClD,IACA;AAAA,IACN;AAAA,EACF;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc,QAAQ,gBAAgB,YAAY,YAAY;AAAA,IAC9D,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ,eAAe,UAAU,QAAQ,YAAY,IAAI;AAAA,IACzE,cAAc,cACV;AAAA,MACE,IAAI,YAAY;AAAA,MAChB,QAAQ,YAAY;AAAA,MACpB,YAAY,YAAY,aAAa,UAAU,YAAY,UAAU,IAAI;AAAA,MACzE,aAAa,MAAM,YAAY,WAAW;AAAA,IAC5C,IACA;AAAA,IACJ;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|