@dainamite/billing 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +90 -0
- package/dist/modules/billing/acl.js +13 -1
- package/dist/modules/billing/acl.js.map +2 -2
- package/dist/modules/billing/api/accounts/[id]/summary/route.js +52 -0
- package/dist/modules/billing/api/accounts/[id]/summary/route.js.map +7 -0
- package/dist/modules/billing/api/accounts/route.js +46 -4
- package/dist/modules/billing/api/accounts/route.js.map +2 -2
- package/dist/modules/billing/api/export/account/[id]/route.js +11 -7
- package/dist/modules/billing/api/export/account/[id]/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/[id]/memos/route.js +54 -0
- package/dist/modules/billing/api/invoices/[id]/memos/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/[id]/pdf/route.js +69 -0
- package/dist/modules/billing/api/invoices/[id]/pdf/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/[id]/route.js +44 -24
- package/dist/modules/billing/api/invoices/[id]/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/[id]/send/route.js +107 -0
- package/dist/modules/billing/api/invoices/[id]/send/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/add-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/add-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/delete-draft/route.js +33 -0
- package/dist/modules/billing/api/invoices/delete-draft/route.js.map +7 -0
- package/dist/modules/billing/api/invoices/edit-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/edit-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/post/route.js +2 -2
- package/dist/modules/billing/api/invoices/post/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/remove-line/route.js +2 -2
- package/dist/modules/billing/api/invoices/remove-line/route.js.map +2 -2
- package/dist/modules/billing/api/invoices/route.js +45 -46
- package/dist/modules/billing/api/invoices/route.js.map +2 -2
- package/dist/modules/billing/api/items/bulk/route.js +1 -1
- package/dist/modules/billing/api/items/bulk/route.js.map +2 -2
- package/dist/modules/billing/api/items/change-price/route.js +44 -0
- package/dist/modules/billing/api/items/change-price/route.js.map +7 -0
- package/dist/modules/billing/api/items/route.js +19 -7
- package/dist/modules/billing/api/items/route.js.map +2 -2
- package/dist/modules/billing/api/payment-imports/[id]/route.js +49 -0
- package/dist/modules/billing/api/payment-imports/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/payment-imports/route.js +57 -0
- package/dist/modules/billing/api/payment-imports/route.js.map +7 -0
- package/dist/modules/billing/api/payments/[id]/route.js +60 -0
- package/dist/modules/billing/api/payments/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/payments/allocate/route.js +35 -0
- package/dist/modules/billing/api/payments/allocate/route.js.map +7 -0
- package/dist/modules/billing/api/payments/assign/route.js +36 -0
- package/dist/modules/billing/api/payments/assign/route.js.map +7 -0
- package/dist/modules/billing/api/payments/convert-to-topup/route.js +35 -0
- package/dist/modules/billing/api/payments/convert-to-topup/route.js.map +7 -0
- package/dist/modules/billing/api/payments/ignore/route.js +35 -0
- package/dist/modules/billing/api/payments/ignore/route.js.map +7 -0
- package/dist/modules/billing/api/payments/import/route.js +63 -0
- package/dist/modules/billing/api/payments/import/route.js.map +7 -0
- package/dist/modules/billing/api/payments/restore/route.js +35 -0
- package/dist/modules/billing/api/payments/restore/route.js.map +7 -0
- package/dist/modules/billing/api/payments/route.js +114 -0
- package/dist/modules/billing/api/payments/route.js.map +7 -0
- package/dist/modules/billing/api/payments/unallocate/route.js +35 -0
- package/dist/modules/billing/api/payments/unallocate/route.js.map +7 -0
- package/dist/modules/billing/api/payments/unassign/route.js +35 -0
- package/dist/modules/billing/api/payments/unassign/route.js.map +7 -0
- package/dist/modules/billing/api/run-outcomes/route.js +43 -6
- package/dist/modules/billing/api/run-outcomes/route.js.map +2 -2
- package/dist/modules/billing/api/runs/[id]/post-drafts/route.js +61 -0
- package/dist/modules/billing/api/runs/[id]/post-drafts/route.js.map +7 -0
- package/dist/modules/billing/api/runs/[id]/route.js +53 -0
- package/dist/modules/billing/api/runs/[id]/route.js.map +7 -0
- package/dist/modules/billing/api/runs/retry-failed/route.js +1 -1
- package/dist/modules/billing/api/runs/retry-failed/route.js.map +2 -2
- package/dist/modules/billing/api/runs/route.js +9 -3
- package/dist/modules/billing/api/runs/route.js.map +2 -2
- package/dist/modules/billing/api/settings/number-preview/route.js +42 -0
- package/dist/modules/billing/api/settings/number-preview/route.js.map +7 -0
- package/dist/modules/billing/api/settings/route.js +92 -0
- package/dist/modules/billing/api/settings/route.js.map +7 -0
- package/dist/modules/billing/api/statements/route.js +3 -0
- package/dist/modules/billing/api/statements/route.js.map +2 -2
- package/dist/modules/billing/api/test-invoices/wipe/route.js +2 -2
- package/dist/modules/billing/api/test-invoices/wipe/route.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/[id]/page.js +121 -232
- package/dist/modules/billing/backend/billing/accounts/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/create/page.js +6 -0
- package/dist/modules/billing/backend/billing/accounts/create/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/accounts/page.js +63 -4
- package/dist/modules/billing/backend/billing/accounts/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/invoices/[id]/page.js +297 -65
- package/dist/modules/billing/backend/billing/invoices/[id]/page.js.map +3 -3
- package/dist/modules/billing/backend/billing/invoices/page.js +6 -172
- package/dist/modules/billing/backend/billing/invoices/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/[id]/page.js +51 -7
- package/dist/modules/billing/backend/billing/items/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/create/page.js +9 -6
- package/dist/modules/billing/backend/billing/items/create/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/items/page.js +8 -2
- package/dist/modules/billing/backend/billing/items/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/payments/[id]/page.js +297 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js +21 -0
- package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js +74 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js +21 -0
- package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/page.js +58 -0
- package/dist/modules/billing/backend/billing/payments/page.js.map +7 -0
- package/dist/modules/billing/backend/billing/payments/page.meta.js +18 -0
- package/dist/modules/billing/backend/billing/payments/page.meta.js.map +7 -0
- package/dist/modules/billing/backend/billing/runs/[id]/page.js +49 -14
- package/dist/modules/billing/backend/billing/runs/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/runs/page.js +58 -7
- package/dist/modules/billing/backend/billing/runs/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/statements/[id]/page.js +61 -6
- package/dist/modules/billing/backend/billing/statements/[id]/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/statements/page.js +1 -1
- package/dist/modules/billing/backend/billing/statements/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/topups/page.js +1 -1
- package/dist/modules/billing/backend/billing/topups/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/transactions/page.js +1 -1
- package/dist/modules/billing/backend/billing/transactions/page.js.map +2 -2
- package/dist/modules/billing/backend/billing/usage/create/page.js +3 -2
- package/dist/modules/billing/backend/billing/usage/create/page.js.map +2 -2
- package/dist/modules/billing/backend/config/billing/page.js +472 -0
- package/dist/modules/billing/backend/config/billing/page.js.map +7 -0
- package/dist/modules/billing/backend/config/billing/page.meta.js +19 -0
- package/dist/modules/billing/backend/config/billing/page.meta.js.map +7 -0
- package/dist/modules/billing/cli.js +22 -1
- package/dist/modules/billing/cli.js.map +2 -2
- package/dist/modules/billing/commands/accounts.js +6 -0
- package/dist/modules/billing/commands/accounts.js.map +2 -2
- package/dist/modules/billing/commands/index.js +3 -0
- package/dist/modules/billing/commands/index.js.map +2 -2
- package/dist/modules/billing/commands/invoices.js +269 -167
- package/dist/modules/billing/commands/invoices.js.map +2 -2
- package/dist/modules/billing/commands/items.js +108 -0
- package/dist/modules/billing/commands/items.js.map +2 -2
- package/dist/modules/billing/commands/memos.js +179 -0
- package/dist/modules/billing/commands/memos.js.map +7 -0
- package/dist/modules/billing/commands/payments.js +379 -0
- package/dist/modules/billing/commands/payments.js.map +7 -0
- package/dist/modules/billing/commands/runs.js +151 -4
- package/dist/modules/billing/commands/runs.js.map +2 -2
- package/dist/modules/billing/commands/settings.js +59 -0
- package/dist/modules/billing/commands/settings.js.map +7 -0
- package/dist/modules/billing/commands/topups.js +9 -2
- package/dist/modules/billing/commands/topups.js.map +2 -2
- package/dist/modules/billing/commands/transactions.js +2 -2
- package/dist/modules/billing/commands/transactions.js.map +2 -2
- package/dist/modules/billing/components/AccountForm.js +149 -42
- package/dist/modules/billing/components/AccountForm.js.map +2 -2
- package/dist/modules/billing/components/AccountInvoicesSection.js +64 -0
- package/dist/modules/billing/components/AccountInvoicesSection.js.map +7 -0
- package/dist/modules/billing/components/AccountPaymentsSection.js +43 -0
- package/dist/modules/billing/components/AccountPaymentsSection.js.map +7 -0
- package/dist/modules/billing/components/AccountPicker.js +56 -0
- package/dist/modules/billing/components/AccountPicker.js.map +7 -0
- package/dist/modules/billing/components/AllocatePaymentDialog.js +134 -0
- package/dist/modules/billing/components/AllocatePaymentDialog.js.map +7 -0
- package/dist/modules/billing/components/BillingDataTable.js +21 -0
- package/dist/modules/billing/components/BillingDataTable.js.map +7 -0
- package/dist/modules/billing/components/BillingSettingsLink.js +19 -0
- package/dist/modules/billing/components/BillingSettingsLink.js.map +7 -0
- package/dist/modules/billing/components/ChangeItemPriceDialog.js +158 -0
- package/dist/modules/billing/components/ChangeItemPriceDialog.js.map +7 -0
- package/dist/modules/billing/components/CreateMemoDialog.js +200 -0
- package/dist/modules/billing/components/CreateMemoDialog.js.map +7 -0
- package/dist/modules/billing/components/CustomerLabel.js +33 -0
- package/dist/modules/billing/components/CustomerLabel.js.map +7 -0
- package/dist/modules/billing/components/InvoicesTable.js +270 -0
- package/dist/modules/billing/components/InvoicesTable.js.map +7 -0
- package/dist/modules/billing/components/ItemForm.js +176 -44
- package/dist/modules/billing/components/ItemForm.js.map +2 -2
- package/dist/modules/billing/components/ItemPriceField.js +46 -0
- package/dist/modules/billing/components/ItemPriceField.js.map +7 -0
- package/dist/modules/billing/components/LineFormDialog.js +25 -2
- package/dist/modules/billing/components/LineFormDialog.js.map +2 -2
- package/dist/modules/billing/components/ManualPaymentDialog.js +122 -0
- package/dist/modules/billing/components/ManualPaymentDialog.js.map +7 -0
- package/dist/modules/billing/components/MoneyInput.js +14 -0
- package/dist/modules/billing/components/MoneyInput.js.map +7 -0
- package/dist/modules/billing/components/PaymentUploadDialog.js +115 -0
- package/dist/modules/billing/components/PaymentUploadDialog.js.map +7 -0
- package/dist/modules/billing/components/PaymentsTable.js +171 -0
- package/dist/modules/billing/components/PaymentsTable.js.map +7 -0
- package/dist/modules/billing/components/PostRunDraftsButton.js +105 -0
- package/dist/modules/billing/components/PostRunDraftsButton.js.map +7 -0
- package/dist/modules/billing/components/PrepaidPanel.js +14 -4
- package/dist/modules/billing/components/PrepaidPanel.js.map +2 -2
- package/dist/modules/billing/components/RunCyclesSection.js +209 -0
- package/dist/modules/billing/components/RunCyclesSection.js.map +7 -0
- package/dist/modules/billing/components/TestRunActions.js +127 -0
- package/dist/modules/billing/components/TestRunActions.js.map +7 -0
- package/dist/modules/billing/components/account/AccountItemsTab.js +157 -0
- package/dist/modules/billing/components/account/AccountItemsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountRunBillingDialog.js +122 -0
- package/dist/modules/billing/components/account/AccountRunBillingDialog.js.map +7 -0
- package/dist/modules/billing/components/account/AccountRunsTab.js +152 -0
- package/dist/modules/billing/components/account/AccountRunsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountStatementsTab.js +98 -0
- package/dist/modules/billing/components/account/AccountStatementsTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountSummaryCards.js +125 -0
- package/dist/modules/billing/components/account/AccountSummaryCards.js.map +7 -0
- package/dist/modules/billing/components/account/AccountUsageTab.js +91 -0
- package/dist/modules/billing/components/account/AccountUsageTab.js.map +7 -0
- package/dist/modules/billing/components/account/AccountView.js +73 -0
- package/dist/modules/billing/components/account/AccountView.js.map +7 -0
- package/dist/modules/billing/components/account/accountRow.js +39 -0
- package/dist/modules/billing/components/account/accountRow.js.map +7 -0
- package/dist/modules/billing/components/customerNames.js +42 -0
- package/dist/modules/billing/components/customerNames.js.map +7 -0
- package/dist/modules/billing/data/entities.js +560 -4
- package/dist/modules/billing/data/entities.js.map +2 -2
- package/dist/modules/billing/data/entityIds.js +10 -1
- package/dist/modules/billing/data/entityIds.js.map +2 -2
- package/dist/modules/billing/data/validators.js +269 -15
- package/dist/modules/billing/data/validators.js.map +2 -2
- package/dist/modules/billing/events.js +50 -0
- package/dist/modules/billing/events.js.map +2 -2
- package/dist/modules/billing/i18n/en.json +457 -21
- package/dist/modules/billing/i18n/pl.json +457 -21
- package/dist/modules/billing/index.js +6 -2
- package/dist/modules/billing/index.js.map +2 -2
- package/dist/modules/billing/lib/accountFinancials.js +58 -0
- package/dist/modules/billing/lib/accountFinancials.js.map +7 -0
- package/dist/modules/billing/lib/accountLock.js +14 -0
- package/dist/modules/billing/lib/accountLock.js.map +7 -0
- package/dist/modules/billing/lib/accountStatus.js +9 -7
- package/dist/modules/billing/lib/accountStatus.js.map +2 -2
- package/dist/modules/billing/lib/accountSummary.js +106 -0
- package/dist/modules/billing/lib/accountSummary.js.map +7 -0
- package/dist/modules/billing/lib/allocation.js +356 -0
- package/dist/modules/billing/lib/allocation.js.map +7 -0
- package/dist/modules/billing/lib/allocationEvents.js +22 -0
- package/dist/modules/billing/lib/allocationEvents.js.map +7 -0
- package/dist/modules/billing/lib/billPeriod.js +15 -1
- package/dist/modules/billing/lib/billPeriod.js.map +2 -2
- package/dist/modules/billing/lib/billRunEngine.js +237 -102
- package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
- package/dist/modules/billing/lib/billingSettings.js +116 -0
- package/dist/modules/billing/lib/billingSettings.js.map +7 -0
- package/dist/modules/billing/lib/commandRoute.js +81 -0
- package/dist/modules/billing/lib/commandRoute.js.map +7 -0
- package/dist/modules/billing/lib/customerLookup.js +97 -0
- package/dist/modules/billing/lib/customerLookup.js.map +7 -0
- package/dist/modules/billing/lib/dateOnly.js +13 -0
- package/dist/modules/billing/lib/dateOnly.js.map +7 -0
- package/dist/modules/billing/lib/documentParties.js +16 -0
- package/dist/modules/billing/lib/documentParties.js.map +7 -0
- package/dist/modules/billing/lib/documentTypes.js +27 -0
- package/dist/modules/billing/lib/documentTypes.js.map +7 -0
- package/dist/modules/billing/lib/dueDate.js +18 -0
- package/dist/modules/billing/lib/dueDate.js.map +7 -0
- package/dist/modules/billing/lib/iban.js +29 -0
- package/dist/modules/billing/lib/iban.js.map +7 -0
- package/dist/modules/billing/lib/invoiceDelivery.js +131 -0
- package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
- package/dist/modules/billing/lib/invoiceLanguages.js +16 -0
- package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
- package/dist/modules/billing/lib/invoiceWriter.js +107 -99
- package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
- package/dist/modules/billing/lib/itemBillingState.js +27 -0
- package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
- package/dist/modules/billing/lib/itemPriceChange.js +18 -0
- package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
- package/dist/modules/billing/lib/itemSelector.js.map +2 -2
- package/dist/modules/billing/lib/lineAmounts.js +32 -0
- package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
- package/dist/modules/billing/lib/memoGuards.js +25 -0
- package/dist/modules/billing/lib/memoGuards.js.map +7 -0
- package/dist/modules/billing/lib/navigation.js +48 -0
- package/dist/modules/billing/lib/navigation.js.map +7 -0
- package/dist/modules/billing/lib/numbering.js +120 -0
- package/dist/modules/billing/lib/numbering.js.map +7 -0
- package/dist/modules/billing/lib/overdue.js +36 -0
- package/dist/modules/billing/lib/overdue.js.map +7 -0
- package/dist/modules/billing/lib/paymentCsv.js +125 -0
- package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
- package/dist/modules/billing/lib/paymentGateway.js +15 -0
- package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
- package/dist/modules/billing/lib/paymentImport.js +164 -0
- package/dist/modules/billing/lib/paymentImport.js.map +7 -0
- package/dist/modules/billing/lib/paymentMatcher.js +36 -0
- package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
- package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
- package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
- package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
- package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
- package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
- package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
- package/dist/modules/billing/lib/pdf/invoiceTemplate.js +274 -0
- package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
- package/dist/modules/billing/lib/prepaidConfig.js +17 -25
- package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
- package/dist/modules/billing/lib/prepaidConsume.js +26 -7
- package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
- package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
- package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
- package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
- package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
- package/dist/modules/billing/lib/seeds/demo.js +51 -3
- package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
- package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
- package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
- package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
- package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
- package/dist/modules/billing/lib/servicePeriods.js +121 -0
- package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
- package/dist/modules/billing/lib/testRunCleanup.js +24 -0
- package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
- package/dist/modules/billing/lib/topupCapture.js +2 -2
- package/dist/modules/billing/lib/topupCapture.js.map +2 -2
- package/dist/modules/billing/lib/topupReceipt.js +58 -79
- package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
- package/dist/modules/billing/lib/usageRater.js.map +1 -1
- package/dist/modules/billing/lib/usageRunner.js +14 -6
- package/dist/modules/billing/lib/usageRunner.js.map +2 -2
- package/dist/modules/billing/lib/vat.js +39 -0
- package/dist/modules/billing/lib/vat.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
- package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
- package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
- package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
- package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
- package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
- package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
- package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
- package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
- package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
- package/dist/modules/billing/setup.js +7 -184
- package/dist/modules/billing/setup.js.map +2 -2
- package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
- package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
- package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
- package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
- package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
- package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
- package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
- package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
- package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
- package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
- package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
- package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
- package/generated/entities/billing_account/index.ts +3 -0
- package/generated/entities/billing_allocation/index.ts +18 -0
- package/generated/entities/billing_document_sequence/index.ts +11 -0
- package/generated/entities/billing_invoice/index.ts +38 -0
- package/generated/entities/billing_invoice_line/index.ts +24 -0
- package/generated/entities/billing_item/index.ts +4 -0
- package/generated/entities/billing_payment/index.ts +25 -0
- package/generated/entities/billing_payment_import/index.ts +14 -0
- package/generated/entities/billing_run/index.ts +0 -1
- package/generated/entities/billing_run_outcome/index.ts +1 -0
- package/generated/entities/billing_settings/index.ts +26 -0
- package/generated/entities/billing_statement/index.ts +1 -0
- package/generated/entities.ids.generated.ts +7 -0
- package/package.json +5 -1
- package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +170 -0
- package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
- package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
- package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
- package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
- package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
- package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
- package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
- package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
- package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
- package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
- package/src/modules/billing/__tests__/commands/invoices.test.ts +436 -354
- package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
- package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
- package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
- package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
- package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
- package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
- package/src/modules/billing/__tests__/entityRegistry.test.ts +8 -1
- package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
- package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
- package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
- package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
- package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +228 -17
- package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
- package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
- package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
- package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
- package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +189 -0
- package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
- package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
- package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
- package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
- package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
- package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
- package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
- package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
- package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
- package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
- package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +199 -0
- package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
- package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
- package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
- package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
- package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
- package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
- package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
- package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
- package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
- package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
- package/src/modules/billing/__tests__/setup.test.ts +13 -4
- package/src/modules/billing/__tests__/validators.test.ts +193 -3
- package/src/modules/billing/acl.ts +12 -0
- package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
- package/src/modules/billing/api/accounts/route.ts +58 -4
- package/src/modules/billing/api/export/account/[id]/route.ts +13 -11
- package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
- package/src/modules/billing/api/invoices/[id]/pdf/route.ts +79 -0
- package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
- package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
- package/src/modules/billing/api/invoices/add-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
- package/src/modules/billing/api/invoices/edit-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/post/route.ts +7 -6
- package/src/modules/billing/api/invoices/remove-line/route.ts +2 -2
- package/src/modules/billing/api/invoices/route.ts +81 -86
- package/src/modules/billing/api/items/bulk/route.ts +2 -1
- package/src/modules/billing/api/items/change-price/route.ts +54 -0
- package/src/modules/billing/api/items/route.ts +23 -7
- package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
- package/src/modules/billing/api/payment-imports/route.ts +57 -0
- package/src/modules/billing/api/payments/[id]/route.ts +63 -0
- package/src/modules/billing/api/payments/allocate/route.ts +35 -0
- package/src/modules/billing/api/payments/assign/route.ts +36 -0
- package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
- package/src/modules/billing/api/payments/ignore/route.ts +35 -0
- package/src/modules/billing/api/payments/import/route.ts +72 -0
- package/src/modules/billing/api/payments/restore/route.ts +35 -0
- package/src/modules/billing/api/payments/route.ts +147 -0
- package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
- package/src/modules/billing/api/payments/unassign/route.ts +35 -0
- package/src/modules/billing/api/run-outcomes/route.ts +49 -6
- package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
- package/src/modules/billing/api/runs/[id]/route.ts +59 -0
- package/src/modules/billing/api/runs/retry-failed/route.ts +2 -1
- package/src/modules/billing/api/runs/route.ts +15 -7
- package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
- package/src/modules/billing/api/settings/route.ts +116 -0
- package/src/modules/billing/api/statements/route.ts +5 -0
- package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
- package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
- package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
- package/src/modules/billing/backend/billing/accounts/page.tsx +70 -4
- package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +444 -95
- package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
- package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
- package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
- package/src/modules/billing/backend/billing/items/page.tsx +18 -2
- package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
- package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
- package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
- package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
- package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
- package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
- package/src/modules/billing/backend/billing/runs/[id]/page.tsx +49 -18
- package/src/modules/billing/backend/billing/runs/page.tsx +59 -8
- package/src/modules/billing/backend/billing/statements/[id]/page.tsx +86 -5
- package/src/modules/billing/backend/billing/statements/page.tsx +1 -1
- package/src/modules/billing/backend/billing/topups/page.tsx +1 -1
- package/src/modules/billing/backend/billing/transactions/page.tsx +1 -1
- package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
- package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
- package/src/modules/billing/backend/config/billing/page.tsx +549 -0
- package/src/modules/billing/cli.ts +31 -1
- package/src/modules/billing/commands/accounts.ts +6 -0
- package/src/modules/billing/commands/index.ts +3 -0
- package/src/modules/billing/commands/invoices.ts +364 -231
- package/src/modules/billing/commands/items.ts +143 -0
- package/src/modules/billing/commands/memos.ts +218 -0
- package/src/modules/billing/commands/payments.ts +428 -0
- package/src/modules/billing/commands/runs.ts +205 -3
- package/src/modules/billing/commands/settings.ts +77 -0
- package/src/modules/billing/commands/topups.ts +12 -3
- package/src/modules/billing/commands/transactions.ts +2 -2
- package/src/modules/billing/components/AccountForm.tsx +199 -53
- package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
- package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
- package/src/modules/billing/components/AccountPicker.tsx +70 -0
- package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
- package/src/modules/billing/components/BillingDataTable.tsx +34 -0
- package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
- package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
- package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
- package/src/modules/billing/components/CustomerLabel.tsx +53 -0
- package/src/modules/billing/components/InvoicesTable.tsx +344 -0
- package/src/modules/billing/components/ItemForm.tsx +233 -44
- package/src/modules/billing/components/ItemPriceField.tsx +81 -0
- package/src/modules/billing/components/LineFormDialog.tsx +25 -1
- package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
- package/src/modules/billing/components/MoneyInput.tsx +26 -0
- package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
- package/src/modules/billing/components/PaymentsTable.tsx +213 -0
- package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
- package/src/modules/billing/components/PrepaidPanel.tsx +19 -6
- package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
- package/src/modules/billing/components/TestRunActions.tsx +152 -0
- package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
- package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
- package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
- package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
- package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
- package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
- package/src/modules/billing/components/account/AccountView.tsx +101 -0
- package/src/modules/billing/components/account/accountRow.ts +70 -0
- package/src/modules/billing/components/customerNames.ts +62 -0
- package/src/modules/billing/data/entities.ts +654 -5
- package/src/modules/billing/data/entityIds.ts +9 -0
- package/src/modules/billing/data/validators.ts +388 -8
- package/src/modules/billing/events.ts +56 -3
- package/src/modules/billing/i18n/en.json +457 -21
- package/src/modules/billing/i18n/pl.json +457 -21
- package/src/modules/billing/index.ts +6 -2
- package/src/modules/billing/lib/accountFinancials.ts +84 -0
- package/src/modules/billing/lib/accountLock.ts +32 -0
- package/src/modules/billing/lib/accountStatus.ts +11 -9
- package/src/modules/billing/lib/accountSummary.ts +172 -0
- package/src/modules/billing/lib/allocation.ts +515 -0
- package/src/modules/billing/lib/allocationEvents.ts +26 -0
- package/src/modules/billing/lib/billPeriod.ts +19 -0
- package/src/modules/billing/lib/billRunEngine.ts +350 -150
- package/src/modules/billing/lib/billingSettings.ts +145 -0
- package/src/modules/billing/lib/commandRoute.ts +112 -0
- package/src/modules/billing/lib/customerLookup.ts +157 -0
- package/src/modules/billing/lib/dateOnly.ts +22 -0
- package/src/modules/billing/lib/documentParties.ts +23 -0
- package/src/modules/billing/lib/documentTypes.ts +37 -0
- package/src/modules/billing/lib/dueDate.ts +26 -0
- package/src/modules/billing/lib/iban.ts +36 -0
- package/src/modules/billing/lib/invoiceDelivery.ts +197 -0
- package/src/modules/billing/lib/invoiceLanguages.ts +34 -0
- package/src/modules/billing/lib/invoiceWriter.ts +162 -148
- package/src/modules/billing/lib/itemBillingState.ts +67 -0
- package/src/modules/billing/lib/itemPriceChange.ts +56 -0
- package/src/modules/billing/lib/itemSelector.ts +4 -1
- package/src/modules/billing/lib/lineAmounts.ts +61 -0
- package/src/modules/billing/lib/memoGuards.ts +41 -0
- package/src/modules/billing/lib/navigation.ts +64 -0
- package/src/modules/billing/lib/numbering.ts +174 -0
- package/src/modules/billing/lib/overdue.ts +60 -0
- package/src/modules/billing/lib/paymentCsv.ts +171 -0
- package/src/modules/billing/lib/paymentGateway.ts +52 -0
- package/src/modules/billing/lib/paymentImport.ts +228 -0
- package/src/modules/billing/lib/paymentMatcher.ts +88 -0
- package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
- package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
- package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
- package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
- package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
- package/src/modules/billing/lib/pdf/invoiceModel.ts +328 -0
- package/src/modules/billing/lib/pdf/invoicePdf.ts +216 -0
- package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
- package/src/modules/billing/lib/prepaidConfig.ts +27 -36
- package/src/modules/billing/lib/prepaidConsume.ts +29 -6
- package/src/modules/billing/lib/prepaidPeriodClose.ts +407 -239
- package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
- package/src/modules/billing/lib/seeds/demo.ts +79 -6
- package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
- package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
- package/src/modules/billing/lib/servicePeriods.ts +226 -0
- package/src/modules/billing/lib/testRunCleanup.ts +42 -0
- package/src/modules/billing/lib/topupCapture.ts +3 -4
- package/src/modules/billing/lib/topupReceipt.ts +70 -103
- package/src/modules/billing/lib/usageRater.ts +1 -1
- package/src/modules/billing/lib/usageRunner.ts +17 -5
- package/src/modules/billing/lib/vat.ts +56 -0
- package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
- package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
- package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
- package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
- package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
- package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
- package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
- package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
- package/src/modules/billing/setup.ts +11 -237
- package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
- package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
- package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
- package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
- package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
- package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
- package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
- package/dist/modules/billing/lib/invoiceStatus.js +0 -38
- package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
- package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
- package/src/modules/billing/lib/invoiceStatus.ts +0 -61
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/billing/api/payment-imports/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport {\n organizationScopeRequiredResponse,\n resolveActiveOrganizationId,\n} from '@open-mercato/shared/lib/auth/organizationScope'\nimport { buildQueryParams } from '@open-mercato/shared/lib/crud/query-params'\nimport { billingPaymentImportListQuerySchema } from '../../data/validators'\n\n/** `GET /api/billing/payment-imports` \u2014 CSV upload batches, newest first (Spec C, C-D4). */\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.payment.view'] },\n}\n\nexport async function GET(req: Request) {\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.tenantId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const organizationId = resolveActiveOrganizationId(auth)\n if (!organizationId) return organizationScopeRequiredResponse()\n const query = billingPaymentImportListQuerySchema.parse(buildQueryParams(new URL(req.url).searchParams))\n const em = (container.resolve('em') as EntityManager).fork()\n const where = ['tenant_id = ?', 'organization_id = ?', 'deleted_at IS NULL']\n const params: unknown[] = [auth.tenantId, organizationId]\n if (query.id) {\n where.push('id = ?')\n params.push(query.id)\n }\n const totalRows = (await em.execute(`SELECT COUNT(*)::int AS total FROM billing_payment_imports WHERE ${where.join(' AND ')}`, params)) as unknown as Array<{ total: number }>\n const total = totalRows?.[0]?.total ?? 0\n const items = await em.execute(\n `SELECT id, file_name, row_count, counts, user_id, created_at\n FROM billing_payment_imports WHERE ${where.join(' AND ')}\n ORDER BY created_at DESC LIMIT ? OFFSET ?`,\n [...params, query.pageSize, (query.page - 1) * query.pageSize],\n )\n return NextResponse.json({ items, total, page: query.page, pageSize: query.pageSize, totalPages: total === 0 ? 1 : Math.ceil(total / query.pageSize) })\n } catch (err) {\n console.error('[billing/payment-imports.GET]', err)\n return NextResponse.json({ error: 'Internal error' }, { status: 500 })\n }\n}\n\nexport const openApi = {\n methods: {\n GET: {\n tags: ['Billing'],\n summary: 'List payment import batches',\n description: 'CSV uploads with counts per outcome (allocated, partially_allocated, matched, unmatched, duplicate, rejected).',\n query: billingPaymentImportListQuerySchema,\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB;AAE7B,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC,SAAS,2CAA2C;AAI7C,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,sBAAsB,EAAE;AACtE;AAEA,eAAsB,IAAI,KAAc;AACtC,MAAI;AACF,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,QAAI,CAAC,QAAQ,CAAC,KAAK,SAAU,QAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAChG,UAAM,iBAAiB,4BAA4B,IAAI;AACvD,QAAI,CAAC,eAAgB,QAAO,kCAAkC;AAC9D,UAAM,QAAQ,oCAAoC,MAAM,iBAAiB,IAAI,IAAI,IAAI,GAAG,EAAE,YAAY,CAAC;AACvG,UAAM,KAAM,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC3D,UAAM,QAAQ,CAAC,iBAAiB,uBAAuB,oBAAoB;AAC3E,UAAM,SAAoB,CAAC,KAAK,UAAU,cAAc;AACxD,QAAI,MAAM,IAAI;AACZ,YAAM,KAAK,QAAQ;AACnB,aAAO,KAAK,MAAM,EAAE;AAAA,IACtB;AACA,UAAM,YAAa,MAAM,GAAG,QAAQ,oEAAoE,MAAM,KAAK,OAAO,CAAC,IAAI,MAAM;AACrI,UAAM,QAAQ,YAAY,CAAC,GAAG,SAAS;AACvC,UAAM,QAAQ,MAAM,GAAG;AAAA,MACrB;AAAA,8CACwC,MAAM,KAAK,OAAO,CAAC;AAAA;AAAA,MAE3D,CAAC,GAAG,QAAQ,MAAM,WAAW,MAAM,OAAO,KAAK,MAAM,QAAQ;AAAA,IAC/D;AACA,WAAO,aAAa,KAAK,EAAE,OAAO,OAAO,MAAM,MAAM,MAAM,UAAU,MAAM,UAAU,YAAY,UAAU,IAAI,IAAI,KAAK,KAAK,QAAQ,MAAM,QAAQ,EAAE,CAAC;AAAA,EACxJ,SAAS,KAAK;AACZ,YAAQ,MAAM,iCAAiC,GAAG;AAClD,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvE;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,KAAK;AAAA,MACH,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
3
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
4
|
+
import {
|
|
5
|
+
organizationScopeRequiredResponse,
|
|
6
|
+
resolveActiveOrganizationId
|
|
7
|
+
} from "@open-mercato/shared/lib/auth/organizationScope";
|
|
8
|
+
const metadata = {
|
|
9
|
+
GET: { requireAuth: true, requireFeatures: ["billing.payment.view"] }
|
|
10
|
+
};
|
|
11
|
+
async function GET(req, { params }) {
|
|
12
|
+
try {
|
|
13
|
+
const container = await createRequestContainer();
|
|
14
|
+
const auth = await getAuthFromRequest(req);
|
|
15
|
+
if (!auth || !auth.tenantId) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
16
|
+
const organizationId = resolveActiveOrganizationId(auth);
|
|
17
|
+
if (!organizationId) return organizationScopeRequiredResponse();
|
|
18
|
+
const { id } = await params;
|
|
19
|
+
const em = container.resolve("em").fork();
|
|
20
|
+
const rows = await em.execute(
|
|
21
|
+
`SELECT p.*, a.name AS bill_account_name, a.billing_mode AS bill_account_mode
|
|
22
|
+
FROM billing_payments p
|
|
23
|
+
LEFT JOIN billing_accounts a ON a.id = p.bill_account_id AND a.tenant_id = p.tenant_id
|
|
24
|
+
WHERE p.id = ? AND p.tenant_id = ? AND p.organization_id = ? AND p.deleted_at IS NULL`,
|
|
25
|
+
[id, auth.tenantId, organizationId]
|
|
26
|
+
);
|
|
27
|
+
if (!rows?.length) return NextResponse.json({ error: "Payment not found" }, { status: 404 });
|
|
28
|
+
const allocations = await em.execute(
|
|
29
|
+
`SELECT al.id, al.invoice_id, i.number AS invoice_number, i.document_type, i.status AS invoice_status,
|
|
30
|
+
al.amount, al.currency_code, al.allocated_by, al.user_id, al.created_at
|
|
31
|
+
FROM billing_allocations al
|
|
32
|
+
LEFT JOIN billing_invoices i ON i.id = al.invoice_id
|
|
33
|
+
WHERE al.source_type = 'payment' AND al.source_id = ? AND al.tenant_id = ? AND al.organization_id = ?
|
|
34
|
+
AND al.deleted_at IS NULL
|
|
35
|
+
ORDER BY al.created_at ASC`,
|
|
36
|
+
[id, auth.tenantId, organizationId]
|
|
37
|
+
);
|
|
38
|
+
return NextResponse.json({ payment: rows[0], allocations });
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error("[billing/payments/[id].GET]", err);
|
|
41
|
+
return NextResponse.json({ error: "Internal error" }, { status: 500 });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const openApi = {
|
|
45
|
+
methods: {
|
|
46
|
+
GET: {
|
|
47
|
+
tags: ["Billing"],
|
|
48
|
+
summary: "Get a billing payment",
|
|
49
|
+
description: "The payment (incl. match reason, account, top-up link) and its active allocations.",
|
|
50
|
+
responses: [{ status: 200, description: "`{ payment, allocations[] }`" }],
|
|
51
|
+
errors: [{ status: 404, description: "Payment not found in this organization" }]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
GET,
|
|
57
|
+
metadata,
|
|
58
|
+
openApi
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/payments/%5Bid%5D/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport {\n organizationScopeRequiredResponse,\n resolveActiveOrganizationId,\n} from '@open-mercato/shared/lib/auth/organizationScope'\n\n/**\n * `GET /api/billing/payments/[id]` \u2014 one payment with its active\n * allocations (invoice number, amount, who / how allocated) \u2014 Spec C.\n */\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.payment.view'] },\n}\n\nexport async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) {\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.tenantId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const organizationId = resolveActiveOrganizationId(auth)\n if (!organizationId) return organizationScopeRequiredResponse()\n const { id } = await params\n const em = (container.resolve('em') as EntityManager).fork()\n const rows = (await em.execute(\n `SELECT p.*, a.name AS bill_account_name, a.billing_mode AS bill_account_mode\n FROM billing_payments p\n LEFT JOIN billing_accounts a ON a.id = p.bill_account_id AND a.tenant_id = p.tenant_id\n WHERE p.id = ? AND p.tenant_id = ? AND p.organization_id = ? AND p.deleted_at IS NULL`,\n [id, auth.tenantId, organizationId],\n )) as unknown as Array<Record<string, unknown>>\n if (!rows?.length) return NextResponse.json({ error: 'Payment not found' }, { status: 404 })\n const allocations = await em.execute(\n `SELECT al.id, al.invoice_id, i.number AS invoice_number, i.document_type, i.status AS invoice_status,\n al.amount, al.currency_code, al.allocated_by, al.user_id, al.created_at\n FROM billing_allocations al\n LEFT JOIN billing_invoices i ON i.id = al.invoice_id\n WHERE al.source_type = 'payment' AND al.source_id = ? AND al.tenant_id = ? AND al.organization_id = ?\n AND al.deleted_at IS NULL\n ORDER BY al.created_at ASC`,\n [id, auth.tenantId, organizationId],\n )\n return NextResponse.json({ payment: rows[0], allocations })\n } catch (err) {\n console.error('[billing/payments/[id].GET]', err)\n return NextResponse.json({ error: 'Internal error' }, { status: 500 })\n }\n}\n\nexport const openApi = {\n methods: {\n GET: {\n tags: ['Billing'],\n summary: 'Get a billing payment',\n description: 'The payment (incl. match reason, account, top-up link) and its active allocations.',\n responses: [{ status: 200, description: '`{ payment, allocations[] }`' }],\n errors: [{ status: 404, description: 'Payment not found in this organization' }],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB;AAE7B,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAOA,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,sBAAsB,EAAE;AACtE;AAEA,eAAsB,IAAI,KAAc,EAAE,OAAO,GAAwC;AACvF,MAAI;AACF,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,QAAI,CAAC,QAAQ,CAAC,KAAK,SAAU,QAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAChG,UAAM,iBAAiB,4BAA4B,IAAI;AACvD,QAAI,CAAC,eAAgB,QAAO,kCAAkC;AAC9D,UAAM,EAAE,GAAG,IAAI,MAAM;AACrB,UAAM,KAAM,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC3D,UAAM,OAAQ,MAAM,GAAG;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAIA,CAAC,IAAI,KAAK,UAAU,cAAc;AAAA,IACpC;AACA,QAAI,CAAC,MAAM,OAAQ,QAAO,aAAa,KAAK,EAAE,OAAO,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAC3F,UAAM,cAAc,MAAM,GAAG;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,CAAC,IAAI,KAAK,UAAU,cAAc;AAAA,IACpC;AACA,WAAO,aAAa,KAAK,EAAE,SAAS,KAAK,CAAC,GAAG,YAAY,CAAC;AAAA,EAC5D,SAAS,KAAK;AACZ,YAAQ,MAAM,+BAA+B,GAAG;AAChD,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvE;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,KAAK;AAAA,MACH,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,+BAA+B,CAAC;AAAA,MACxE,QAAQ,CAAC,EAAE,QAAQ,KAAK,aAAa,yCAAyC,CAAC;AAAA,IACjF;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(), allocations: z.array(z.object({ invoiceId: z.string().uuid(), amount: z.coerce.number().positive() })).min(1).max(100) });
|
|
7
|
+
async function POST(req) {
|
|
8
|
+
return runCommandRoute(req, {
|
|
9
|
+
commandId: "billing.payments.allocate",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.paymentId,
|
|
13
|
+
logLabel: "billing/payments/allocate.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Allocate a payment to invoices",
|
|
21
|
+
description: "Allocates amounts of a payment to open invoices / debit memos of its account. Invoice paid / outstanding / status are recomputed from allocations.",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 409, description: "`billing.allocation.exceeds_outstanding` / `insufficient_unallocated` / `account_mismatch` / `currency_mismatch` / `invoice_not_open`" }
|
|
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/allocate/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/allocate` \u2014 allocate a payment to invoices (Spec C). */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.payment.manage'] },\n}\n\nconst bodySchema = z.object({ paymentId: z.string().uuid(), allocations: z.array(z.object({ invoiceId: z.string().uuid(), amount: z.coerce.number().positive() })).min(1).max(100) })\n\nexport async function POST(req: Request) {\n return runCommandRoute(req, {\n commandId: 'billing.payments.allocate',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.paymentId,\n logLabel: 'billing/payments/allocate.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Allocate a payment to invoices',\n description: 'Allocates amounts of a payment to open invoices / debit memos of its account. Invoice paid / outstanding / status are recomputed from allocations.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 409, description: '`billing.allocation.exceeds_outstanding` / `insufficient_unallocated` / `account_mismatch` / `currency_mismatch` / `invoice_not_open`' },\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,GAAG,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,GAAG,QAAQ,EAAE,OAAO,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC;AAEpL,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,wIAAwI;AAAA,MACtK;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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(), billAccountId: z.string().uuid() });
|
|
7
|
+
async function POST(req) {
|
|
8
|
+
return runCommandRoute(req, {
|
|
9
|
+
commandId: "billing.payments.assign",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.paymentId,
|
|
13
|
+
logLabel: "billing/payments/assign.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Assign a payment to a billing account",
|
|
21
|
+
description: "Assigns an unmatched payment to a postpaid account (status \u2192 matched) and applies it as credit to the account's open invoices, oldest due first.",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 404, description: "Payment or account not found" },
|
|
26
|
+
{ status: 409, description: "`billing.payment.not_unmatched` / `prepaid_account` / `currency_mismatch`" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
POST,
|
|
33
|
+
metadata,
|
|
34
|
+
openApi
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/payments/assign/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/assign` \u2014 assign a payment to a billing account (Spec C). */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.payment.manage'] },\n}\n\nconst bodySchema = z.object({ paymentId: z.string().uuid(), billAccountId: z.string().uuid() })\n\nexport async function POST(req: Request) {\n return runCommandRoute(req, {\n commandId: 'billing.payments.assign',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.paymentId,\n logLabel: 'billing/payments/assign.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Assign a payment to a billing account',\n description: 'Assigns an unmatched payment to a postpaid account (status \u2192 matched) and applies it as credit to the account\\'s open invoices, oldest due first.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 404, description: 'Payment or account not found' },\n { status: 409, description: '`billing.payment.not_unmatched` / `prepaid_account` / `currency_mismatch`' },\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,GAAG,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE9F,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,+BAA+B;AAAA,QAC3D,EAAE,QAAQ,KAAK,aAAa,4EAA4E;AAAA,MAC1G;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", "billing.topup.create"] }
|
|
5
|
+
};
|
|
6
|
+
const bodySchema = z.object({ paymentId: z.string().uuid(), billAccountId: z.string().uuid() });
|
|
7
|
+
async function POST(req) {
|
|
8
|
+
return runCommandRoute(req, {
|
|
9
|
+
commandId: "billing.payments.convert_to_topup",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.paymentId,
|
|
13
|
+
logLabel: "billing/payments/convert-to-topup.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Convert a payment into a prepaid top-up",
|
|
21
|
+
description: "Turns an unmatched payment into a captured top-up of a prepaid account (balance credit, transaction and VAT receipt). Terminal; idempotent per payment.",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 409, description: "`billing.payment.not_prepaid` / `currency_mismatch` / `not_convertible`" }
|
|
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/convert-to-topup/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/convert-to-topup` \u2014 convert a payment into a prepaid top-up (Spec C). */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.payment.manage', 'billing.topup.create'] },\n}\n\nconst bodySchema = z.object({ paymentId: z.string().uuid(), billAccountId: z.string().uuid() })\n\nexport async function POST(req: Request) {\n return runCommandRoute(req, {\n commandId: 'billing.payments.convert_to_topup',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.paymentId,\n logLabel: 'billing/payments/convert-to-topup.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Convert a payment into a prepaid top-up',\n description: 'Turns an unmatched payment into a captured top-up of a prepaid account (balance credit, transaction and VAT receipt). Terminal; idempotent per payment.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 409, description: '`billing.payment.not_prepaid` / `currency_mismatch` / `not_convertible`' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,uBAAuB;AAIzB,MAAM,WAAW;AAAA,EACtB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,0BAA0B,sBAAsB,EAAE;AACjG;AAEA,MAAM,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,GAAG,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE9F,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,0EAA0E;AAAA,MACxG;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.ignore",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.paymentId,
|
|
13
|
+
logLabel: "billing/payments/ignore.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Ignore a payment",
|
|
21
|
+
description: "Excludes an unallocated payment from matching and credit (fees, misdirected transfers). Reversible with restore.",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 409, description: "`billing.payment.has_allocations`" }
|
|
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/ignore/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/ignore` \u2014 ignore 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.ignore',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.paymentId,\n logLabel: 'billing/payments/ignore.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Ignore a payment',\n description: 'Excludes an unallocated payment from matching and credit (fees, misdirected transfers). Reversible with restore.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 409, description: '`billing.payment.has_allocations`' },\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,oCAAoC;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { PAYMENT_IMPORT_MAX_BYTES } from "../../../data/validators.js";
|
|
4
|
+
import { readRequestBody, runCommandRoute } from "../../../lib/commandRoute.js";
|
|
5
|
+
const metadata = {
|
|
6
|
+
POST: { requireAuth: true, requireFeatures: ["billing.payment.import"] }
|
|
7
|
+
};
|
|
8
|
+
const bodySchema = z.object({
|
|
9
|
+
fileName: z.string().trim().min(1).max(255),
|
|
10
|
+
content: z.string().max(PAYMENT_IMPORT_MAX_BYTES)
|
|
11
|
+
});
|
|
12
|
+
async function readUpload(req) {
|
|
13
|
+
const declared = Number(req.headers.get("content-length") ?? "0");
|
|
14
|
+
if (declared > PAYMENT_IMPORT_MAX_BYTES + 64 * 1024) {
|
|
15
|
+
return NextResponse.json({ error: "The file is larger than 2 MB", code: "billing.payment_import.too_large" }, { status: 413 });
|
|
16
|
+
}
|
|
17
|
+
if ((req.headers.get("content-type") ?? "").includes("multipart/form-data")) {
|
|
18
|
+
const form = await req.formData();
|
|
19
|
+
const file = form.get("file");
|
|
20
|
+
if (!file || typeof file === "string") return { fileName: "", content: "" };
|
|
21
|
+
if (file.size > PAYMENT_IMPORT_MAX_BYTES) {
|
|
22
|
+
return NextResponse.json({ error: "The file is larger than 2 MB", code: "billing.payment_import.too_large" }, { status: 413 });
|
|
23
|
+
}
|
|
24
|
+
return { fileName: file.name || "payments.csv", content: await file.text() };
|
|
25
|
+
}
|
|
26
|
+
return readRequestBody(req);
|
|
27
|
+
}
|
|
28
|
+
async function POST(req) {
|
|
29
|
+
const body = await readUpload(req.clone());
|
|
30
|
+
if (body instanceof Response) return body;
|
|
31
|
+
return runCommandRoute(
|
|
32
|
+
req,
|
|
33
|
+
{
|
|
34
|
+
commandId: "billing.payments.import",
|
|
35
|
+
bodySchema,
|
|
36
|
+
resourceKind: "billing.payment_import",
|
|
37
|
+
resourceId: () => null,
|
|
38
|
+
logLabel: "billing/payments/import.POST"
|
|
39
|
+
},
|
|
40
|
+
body
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const openApi = {
|
|
44
|
+
methods: {
|
|
45
|
+
POST: {
|
|
46
|
+
tags: ["Billing"],
|
|
47
|
+
summary: "Import bank payments from CSV",
|
|
48
|
+
description: 'CSV header `date,amount,currency,reference,payer_name,payer_account` (UTF-8, comma separated, "." decimals, amount > 0, \u2264 5,000 rows, \u2264 2 MB). Each new row becomes a payment, matched by the invoice number in `reference`; re-uploaded lines are counted as duplicates. Send multipart `file` or JSON `{ fileName, content }`.',
|
|
49
|
+
requestBody: { schema: bodySchema },
|
|
50
|
+
responses: [{ status: 200, description: "`{ importId, fileName, rowCount, counts, errors[] }`" }],
|
|
51
|
+
errors: [
|
|
52
|
+
{ status: 400, description: "`billing.payment_import.invalid_file` (header / empty / too many rows)" },
|
|
53
|
+
{ status: 413, description: "`billing.payment_import.too_large`" }
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
POST,
|
|
60
|
+
metadata,
|
|
61
|
+
openApi
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/billing/api/payments/import/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { PAYMENT_IMPORT_MAX_BYTES } from '../../../data/validators'\nimport { readRequestBody, runCommandRoute } from '../../../lib/commandRoute'\n\n/**\n * `POST /api/billing/payments/import` \u2014 bank CSV upload (Spec C, C-D4).\n * Accepts `multipart/form-data` (`file`) or JSON `{ fileName, content }`.\n * 413 over 2 MB. Returns the import summary (counts per outcome + row errors).\n */\n\nexport const metadata = {\n POST: { requireAuth: true, requireFeatures: ['billing.payment.import'] },\n}\n\nconst bodySchema = z.object({\n fileName: z.string().trim().min(1).max(255),\n content: z.string().max(PAYMENT_IMPORT_MAX_BYTES),\n})\n\nasync function readUpload(req: Request): Promise<unknown | Response> {\n const declared = Number(req.headers.get('content-length') ?? '0')\n if (declared > PAYMENT_IMPORT_MAX_BYTES + 64 * 1024) {\n return NextResponse.json({ error: 'The file is larger than 2 MB', code: 'billing.payment_import.too_large' }, { status: 413 })\n }\n if ((req.headers.get('content-type') ?? '').includes('multipart/form-data')) {\n const form = await req.formData()\n const file = form.get('file')\n if (!file || typeof file === 'string') return { fileName: '', content: '' }\n if (file.size > PAYMENT_IMPORT_MAX_BYTES) {\n return NextResponse.json({ error: 'The file is larger than 2 MB', code: 'billing.payment_import.too_large' }, { status: 413 })\n }\n return { fileName: file.name || 'payments.csv', content: await file.text() }\n }\n return readRequestBody(req)\n}\n\nexport async function POST(req: Request) {\n const body = await readUpload(req.clone())\n if (body instanceof Response) return body\n return runCommandRoute(\n req,\n {\n commandId: 'billing.payments.import',\n bodySchema,\n resourceKind: 'billing.payment_import',\n resourceId: () => null,\n logLabel: 'billing/payments/import.POST',\n },\n body,\n )\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Import bank payments from CSV',\n description:\n 'CSV header `date,amount,currency,reference,payer_name,payer_account` (UTF-8, comma separated, ' +\n '\".\" decimals, amount > 0, \u2264 5,000 rows, \u2264 2 MB). Each new row becomes a payment, matched by the ' +\n 'invoice number in `reference`; re-uploaded lines are counted as duplicates. Send multipart `file` or ' +\n 'JSON `{ fileName, content }`.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: '`{ importId, fileName, rowCount, counts, errors[] }`' }],\n errors: [\n { status: 400, description: '`billing.payment_import.invalid_file` (header / empty / too many rows)' },\n { status: 413, description: '`billing.payment_import.too_large`' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAClB,SAAS,gCAAgC;AACzC,SAAS,iBAAiB,uBAAuB;AAQ1C,MAAM,WAAW;AAAA,EACtB,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACzE;AAEA,MAAM,aAAa,EAAE,OAAO;AAAA,EAC1B,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC1C,SAAS,EAAE,OAAO,EAAE,IAAI,wBAAwB;AAClD,CAAC;AAED,eAAe,WAAW,KAA2C;AACnE,QAAM,WAAW,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,GAAG;AAChE,MAAI,WAAW,2BAA2B,KAAK,MAAM;AACnD,WAAO,aAAa,KAAK,EAAE,OAAO,gCAAgC,MAAM,mCAAmC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/H;AACA,OAAK,IAAI,QAAQ,IAAI,cAAc,KAAK,IAAI,SAAS,qBAAqB,GAAG;AAC3E,UAAM,OAAO,MAAM,IAAI,SAAS;AAChC,UAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,QAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO,EAAE,UAAU,IAAI,SAAS,GAAG;AAC1E,QAAI,KAAK,OAAO,0BAA0B;AACxC,aAAO,aAAa,KAAK,EAAE,OAAO,gCAAgC,MAAM,mCAAmC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC/H;AACA,WAAO,EAAE,UAAU,KAAK,QAAQ,gBAAgB,SAAS,MAAM,KAAK,KAAK,EAAE;AAAA,EAC7E;AACA,SAAO,gBAAgB,GAAG;AAC5B;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,WAAW,IAAI,MAAM,CAAC;AACzC,MAAI,gBAAgB,SAAU,QAAO;AACrC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA,cAAc;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aACE;AAAA,MAIF,aAAa,EAAE,QAAQ,WAAW;AAAA,MAClC,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,uDAAuD,CAAC;AAAA,MAChG,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,yEAAyE;AAAA,QACrG,EAAE,QAAQ,KAAK,aAAa,qCAAqC;AAAA,MACnE;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.restore",
|
|
10
|
+
bodySchema,
|
|
11
|
+
resourceKind: "billing.payment",
|
|
12
|
+
resourceId: (body) => body.paymentId,
|
|
13
|
+
logLabel: "billing/payments/restore.POST"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const openApi = {
|
|
17
|
+
methods: {
|
|
18
|
+
POST: {
|
|
19
|
+
tags: ["Billing"],
|
|
20
|
+
summary: "Restore an ignored payment",
|
|
21
|
+
description: "Restores an ignored payment to matched (credit applied again) or unmatched.",
|
|
22
|
+
requestBody: { schema: bodySchema },
|
|
23
|
+
responses: [{ status: 200, description: "Updated payment state" }],
|
|
24
|
+
errors: [
|
|
25
|
+
{ status: 409, description: "`billing.payment.not_ignored`" }
|
|
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/restore/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { runCommandRoute } from '../../../lib/commandRoute'\n\n/** `POST /api/billing/payments/restore` \u2014 restore an ignored 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.restore',\n bodySchema,\n resourceKind: 'billing.payment',\n resourceId: (body) => body.paymentId,\n logLabel: 'billing/payments/restore.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n POST: {\n tags: ['Billing'],\n summary: 'Restore an ignored payment',\n description: 'Restores an ignored payment to matched (credit applied again) or unmatched.',\n requestBody: { schema: bodySchema },\n responses: [{ status: 200, description: 'Updated payment state' }],\n errors: [\n { status: 409, description: '`billing.payment.not_ignored`' },\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,gCAAgC;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
4
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
5
|
+
import {
|
|
6
|
+
organizationScopeRequiredResponse,
|
|
7
|
+
resolveActiveOrganizationId
|
|
8
|
+
} from "@open-mercato/shared/lib/auth/organizationScope";
|
|
9
|
+
import { buildQueryParams } from "@open-mercato/shared/lib/crud/query-params";
|
|
10
|
+
import { billingPaymentListQuerySchema } from "../../data/validators.js";
|
|
11
|
+
import { runCommandRoute } from "../../lib/commandRoute.js";
|
|
12
|
+
const metadata = {
|
|
13
|
+
GET: { requireAuth: true, requireFeatures: ["billing.payment.view"] },
|
|
14
|
+
POST: { requireAuth: true, requireFeatures: ["billing.payment.manage"] }
|
|
15
|
+
};
|
|
16
|
+
async function GET(req) {
|
|
17
|
+
try {
|
|
18
|
+
const container = await createRequestContainer();
|
|
19
|
+
const auth = await getAuthFromRequest(req);
|
|
20
|
+
if (!auth || !auth.tenantId) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
21
|
+
const organizationId = resolveActiveOrganizationId(auth);
|
|
22
|
+
if (!organizationId) return organizationScopeRequiredResponse();
|
|
23
|
+
const query = billingPaymentListQuerySchema.parse(buildQueryParams(new URL(req.url).searchParams));
|
|
24
|
+
const em = container.resolve("em").fork();
|
|
25
|
+
const where = ["p.tenant_id = ?", "p.organization_id = ?", "p.deleted_at IS NULL"];
|
|
26
|
+
const params = [auth.tenantId, organizationId];
|
|
27
|
+
const filters = [
|
|
28
|
+
[query.id, "p.id = ?"],
|
|
29
|
+
[query.status, "p.status = ?"],
|
|
30
|
+
[query.billAccountId, "p.bill_account_id = ?"],
|
|
31
|
+
[query.importId, "p.import_id = ?"],
|
|
32
|
+
[query.receivedFrom, "p.received_at >= ?::date"],
|
|
33
|
+
[query.receivedTo, "p.received_at <= ?::date"]
|
|
34
|
+
];
|
|
35
|
+
for (const [value, clause] of filters) {
|
|
36
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
37
|
+
where.push(clause);
|
|
38
|
+
params.push(value);
|
|
39
|
+
}
|
|
40
|
+
if (query.search) {
|
|
41
|
+
const like = `%${query.search.replace(/[%_\\]/g, (m) => `\\${m}`)}%`;
|
|
42
|
+
where.push("(p.reference ILIKE ? OR p.payer_name ILIKE ? OR p.payer_account ILIKE ?)");
|
|
43
|
+
params.push(like, like, like);
|
|
44
|
+
}
|
|
45
|
+
const whereSql = where.join(" AND ");
|
|
46
|
+
const totalRows = await em.execute(`SELECT COUNT(*)::int AS total FROM billing_payments p WHERE ${whereSql}`, params);
|
|
47
|
+
const total = totalRows?.[0]?.total ?? 0;
|
|
48
|
+
const items = await em.execute(
|
|
49
|
+
`SELECT p.id, p.received_at, p.amount, p.currency_code, p.reference, p.payer_name, p.payer_account, p.source,
|
|
50
|
+
p.import_id, p.bill_account_id, a.name AS bill_account_name, p.status, p.unallocated_amount,
|
|
51
|
+
p.match_reason, p.topup_id, p.created_at
|
|
52
|
+
FROM billing_payments p
|
|
53
|
+
LEFT JOIN billing_accounts a ON a.id = p.bill_account_id AND a.tenant_id = p.tenant_id
|
|
54
|
+
WHERE ${whereSql}
|
|
55
|
+
ORDER BY p.received_at DESC, p.created_at DESC
|
|
56
|
+
LIMIT ? OFFSET ?`,
|
|
57
|
+
[...params, query.pageSize, (query.page - 1) * query.pageSize]
|
|
58
|
+
);
|
|
59
|
+
return NextResponse.json({
|
|
60
|
+
items,
|
|
61
|
+
total,
|
|
62
|
+
page: query.page,
|
|
63
|
+
pageSize: query.pageSize,
|
|
64
|
+
totalPages: total === 0 ? 1 : Math.ceil(total / query.pageSize)
|
|
65
|
+
});
|
|
66
|
+
} catch (err) {
|
|
67
|
+
if (err instanceof z.ZodError) return NextResponse.json({ error: "Invalid query", issues: err.issues }, { status: 400 });
|
|
68
|
+
console.error("[billing/payments.GET]", err);
|
|
69
|
+
return NextResponse.json({ error: "Internal error" }, { status: 500 });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const createBodySchema = z.object({
|
|
73
|
+
receivedAt: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
74
|
+
amount: z.coerce.number().positive(),
|
|
75
|
+
currencyCode: z.string().trim().length(3),
|
|
76
|
+
reference: z.string().trim().max(500).optional(),
|
|
77
|
+
payerName: z.string().trim().max(255).optional(),
|
|
78
|
+
payerAccount: z.string().trim().max(64).optional(),
|
|
79
|
+
billAccountId: z.string().uuid().optional()
|
|
80
|
+
});
|
|
81
|
+
async function POST(req) {
|
|
82
|
+
return runCommandRoute(req, {
|
|
83
|
+
commandId: "billing.payments.create",
|
|
84
|
+
bodySchema: createBodySchema,
|
|
85
|
+
resourceKind: "billing.payment",
|
|
86
|
+
resourceId: () => null,
|
|
87
|
+
logLabel: "billing/payments.POST"
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const openApi = {
|
|
91
|
+
methods: {
|
|
92
|
+
GET: {
|
|
93
|
+
tags: ["Billing"],
|
|
94
|
+
summary: "List billing payments",
|
|
95
|
+
description: "Payment register (bank CSV lines, manual entries, gateway captures). Filters: status (`unmatched | matched | partially_allocated | allocated | ignored | converted_to_topup`), billAccountId, importId, receivedFrom / receivedTo (YYYY-MM-DD), search (reference, payer). pageSize \u2264 100.",
|
|
96
|
+
query: billingPaymentListQuerySchema
|
|
97
|
+
},
|
|
98
|
+
POST: {
|
|
99
|
+
tags: ["Billing"],
|
|
100
|
+
summary: "Record a payment manually",
|
|
101
|
+
description: "Creates a manual payment. With `billAccountId` it is matched and applied as credit to the account's open invoices (oldest due first); otherwise it stays unmatched.",
|
|
102
|
+
requestBody: { schema: createBodySchema },
|
|
103
|
+
responses: [{ status: 200, description: "`{ paymentId, status, unallocatedAmount }`" }],
|
|
104
|
+
errors: [{ status: 409, description: "`billing.payment.currency_mismatch`" }]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
export {
|
|
109
|
+
GET,
|
|
110
|
+
POST,
|
|
111
|
+
metadata,
|
|
112
|
+
openApi
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/billing/api/payments/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport {\n organizationScopeRequiredResponse,\n resolveActiveOrganizationId,\n} from '@open-mercato/shared/lib/auth/organizationScope'\nimport { buildQueryParams } from '@open-mercato/shared/lib/crud/query-params'\nimport { billingPaymentListQuerySchema } from '../../data/validators'\nimport { runCommandRoute } from '../../lib/commandRoute'\n\n/**\n * `GET /api/billing/payments` \u2014 the payment register (Spec C), newest first.\n * Filters: status, billAccountId, importId, receivedFrom / receivedTo,\n * search (reference / payer name / payer account). Rows carry the account\n * name (joined). Hand-written SQL like the invoice list.\n *\n * `POST /api/billing/payments` \u2014 manual payment entry (`billing.payments.create`).\n */\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['billing.payment.view'] },\n POST: { requireAuth: true, requireFeatures: ['billing.payment.manage'] },\n}\n\nexport type BillingPaymentRow = {\n id: string\n received_at: string\n amount: string\n currency_code: string\n reference: string | null\n payer_name: string | null\n payer_account: string | null\n source: string\n import_id: string | null\n bill_account_id: string | null\n bill_account_name: string | null\n status: string\n unallocated_amount: string\n match_reason: string | null\n topup_id: string | null\n created_at: string\n}\n\nexport async function GET(req: Request) {\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.tenantId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const organizationId = resolveActiveOrganizationId(auth)\n if (!organizationId) return organizationScopeRequiredResponse()\n const query = billingPaymentListQuerySchema.parse(buildQueryParams(new URL(req.url).searchParams))\n const em = (container.resolve('em') as EntityManager).fork()\n\n const where: string[] = ['p.tenant_id = ?', 'p.organization_id = ?', 'p.deleted_at IS NULL']\n const params: unknown[] = [auth.tenantId, organizationId]\n const filters: Array<[unknown, string]> = [\n [query.id, 'p.id = ?'],\n [query.status, 'p.status = ?'],\n [query.billAccountId, 'p.bill_account_id = ?'],\n [query.importId, 'p.import_id = ?'],\n [query.receivedFrom, 'p.received_at >= ?::date'],\n [query.receivedTo, 'p.received_at <= ?::date'],\n ]\n for (const [value, clause] of filters) {\n if (value === undefined || value === null || value === '') continue\n where.push(clause)\n params.push(value)\n }\n if (query.search) {\n const like = `%${query.search.replace(/[%_\\\\]/g, (m) => `\\\\${m}`)}%`\n where.push('(p.reference ILIKE ? OR p.payer_name ILIKE ? OR p.payer_account ILIKE ?)')\n params.push(like, like, like)\n }\n const whereSql = where.join(' AND ')\n const totalRows = (await em.execute(`SELECT COUNT(*)::int AS total FROM billing_payments p WHERE ${whereSql}`, params)) as unknown as Array<{ total: number }>\n const total = totalRows?.[0]?.total ?? 0\n const items = (await em.execute(\n `SELECT p.id, p.received_at, p.amount, p.currency_code, p.reference, p.payer_name, p.payer_account, p.source,\n p.import_id, p.bill_account_id, a.name AS bill_account_name, p.status, p.unallocated_amount,\n p.match_reason, p.topup_id, p.created_at\n FROM billing_payments p\n LEFT JOIN billing_accounts a ON a.id = p.bill_account_id AND a.tenant_id = p.tenant_id\n WHERE ${whereSql}\n ORDER BY p.received_at DESC, p.created_at DESC\n LIMIT ? OFFSET ?`,\n [...params, query.pageSize, (query.page - 1) * query.pageSize],\n )) as unknown as BillingPaymentRow[]\n return NextResponse.json({\n items,\n total,\n page: query.page,\n pageSize: query.pageSize,\n totalPages: total === 0 ? 1 : Math.ceil(total / query.pageSize),\n })\n } catch (err) {\n if (err instanceof z.ZodError) return NextResponse.json({ error: 'Invalid query', issues: err.issues }, { status: 400 })\n console.error('[billing/payments.GET]', err)\n return NextResponse.json({ error: 'Internal error' }, { status: 500 })\n }\n}\n\nconst createBodySchema = z.object({\n receivedAt: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/),\n amount: z.coerce.number().positive(),\n currencyCode: z.string().trim().length(3),\n reference: z.string().trim().max(500).optional(),\n payerName: z.string().trim().max(255).optional(),\n payerAccount: z.string().trim().max(64).optional(),\n billAccountId: z.string().uuid().optional(),\n})\n\nexport async function POST(req: Request) {\n return runCommandRoute(req, {\n commandId: 'billing.payments.create',\n bodySchema: createBodySchema,\n resourceKind: 'billing.payment',\n resourceId: () => null,\n logLabel: 'billing/payments.POST',\n })\n}\n\nexport const openApi = {\n methods: {\n GET: {\n tags: ['Billing'],\n summary: 'List billing payments',\n description:\n 'Payment register (bank CSV lines, manual entries, gateway captures). Filters: status ' +\n '(`unmatched | matched | partially_allocated | allocated | ignored | converted_to_topup`), billAccountId, ' +\n 'importId, receivedFrom / receivedTo (YYYY-MM-DD), search (reference, payer). pageSize \u2264 100.',\n query: billingPaymentListQuerySchema,\n },\n POST: {\n tags: ['Billing'],\n summary: 'Record a payment manually',\n description:\n 'Creates a manual payment. With `billAccountId` it is matched and applied as credit to the ' +\n \"account's open invoices (oldest due first); otherwise it stays unmatched.\",\n requestBody: { schema: createBodySchema },\n responses: [{ status: 200, description: '`{ paymentId, status, unallocatedAmount }`' }],\n errors: [{ status: 409, description: '`billing.payment.currency_mismatch`' }],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC,SAAS,qCAAqC;AAC9C,SAAS,uBAAuB;AAWzB,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,sBAAsB,EAAE;AAAA,EACpE,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACzE;AAqBA,eAAsB,IAAI,KAAc;AACtC,MAAI;AACF,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,QAAI,CAAC,QAAQ,CAAC,KAAK,SAAU,QAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAChG,UAAM,iBAAiB,4BAA4B,IAAI;AACvD,QAAI,CAAC,eAAgB,QAAO,kCAAkC;AAC9D,UAAM,QAAQ,8BAA8B,MAAM,iBAAiB,IAAI,IAAI,IAAI,GAAG,EAAE,YAAY,CAAC;AACjG,UAAM,KAAM,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAE3D,UAAM,QAAkB,CAAC,mBAAmB,yBAAyB,sBAAsB;AAC3F,UAAM,SAAoB,CAAC,KAAK,UAAU,cAAc;AACxD,UAAM,UAAoC;AAAA,MACxC,CAAC,MAAM,IAAI,UAAU;AAAA,MACrB,CAAC,MAAM,QAAQ,cAAc;AAAA,MAC7B,CAAC,MAAM,eAAe,uBAAuB;AAAA,MAC7C,CAAC,MAAM,UAAU,iBAAiB;AAAA,MAClC,CAAC,MAAM,cAAc,0BAA0B;AAAA,MAC/C,CAAC,MAAM,YAAY,0BAA0B;AAAA,IAC/C;AACA,eAAW,CAAC,OAAO,MAAM,KAAK,SAAS;AACrC,UAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,GAAI;AAC3D,YAAM,KAAK,MAAM;AACjB,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,QAAI,MAAM,QAAQ;AAChB,YAAM,OAAO,IAAI,MAAM,OAAO,QAAQ,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;AACjE,YAAM,KAAK,0EAA0E;AACrF,aAAO,KAAK,MAAM,MAAM,IAAI;AAAA,IAC9B;AACA,UAAM,WAAW,MAAM,KAAK,OAAO;AACnC,UAAM,YAAa,MAAM,GAAG,QAAQ,+DAA+D,QAAQ,IAAI,MAAM;AACrH,UAAM,QAAQ,YAAY,CAAC,GAAG,SAAS;AACvC,UAAM,QAAS,MAAM,GAAG;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKU,QAAQ;AAAA;AAAA;AAAA,MAGlB,CAAC,GAAG,QAAQ,MAAM,WAAW,MAAM,OAAO,KAAK,MAAM,QAAQ;AAAA,IAC/D;AACA,WAAO,aAAa,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,YAAY,UAAU,IAAI,IAAI,KAAK,KAAK,QAAQ,MAAM,QAAQ;AAAA,IAChE,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,eAAe,EAAE,SAAU,QAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,QAAQ,IAAI,OAAO,GAAG,EAAE,QAAQ,IAAI,CAAC;AACvH,YAAQ,MAAM,0BAA0B,GAAG;AAC3C,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvE;AACF;AAEA,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB;AAAA,EAClD,QAAQ,EAAE,OAAO,OAAO,EAAE,SAAS;AAAA,EACnC,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;AAAA,EACxC,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC/C,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC/C,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACjD,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAC5C,CAAC;AAED,eAAsB,KAAK,KAAc;AACvC,SAAO,gBAAgB,KAAK;AAAA,IAC1B,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,YAAY,MAAM;AAAA,IAClB,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,MAAM,UAAU;AAAA,EACrB,SAAS;AAAA,IACP,KAAK;AAAA,MACH,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aACE;AAAA,MAGF,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,aACE;AAAA,MAEF,aAAa,EAAE,QAAQ,iBAAiB;AAAA,MACxC,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,6CAA6C,CAAC;AAAA,MACtF,QAAQ,CAAC,EAAE,QAAQ,KAAK,aAAa,sCAAsC,CAAC;AAAA,IAC9E;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({ 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
|
+
}
|