@ketvietlab/ketsuite 0.1.2 → 0.1.3
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/LICENSE +1 -1
- package/README.md +15 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +59 -0
- package/dist/cli.js.map +1 -0
- package/dist/deployment.d.ts +5 -0
- package/dist/deployment.d.ts.map +1 -0
- package/dist/deployment.js +152 -0
- package/dist/deployment.js.map +1 -0
- package/dist/development.d.ts +8 -0
- package/dist/development.d.ts.map +1 -0
- package/dist/development.js +40 -0
- package/dist/development.js.map +1 -0
- package/dist/index.d.ts +77 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +66 -6
- package/dist/index.js.map +1 -1
- package/dist/modules/account/analytics.d.ts +32 -0
- package/dist/modules/account/analytics.d.ts.map +1 -0
- package/dist/modules/account/analytics.js +457 -0
- package/dist/modules/account/analytics.js.map +1 -0
- package/dist/modules/account/assets-costing.d.ts +4 -0
- package/dist/modules/account/assets-costing.d.ts.map +1 -0
- package/dist/modules/account/assets-costing.js +1134 -0
- package/dist/modules/account/assets-costing.js.map +1 -0
- package/dist/modules/account/audit.d.ts +3 -0
- package/dist/modules/account/audit.d.ts.map +1 -0
- package/dist/modules/account/audit.js +14 -0
- package/dist/modules/account/audit.js.map +1 -0
- package/dist/modules/account/books.d.ts +4 -0
- package/dist/modules/account/books.d.ts.map +1 -0
- package/dist/modules/account/books.js +150 -0
- package/dist/modules/account/books.js.map +1 -0
- package/dist/modules/account/cash-receivables.d.ts +3 -0
- package/dist/modules/account/cash-receivables.d.ts.map +1 -0
- package/dist/modules/account/cash-receivables.js +1087 -0
- package/dist/modules/account/cash-receivables.js.map +1 -0
- package/dist/modules/account/close.d.ts +4 -0
- package/dist/modules/account/close.d.ts.map +1 -0
- package/dist/modules/account/close.js +343 -0
- package/dist/modules/account/close.js.map +1 -0
- package/dist/modules/account/date.d.ts +21 -0
- package/dist/modules/account/date.d.ts.map +1 -0
- package/dist/modules/account/date.js +70 -0
- package/dist/modules/account/date.js.map +1 -0
- package/dist/modules/account/functions.d.ts +131 -3
- package/dist/modules/account/functions.d.ts.map +1 -1
- package/dist/modules/account/functions.js +2570 -389
- package/dist/modules/account/functions.js.map +1 -1
- package/dist/modules/account/index.d.ts +1 -2
- package/dist/modules/account/index.d.ts.map +1 -1
- package/dist/modules/account/index.js +403 -8
- package/dist/modules/account/index.js.map +1 -1
- package/dist/modules/account/models.d.ts.map +1 -1
- package/dist/modules/account/models.js +748 -0
- package/dist/modules/account/models.js.map +1 -1
- package/dist/modules/account/money.d.ts +60 -0
- package/dist/modules/account/money.d.ts.map +1 -0
- package/dist/modules/account/money.js +237 -0
- package/dist/modules/account/money.js.map +1 -0
- package/dist/modules/account/open-items.d.ts +3 -0
- package/dist/modules/account/open-items.d.ts.map +1 -0
- package/dist/modules/account/open-items.js +390 -0
- package/dist/modules/account/open-items.js.map +1 -0
- package/dist/modules/account/opening.d.ts +3 -0
- package/dist/modules/account/opening.d.ts.map +1 -0
- package/dist/modules/account/opening.js +323 -0
- package/dist/modules/account/opening.js.map +1 -0
- package/dist/modules/account/period.d.ts +21 -0
- package/dist/modules/account/period.d.ts.map +1 -0
- package/dist/modules/account/period.js +155 -0
- package/dist/modules/account/period.js.map +1 -0
- package/dist/modules/account/relations.d.ts.map +1 -1
- package/dist/modules/account/relations.js +46 -0
- package/dist/modules/account/relations.js.map +1 -1
- package/dist/modules/account/reports.d.ts +4 -0
- package/dist/modules/account/reports.d.ts.map +1 -0
- package/dist/modules/account/reports.js +125 -0
- package/dist/modules/account/reports.js.map +1 -0
- package/dist/modules/account/setup.d.ts +3 -1
- package/dist/modules/account/setup.d.ts.map +1 -1
- package/dist/modules/account/setup.js +45 -160
- package/dist/modules/account/setup.js.map +1 -1
- package/dist/modules/account_activity_backend/index.d.ts.map +1 -1
- package/dist/modules/account_activity_backend/index.js +0 -1
- package/dist/modules/account_activity_backend/index.js.map +1 -1
- package/dist/modules/account_backend/index.js +3339 -494
- package/dist/modules/account_backend/index.js.map +1 -1
- package/dist/modules/account_backend/overview.d.ts +92 -0
- package/dist/modules/account_backend/overview.d.ts.map +1 -0
- package/dist/modules/account_backend/overview.js +257 -0
- package/dist/modules/account_backend/overview.js.map +1 -0
- package/dist/modules/account_backend/relation-control.d.ts +48 -0
- package/dist/modules/account_backend/relation-control.d.ts.map +1 -0
- package/dist/modules/account_backend/relation-control.js +67 -0
- package/dist/modules/account_backend/relation-control.js.map +1 -0
- package/dist/modules/account_backend/screens/account-defaults.d.ts +28 -0
- package/dist/modules/account_backend/screens/account-defaults.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/account-defaults.js +60 -0
- package/dist/modules/account_backend/screens/account-defaults.js.map +1 -0
- package/dist/modules/account_backend/screens/account-form.d.ts +16 -0
- package/dist/modules/account_backend/screens/account-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/account-form.js +53 -0
- package/dist/modules/account_backend/screens/account-form.js.map +1 -0
- package/dist/modules/account_backend/screens/accounting-books.d.ts +15 -0
- package/dist/modules/account_backend/screens/accounting-books.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/accounting-books.js +86 -0
- package/dist/modules/account_backend/screens/accounting-books.js.map +1 -0
- package/dist/modules/account_backend/screens/accounts-list.d.ts +50 -0
- package/dist/modules/account_backend/screens/accounts-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/accounts-list.js +66 -0
- package/dist/modules/account_backend/screens/accounts-list.js.map +1 -0
- package/dist/modules/account_backend/screens/customer-invoice-form.d.ts +13 -0
- package/dist/modules/account_backend/screens/customer-invoice-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/customer-invoice-form.js +20 -0
- package/dist/modules/account_backend/screens/customer-invoice-form.js.map +1 -0
- package/dist/modules/account_backend/screens/customer-invoices-list.d.ts +62 -0
- package/dist/modules/account_backend/screens/customer-invoices-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/customer-invoices-list.js +82 -0
- package/dist/modules/account_backend/screens/customer-invoices-list.js.map +1 -0
- package/dist/modules/account_backend/screens/general-ledger.d.ts +24 -0
- package/dist/modules/account_backend/screens/general-ledger.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/general-ledger.js +73 -0
- package/dist/modules/account_backend/screens/general-ledger.js.map +1 -0
- package/dist/modules/account_backend/screens/index.d.ts +27 -0
- package/dist/modules/account_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/index.js +27 -0
- package/dist/modules/account_backend/screens/index.js.map +1 -0
- package/dist/modules/account_backend/screens/journal-entries-list.d.ts +48 -0
- package/dist/modules/account_backend/screens/journal-entries-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/journal-entries-list.js +58 -0
- package/dist/modules/account_backend/screens/journal-entries-list.js.map +1 -0
- package/dist/modules/account_backend/screens/journal-entry-create.d.ts +14 -0
- package/dist/modules/account_backend/screens/journal-entry-create.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/journal-entry-create.js +41 -0
- package/dist/modules/account_backend/screens/journal-entry-create.js.map +1 -0
- package/dist/modules/account_backend/screens/journal-form.d.ts +15 -0
- package/dist/modules/account_backend/screens/journal-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/journal-form.js +53 -0
- package/dist/modules/account_backend/screens/journal-form.js.map +1 -0
- package/dist/modules/account_backend/screens/journals-list.d.ts +51 -0
- package/dist/modules/account_backend/screens/journals-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/journals-list.js +70 -0
- package/dist/modules/account_backend/screens/journals-list.js.map +1 -0
- package/dist/modules/account_backend/screens/move-detail.d.ts +26 -0
- package/dist/modules/account_backend/screens/move-detail.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/move-detail.js +130 -0
- package/dist/modules/account_backend/screens/move-detail.js.map +1 -0
- package/dist/modules/account_backend/screens/opening-balances.d.ts +28 -0
- package/dist/modules/account_backend/screens/opening-balances.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/opening-balances.js +96 -0
- package/dist/modules/account_backend/screens/opening-balances.js.map +1 -0
- package/dist/modules/account_backend/screens/overview.d.ts +62 -0
- package/dist/modules/account_backend/screens/overview.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/overview.js +215 -0
- package/dist/modules/account_backend/screens/overview.js.map +1 -0
- package/dist/modules/account_backend/screens/partner-statement.d.ts +26 -0
- package/dist/modules/account_backend/screens/partner-statement.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/partner-statement.js +82 -0
- package/dist/modules/account_backend/screens/partner-statement.js.map +1 -0
- package/dist/modules/account_backend/screens/payment-form.d.ts +14 -0
- package/dist/modules/account_backend/screens/payment-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/payment-form.js +21 -0
- package/dist/modules/account_backend/screens/payment-form.js.map +1 -0
- package/dist/modules/account_backend/screens/payment-term-form.d.ts +25 -0
- package/dist/modules/account_backend/screens/payment-term-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/payment-term-form.js +96 -0
- package/dist/modules/account_backend/screens/payment-term-form.js.map +1 -0
- package/dist/modules/account_backend/screens/payment-terms-list.d.ts +23 -0
- package/dist/modules/account_backend/screens/payment-terms-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/payment-terms-list.js +104 -0
- package/dist/modules/account_backend/screens/payment-terms-list.js.map +1 -0
- package/dist/modules/account_backend/screens/payments-list.d.ts +62 -0
- package/dist/modules/account_backend/screens/payments-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/payments-list.js +71 -0
- package/dist/modules/account_backend/screens/payments-list.js.map +1 -0
- package/dist/modules/account_backend/screens/period-closes.d.ts +21 -0
- package/dist/modules/account_backend/screens/period-closes.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/period-closes.js +123 -0
- package/dist/modules/account_backend/screens/period-closes.js.map +1 -0
- package/dist/modules/account_backend/screens/shared.d.ts +16 -0
- package/dist/modules/account_backend/screens/shared.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/shared.js +15 -0
- package/dist/modules/account_backend/screens/shared.js.map +1 -0
- package/dist/modules/account_backend/screens/tax-form.d.ts +14 -0
- package/dist/modules/account_backend/screens/tax-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/tax-form.js +25 -0
- package/dist/modules/account_backend/screens/tax-form.js.map +1 -0
- package/dist/modules/account_backend/screens/taxes-list.d.ts +55 -0
- package/dist/modules/account_backend/screens/taxes-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/taxes-list.js +83 -0
- package/dist/modules/account_backend/screens/taxes-list.js.map +1 -0
- package/dist/modules/account_backend/screens/trial-balance.d.ts +19 -0
- package/dist/modules/account_backend/screens/trial-balance.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/trial-balance.js +75 -0
- package/dist/modules/account_backend/screens/trial-balance.js.map +1 -0
- package/dist/modules/account_backend/screens/vendor-bill-form.d.ts +13 -0
- package/dist/modules/account_backend/screens/vendor-bill-form.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/vendor-bill-form.js +20 -0
- package/dist/modules/account_backend/screens/vendor-bill-form.js.map +1 -0
- package/dist/modules/account_backend/screens/vendor-bills-list.d.ts +62 -0
- package/dist/modules/account_backend/screens/vendor-bills-list.d.ts.map +1 -0
- package/dist/modules/account_backend/screens/vendor-bills-list.js +84 -0
- package/dist/modules/account_backend/screens/vendor-bills-list.js.map +1 -0
- package/dist/modules/account_mail_backend/index.d.ts.map +1 -1
- package/dist/modules/account_mail_backend/index.js +0 -1
- package/dist/modules/account_mail_backend/index.js.map +1 -1
- package/dist/modules/account_partner/index.js +0 -2
- package/dist/modules/account_partner/index.js.map +1 -1
- package/dist/modules/account_partner_backend/index.d.ts +1 -1
- package/dist/modules/account_partner_backend/index.d.ts.map +1 -1
- package/dist/modules/account_partner_backend/index.js +2 -3
- package/dist/modules/account_partner_backend/index.js.map +1 -1
- package/dist/modules/account_partner_backend/routes.d.ts.map +1 -1
- package/dist/modules/account_partner_backend/routes.js +19 -25
- package/dist/modules/account_partner_backend/routes.js.map +1 -1
- package/dist/modules/account_partner_backend/screens/accounting-terms.d.ts +20 -0
- package/dist/modules/account_partner_backend/screens/accounting-terms.d.ts.map +1 -0
- package/dist/modules/account_partner_backend/screens/accounting-terms.js +63 -0
- package/dist/modules/account_partner_backend/screens/accounting-terms.js.map +1 -0
- package/dist/modules/account_partner_backend/screens/index.d.ts +2 -0
- package/dist/modules/account_partner_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/account_partner_backend/screens/index.js +2 -0
- package/dist/modules/account_partner_backend/screens/index.js.map +1 -0
- package/dist/modules/account_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/account_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/account_staff_channel/channel-routes.js +787 -0
- package/dist/modules/account_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/account_staff_channel/functions.d.ts.map +1 -0
- package/dist/modules/account_staff_channel/functions.js +143 -0
- package/dist/modules/account_staff_channel/functions.js.map +1 -0
- package/dist/modules/account_staff_channel/index.d.ts +5 -0
- package/dist/modules/account_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/account_staff_channel/index.js +42 -0
- package/dist/modules/account_staff_channel/index.js.map +1 -0
- package/dist/modules/account_staff_channel/models.d.ts.map +1 -0
- package/dist/modules/account_staff_channel/models.js +30 -0
- package/dist/modules/account_staff_channel/models.js.map +1 -0
- package/dist/modules/activity/index.d.ts.map +1 -1
- package/dist/modules/activity/index.js +0 -1
- package/dist/modules/activity/index.js.map +1 -1
- package/dist/modules/activity_backend/index.d.ts +1 -1
- package/dist/modules/activity_backend/index.d.ts.map +1 -1
- package/dist/modules/activity_backend/index.js +3 -12
- package/dist/modules/activity_backend/index.js.map +1 -1
- package/dist/modules/activity_backend/routes.d.ts.map +1 -1
- package/dist/modules/activity_backend/routes.js +36 -22
- package/dist/modules/activity_backend/routes.js.map +1 -1
- package/dist/modules/activity_backend/screens/activities-list.d.ts +15 -0
- package/dist/modules/activity_backend/screens/activities-list.d.ts.map +1 -0
- package/dist/modules/activity_backend/screens/activities-list.js +40 -0
- package/dist/modules/activity_backend/screens/activities-list.js.map +1 -0
- package/dist/modules/activity_backend/screens/index.d.ts +2 -0
- package/dist/modules/activity_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/activity_backend/screens/index.js +2 -0
- package/dist/modules/activity_backend/screens/index.js.map +1 -0
- package/dist/modules/address/data/VN/NOTICE.md +1 -1
- package/dist/modules/address/index.d.ts.map +1 -1
- package/dist/modules/address/index.js +0 -1
- package/dist/modules/address/index.js.map +1 -1
- package/dist/modules/address_backend/index.d.ts +1 -1
- package/dist/modules/address_backend/index.d.ts.map +1 -1
- package/dist/modules/address_backend/index.js +1 -3
- package/dist/modules/address_backend/index.js.map +1 -1
- package/dist/modules/address_backend/routes.d.ts.map +1 -1
- package/dist/modules/address_backend/routes.js +20 -27
- package/dist/modules/address_backend/routes.js.map +1 -1
- package/dist/modules/address_backend/screens/catalogs-list.d.ts +14 -0
- package/dist/modules/address_backend/screens/catalogs-list.d.ts.map +1 -0
- package/dist/modules/address_backend/screens/catalogs-list.js +38 -0
- package/dist/modules/address_backend/screens/catalogs-list.js.map +1 -0
- package/dist/modules/address_backend/screens/country-browser.d.ts +12 -0
- package/dist/modules/address_backend/screens/country-browser.d.ts.map +1 -0
- package/dist/modules/address_backend/screens/country-browser.js +74 -0
- package/dist/modules/address_backend/screens/country-browser.js.map +1 -0
- package/dist/modules/address_backend/screens/index.d.ts +4 -0
- package/dist/modules/address_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/address_backend/screens/index.js +3 -0
- package/dist/modules/address_backend/screens/index.js.map +1 -0
- package/dist/modules/address_backend/screens/types.d.ts +20 -0
- package/dist/modules/address_backend/screens/types.d.ts.map +1 -0
- package/dist/modules/address_backend/screens/types.js.map +1 -0
- package/dist/modules/attendance/channel-routes.d.ts +2 -0
- package/dist/modules/attendance/channel-routes.d.ts.map +1 -0
- package/dist/modules/attendance/channel-routes.js +234 -0
- package/dist/modules/attendance/channel-routes.js.map +1 -0
- package/dist/modules/attendance/functions.d.ts.map +1 -1
- package/dist/modules/attendance/functions.js +171 -22
- package/dist/modules/attendance/functions.js.map +1 -1
- package/dist/modules/attendance/index.d.ts.map +1 -1
- package/dist/modules/attendance/index.js +4 -2
- package/dist/modules/attendance/index.js.map +1 -1
- package/dist/modules/attendance/messages.d.ts +6 -0
- package/dist/modules/attendance/messages.d.ts.map +1 -1
- package/dist/modules/attendance/messages.js +6 -0
- package/dist/modules/attendance/messages.js.map +1 -1
- package/dist/modules/attendance/models.d.ts.map +1 -1
- package/dist/modules/attendance/models.js +1 -0
- package/dist/modules/attendance/models.js.map +1 -1
- package/dist/modules/attendance_backend/index.d.ts +3 -1
- package/dist/modules/attendance_backend/index.d.ts.map +1 -1
- package/dist/modules/attendance_backend/index.js +65 -4
- package/dist/modules/attendance_backend/index.js.map +1 -1
- package/dist/modules/attendance_backend/routes.d.ts.map +1 -1
- package/dist/modules/attendance_backend/routes.js +240 -53
- package/dist/modules/attendance_backend/routes.js.map +1 -1
- package/dist/modules/attendance_backend/screens/credentials.d.ts +32 -0
- package/dist/modules/attendance_backend/screens/credentials.d.ts.map +1 -0
- package/dist/modules/attendance_backend/screens/credentials.js +84 -0
- package/dist/modules/attendance_backend/screens/credentials.js.map +1 -0
- package/dist/modules/attendance_backend/screens/index.d.ts +4 -0
- package/dist/modules/attendance_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/attendance_backend/screens/index.js +4 -0
- package/dist/modules/attendance_backend/screens/index.js.map +1 -0
- package/dist/modules/attendance_backend/screens/my-work.d.ts +35 -0
- package/dist/modules/attendance_backend/screens/my-work.d.ts.map +1 -0
- package/dist/modules/attendance_backend/screens/my-work.js +189 -0
- package/dist/modules/attendance_backend/screens/my-work.js.map +1 -0
- package/dist/modules/attendance_backend/screens/period.d.ts +22 -0
- package/dist/modules/attendance_backend/screens/period.d.ts.map +1 -0
- package/dist/modules/attendance_backend/screens/period.js +85 -0
- package/dist/modules/attendance_backend/screens/period.js.map +1 -0
- package/dist/modules/attendance_backend/screens.d.ts +0 -4
- package/dist/modules/attendance_backend/screens.d.ts.map +1 -1
- package/dist/modules/attendance_backend/screens.js +1 -209
- package/dist/modules/attendance_backend/screens.js.map +1 -1
- package/dist/modules/backend/catalogue.d.ts.map +1 -1
- package/dist/modules/backend/catalogue.js +53 -115
- package/dist/modules/backend/catalogue.js.map +1 -1
- package/dist/modules/backend/chart.d.ts +42 -0
- package/dist/modules/backend/chart.d.ts.map +1 -0
- package/dist/modules/backend/chart.js +39 -0
- package/dist/modules/backend/chart.js.map +1 -0
- package/dist/modules/backend/design/HANDOFF.md +118 -38
- package/dist/modules/backend/design/auth.css +463 -0
- package/dist/modules/backend/design/brand/logo-dark.png +0 -0
- package/dist/modules/backend/design/brand/logo-light.png +0 -0
- package/dist/modules/backend/design/charts.css +229 -0
- package/dist/modules/backend/design/client/chart.d.mts +31 -0
- package/dist/modules/backend/design/client/chart.d.mts.map +1 -0
- package/dist/modules/backend/design/client/chart.mjs +23 -0
- package/dist/modules/backend/design/client/chart.mjs.map +7 -0
- package/dist/modules/backend/design/client/relation-select.d.mts +6 -1
- package/dist/modules/backend/design/client/relation-select.d.mts.map +1 -1
- package/dist/modules/backend/design/client/relation-select.mjs +2 -7
- package/dist/modules/backend/design/client/relation-select.mjs.map +7 -1
- package/dist/modules/backend/design/client/table-selection.d.mts +7 -0
- package/dist/modules/backend/design/client/table-selection.d.mts.map +1 -0
- package/dist/modules/backend/design/client/table-selection.mjs +2 -0
- package/dist/modules/backend/design/client/table-selection.mjs.map +7 -0
- package/dist/modules/backend/design/content.css +766 -0
- package/dist/modules/backend/design/controls.css +451 -0
- package/dist/modules/backend/design/design-system.css +2 -0
- package/dist/modules/backend/design/forms.css +1134 -0
- package/dist/modules/backend/design/foundation.css +423 -0
- package/dist/modules/backend/design/lists.css +1462 -0
- package/dist/modules/backend/design/record.css +526 -0
- package/dist/modules/backend/design/responsive.css +331 -0
- package/dist/modules/backend/design/tokens.css +317 -92
- package/dist/modules/backend/index.d.ts +12 -5
- package/dist/modules/backend/index.d.ts.map +1 -1
- package/dist/modules/backend/index.js +32 -15
- package/dist/modules/backend/index.js.map +1 -1
- package/dist/modules/backend/islands.d.ts.map +1 -1
- package/dist/modules/backend/islands.js +22 -4
- package/dist/modules/backend/islands.js.map +1 -1
- package/dist/modules/backend/joints.d.ts +1 -1
- package/dist/modules/backend/joints.d.ts.map +1 -1
- package/dist/modules/backend/joints.js +14 -6
- package/dist/modules/backend/joints.js.map +1 -1
- package/dist/modules/backend/list-search.d.ts +33 -0
- package/dist/modules/backend/list-search.d.ts.map +1 -0
- package/dist/modules/backend/list-search.js +232 -0
- package/dist/modules/backend/list-search.js.map +1 -0
- package/dist/modules/backend/menus.d.ts.map +1 -1
- package/dist/modules/backend/menus.js +3 -12
- package/dist/modules/backend/menus.js.map +1 -1
- package/dist/modules/backend/messages.d.ts +1 -1
- package/dist/modules/backend/messages.d.ts.map +1 -1
- package/dist/modules/backend/messages.js +48 -35
- package/dist/modules/backend/messages.js.map +1 -1
- package/dist/modules/backend/paging.d.ts +1 -1
- package/dist/modules/backend/paging.d.ts.map +1 -1
- package/dist/modules/backend/paging.js +1 -1
- package/dist/modules/backend/paging.js.map +1 -1
- package/dist/modules/backend/relation-select.d.ts +2 -57
- package/dist/modules/backend/relation-select.d.ts.map +1 -1
- package/dist/modules/backend/relation-select.js +2 -0
- package/dist/modules/backend/relation-select.js.map +1 -1
- package/dist/modules/backend/routes.d.ts +1 -8
- package/dist/modules/backend/routes.d.ts.map +1 -1
- package/dist/modules/backend/routes.js +36 -111
- package/dist/modules/backend/routes.js.map +1 -1
- package/dist/modules/backend/screen.d.ts +130 -0
- package/dist/modules/backend/screen.d.ts.map +1 -0
- package/dist/modules/backend/screen.js +205 -0
- package/dist/modules/backend/screen.js.map +1 -0
- package/dist/modules/backend/screens.d.ts +11 -14
- package/dist/modules/backend/screens.d.ts.map +1 -1
- package/dist/modules/backend/screens.js +13 -70
- package/dist/modules/backend/screens.js.map +1 -1
- package/dist/modules/business_report_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/business_report_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/business_report_staff_channel/channel-routes.js +438 -0
- package/dist/modules/business_report_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/business_report_staff_channel/index.d.ts +5 -0
- package/dist/modules/business_report_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/business_report_staff_channel/index.js +18 -0
- package/dist/modules/business_report_staff_channel/index.js.map +1 -0
- package/dist/modules/calendar/index.d.ts.map +1 -1
- package/dist/modules/calendar/index.js +0 -1
- package/dist/modules/calendar/index.js.map +1 -1
- package/dist/modules/calendar/recurrence.d.ts.map +1 -1
- package/dist/modules/calendar/recurrence.js +3 -11
- package/dist/modules/calendar/recurrence.js.map +1 -1
- package/dist/modules/calendar_activity/index.d.ts.map +1 -1
- package/dist/modules/calendar_activity/index.js +0 -2
- package/dist/modules/calendar_activity/index.js.map +1 -1
- package/dist/modules/calendar_backend/index.d.ts +1 -1
- package/dist/modules/calendar_backend/index.d.ts.map +1 -1
- package/dist/modules/calendar_backend/index.js +1 -3
- package/dist/modules/calendar_backend/index.js.map +1 -1
- package/dist/modules/calendar_backend/routes.d.ts.map +1 -1
- package/dist/modules/calendar_backend/routes.js +10 -22
- package/dist/modules/calendar_backend/routes.js.map +1 -1
- package/dist/modules/calendar_backend/screens/calendar.d.ts +5 -0
- package/dist/modules/calendar_backend/screens/calendar.d.ts.map +1 -0
- package/dist/modules/calendar_backend/screens/calendar.js +10 -0
- package/dist/modules/calendar_backend/screens/calendar.js.map +1 -0
- package/dist/modules/calendar_backend/screens/index.d.ts +2 -0
- package/dist/modules/calendar_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/calendar_backend/screens/index.js +2 -0
- package/dist/modules/calendar_backend/screens/index.js.map +1 -0
- package/dist/modules/calendar_mail_transport/index.d.ts.map +1 -1
- package/dist/modules/calendar_mail_transport/index.js +0 -2
- package/dist/modules/calendar_mail_transport/index.js.map +1 -1
- package/dist/modules/channel_api/core.d.ts +253 -0
- package/dist/modules/channel_api/core.d.ts.map +1 -0
- package/dist/modules/channel_api/core.js +587 -0
- package/dist/modules/channel_api/core.js.map +1 -0
- package/dist/modules/channel_api/customer.d.ts +21 -0
- package/dist/modules/channel_api/customer.d.ts.map +1 -0
- package/dist/modules/channel_api/customer.js +368 -0
- package/dist/modules/channel_api/customer.js.map +1 -0
- package/dist/modules/channel_api/index.d.ts +6 -0
- package/dist/modules/channel_api/index.d.ts.map +1 -0
- package/dist/modules/channel_api/index.js +66 -0
- package/dist/modules/channel_api/index.js.map +1 -0
- package/dist/modules/channel_api/openapi.d.ts +17 -0
- package/dist/modules/channel_api/openapi.d.ts.map +1 -0
- package/dist/modules/channel_api/openapi.js +105 -0
- package/dist/modules/channel_api/openapi.js.map +1 -0
- package/dist/modules/channel_api/staff.d.ts +7 -0
- package/dist/modules/channel_api/staff.d.ts.map +1 -0
- package/dist/modules/channel_api/staff.js +209 -0
- package/dist/modules/channel_api/staff.js.map +1 -0
- package/dist/modules/company/functions.d.ts.map +1 -1
- package/dist/modules/company/functions.js +93 -12
- package/dist/modules/company/functions.js.map +1 -1
- package/dist/modules/company/index.js +3 -3
- package/dist/modules/company/index.js.map +1 -1
- package/dist/modules/company/messages.d.ts +8 -0
- package/dist/modules/company/messages.d.ts.map +1 -1
- package/dist/modules/company/messages.js +8 -0
- package/dist/modules/company/messages.js.map +1 -1
- package/dist/modules/company/models.d.ts +2 -2
- package/dist/modules/company/models.d.ts.map +1 -1
- package/dist/modules/company/models.js +12 -2
- package/dist/modules/company/models.js.map +1 -1
- package/dist/modules/company_backend/index.d.ts +2 -1
- package/dist/modules/company_backend/index.d.ts.map +1 -1
- package/dist/modules/company_backend/index.js +25 -4
- package/dist/modules/company_backend/index.js.map +1 -1
- package/dist/modules/company_backend/routes.d.ts.map +1 -1
- package/dist/modules/company_backend/routes.js +314 -96
- package/dist/modules/company_backend/routes.js.map +1 -1
- package/dist/modules/company_backend/screens/branch-form.d.ts +18 -0
- package/dist/modules/company_backend/screens/branch-form.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/branch-form.js +63 -0
- package/dist/modules/company_backend/screens/branch-form.js.map +1 -0
- package/dist/modules/company_backend/screens/companies-list.d.ts +18 -0
- package/dist/modules/company_backend/screens/companies-list.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/companies-list.js +49 -0
- package/dist/modules/company_backend/screens/companies-list.js.map +1 -0
- package/dist/modules/company_backend/screens/company-form.d.ts +25 -0
- package/dist/modules/company_backend/screens/company-form.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/company-form.js +159 -0
- package/dist/modules/company_backend/screens/company-form.js.map +1 -0
- package/dist/modules/company_backend/screens/context.d.ts +30 -0
- package/dist/modules/company_backend/screens/context.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/context.js +48 -0
- package/dist/modules/company_backend/screens/context.js.map +1 -0
- package/dist/modules/company_backend/screens/hierarchy.d.ts +16 -0
- package/dist/modules/company_backend/screens/hierarchy.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/hierarchy.js +41 -0
- package/dist/modules/company_backend/screens/hierarchy.js.map +1 -0
- package/dist/modules/company_backend/screens/index.d.ts +7 -0
- package/dist/modules/company_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/index.js +6 -0
- package/dist/modules/company_backend/screens/index.js.map +1 -0
- package/dist/modules/company_backend/screens/types.d.ts +22 -0
- package/dist/modules/company_backend/screens/types.d.ts.map +1 -0
- package/dist/modules/company_backend/screens/types.js +2 -0
- package/dist/modules/company_backend/screens/types.js.map +1 -0
- package/dist/modules/crm/functions.d.ts +1 -1
- package/dist/modules/crm/functions.d.ts.map +1 -1
- package/dist/modules/crm/functions.js +534 -75
- package/dist/modules/crm/functions.js.map +1 -1
- package/dist/modules/crm/index.d.ts +2 -1
- package/dist/modules/crm/index.d.ts.map +1 -1
- package/dist/modules/crm/index.js +3 -4
- package/dist/modules/crm/index.js.map +1 -1
- package/dist/modules/crm/jobs.d.ts +10 -0
- package/dist/modules/crm/jobs.d.ts.map +1 -1
- package/dist/modules/crm/jobs.js +50 -1
- package/dist/modules/crm/jobs.js.map +1 -1
- package/dist/modules/crm/messages.d.ts +14 -1
- package/dist/modules/crm/messages.d.ts.map +1 -1
- package/dist/modules/crm/messages.js +26 -0
- package/dist/modules/crm/messages.js.map +1 -1
- package/dist/modules/crm/models.d.ts.map +1 -1
- package/dist/modules/crm/models.js +25 -0
- package/dist/modules/crm/models.js.map +1 -1
- package/dist/modules/crm/operations.d.ts +110 -1
- package/dist/modules/crm/operations.d.ts.map +1 -1
- package/dist/modules/crm/operations.js +612 -84
- package/dist/modules/crm/operations.js.map +1 -1
- package/dist/modules/crm_backend/client/crm-kanban-view.d.mts.map +1 -1
- package/dist/modules/crm_backend/client/crm-kanban-view.mjs +132 -32
- package/dist/modules/crm_backend/client/crm-kanban-view.mjs.map +1 -1
- package/dist/modules/crm_backend/client/crm.css +398 -63
- package/dist/modules/crm_backend/index.d.ts.map +1 -1
- package/dist/modules/crm_backend/index.js +12 -4
- package/dist/modules/crm_backend/index.js.map +1 -1
- package/dist/modules/crm_backend/messages.d.ts +212 -0
- package/dist/modules/crm_backend/messages.d.ts.map +1 -1
- package/dist/modules/crm_backend/messages.js +212 -0
- package/dist/modules/crm_backend/messages.js.map +1 -1
- package/dist/modules/crm_backend/relation-control.d.ts +51 -0
- package/dist/modules/crm_backend/relation-control.d.ts.map +1 -0
- package/dist/modules/crm_backend/relation-control.js +107 -0
- package/dist/modules/crm_backend/relation-control.js.map +1 -0
- package/dist/modules/crm_backend/routes.d.ts.map +1 -1
- package/dist/modules/crm_backend/routes.js +1068 -260
- package/dist/modules/crm_backend/routes.js.map +1 -1
- package/dist/modules/crm_backend/screens/activity-planner.d.ts +22 -0
- package/dist/modules/crm_backend/screens/activity-planner.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/activity-planner.js +159 -0
- package/dist/modules/crm_backend/screens/activity-planner.js.map +1 -0
- package/dist/modules/crm_backend/screens/case-create.d.ts +15 -0
- package/dist/modules/crm_backend/screens/case-create.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/case-create.js +19 -0
- package/dist/modules/crm_backend/screens/case-create.js.map +1 -0
- package/dist/modules/crm_backend/screens/case-detail.d.ts +46 -0
- package/dist/modules/crm_backend/screens/case-detail.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/case-detail.js +506 -0
- package/dist/modules/crm_backend/screens/case-detail.js.map +1 -0
- package/dist/modules/crm_backend/screens/cases-list.d.ts +16 -0
- package/dist/modules/crm_backend/screens/cases-list.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/cases-list.js +86 -0
- package/dist/modules/crm_backend/screens/cases-list.js.map +1 -0
- package/dist/modules/crm_backend/screens/configuration.d.ts +28 -0
- package/dist/modules/crm_backend/screens/configuration.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/configuration.js +115 -0
- package/dist/modules/crm_backend/screens/configuration.js.map +1 -0
- package/dist/modules/crm_backend/screens/index.d.ts +14 -0
- package/dist/modules/crm_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/index.js +8 -0
- package/dist/modules/crm_backend/screens/index.js.map +1 -0
- package/dist/modules/crm_backend/screens/leaderboard.d.ts +12 -0
- package/dist/modules/crm_backend/screens/leaderboard.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/leaderboard.js +89 -0
- package/dist/modules/crm_backend/screens/leaderboard.js.map +1 -0
- package/dist/modules/crm_backend/screens/pipeline.d.ts +21 -0
- package/dist/modules/crm_backend/screens/pipeline.d.ts.map +1 -0
- package/dist/modules/crm_backend/screens/pipeline.js +22 -0
- package/dist/modules/crm_backend/screens/pipeline.js.map +1 -0
- package/dist/modules/crm_sale/index.d.ts.map +1 -1
- package/dist/modules/crm_sale/index.js +3 -4
- package/dist/modules/crm_sale/index.js.map +1 -1
- package/dist/modules/crm_sale/messages.d.ts +3 -1
- package/dist/modules/crm_sale/messages.d.ts.map +1 -1
- package/dist/modules/crm_sale/messages.js +4 -0
- package/dist/modules/crm_sale/messages.js.map +1 -1
- package/dist/modules/crm_sale/sale-functions.d.ts +8 -1
- package/dist/modules/crm_sale/sale-functions.d.ts.map +1 -1
- package/dist/modules/crm_sale/sale-functions.js +184 -55
- package/dist/modules/crm_sale/sale-functions.js.map +1 -1
- package/dist/modules/crm_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/crm_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/crm_staff_channel/channel-routes.js +788 -0
- package/dist/modules/crm_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/crm_staff_channel/index.d.ts +5 -0
- package/dist/modules/crm_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/crm_staff_channel/index.js +30 -0
- package/dist/modules/crm_staff_channel/index.js.map +1 -0
- package/dist/modules/crm_website/functions.d.ts.map +1 -1
- package/dist/modules/crm_website/functions.js +89 -10
- package/dist/modules/crm_website/functions.js.map +1 -1
- package/dist/modules/crm_website/index.js +1 -2
- package/dist/modules/crm_website/index.js.map +1 -1
- package/dist/modules/crm_website/messages.d.ts +4 -1
- package/dist/modules/crm_website/messages.d.ts.map +1 -1
- package/dist/modules/crm_website/messages.js +6 -0
- package/dist/modules/crm_website/messages.js.map +1 -1
- package/dist/modules/crm_website/models.d.ts.map +1 -1
- package/dist/modules/crm_website/models.js +18 -0
- package/dist/modules/crm_website/models.js.map +1 -1
- package/dist/modules/crm_website/routes.d.ts.map +1 -1
- package/dist/modules/crm_website/routes.js +44 -12
- package/dist/modules/crm_website/routes.js.map +1 -1
- package/dist/modules/crm_website/screens.d.ts +7 -1
- package/dist/modules/crm_website/screens.d.ts.map +1 -1
- package/dist/modules/crm_website/screens.js +13 -8
- package/dist/modules/crm_website/screens.js.map +1 -1
- package/dist/modules/flow/functions.d.ts +3 -0
- package/dist/modules/flow/functions.d.ts.map +1 -0
- package/dist/modules/flow/functions.js +1876 -0
- package/dist/modules/flow/functions.js.map +1 -0
- package/dist/modules/flow/index.d.ts +12 -0
- package/dist/modules/flow/index.d.ts.map +1 -0
- package/dist/modules/flow/index.js +30 -0
- package/dist/modules/flow/index.js.map +1 -0
- package/dist/modules/flow/jobs.d.ts +3 -0
- package/dist/modules/flow/jobs.d.ts.map +1 -0
- package/dist/modules/flow/jobs.js +136 -0
- package/dist/modules/flow/jobs.js.map +1 -0
- package/dist/modules/flow/membership.d.ts +72 -0
- package/dist/modules/flow/membership.d.ts.map +1 -0
- package/dist/modules/flow/membership.js +176 -0
- package/dist/modules/flow/membership.js.map +1 -0
- package/dist/modules/flow/messages.d.ts +79 -0
- package/dist/modules/flow/messages.d.ts.map +1 -0
- package/dist/modules/flow/messages.js +152 -0
- package/dist/modules/flow/messages.js.map +1 -0
- package/dist/modules/flow/models.d.ts +3 -0
- package/dist/modules/flow/models.d.ts.map +1 -0
- package/dist/modules/flow/models.js +453 -0
- package/dist/modules/flow/models.js.map +1 -0
- package/dist/modules/flow/operations.d.ts +408 -0
- package/dist/modules/flow/operations.d.ts.map +1 -0
- package/dist/modules/flow/operations.js +1665 -0
- package/dist/modules/flow/operations.js.map +1 -0
- package/dist/modules/flow/pages.d.ts +146 -0
- package/dist/modules/flow/pages.d.ts.map +1 -0
- package/dist/modules/flow/pages.js +394 -0
- package/dist/modules/flow/pages.js.map +1 -0
- package/dist/modules/flow/projects.d.ts +41 -0
- package/dist/modules/flow/projects.d.ts.map +1 -0
- package/dist/modules/flow/projects.js +74 -0
- package/dist/modules/flow/projects.js.map +1 -0
- package/dist/modules/flow/search.d.ts +57 -0
- package/dist/modules/flow/search.d.ts.map +1 -0
- package/dist/modules/flow/search.js +110 -0
- package/dist/modules/flow/search.js.map +1 -0
- package/dist/modules/flow/types.d.ts +17 -0
- package/dist/modules/flow/types.d.ts.map +1 -0
- package/dist/modules/flow/types.js +13 -0
- package/dist/modules/flow/types.js.map +1 -0
- package/dist/modules/flow_backend/functions.d.ts +3 -0
- package/dist/modules/flow_backend/functions.d.ts.map +1 -0
- package/dist/modules/flow_backend/functions.js +162 -0
- package/dist/modules/flow_backend/functions.js.map +1 -0
- package/dist/modules/flow_backend/index.d.ts +3 -0
- package/dist/modules/flow_backend/index.d.ts.map +1 -0
- package/dist/modules/flow_backend/index.js +96 -0
- package/dist/modules/flow_backend/index.js.map +1 -0
- package/dist/modules/flow_backend/islands.d.ts +3 -0
- package/dist/modules/flow_backend/islands.d.ts.map +1 -0
- package/dist/modules/flow_backend/islands.js +31 -0
- package/dist/modules/flow_backend/islands.js.map +1 -0
- package/dist/modules/flow_backend/messages.d.ts +248 -0
- package/dist/modules/flow_backend/messages.d.ts.map +1 -0
- package/dist/modules/flow_backend/messages.js +470 -0
- package/dist/modules/flow_backend/messages.js.map +1 -0
- package/dist/modules/flow_backend/relation-control.d.ts +53 -0
- package/dist/modules/flow_backend/relation-control.d.ts.map +1 -0
- package/dist/modules/flow_backend/relation-control.js +106 -0
- package/dist/modules/flow_backend/relation-control.js.map +1 -0
- package/dist/modules/flow_backend/routes.d.ts +3 -0
- package/dist/modules/flow_backend/routes.d.ts.map +1 -0
- package/dist/modules/flow_backend/routes.js +2519 -0
- package/dist/modules/flow_backend/routes.js.map +1 -0
- package/dist/modules/flow_backend/screens/all-epics.d.ts +19 -0
- package/dist/modules/flow_backend/screens/all-epics.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/all-epics.js +59 -0
- package/dist/modules/flow_backend/screens/all-epics.js.map +1 -0
- package/dist/modules/flow_backend/screens/all-pages.d.ts +19 -0
- package/dist/modules/flow_backend/screens/all-pages.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/all-pages.js +65 -0
- package/dist/modules/flow_backend/screens/all-pages.js.map +1 -0
- package/dist/modules/flow_backend/screens/board.d.ts +5 -0
- package/dist/modules/flow_backend/screens/board.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/board.js +7 -0
- package/dist/modules/flow_backend/screens/board.js.map +1 -0
- package/dist/modules/flow_backend/screens/epic-detail.d.ts +22 -0
- package/dist/modules/flow_backend/screens/epic-detail.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/epic-detail.js +41 -0
- package/dist/modules/flow_backend/screens/epic-detail.js.map +1 -0
- package/dist/modules/flow_backend/screens/gantt.d.ts +21 -0
- package/dist/modules/flow_backend/screens/gantt.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/gantt.js +42 -0
- package/dist/modules/flow_backend/screens/gantt.js.map +1 -0
- package/dist/modules/flow_backend/screens/index.d.ts +29 -0
- package/dist/modules/flow_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/index.js +23 -0
- package/dist/modules/flow_backend/screens/index.js.map +1 -0
- package/dist/modules/flow_backend/screens/issue-detail.d.ts +38 -0
- package/dist/modules/flow_backend/screens/issue-detail.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/issue-detail.js +336 -0
- package/dist/modules/flow_backend/screens/issue-detail.js.map +1 -0
- package/dist/modules/flow_backend/screens/issues.d.ts +34 -0
- package/dist/modules/flow_backend/screens/issues.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/issues.js +118 -0
- package/dist/modules/flow_backend/screens/issues.js.map +1 -0
- package/dist/modules/flow_backend/screens/map.d.ts +13 -0
- package/dist/modules/flow_backend/screens/map.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/map.js +16 -0
- package/dist/modules/flow_backend/screens/map.js.map +1 -0
- package/dist/modules/flow_backend/screens/my-work.d.ts +42 -0
- package/dist/modules/flow_backend/screens/my-work.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/my-work.js +157 -0
- package/dist/modules/flow_backend/screens/my-work.js.map +1 -0
- package/dist/modules/flow_backend/screens/nav.d.ts +3 -0
- package/dist/modules/flow_backend/screens/nav.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/nav.js +79 -0
- package/dist/modules/flow_backend/screens/nav.js.map +1 -0
- package/dist/modules/flow_backend/screens/page-detail.d.ts +31 -0
- package/dist/modules/flow_backend/screens/page-detail.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/page-detail.js +113 -0
- package/dist/modules/flow_backend/screens/page-detail.js.map +1 -0
- package/dist/modules/flow_backend/screens/project-create.d.ts +26 -0
- package/dist/modules/flow_backend/screens/project-create.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/project-create.js +56 -0
- package/dist/modules/flow_backend/screens/project-create.js.map +1 -0
- package/dist/modules/flow_backend/screens/project-epics.d.ts +33 -0
- package/dist/modules/flow_backend/screens/project-epics.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/project-epics.js +90 -0
- package/dist/modules/flow_backend/screens/project-epics.js.map +1 -0
- package/dist/modules/flow_backend/screens/project-pages.d.ts +34 -0
- package/dist/modules/flow_backend/screens/project-pages.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/project-pages.js +66 -0
- package/dist/modules/flow_backend/screens/project-pages.js.map +1 -0
- package/dist/modules/flow_backend/screens/project-settings.d.ts +69 -0
- package/dist/modules/flow_backend/screens/project-settings.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/project-settings.js +248 -0
- package/dist/modules/flow_backend/screens/project-settings.js.map +1 -0
- package/dist/modules/flow_backend/screens/projects-list.d.ts +30 -0
- package/dist/modules/flow_backend/screens/projects-list.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/projects-list.js +121 -0
- package/dist/modules/flow_backend/screens/projects-list.js.map +1 -0
- package/dist/modules/flow_backend/screens/shared.d.ts +28 -0
- package/dist/modules/flow_backend/screens/shared.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/shared.js +46 -0
- package/dist/modules/flow_backend/screens/shared.js.map +1 -0
- package/dist/modules/flow_backend/screens/sprints.d.ts +33 -0
- package/dist/modules/flow_backend/screens/sprints.d.ts.map +1 -0
- package/dist/modules/flow_backend/screens/sprints.js +159 -0
- package/dist/modules/flow_backend/screens/sprints.js.map +1 -0
- package/dist/modules/flow_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/flow_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/flow_staff_channel/channel-routes.js +444 -0
- package/dist/modules/flow_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/flow_staff_channel/index.d.ts +5 -0
- package/dist/modules/flow_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/flow_staff_channel/index.js +30 -0
- package/dist/modules/flow_staff_channel/index.js.map +1 -0
- package/dist/modules/hospitality_billing/functions.d.ts +18 -0
- package/dist/modules/hospitality_billing/functions.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/functions.js +426 -0
- package/dist/modules/hospitality_billing/functions.js.map +1 -0
- package/dist/modules/hospitality_billing/index.d.ts +3 -0
- package/dist/modules/hospitality_billing/index.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/index.js +25 -0
- package/dist/modules/hospitality_billing/index.js.map +1 -0
- package/dist/modules/hospitality_billing/jobs.d.ts +17 -0
- package/dist/modules/hospitality_billing/jobs.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/jobs.js +83 -0
- package/dist/modules/hospitality_billing/jobs.js.map +1 -0
- package/dist/modules/hospitality_billing/menus.d.ts +9 -0
- package/dist/modules/hospitality_billing/menus.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/menus.js +25 -0
- package/dist/modules/hospitality_billing/menus.js.map +1 -0
- package/dist/modules/hospitality_billing/messages.d.ts +3 -0
- package/dist/modules/hospitality_billing/messages.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/messages.js +163 -0
- package/dist/modules/hospitality_billing/messages.js.map +1 -0
- package/dist/modules/hospitality_billing/models.d.ts +3 -0
- package/dist/modules/hospitality_billing/models.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/models.js +65 -0
- package/dist/modules/hospitality_billing/models.js.map +1 -0
- package/dist/modules/hospitality_billing/routes.d.ts +3 -0
- package/dist/modules/hospitality_billing/routes.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/routes.js +189 -0
- package/dist/modules/hospitality_billing/routes.js.map +1 -0
- package/dist/modules/hospitality_billing/screens/billing.d.ts +3 -0
- package/dist/modules/hospitality_billing/screens/billing.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/screens/billing.js +20 -0
- package/dist/modules/hospitality_billing/screens/billing.js.map +1 -0
- package/dist/modules/hospitality_billing/screens/charge-rules.d.ts +12 -0
- package/dist/modules/hospitality_billing/screens/charge-rules.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/screens/charge-rules.js +86 -0
- package/dist/modules/hospitality_billing/screens/charge-rules.js.map +1 -0
- package/dist/modules/hospitality_billing/screens/index.d.ts +4 -0
- package/dist/modules/hospitality_billing/screens/index.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/screens/index.js +4 -0
- package/dist/modules/hospitality_billing/screens/index.js.map +1 -0
- package/dist/modules/hospitality_billing/screens/page-frame.d.ts +14 -0
- package/dist/modules/hospitality_billing/screens/page-frame.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/screens/page-frame.js +6 -0
- package/dist/modules/hospitality_billing/screens/page-frame.js.map +1 -0
- package/dist/modules/hospitality_billing/screens/shared.d.ts +64 -0
- package/dist/modules/hospitality_billing/screens/shared.d.ts.map +1 -0
- package/dist/modules/hospitality_billing/screens/shared.js +117 -0
- package/dist/modules/hospitality_billing/screens/shared.js.map +1 -0
- package/dist/modules/hospitality_core/calendar.d.ts.map +1 -1
- package/dist/modules/hospitality_core/calendar.js +2 -1
- package/dist/modules/hospitality_core/calendar.js.map +1 -1
- package/dist/modules/hospitality_core/functions.d.ts.map +1 -1
- package/dist/modules/hospitality_core/functions.js +114 -14
- package/dist/modules/hospitality_core/functions.js.map +1 -1
- package/dist/modules/hospitality_core/index.d.ts +2 -2
- package/dist/modules/hospitality_core/index.d.ts.map +1 -1
- package/dist/modules/hospitality_core/index.js +3 -2
- package/dist/modules/hospitality_core/index.js.map +1 -1
- package/dist/modules/hospitality_core/inventory.d.ts +53 -4
- package/dist/modules/hospitality_core/inventory.d.ts.map +1 -1
- package/dist/modules/hospitality_core/inventory.js +121 -14
- package/dist/modules/hospitality_core/inventory.js.map +1 -1
- package/dist/modules/hospitality_core/menus.d.ts.map +1 -1
- package/dist/modules/hospitality_core/menus.js +31 -0
- package/dist/modules/hospitality_core/menus.js.map +1 -1
- package/dist/modules/hospitality_core/messages.d.ts.map +1 -1
- package/dist/modules/hospitality_core/messages.js +383 -183
- package/dist/modules/hospitality_core/messages.js.map +1 -1
- package/dist/modules/hospitality_core/models.d.ts +1 -1
- package/dist/modules/hospitality_core/models.d.ts.map +1 -1
- package/dist/modules/hospitality_core/models.js +47 -2
- package/dist/modules/hospitality_core/models.js.map +1 -1
- package/dist/modules/hospitality_core/night-audit.d.ts +1 -0
- package/dist/modules/hospitality_core/night-audit.d.ts.map +1 -1
- package/dist/modules/hospitality_core/night-audit.js +39 -1
- package/dist/modules/hospitality_core/night-audit.js.map +1 -1
- package/dist/modules/hospitality_core/online-booking.d.ts +5 -0
- package/dist/modules/hospitality_core/online-booking.d.ts.map +1 -0
- package/dist/modules/hospitality_core/online-booking.js +775 -0
- package/dist/modules/hospitality_core/online-booking.js.map +1 -0
- package/dist/modules/hospitality_core/operations.d.ts +21 -1
- package/dist/modules/hospitality_core/operations.d.ts.map +1 -1
- package/dist/modules/hospitality_core/operations.js +432 -67
- package/dist/modules/hospitality_core/operations.js.map +1 -1
- package/dist/modules/hospitality_core/routes.d.ts.map +1 -1
- package/dist/modules/hospitality_core/routes.js +503 -106
- package/dist/modules/hospitality_core/routes.js.map +1 -1
- package/dist/modules/hospitality_core/screens/amenities.d.ts +10 -0
- package/dist/modules/hospitality_core/screens/amenities.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/amenities.js +65 -0
- package/dist/modules/hospitality_core/screens/amenities.js.map +1 -0
- package/dist/modules/hospitality_core/screens/building-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/building-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/building-detail.js +69 -0
- package/dist/modules/hospitality_core/screens/building-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/cleaning-task-detail.d.ts +7 -0
- package/dist/modules/hospitality_core/screens/cleaning-task-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/cleaning-task-detail.js +109 -0
- package/dist/modules/hospitality_core/screens/cleaning-task-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts +20 -0
- package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/cleaning-tasks.js +139 -0
- package/dist/modules/hospitality_core/screens/cleaning-tasks.js.map +1 -0
- package/dist/modules/hospitality_core/screens/content.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/content.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/content.js +114 -0
- package/dist/modules/hospitality_core/screens/content.js.map +1 -0
- package/dist/modules/hospitality_core/screens/floor-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/floor-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/floor-detail.js +74 -0
- package/dist/modules/hospitality_core/screens/floor-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/folio-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/folio-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/folio-detail.js +142 -0
- package/dist/modules/hospitality_core/screens/folio-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/folios.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/folios.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/folios.js +7 -0
- package/dist/modules/hospitality_core/screens/folios.js.map +1 -0
- package/dist/modules/hospitality_core/screens/front-desk.d.ts +35 -0
- package/dist/modules/hospitality_core/screens/front-desk.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/front-desk.js +195 -0
- package/dist/modules/hospitality_core/screens/front-desk.js.map +1 -0
- package/dist/modules/hospitality_core/screens/housekeeping-room-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/housekeeping-room-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/housekeeping-room-detail.js +121 -0
- package/dist/modules/hospitality_core/screens/housekeeping-room-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/housekeeping-rooms.d.ts +9 -0
- package/dist/modules/hospitality_core/screens/housekeeping-rooms.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/housekeeping-rooms.js +54 -0
- package/dist/modules/hospitality_core/screens/housekeeping-rooms.js.map +1 -0
- package/dist/modules/hospitality_core/screens/index.d.ts +33 -0
- package/dist/modules/hospitality_core/screens/index.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/index.js +33 -0
- package/dist/modules/hospitality_core/screens/index.js.map +1 -0
- package/dist/modules/hospitality_core/screens/inventory.d.ts +8 -0
- package/dist/modules/hospitality_core/screens/inventory.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/inventory.js +122 -0
- package/dist/modules/hospitality_core/screens/inventory.js.map +1 -0
- package/dist/modules/hospitality_core/screens/new-property.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/new-property.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/new-property.js +8 -0
- package/dist/modules/hospitality_core/screens/new-property.js.map +1 -0
- package/dist/modules/hospitality_core/screens/new-room-type.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/new-room-type.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/new-room-type.js +8 -0
- package/dist/modules/hospitality_core/screens/new-room-type.js.map +1 -0
- package/dist/modules/hospitality_core/screens/new-room.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/new-room.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/new-room.js +8 -0
- package/dist/modules/hospitality_core/screens/new-room.js.map +1 -0
- package/dist/modules/hospitality_core/screens/night-audit.d.ts +10 -0
- package/dist/modules/hospitality_core/screens/night-audit.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/night-audit.js +67 -0
- package/dist/modules/hospitality_core/screens/night-audit.js.map +1 -0
- package/dist/modules/hospitality_core/screens/page-frame.d.ts +15 -0
- package/dist/modules/hospitality_core/screens/page-frame.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/page-frame.js +10 -0
- package/dist/modules/hospitality_core/screens/page-frame.js.map +1 -0
- package/dist/modules/hospitality_core/screens/policies.d.ts +10 -0
- package/dist/modules/hospitality_core/screens/policies.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/policies.js +72 -0
- package/dist/modules/hospitality_core/screens/policies.js.map +1 -0
- package/dist/modules/hospitality_core/screens/properties.d.ts +7 -0
- package/dist/modules/hospitality_core/screens/properties.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/properties.js +45 -0
- package/dist/modules/hospitality_core/screens/properties.js.map +1 -0
- package/dist/modules/hospitality_core/screens/property-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/property-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/property-detail.js +92 -0
- package/dist/modules/hospitality_core/screens/property-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/rate-plans.d.ts +10 -0
- package/dist/modules/hospitality_core/screens/rate-plans.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/rate-plans.js +123 -0
- package/dist/modules/hospitality_core/screens/rate-plans.js.map +1 -0
- package/dist/modules/hospitality_core/screens/reservation-detail.d.ts +11 -0
- package/dist/modules/hospitality_core/screens/reservation-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/reservation-detail.js +237 -0
- package/dist/modules/hospitality_core/screens/reservation-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/reservations.d.ts +17 -0
- package/dist/modules/hospitality_core/screens/reservations.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/reservations.js +166 -0
- package/dist/modules/hospitality_core/screens/reservations.js.map +1 -0
- package/dist/modules/hospitality_core/screens/room-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/room-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/room-detail.js +75 -0
- package/dist/modules/hospitality_core/screens/room-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/room-type-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/room-type-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/room-type-detail.js +91 -0
- package/dist/modules/hospitality_core/screens/room-type-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/room-types.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/room-types.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/room-types.js +61 -0
- package/dist/modules/hospitality_core/screens/room-types.js.map +1 -0
- package/dist/modules/hospitality_core/screens/rooms.d.ts +10 -0
- package/dist/modules/hospitality_core/screens/rooms.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/rooms.js +150 -0
- package/dist/modules/hospitality_core/screens/rooms.js.map +1 -0
- package/dist/modules/hospitality_core/screens/services.d.ts +18 -0
- package/dist/modules/hospitality_core/screens/services.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/services.js +196 -0
- package/dist/modules/hospitality_core/screens/services.js.map +1 -0
- package/dist/modules/hospitality_core/screens/shared.d.ts +777 -0
- package/dist/modules/hospitality_core/screens/shared.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/shared.js +1586 -0
- package/dist/modules/hospitality_core/screens/shared.js.map +1 -0
- package/dist/modules/hospitality_core/screens/stay-detail.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/stay-detail.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/stay-detail.js +233 -0
- package/dist/modules/hospitality_core/screens/stay-detail.js.map +1 -0
- package/dist/modules/hospitality_core/screens/stay-notices.d.ts +9 -0
- package/dist/modules/hospitality_core/screens/stay-notices.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/stay-notices.js +87 -0
- package/dist/modules/hospitality_core/screens/stay-notices.js.map +1 -0
- package/dist/modules/hospitality_core/screens/stays.d.ts +3 -0
- package/dist/modules/hospitality_core/screens/stays.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/stays.js +7 -0
- package/dist/modules/hospitality_core/screens/stays.js.map +1 -0
- package/dist/modules/hospitality_core/screens/tape-chart.d.ts +7 -0
- package/dist/modules/hospitality_core/screens/tape-chart.d.ts.map +1 -0
- package/dist/modules/hospitality_core/screens/tape-chart.js +99 -0
- package/dist/modules/hospitality_core/screens/tape-chart.js.map +1 -0
- package/dist/modules/hospitality_core/services.d.ts.map +1 -1
- package/dist/modules/hospitality_core/services.js +133 -30
- package/dist/modules/hospitality_core/services.js.map +1 -1
- package/dist/modules/hospitality_core/stay-notices.js +2 -2
- package/dist/modules/hospitality_core/stay-notices.js.map +1 -1
- package/dist/modules/hospitality_core/types.d.ts +26 -5
- package/dist/modules/hospitality_core/types.d.ts.map +1 -1
- package/dist/modules/hospitality_core/types.js +47 -5
- package/dist/modules/hospitality_core/types.js.map +1 -1
- package/dist/modules/hospitality_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/hospitality_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/hospitality_staff_channel/channel-routes.js +1227 -0
- package/dist/modules/hospitality_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/hospitality_staff_channel/index.d.ts +5 -0
- package/dist/modules/hospitality_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/hospitality_staff_channel/index.js +34 -0
- package/dist/modules/hospitality_staff_channel/index.js.map +1 -0
- package/dist/modules/hr/functions.d.ts.map +1 -1
- package/dist/modules/hr/functions.js +108 -44
- package/dist/modules/hr/functions.js.map +1 -1
- package/dist/modules/hr/index.d.ts.map +1 -1
- package/dist/modules/hr/index.js +0 -1
- package/dist/modules/hr/index.js.map +1 -1
- package/dist/modules/hr_backend/index.d.ts +2 -1
- package/dist/modules/hr_backend/index.d.ts.map +1 -1
- package/dist/modules/hr_backend/index.js +39 -7
- package/dist/modules/hr_backend/index.js.map +1 -1
- package/dist/modules/hr_backend/routes.d.ts.map +1 -1
- package/dist/modules/hr_backend/routes.js +279 -42
- package/dist/modules/hr_backend/routes.js.map +1 -1
- package/dist/modules/hr_backend/screens/employee-form.d.ts +28 -0
- package/dist/modules/hr_backend/screens/employee-form.d.ts.map +1 -0
- package/dist/modules/hr_backend/screens/employee-form.js +110 -0
- package/dist/modules/hr_backend/screens/employee-form.js.map +1 -0
- package/dist/modules/hr_backend/screens/employees-list.d.ts +22 -0
- package/dist/modules/hr_backend/screens/employees-list.d.ts.map +1 -0
- package/dist/modules/hr_backend/screens/employees-list.js +53 -0
- package/dist/modules/hr_backend/screens/employees-list.js.map +1 -0
- package/dist/modules/hr_backend/screens/index.d.ts +5 -0
- package/dist/modules/hr_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/hr_backend/screens/index.js +5 -0
- package/dist/modules/hr_backend/screens/index.js.map +1 -0
- package/dist/modules/hr_backend/screens/leaves-list.d.ts +22 -0
- package/dist/modules/hr_backend/screens/leaves-list.d.ts.map +1 -0
- package/dist/modules/hr_backend/screens/leaves-list.js +78 -0
- package/dist/modules/hr_backend/screens/leaves-list.js.map +1 -0
- package/dist/modules/hr_backend/screens/roster.d.ts +19 -0
- package/dist/modules/hr_backend/screens/roster.d.ts.map +1 -0
- package/dist/modules/hr_backend/screens/roster.js +83 -0
- package/dist/modules/hr_backend/screens/roster.js.map +1 -0
- package/dist/modules/inventory_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/inventory_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/inventory_staff_channel/channel-routes.js +724 -0
- package/dist/modules/inventory_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/inventory_staff_channel/index.d.ts +5 -0
- package/dist/modules/inventory_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/inventory_staff_channel/index.js +38 -0
- package/dist/modules/inventory_staff_channel/index.js.map +1 -0
- package/dist/modules/livedoc/documents.d.ts +48 -0
- package/dist/modules/livedoc/documents.d.ts.map +1 -0
- package/dist/modules/livedoc/documents.js +99 -0
- package/dist/modules/livedoc/documents.js.map +1 -0
- package/dist/modules/livedoc/functions.d.ts +3 -0
- package/dist/modules/livedoc/functions.d.ts.map +1 -0
- package/dist/modules/livedoc/functions.js +47 -0
- package/dist/modules/livedoc/functions.js.map +1 -0
- package/dist/modules/livedoc/index.d.ts +22 -0
- package/dist/modules/livedoc/index.d.ts.map +1 -0
- package/dist/modules/livedoc/index.js +37 -0
- package/dist/modules/livedoc/index.js.map +1 -0
- package/dist/modules/livedoc/islands.d.ts +3 -0
- package/dist/modules/livedoc/islands.d.ts.map +1 -0
- package/dist/modules/livedoc/islands.js +22 -0
- package/dist/modules/livedoc/islands.js.map +1 -0
- package/dist/modules/livedoc/routes.d.ts +11 -0
- package/dist/modules/livedoc/routes.d.ts.map +1 -0
- package/dist/modules/livedoc/routes.js +232 -0
- package/dist/modules/livedoc/routes.js.map +1 -0
- package/dist/modules/livedoc/sync.d.ts +124 -0
- package/dist/modules/livedoc/sync.d.ts.map +1 -0
- package/dist/modules/livedoc/sync.js +218 -0
- package/dist/modules/livedoc/sync.js.map +1 -0
- package/dist/modules/loyalty/admin-functions.d.ts.map +1 -1
- package/dist/modules/loyalty/admin-functions.js +42 -6
- package/dist/modules/loyalty/admin-functions.js.map +1 -1
- package/dist/modules/loyalty/engine.d.ts +1 -0
- package/dist/modules/loyalty/engine.d.ts.map +1 -1
- package/dist/modules/loyalty/engine.js +88 -28
- package/dist/modules/loyalty/engine.js.map +1 -1
- package/dist/modules/loyalty/index.d.ts.map +1 -1
- package/dist/modules/loyalty/index.js +10 -2
- package/dist/modules/loyalty/index.js.map +1 -1
- package/dist/modules/loyalty/ledger.d.ts.map +1 -1
- package/dist/modules/loyalty/ledger.js +11 -0
- package/dist/modules/loyalty/ledger.js.map +1 -1
- package/dist/modules/loyalty/membership-functions.d.ts.map +1 -1
- package/dist/modules/loyalty/membership-functions.js +23 -7
- package/dist/modules/loyalty/membership-functions.js.map +1 -1
- package/dist/modules/loyalty/messages.d.ts +8 -0
- package/dist/modules/loyalty/messages.d.ts.map +1 -1
- package/dist/modules/loyalty/messages.js +8 -0
- package/dist/modules/loyalty/messages.js.map +1 -1
- package/dist/modules/loyalty/models.d.ts.map +1 -1
- package/dist/modules/loyalty/models.js +20 -0
- package/dist/modules/loyalty/models.js.map +1 -1
- package/dist/modules/loyalty/order-functions.d.ts +16 -1
- package/dist/modules/loyalty/order-functions.d.ts.map +1 -1
- package/dist/modules/loyalty/order-functions.js +513 -291
- package/dist/modules/loyalty/order-functions.js.map +1 -1
- package/dist/modules/loyalty/stats.d.ts +17 -0
- package/dist/modules/loyalty/stats.d.ts.map +1 -0
- package/dist/modules/loyalty/stats.js +178 -0
- package/dist/modules/loyalty/stats.js.map +1 -0
- package/dist/modules/loyalty/stored-value.d.ts +42 -0
- package/dist/modules/loyalty/stored-value.d.ts.map +1 -0
- package/dist/modules/loyalty/stored-value.js +368 -0
- package/dist/modules/loyalty/stored-value.js.map +1 -0
- package/dist/modules/loyalty/types.d.ts +6 -4
- package/dist/modules/loyalty/types.d.ts.map +1 -1
- package/dist/modules/loyalty/types.js +1 -1
- package/dist/modules/loyalty/types.js.map +1 -1
- package/dist/modules/loyalty_backend/index.js +443 -172
- package/dist/modules/loyalty_backend/index.js.map +1 -1
- package/dist/modules/loyalty_backend/messages.d.ts +58 -1
- package/dist/modules/loyalty_backend/messages.d.ts.map +1 -1
- package/dist/modules/loyalty_backend/messages.js +114 -0
- package/dist/modules/loyalty_backend/messages.js.map +1 -1
- package/dist/modules/loyalty_backend/screens/index.d.ts +90 -0
- package/dist/modules/loyalty_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/loyalty_backend/screens/index.js +912 -0
- package/dist/modules/loyalty_backend/screens/index.js.map +1 -0
- package/dist/modules/loyalty_backend/screens/page-frame.d.ts +14 -0
- package/dist/modules/loyalty_backend/screens/page-frame.d.ts.map +1 -0
- package/dist/modules/loyalty_backend/screens/page-frame.js +13 -0
- package/dist/modules/loyalty_backend/screens/page-frame.js.map +1 -0
- package/dist/modules/loyalty_pos/channel.d.ts +2 -0
- package/dist/modules/loyalty_pos/channel.d.ts.map +1 -0
- package/dist/modules/loyalty_pos/channel.js +270 -0
- package/dist/modules/loyalty_pos/channel.js.map +1 -0
- package/dist/modules/loyalty_pos/functions.d.ts +11 -17
- package/dist/modules/loyalty_pos/functions.d.ts.map +1 -1
- package/dist/modules/loyalty_pos/functions.js +454 -94
- package/dist/modules/loyalty_pos/functions.js.map +1 -1
- package/dist/modules/loyalty_pos/index.js +6 -16
- package/dist/modules/loyalty_pos/index.js.map +1 -1
- package/dist/modules/loyalty_pos/jobs.d.ts +3 -0
- package/dist/modules/loyalty_pos/jobs.d.ts.map +1 -0
- package/dist/modules/loyalty_pos/jobs.js +30 -0
- package/dist/modules/loyalty_pos/jobs.js.map +1 -0
- package/dist/modules/loyalty_sale/functions.d.ts +2 -2
- package/dist/modules/loyalty_sale/functions.d.ts.map +1 -1
- package/dist/modules/loyalty_sale/functions.js +53 -34
- package/dist/modules/loyalty_sale/functions.js.map +1 -1
- package/dist/modules/loyalty_sale/index.js +0 -2
- package/dist/modules/loyalty_sale/index.js.map +1 -1
- package/dist/modules/mail/functions.d.ts.map +1 -1
- package/dist/modules/mail/functions.js +48 -6
- package/dist/modules/mail/functions.js.map +1 -1
- package/dist/modules/mail/index.d.ts.map +1 -1
- package/dist/modules/mail/index.js +0 -1
- package/dist/modules/mail/index.js.map +1 -1
- package/dist/modules/mail/operations.d.ts +19 -0
- package/dist/modules/mail/operations.d.ts.map +1 -1
- package/dist/modules/mail/operations.js +69 -0
- package/dist/modules/mail/operations.js.map +1 -1
- package/dist/modules/mail_backend/index.d.ts +1 -1
- package/dist/modules/mail_backend/index.d.ts.map +1 -1
- package/dist/modules/mail_backend/index.js +5 -14
- package/dist/modules/mail_backend/index.js.map +1 -1
- package/dist/modules/mail_backend/islands.js +2 -2
- package/dist/modules/mail_backend/islands.js.map +1 -1
- package/dist/modules/mail_backend/routes.d.ts.map +1 -1
- package/dist/modules/mail_backend/routes.js +25 -20
- package/dist/modules/mail_backend/routes.js.map +1 -1
- package/dist/modules/mail_backend/screens/inbox-list.d.ts +9 -0
- package/dist/modules/mail_backend/screens/inbox-list.d.ts.map +1 -0
- package/dist/modules/mail_backend/screens/inbox-list.js +13 -0
- package/dist/modules/mail_backend/screens/inbox-list.js.map +1 -0
- package/dist/modules/mail_backend/screens/index.d.ts +3 -0
- package/dist/modules/mail_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/mail_backend/screens/index.js +2 -0
- package/dist/modules/mail_backend/screens/index.js.map +1 -0
- package/dist/modules/mail_inbound/index.d.ts.map +1 -1
- package/dist/modules/mail_inbound/index.js +0 -1
- package/dist/modules/mail_inbound/index.js.map +1 -1
- package/dist/modules/mail_inbound_backend/index.d.ts +1 -1
- package/dist/modules/mail_inbound_backend/index.d.ts.map +1 -1
- package/dist/modules/mail_inbound_backend/index.js +3 -12
- package/dist/modules/mail_inbound_backend/index.js.map +1 -1
- package/dist/modules/mail_inbound_backend/routes.d.ts.map +1 -1
- package/dist/modules/mail_inbound_backend/routes.js +6 -21
- package/dist/modules/mail_inbound_backend/routes.js.map +1 -1
- package/dist/modules/mail_inbound_backend/screens/inbound-list.d.ts +8 -0
- package/dist/modules/mail_inbound_backend/screens/inbound-list.d.ts.map +1 -0
- package/dist/modules/mail_inbound_backend/screens/inbound-list.js +20 -0
- package/dist/modules/mail_inbound_backend/screens/inbound-list.js.map +1 -0
- package/dist/modules/mail_inbound_backend/screens/index.d.ts +3 -0
- package/dist/modules/mail_inbound_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/mail_inbound_backend/screens/index.js +2 -0
- package/dist/modules/mail_inbound_backend/screens/index.js.map +1 -0
- package/dist/modules/mail_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/mail_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/mail_staff_channel/channel-routes.js +183 -0
- package/dist/modules/mail_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/mail_staff_channel/index.d.ts +5 -0
- package/dist/modules/mail_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/mail_staff_channel/index.js +28 -0
- package/dist/modules/mail_staff_channel/index.js.map +1 -0
- package/dist/modules/mail_transport/index.d.ts.map +1 -1
- package/dist/modules/mail_transport/index.js +0 -1
- package/dist/modules/mail_transport/index.js.map +1 -1
- package/dist/modules/mail_transport_backend/index.d.ts +1 -1
- package/dist/modules/mail_transport_backend/index.d.ts.map +1 -1
- package/dist/modules/mail_transport_backend/index.js +3 -12
- package/dist/modules/mail_transport_backend/index.js.map +1 -1
- package/dist/modules/mail_transport_backend/routes.d.ts.map +1 -1
- package/dist/modules/mail_transport_backend/routes.js +23 -22
- package/dist/modules/mail_transport_backend/routes.js.map +1 -1
- package/dist/modules/mail_transport_backend/screens/index.d.ts +3 -0
- package/dist/modules/mail_transport_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/mail_transport_backend/screens/index.js +2 -0
- package/dist/modules/mail_transport_backend/screens/index.js.map +1 -0
- package/dist/modules/mail_transport_backend/screens/outbox-list.d.ts +9 -0
- package/dist/modules/mail_transport_backend/screens/outbox-list.d.ts.map +1 -0
- package/dist/modules/mail_transport_backend/screens/outbox-list.js +29 -0
- package/dist/modules/mail_transport_backend/screens/outbox-list.js.map +1 -0
- package/dist/modules/manufacturing/functions.d.ts +3 -0
- package/dist/modules/manufacturing/functions.d.ts.map +1 -0
- package/dist/modules/manufacturing/functions.js +912 -0
- package/dist/modules/manufacturing/functions.js.map +1 -0
- package/dist/modules/manufacturing/index.d.ts +6 -0
- package/dist/modules/manufacturing/index.d.ts.map +1 -0
- package/dist/modules/manufacturing/index.js +42 -0
- package/dist/modules/manufacturing/index.js.map +1 -0
- package/dist/modules/manufacturing/models.d.ts +8 -0
- package/dist/modules/manufacturing/models.d.ts.map +1 -0
- package/dist/modules/manufacturing/models.js +145 -0
- package/dist/modules/manufacturing/models.js.map +1 -0
- package/dist/modules/manufacturing/relations.d.ts.map +1 -0
- package/dist/modules/manufacturing/relations.js +37 -0
- package/dist/modules/manufacturing/relations.js.map +1 -0
- package/dist/modules/manufacturing/types.d.ts +7 -0
- package/dist/modules/manufacturing/types.d.ts.map +1 -0
- package/dist/modules/manufacturing/types.js +11 -0
- package/dist/modules/manufacturing/types.js.map +1 -0
- package/dist/modules/manufacturing_backend/index.d.ts +5 -0
- package/dist/modules/manufacturing_backend/index.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/index.js +146 -0
- package/dist/modules/manufacturing_backend/index.js.map +1 -0
- package/dist/modules/manufacturing_backend/routes.d.ts +3 -0
- package/dist/modules/manufacturing_backend/routes.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/routes.js +477 -0
- package/dist/modules/manufacturing_backend/routes.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/bom-create.d.ts +15 -0
- package/dist/modules/manufacturing_backend/screens/bom-create.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/bom-create.js +39 -0
- package/dist/modules/manufacturing_backend/screens/bom-create.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/boms-list.d.ts +18 -0
- package/dist/modules/manufacturing_backend/screens/boms-list.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/boms-list.js +36 -0
- package/dist/modules/manufacturing_backend/screens/boms-list.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/index.d.ts +8 -0
- package/dist/modules/manufacturing_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/index.js +8 -0
- package/dist/modules/manufacturing_backend/screens/index.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/order-create.d.ts +13 -0
- package/dist/modules/manufacturing_backend/screens/order-create.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/order-create.js +20 -0
- package/dist/modules/manufacturing_backend/screens/order-create.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/order-execution.d.ts +7 -0
- package/dist/modules/manufacturing_backend/screens/order-execution.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/order-execution.js +129 -0
- package/dist/modules/manufacturing_backend/screens/order-execution.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/orders-list.d.ts +21 -0
- package/dist/modules/manufacturing_backend/screens/orders-list.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/orders-list.js +49 -0
- package/dist/modules/manufacturing_backend/screens/orders-list.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/work-center-form.d.ts +24 -0
- package/dist/modules/manufacturing_backend/screens/work-center-form.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/work-center-form.js +80 -0
- package/dist/modules/manufacturing_backend/screens/work-center-form.js.map +1 -0
- package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts +23 -0
- package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts.map +1 -0
- package/dist/modules/manufacturing_backend/screens/work-centers-list.js +61 -0
- package/dist/modules/manufacturing_backend/screens/work-centers-list.js.map +1 -0
- package/dist/modules/oauth/index.d.ts.map +1 -1
- package/dist/modules/oauth/index.js +0 -1
- package/dist/modules/oauth/index.js.map +1 -1
- package/dist/modules/oauth/models.d.ts.map +1 -1
- package/dist/modules/oauth/models.js +2 -1
- package/dist/modules/oauth/models.js.map +1 -1
- package/dist/modules/oauth_backend/index.d.ts +1 -1
- package/dist/modules/oauth_backend/index.d.ts.map +1 -1
- package/dist/modules/oauth_backend/index.js +3 -5
- package/dist/modules/oauth_backend/index.js.map +1 -1
- package/dist/modules/oauth_backend/messages.d.ts +4 -0
- package/dist/modules/oauth_backend/messages.d.ts.map +1 -1
- package/dist/modules/oauth_backend/messages.js +4 -0
- package/dist/modules/oauth_backend/messages.js.map +1 -1
- package/dist/modules/oauth_backend/routes.d.ts.map +1 -1
- package/dist/modules/oauth_backend/routes.js +28 -30
- package/dist/modules/oauth_backend/routes.js.map +1 -1
- package/dist/modules/oauth_backend/screens/index.d.ts +66 -0
- package/dist/modules/oauth_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/oauth_backend/screens/index.js +306 -0
- package/dist/modules/oauth_backend/screens/index.js.map +1 -0
- package/dist/modules/partner/functions.d.ts.map +1 -1
- package/dist/modules/partner/functions.js +74 -6
- package/dist/modules/partner/functions.js.map +1 -1
- package/dist/modules/partner/index.d.ts.map +1 -1
- package/dist/modules/partner/index.js +0 -1
- package/dist/modules/partner/index.js.map +1 -1
- package/dist/modules/partner/models.d.ts +4 -4
- package/dist/modules/partner/models.d.ts.map +1 -1
- package/dist/modules/partner/models.js +9 -7
- package/dist/modules/partner/models.js.map +1 -1
- package/dist/modules/partner/types.d.ts +2 -2
- package/dist/modules/partner/types.js +2 -2
- package/dist/modules/partner_backend/client/address-view.mjs +5 -5
- package/dist/modules/partner_backend/client/address-view.mjs.map +1 -1
- package/dist/modules/partner_backend/client/address.css +22 -10
- package/dist/modules/partner_backend/client/partner.css +116 -0
- package/dist/modules/partner_backend/index.d.ts +1 -1
- package/dist/modules/partner_backend/index.d.ts.map +1 -1
- package/dist/modules/partner_backend/index.js +34 -4
- package/dist/modules/partner_backend/index.js.map +1 -1
- package/dist/modules/partner_backend/menus.js +2 -2
- package/dist/modules/partner_backend/menus.js.map +1 -1
- package/dist/modules/partner_backend/routes.d.ts +3 -1
- package/dist/modules/partner_backend/routes.d.ts.map +1 -1
- package/dist/modules/partner_backend/routes.js +236 -91
- package/dist/modules/partner_backend/routes.js.map +1 -1
- package/dist/modules/partner_backend/screens/form.d.ts +21 -0
- package/dist/modules/partner_backend/screens/form.d.ts.map +1 -0
- package/dist/modules/partner_backend/screens/form.js +101 -0
- package/dist/modules/partner_backend/screens/form.js.map +1 -0
- package/dist/modules/partner_backend/screens/index.d.ts +5 -0
- package/dist/modules/partner_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/partner_backend/screens/index.js +4 -0
- package/dist/modules/partner_backend/screens/index.js.map +1 -0
- package/dist/modules/partner_backend/screens/list.d.ts +6 -0
- package/dist/modules/partner_backend/screens/list.d.ts.map +1 -0
- package/dist/modules/partner_backend/screens/list.js +94 -0
- package/dist/modules/partner_backend/screens/list.js.map +1 -0
- package/dist/modules/partner_backend/screens/new.d.ts +5 -0
- package/dist/modules/partner_backend/screens/new.d.ts.map +1 -0
- package/dist/modules/partner_backend/screens/new.js +58 -0
- package/dist/modules/partner_backend/screens/new.js.map +1 -0
- package/dist/modules/partner_backend/screens/types.d.ts +44 -0
- package/dist/modules/partner_backend/screens/types.d.ts.map +1 -0
- package/dist/modules/partner_backend/screens/types.js +2 -0
- package/dist/modules/partner_backend/screens/types.js.map +1 -0
- package/dist/modules/partner_mail_backend/index.d.ts +5 -0
- package/dist/modules/partner_mail_backend/index.d.ts.map +1 -0
- package/dist/modules/partner_mail_backend/index.js +29 -0
- package/dist/modules/partner_mail_backend/index.js.map +1 -0
- package/dist/modules/pos/functions.d.ts +18 -2
- package/dist/modules/pos/functions.d.ts.map +1 -1
- package/dist/modules/pos/functions.js +3279 -345
- package/dist/modules/pos/functions.js.map +1 -1
- package/dist/modules/pos/index.d.ts +2 -1
- package/dist/modules/pos/index.d.ts.map +1 -1
- package/dist/modules/pos/index.js +5 -5
- package/dist/modules/pos/index.js.map +1 -1
- package/dist/modules/pos/models.d.ts.map +1 -1
- package/dist/modules/pos/models.js +189 -1
- package/dist/modules/pos/models.js.map +1 -1
- package/dist/modules/pos/relations.d.ts.map +1 -1
- package/dist/modules/pos/relations.js +11 -0
- package/dist/modules/pos/relations.js.map +1 -1
- package/dist/modules/pos_backend/index.js +182 -154
- package/dist/modules/pos_backend/index.js.map +1 -1
- package/dist/modules/pos_backend/screens.d.ts +1 -0
- package/dist/modules/pos_backend/screens.d.ts.map +1 -1
- package/dist/modules/pos_backend/screens.js +28 -38
- package/dist/modules/pos_backend/screens.js.map +1 -1
- package/dist/modules/pos_channel/catalog.d.ts +27 -0
- package/dist/modules/pos_channel/catalog.d.ts.map +1 -0
- package/dist/modules/pos_channel/catalog.js +310 -0
- package/dist/modules/pos_channel/catalog.js.map +1 -0
- package/dist/modules/pos_channel/index.d.ts +7 -0
- package/dist/modules/pos_channel/index.d.ts.map +1 -0
- package/dist/modules/pos_channel/index.js +61 -0
- package/dist/modules/pos_channel/index.js.map +1 -0
- package/dist/modules/pos_channel/offline.d.ts +66 -0
- package/dist/modules/pos_channel/offline.d.ts.map +1 -0
- package/dist/modules/pos_channel/offline.js +16 -0
- package/dist/modules/pos_channel/offline.js.map +1 -0
- package/dist/modules/pos_channel/operations.d.ts +422 -0
- package/dist/modules/pos_channel/operations.d.ts.map +1 -0
- package/dist/modules/pos_channel/operations.js +1781 -0
- package/dist/modules/pos_channel/operations.js.map +1 -0
- package/dist/modules/pos_channel/sync.d.ts +6 -0
- package/dist/modules/pos_channel/sync.d.ts.map +1 -0
- package/dist/modules/pos_channel/sync.js +1161 -0
- package/dist/modules/pos_channel/sync.js.map +1 -0
- package/dist/modules/pricing/index.d.ts.map +1 -1
- package/dist/modules/pricing/index.js +3 -4
- package/dist/modules/pricing/index.js.map +1 -1
- package/dist/modules/pricing_backend/index.js +135 -78
- package/dist/modules/pricing_backend/index.js.map +1 -1
- package/dist/modules/pricing_backend/screens/index.d.ts +5 -0
- package/dist/modules/pricing_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/pricing_backend/screens/index.js +4 -0
- package/dist/modules/pricing_backend/screens/index.js.map +1 -0
- package/dist/modules/pricing_backend/screens/pricelist-create.d.ts +10 -0
- package/dist/modules/pricing_backend/screens/pricelist-create.d.ts.map +1 -0
- package/dist/modules/pricing_backend/screens/pricelist-create.js +30 -0
- package/dist/modules/pricing_backend/screens/pricelist-create.js.map +1 -0
- package/dist/modules/pricing_backend/screens/pricelist-detail.d.ts +15 -0
- package/dist/modules/pricing_backend/screens/pricelist-detail.d.ts.map +1 -0
- package/dist/modules/pricing_backend/screens/pricelist-detail.js +164 -0
- package/dist/modules/pricing_backend/screens/pricelist-detail.js.map +1 -0
- package/dist/modules/pricing_backend/screens/pricelists-list.d.ts +11 -0
- package/dist/modules/pricing_backend/screens/pricelists-list.d.ts.map +1 -0
- package/dist/modules/pricing_backend/screens/pricelists-list.js +27 -0
- package/dist/modules/pricing_backend/screens/pricelists-list.js.map +1 -0
- package/dist/modules/pricing_backend/screens/shared.d.ts +21 -0
- package/dist/modules/pricing_backend/screens/shared.d.ts.map +1 -0
- package/dist/modules/pricing_backend/screens/shared.js +3 -0
- package/dist/modules/pricing_backend/screens/shared.js.map +1 -0
- package/dist/modules/product/functions.d.ts.map +1 -1
- package/dist/modules/product/functions.js +679 -50
- package/dist/modules/product/functions.js.map +1 -1
- package/dist/modules/product/index.d.ts +2 -0
- package/dist/modules/product/index.d.ts.map +1 -1
- package/dist/modules/product/index.js +2 -2
- package/dist/modules/product/index.js.map +1 -1
- package/dist/modules/product/models.d.ts +1 -1
- package/dist/modules/product/models.d.ts.map +1 -1
- package/dist/modules/product/models.js +27 -4
- package/dist/modules/product/models.js.map +1 -1
- package/dist/modules/product/relations.d.ts.map +1 -1
- package/dist/modules/product/relations.js +4 -0
- package/dist/modules/product/relations.js.map +1 -1
- package/dist/modules/product/sellable.d.ts +26 -0
- package/dist/modules/product/sellable.d.ts.map +1 -0
- package/dist/modules/product/sellable.js +56 -0
- package/dist/modules/product/sellable.js.map +1 -0
- package/dist/modules/product/types.d.ts +2 -2
- package/dist/modules/product/views.d.ts.map +1 -1
- package/dist/modules/product/views.js +5 -1
- package/dist/modules/product/views.js.map +1 -1
- package/dist/modules/product_activity_backend/index.d.ts.map +1 -1
- package/dist/modules/product_activity_backend/index.js +2 -3
- package/dist/modules/product_activity_backend/index.js.map +1 -1
- package/dist/modules/product_backend/client/media-upload-view.d.mts.map +1 -1
- package/dist/modules/product_backend/client/media-upload-view.mjs +1 -0
- package/dist/modules/product_backend/client/media-upload-view.mjs.map +1 -1
- package/dist/modules/product_backend/client/product.css +964 -0
- package/dist/modules/product_backend/index.d.ts +5 -6
- package/dist/modules/product_backend/index.d.ts.map +1 -1
- package/dist/modules/product_backend/index.js +203 -14
- package/dist/modules/product_backend/index.js.map +1 -1
- package/dist/modules/product_backend/menus.js +2 -2
- package/dist/modules/product_backend/menus.js.map +1 -1
- package/dist/modules/product_backend/relation-control.d.ts +85 -0
- package/dist/modules/product_backend/relation-control.d.ts.map +1 -0
- package/dist/modules/product_backend/relation-control.js +129 -0
- package/dist/modules/product_backend/relation-control.js.map +1 -0
- package/dist/modules/product_backend/routes.d.ts.map +1 -1
- package/dist/modules/product_backend/routes.js +502 -196
- package/dist/modules/product_backend/routes.js.map +1 -1
- package/dist/modules/product_backend/screens/attributes.d.ts +7 -0
- package/dist/modules/product_backend/screens/attributes.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/attributes.js +66 -0
- package/dist/modules/product_backend/screens/attributes.js.map +1 -0
- package/dist/modules/product_backend/screens/create.d.ts +16 -0
- package/dist/modules/product_backend/screens/create.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/create.js +86 -0
- package/dist/modules/product_backend/screens/create.js.map +1 -0
- package/dist/modules/product_backend/screens/detail.d.ts +87 -0
- package/dist/modules/product_backend/screens/detail.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/detail.js +381 -0
- package/dist/modules/product_backend/screens/detail.js.map +1 -0
- package/dist/modules/product_backend/screens/favorite.d.ts +6 -0
- package/dist/modules/product_backend/screens/favorite.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/favorite.js +43 -0
- package/dist/modules/product_backend/screens/favorite.js.map +1 -0
- package/dist/modules/product_backend/screens/index.d.ts +10 -0
- package/dist/modules/product_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/index.js +7 -0
- package/dist/modules/product_backend/screens/index.js.map +1 -0
- package/dist/modules/product_backend/screens/list.d.ts +54 -0
- package/dist/modules/product_backend/screens/list.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/list.js +124 -0
- package/dist/modules/product_backend/screens/list.js.map +1 -0
- package/dist/modules/product_backend/screens/variant.d.ts +9 -0
- package/dist/modules/product_backend/screens/variant.d.ts.map +1 -0
- package/dist/modules/product_backend/screens/variant.js +113 -0
- package/dist/modules/product_backend/screens/variant.js.map +1 -0
- package/dist/modules/product_mail_backend/index.d.ts.map +1 -1
- package/dist/modules/product_mail_backend/index.js +2 -3
- package/dist/modules/product_mail_backend/index.js.map +1 -1
- package/dist/modules/product_media/functions.d.ts.map +1 -1
- package/dist/modules/product_media/functions.js +59 -6
- package/dist/modules/product_media/functions.js.map +1 -1
- package/dist/modules/product_media/index.js +0 -1
- package/dist/modules/product_media/index.js.map +1 -1
- package/dist/modules/product_variant_activity_backend/index.d.ts.map +1 -1
- package/dist/modules/product_variant_activity_backend/index.js +2 -3
- package/dist/modules/product_variant_activity_backend/index.js.map +1 -1
- package/dist/modules/product_variant_mail_backend/index.d.ts.map +1 -1
- package/dist/modules/product_variant_mail_backend/index.js +2 -3
- package/dist/modules/product_variant_mail_backend/index.js.map +1 -1
- package/dist/modules/purchase/functions.d.ts.map +1 -1
- package/dist/modules/purchase/functions.js +852 -225
- package/dist/modules/purchase/functions.js.map +1 -1
- package/dist/modules/purchase/index.d.ts.map +1 -1
- package/dist/modules/purchase/index.js +30 -5
- package/dist/modules/purchase/index.js.map +1 -1
- package/dist/modules/purchase/models.d.ts.map +1 -1
- package/dist/modules/purchase/models.js +1 -0
- package/dist/modules/purchase/models.js.map +1 -1
- package/dist/modules/purchase/reports.d.ts +4 -0
- package/dist/modules/purchase/reports.d.ts.map +1 -0
- package/dist/modules/purchase/reports.js +86 -0
- package/dist/modules/purchase/reports.js.map +1 -0
- package/dist/modules/purchase_backend/index.js +513 -112
- package/dist/modules/purchase_backend/index.js.map +1 -1
- package/dist/modules/purchase_backend/screens/index.d.ts +10 -0
- package/dist/modules/purchase_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/index.js +10 -0
- package/dist/modules/purchase_backend/screens/index.js.map +1 -0
- package/dist/modules/purchase_backend/screens/order-detail.d.ts +31 -0
- package/dist/modules/purchase_backend/screens/order-detail.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/order-detail.js +204 -0
- package/dist/modules/purchase_backend/screens/order-detail.js.map +1 -0
- package/dist/modules/purchase_backend/screens/order-list-shared.d.ts +7 -0
- package/dist/modules/purchase_backend/screens/order-list-shared.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/order-list-shared.js +58 -0
- package/dist/modules/purchase_backend/screens/order-list-shared.js.map +1 -0
- package/dist/modules/purchase_backend/screens/overview.d.ts +19 -0
- package/dist/modules/purchase_backend/screens/overview.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/overview.js +52 -0
- package/dist/modules/purchase_backend/screens/overview.js.map +1 -0
- package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts +14 -0
- package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/purchase-orders-list.js +26 -0
- package/dist/modules/purchase_backend/screens/purchase-orders-list.js.map +1 -0
- package/dist/modules/purchase_backend/screens/rfq-create.d.ts +16 -0
- package/dist/modules/purchase_backend/screens/rfq-create.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/rfq-create.js +24 -0
- package/dist/modules/purchase_backend/screens/rfq-create.js.map +1 -0
- package/dist/modules/purchase_backend/screens/rfqs-list.d.ts +18 -0
- package/dist/modules/purchase_backend/screens/rfqs-list.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/rfqs-list.js +28 -0
- package/dist/modules/purchase_backend/screens/rfqs-list.js.map +1 -0
- package/dist/modules/purchase_backend/screens/shared.d.ts +18 -0
- package/dist/modules/purchase_backend/screens/shared.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/shared.js +30 -0
- package/dist/modules/purchase_backend/screens/shared.js.map +1 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelist-create.d.ts +20 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelist-create.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelist-create.js +25 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelist-create.js.map +1 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts +33 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts.map +1 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js +73 -0
- package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js.map +1 -0
- package/dist/modules/purchase_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/purchase_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/purchase_staff_channel/channel-routes.js +119 -0
- package/dist/modules/purchase_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/purchase_staff_channel/index.d.ts +8 -0
- package/dist/modules/purchase_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/purchase_staff_channel/index.js +45 -0
- package/dist/modules/purchase_staff_channel/index.js.map +1 -0
- package/dist/modules/purchase_staff_channel/order-routes.d.ts +2 -0
- package/dist/modules/purchase_staff_channel/order-routes.d.ts.map +1 -0
- package/dist/modules/purchase_staff_channel/order-routes.js +754 -0
- package/dist/modules/purchase_staff_channel/order-routes.js.map +1 -0
- package/dist/modules/purchase_staff_channel/product-routes.d.ts +2 -0
- package/dist/modules/purchase_staff_channel/product-routes.d.ts.map +1 -0
- package/dist/modules/purchase_staff_channel/product-routes.js +183 -0
- package/dist/modules/purchase_staff_channel/product-routes.js.map +1 -0
- package/dist/modules/purchase_staff_channel/vendor-bill-routes.d.ts +2 -0
- package/dist/modules/purchase_staff_channel/vendor-bill-routes.d.ts.map +1 -0
- package/dist/modules/purchase_staff_channel/vendor-bill-routes.js +189 -0
- package/dist/modules/purchase_staff_channel/vendor-bill-routes.js.map +1 -0
- package/dist/modules/quality/functions.d.ts +3 -0
- package/dist/modules/quality/functions.d.ts.map +1 -0
- package/dist/modules/quality/functions.js +381 -0
- package/dist/modules/quality/functions.js.map +1 -0
- package/dist/modules/quality/index.d.ts +5 -0
- package/dist/modules/quality/index.d.ts.map +1 -0
- package/dist/modules/quality/index.js +19 -0
- package/dist/modules/quality/index.js.map +1 -0
- package/dist/modules/quality/models.d.ts +3 -0
- package/dist/modules/quality/models.d.ts.map +1 -0
- package/dist/modules/quality/models.js +91 -0
- package/dist/modules/quality/models.js.map +1 -0
- package/dist/modules/quality_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/quality_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/quality_staff_channel/channel-routes.js +495 -0
- package/dist/modules/quality_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/quality_staff_channel/index.d.ts +5 -0
- package/dist/modules/quality_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/quality_staff_channel/index.js +30 -0
- package/dist/modules/quality_staff_channel/index.js.map +1 -0
- package/dist/modules/report/functions.d.ts +3 -0
- package/dist/modules/report/functions.d.ts.map +1 -0
- package/dist/modules/report/functions.js +197 -0
- package/dist/modules/report/functions.js.map +1 -0
- package/dist/modules/report/index.d.ts +3 -0
- package/dist/modules/report/index.d.ts.map +1 -0
- package/dist/modules/report/index.js +21 -0
- package/dist/modules/report/index.js.map +1 -0
- package/dist/modules/report/jobs.d.ts +3 -0
- package/dist/modules/report/jobs.d.ts.map +1 -0
- package/dist/modules/report/jobs.js +18 -0
- package/dist/modules/report/jobs.js.map +1 -0
- package/dist/modules/report/models.d.ts +3 -0
- package/dist/modules/report/models.d.ts.map +1 -0
- package/dist/modules/report/models.js +45 -0
- package/dist/modules/report/models.js.map +1 -0
- package/dist/modules/report/routes.d.ts +19 -0
- package/dist/modules/report/routes.d.ts.map +1 -0
- package/dist/modules/report/routes.js +138 -0
- package/dist/modules/report/routes.js.map +1 -0
- package/dist/modules/report_backend/index.d.ts +3 -0
- package/dist/modules/report_backend/index.d.ts.map +1 -0
- package/dist/modules/report_backend/index.js +67 -0
- package/dist/modules/report_backend/index.js.map +1 -0
- package/dist/modules/report_backend/routes.d.ts +10 -0
- package/dist/modules/report_backend/routes.d.ts.map +1 -0
- package/dist/modules/report_backend/routes.js +87 -0
- package/dist/modules/report_backend/routes.js.map +1 -0
- package/dist/modules/report_backend/screens/index.d.ts +13 -0
- package/dist/modules/report_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/report_backend/screens/index.js +91 -0
- package/dist/modules/report_backend/screens/index.js.map +1 -0
- package/dist/modules/sale/functions.d.ts.map +1 -1
- package/dist/modules/sale/functions.js +796 -238
- package/dist/modules/sale/functions.js.map +1 -1
- package/dist/modules/sale/index.d.ts.map +1 -1
- package/dist/modules/sale/index.js +44 -5
- package/dist/modules/sale/index.js.map +1 -1
- package/dist/modules/sale/models.d.ts.map +1 -1
- package/dist/modules/sale/models.js +47 -1
- package/dist/modules/sale/models.js.map +1 -1
- package/dist/modules/sale/relations.d.ts.map +1 -1
- package/dist/modules/sale/relations.js +6 -0
- package/dist/modules/sale/relations.js.map +1 -1
- package/dist/modules/sale/reports.d.ts +4 -0
- package/dist/modules/sale/reports.d.ts.map +1 -0
- package/dist/modules/sale/reports.js +132 -0
- package/dist/modules/sale/reports.js.map +1 -0
- package/dist/modules/sale/scope.d.ts +31 -0
- package/dist/modules/sale/scope.d.ts.map +1 -0
- package/dist/modules/sale/scope.js +34 -0
- package/dist/modules/sale/scope.js.map +1 -0
- package/dist/modules/sale_activity_backend/index.d.ts.map +1 -1
- package/dist/modules/sale_activity_backend/index.js +0 -1
- package/dist/modules/sale_activity_backend/index.js.map +1 -1
- package/dist/modules/sale_backend/index.js +338 -121
- package/dist/modules/sale_backend/index.js.map +1 -1
- package/dist/modules/sale_backend/screens/index.d.ts +9 -0
- package/dist/modules/sale_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/index.js +9 -0
- package/dist/modules/sale_backend/screens/index.js.map +1 -0
- package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts +14 -0
- package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/invoicing-policies-list.js +48 -0
- package/dist/modules/sale_backend/screens/invoicing-policies-list.js.map +1 -0
- package/dist/modules/sale_backend/screens/invoicing-policy-create.d.ts +14 -0
- package/dist/modules/sale_backend/screens/invoicing-policy-create.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/invoicing-policy-create.js +38 -0
- package/dist/modules/sale_backend/screens/invoicing-policy-create.js.map +1 -0
- package/dist/modules/sale_backend/screens/order-detail.d.ts +43 -0
- package/dist/modules/sale_backend/screens/order-detail.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/order-detail.js +226 -0
- package/dist/modules/sale_backend/screens/order-detail.js.map +1 -0
- package/dist/modules/sale_backend/screens/overview.d.ts +31 -0
- package/dist/modules/sale_backend/screens/overview.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/overview.js +73 -0
- package/dist/modules/sale_backend/screens/overview.js.map +1 -0
- package/dist/modules/sale_backend/screens/quotation-create.d.ts +13 -0
- package/dist/modules/sale_backend/screens/quotation-create.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/quotation-create.js +19 -0
- package/dist/modules/sale_backend/screens/quotation-create.js.map +1 -0
- package/dist/modules/sale_backend/screens/quotations-list.d.ts +25 -0
- package/dist/modules/sale_backend/screens/quotations-list.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/quotations-list.js +96 -0
- package/dist/modules/sale_backend/screens/quotations-list.js.map +1 -0
- package/dist/modules/sale_backend/screens/sales-orders-list.d.ts +25 -0
- package/dist/modules/sale_backend/screens/sales-orders-list.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/sales-orders-list.js +100 -0
- package/dist/modules/sale_backend/screens/sales-orders-list.js.map +1 -0
- package/dist/modules/sale_backend/screens/shared.d.ts +4 -0
- package/dist/modules/sale_backend/screens/shared.d.ts.map +1 -0
- package/dist/modules/sale_backend/screens/shared.js +4 -0
- package/dist/modules/sale_backend/screens/shared.js.map +1 -0
- package/dist/modules/sale_mail_backend/index.d.ts.map +1 -1
- package/dist/modules/sale_mail_backend/index.js +0 -1
- package/dist/modules/sale_mail_backend/index.js.map +1 -1
- package/dist/modules/sale_staff_channel/channel-routes.d.ts +2 -0
- package/dist/modules/sale_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/sale_staff_channel/channel-routes.js +296 -0
- package/dist/modules/sale_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/sale_staff_channel/index.d.ts +7 -0
- package/dist/modules/sale_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/sale_staff_channel/index.js +44 -0
- package/dist/modules/sale_staff_channel/index.js.map +1 -0
- package/dist/modules/sale_staff_channel/order-routes.d.ts +2 -0
- package/dist/modules/sale_staff_channel/order-routes.d.ts.map +1 -0
- package/dist/modules/sale_staff_channel/order-routes.js +658 -0
- package/dist/modules/sale_staff_channel/order-routes.js.map +1 -0
- package/dist/modules/sale_staff_channel/product-routes.d.ts +2 -0
- package/dist/modules/sale_staff_channel/product-routes.d.ts.map +1 -0
- package/dist/modules/sale_staff_channel/product-routes.js +183 -0
- package/dist/modules/sale_staff_channel/product-routes.js.map +1 -0
- package/dist/modules/stock/functions.d.ts.map +1 -1
- package/dist/modules/stock/functions.js +1239 -332
- package/dist/modules/stock/functions.js.map +1 -1
- package/dist/modules/stock/index.d.ts +2 -0
- package/dist/modules/stock/index.d.ts.map +1 -1
- package/dist/modules/stock/index.js +29 -6
- package/dist/modules/stock/index.js.map +1 -1
- package/dist/modules/stock/models.d.ts.map +1 -1
- package/dist/modules/stock/models.js +1 -0
- package/dist/modules/stock/models.js.map +1 -1
- package/dist/modules/stock/reports.d.ts +4 -0
- package/dist/modules/stock/reports.d.ts.map +1 -0
- package/dist/modules/stock/reports.js +100 -0
- package/dist/modules/stock/reports.js.map +1 -0
- package/dist/modules/stock/routing.d.ts +1 -1
- package/dist/modules/stock/routing.d.ts.map +1 -1
- package/dist/modules/stock/routing.js +35 -30
- package/dist/modules/stock/routing.js.map +1 -1
- package/dist/modules/stock/scope.d.ts +23 -0
- package/dist/modules/stock/scope.d.ts.map +1 -0
- package/dist/modules/stock/scope.js +26 -0
- package/dist/modules/stock/scope.js.map +1 -0
- package/dist/modules/stock/units.d.ts +14 -0
- package/dist/modules/stock/units.d.ts.map +1 -0
- package/dist/modules/stock/units.js +50 -0
- package/dist/modules/stock/units.js.map +1 -0
- package/dist/modules/stock_activity_backend/index.d.ts.map +1 -1
- package/dist/modules/stock_activity_backend/index.js +0 -1
- package/dist/modules/stock_activity_backend/index.js.map +1 -1
- package/dist/modules/stock_backend/client/editor-view.d.mts.map +1 -1
- package/dist/modules/stock_backend/client/editor-view.mjs +12 -10
- package/dist/modules/stock_backend/client/editor-view.mjs.map +1 -1
- package/dist/modules/stock_backend/index.js +27 -20
- package/dist/modules/stock_backend/index.js.map +1 -1
- package/dist/modules/stock_backend/routes.d.ts.map +1 -1
- package/dist/modules/stock_backend/routes.js +485 -232
- package/dist/modules/stock_backend/routes.js.map +1 -1
- package/dist/modules/stock_backend/screens/forecast.d.ts +28 -0
- package/dist/modules/stock_backend/screens/forecast.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/forecast.js +108 -0
- package/dist/modules/stock_backend/screens/forecast.js.map +1 -0
- package/dist/modules/stock_backend/screens/index.d.ts +22 -0
- package/dist/modules/stock_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/index.js +22 -0
- package/dist/modules/stock_backend/screens/index.js.map +1 -0
- package/dist/modules/stock_backend/screens/inventory.d.ts +27 -0
- package/dist/modules/stock_backend/screens/inventory.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/inventory.js +128 -0
- package/dist/modules/stock_backend/screens/inventory.js.map +1 -0
- package/dist/modules/stock_backend/screens/location-create.d.ts +15 -0
- package/dist/modules/stock_backend/screens/location-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/location-create.js +75 -0
- package/dist/modules/stock_backend/screens/location-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/locations-list.d.ts +21 -0
- package/dist/modules/stock_backend/screens/locations-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/locations-list.js +62 -0
- package/dist/modules/stock_backend/screens/locations-list.js.map +1 -0
- package/dist/modules/stock_backend/screens/lot-create.d.ts +14 -0
- package/dist/modules/stock_backend/screens/lot-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/lot-create.js +60 -0
- package/dist/modules/stock_backend/screens/lot-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/lot-detail.d.ts +30 -0
- package/dist/modules/stock_backend/screens/lot-detail.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/lot-detail.js +84 -0
- package/dist/modules/stock_backend/screens/lot-detail.js.map +1 -0
- package/dist/modules/stock_backend/screens/lots-list.d.ts +25 -0
- package/dist/modules/stock_backend/screens/lots-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/lots-list.js +54 -0
- package/dist/modules/stock_backend/screens/lots-list.js.map +1 -0
- package/dist/modules/stock_backend/screens/picking-type-create.d.ts +15 -0
- package/dist/modules/stock_backend/screens/picking-type-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/picking-type-create.js +89 -0
- package/dist/modules/stock_backend/screens/picking-type-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/picking-types-list.d.ts +22 -0
- package/dist/modules/stock_backend/screens/picking-types-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/picking-types-list.js +80 -0
- package/dist/modules/stock_backend/screens/picking-types-list.js.map +1 -0
- package/dist/modules/stock_backend/screens/replenishment-create.d.ts +17 -0
- package/dist/modules/stock_backend/screens/replenishment-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/replenishment-create.js +74 -0
- package/dist/modules/stock_backend/screens/replenishment-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/replenishment-list.d.ts +29 -0
- package/dist/modules/stock_backend/screens/replenishment-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/replenishment-list.js +84 -0
- package/dist/modules/stock_backend/screens/replenishment-list.js.map +1 -0
- package/dist/modules/stock_backend/screens/shared.d.ts +12 -0
- package/dist/modules/stock_backend/screens/shared.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/shared.js +29 -0
- package/dist/modules/stock_backend/screens/shared.js.map +1 -0
- package/dist/modules/stock_backend/screens/stock-route-create.d.ts +13 -0
- package/dist/modules/stock_backend/screens/stock-route-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/stock-route-create.js +52 -0
- package/dist/modules/stock_backend/screens/stock-route-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/stock-route-detail.d.ts +30 -0
- package/dist/modules/stock_backend/screens/stock-route-detail.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/stock-route-detail.js +131 -0
- package/dist/modules/stock_backend/screens/stock-route-detail.js.map +1 -0
- package/dist/modules/stock_backend/screens/stock-routes-list.d.ts +22 -0
- package/dist/modules/stock_backend/screens/stock-routes-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/stock-routes-list.js +51 -0
- package/dist/modules/stock_backend/screens/stock-routes-list.js.map +1 -0
- package/dist/modules/stock_backend/screens/stock.d.ts +7 -0
- package/dist/modules/stock_backend/screens/stock.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/stock.js +13 -0
- package/dist/modules/stock_backend/screens/stock.js.map +1 -0
- package/dist/modules/stock_backend/screens/transfer-create.d.ts +13 -0
- package/dist/modules/stock_backend/screens/transfer-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/transfer-create.js +38 -0
- package/dist/modules/stock_backend/screens/transfer-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/transfer-detail.d.ts +27 -0
- package/dist/modules/stock_backend/screens/transfer-detail.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/transfer-detail.js +91 -0
- package/dist/modules/stock_backend/screens/transfer-detail.js.map +1 -0
- package/dist/modules/stock_backend/screens/transfers-list.d.ts +25 -0
- package/dist/modules/stock_backend/screens/transfers-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/transfers-list.js +81 -0
- package/dist/modules/stock_backend/screens/transfers-list.js.map +1 -0
- package/dist/modules/stock_backend/screens/warehouse-create.d.ts +13 -0
- package/dist/modules/stock_backend/screens/warehouse-create.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/warehouse-create.js +79 -0
- package/dist/modules/stock_backend/screens/warehouse-create.js.map +1 -0
- package/dist/modules/stock_backend/screens/warehouses-list.d.ts +21 -0
- package/dist/modules/stock_backend/screens/warehouses-list.d.ts.map +1 -0
- package/dist/modules/stock_backend/screens/warehouses-list.js +60 -0
- package/dist/modules/stock_backend/screens/warehouses-list.js.map +1 -0
- package/dist/modules/stock_lot_activity_backend/index.d.ts.map +1 -1
- package/dist/modules/stock_lot_activity_backend/index.js +0 -1
- package/dist/modules/stock_lot_activity_backend/index.js.map +1 -1
- package/dist/modules/stock_lot_mail_backend/index.d.ts.map +1 -1
- package/dist/modules/stock_lot_mail_backend/index.js +0 -1
- package/dist/modules/stock_lot_mail_backend/index.js.map +1 -1
- package/dist/modules/stock_mail_backend/index.d.ts.map +1 -1
- package/dist/modules/stock_mail_backend/index.js +0 -1
- package/dist/modules/stock_mail_backend/index.js.map +1 -1
- package/dist/modules/stock_mail_inbound/index.d.ts.map +1 -1
- package/dist/modules/stock_mail_inbound/index.js +0 -2
- package/dist/modules/stock_mail_inbound/index.js.map +1 -1
- package/dist/modules/stock_staff_channel/channel-routes.d.ts +656 -0
- package/dist/modules/stock_staff_channel/channel-routes.d.ts.map +1 -0
- package/dist/modules/stock_staff_channel/channel-routes.js +445 -0
- package/dist/modules/stock_staff_channel/channel-routes.js.map +1 -0
- package/dist/modules/stock_staff_channel/functions.d.ts +3 -0
- package/dist/modules/stock_staff_channel/functions.d.ts.map +1 -0
- package/dist/modules/stock_staff_channel/functions.js +954 -0
- package/dist/modules/stock_staff_channel/functions.js.map +1 -0
- package/dist/modules/stock_staff_channel/index.d.ts +8 -0
- package/dist/modules/stock_staff_channel/index.d.ts.map +1 -0
- package/dist/modules/stock_staff_channel/index.js +37 -0
- package/dist/modules/stock_staff_channel/index.js.map +1 -0
- package/dist/modules/stock_staff_channel/models.d.ts +4 -0
- package/dist/modules/stock_staff_channel/models.d.ts.map +1 -0
- package/dist/modules/stock_staff_channel/models.js +119 -0
- package/dist/modules/stock_staff_channel/models.js.map +1 -0
- package/dist/modules/stock_staff_channel/operation-routes.d.ts +2 -0
- package/dist/modules/stock_staff_channel/operation-routes.d.ts.map +1 -0
- package/dist/modules/stock_staff_channel/operation-routes.js +1269 -0
- package/dist/modules/stock_staff_channel/operation-routes.js.map +1 -0
- package/dist/modules/storage/functions.d.ts.map +1 -1
- package/dist/modules/storage/functions.js +18 -5
- package/dist/modules/storage/functions.js.map +1 -1
- package/dist/modules/storage/index.js +0 -1
- package/dist/modules/storage/index.js.map +1 -1
- package/dist/modules/storage/jobs.d.ts +21 -1
- package/dist/modules/storage/jobs.d.ts.map +1 -1
- package/dist/modules/storage/jobs.js +142 -2
- package/dist/modules/storage/jobs.js.map +1 -1
- package/dist/modules/storage/models.d.ts.map +1 -1
- package/dist/modules/storage/models.js +2 -0
- package/dist/modules/storage/models.js.map +1 -1
- package/dist/modules/storage/policy.d.ts +5 -0
- package/dist/modules/storage/policy.d.ts.map +1 -0
- package/dist/modules/storage/policy.js +13 -0
- package/dist/modules/storage/policy.js.map +1 -0
- package/dist/modules/storage/routes.d.ts +1 -0
- package/dist/modules/storage/routes.d.ts.map +1 -1
- package/dist/modules/storage/routes.js +19 -15
- package/dist/modules/storage/routes.js.map +1 -1
- package/dist/modules/uom/convert.d.ts +1 -1
- package/dist/modules/uom/convert.js +2 -2
- package/dist/modules/uom/convert.js.map +1 -1
- package/dist/modules/uom/functions.d.ts.map +1 -1
- package/dist/modules/uom/functions.js +39 -4
- package/dist/modules/uom/functions.js.map +1 -1
- package/dist/modules/uom/index.d.ts.map +1 -1
- package/dist/modules/uom/index.js +1 -2
- package/dist/modules/uom/index.js.map +1 -1
- package/dist/modules/uom/messages.js +2 -2
- package/dist/modules/uom/messages.js.map +1 -1
- package/dist/modules/uom/models.d.ts +1 -1
- package/dist/modules/uom/models.d.ts.map +1 -1
- package/dist/modules/uom/models.js +1 -1
- package/dist/modules/uom/models.js.map +1 -1
- package/dist/modules/user/authorization.d.ts +80 -0
- package/dist/modules/user/authorization.d.ts.map +1 -0
- package/dist/modules/user/authorization.js +1039 -0
- package/dist/modules/user/authorization.js.map +1 -0
- package/dist/modules/user/functions.d.ts.map +1 -1
- package/dist/modules/user/functions.js +188 -32
- package/dist/modules/user/functions.js.map +1 -1
- package/dist/modules/user/index.d.ts +4 -1
- package/dist/modules/user/index.d.ts.map +1 -1
- package/dist/modules/user/index.js +2 -3
- package/dist/modules/user/index.js.map +1 -1
- package/dist/modules/user/login.d.ts +1 -27
- package/dist/modules/user/login.d.ts.map +1 -1
- package/dist/modules/user/login.js +5 -45
- package/dist/modules/user/login.js.map +1 -1
- package/dist/modules/user/messages.d.ts +6 -0
- package/dist/modules/user/messages.d.ts.map +1 -1
- package/dist/modules/user/messages.js +6 -0
- package/dist/modules/user/messages.js.map +1 -1
- package/dist/modules/user/models.d.ts +1 -1
- package/dist/modules/user/models.d.ts.map +1 -1
- package/dist/modules/user/models.js +73 -9
- package/dist/modules/user/models.js.map +1 -1
- package/dist/modules/user/relations.d.ts.map +1 -1
- package/dist/modules/user/relations.js +6 -0
- package/dist/modules/user/relations.js.map +1 -1
- package/dist/modules/user/roles.d.ts +11 -1
- package/dist/modules/user/roles.d.ts.map +1 -1
- package/dist/modules/user/roles.js +402 -117
- package/dist/modules/user/roles.js.map +1 -1
- package/dist/modules/user/routes.js +1 -1
- package/dist/modules/user/routes.js.map +1 -1
- package/dist/modules/user_backend/index.d.ts +1 -1
- package/dist/modules/user_backend/index.d.ts.map +1 -1
- package/dist/modules/user_backend/index.js +1 -3
- package/dist/modules/user_backend/index.js.map +1 -1
- package/dist/modules/user_backend/messages.d.ts +60 -0
- package/dist/modules/user_backend/messages.d.ts.map +1 -1
- package/dist/modules/user_backend/messages.js +60 -0
- package/dist/modules/user_backend/messages.js.map +1 -1
- package/dist/modules/user_backend/routes.d.ts.map +1 -1
- package/dist/modules/user_backend/routes.js +352 -69
- package/dist/modules/user_backend/routes.js.map +1 -1
- package/dist/modules/user_backend/screens/index.d.ts +11 -0
- package/dist/modules/user_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/index.js +8 -0
- package/dist/modules/user_backend/screens/index.js.map +1 -0
- package/dist/modules/user_backend/screens/presets-form.d.ts +16 -0
- package/dist/modules/user_backend/screens/presets-form.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/presets-form.js +37 -0
- package/dist/modules/user_backend/screens/presets-form.js.map +1 -0
- package/dist/modules/user_backend/screens/profile-form.d.ts +14 -0
- package/dist/modules/user_backend/screens/profile-form.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/profile-form.js +37 -0
- package/dist/modules/user_backend/screens/profile-form.js.map +1 -0
- package/dist/modules/user_backend/screens/role-form.d.ts +21 -0
- package/dist/modules/user_backend/screens/role-form.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/role-form.js +93 -0
- package/dist/modules/user_backend/screens/role-form.js.map +1 -0
- package/dist/modules/user_backend/screens/roles-list.d.ts +15 -0
- package/dist/modules/user_backend/screens/roles-list.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/roles-list.js +48 -0
- package/dist/modules/user_backend/screens/roles-list.js.map +1 -0
- package/dist/modules/user_backend/screens/sessions.d.ts +5 -0
- package/dist/modules/user_backend/screens/sessions.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/sessions.js +35 -0
- package/dist/modules/user_backend/screens/sessions.js.map +1 -0
- package/dist/modules/user_backend/screens/types.d.ts +68 -0
- package/dist/modules/user_backend/screens/types.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/types.js +2 -0
- package/dist/modules/user_backend/screens/types.js.map +1 -0
- package/dist/modules/user_backend/screens/user-form.d.ts +55 -0
- package/dist/modules/user_backend/screens/user-form.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/user-form.js +174 -0
- package/dist/modules/user_backend/screens/user-form.js.map +1 -0
- package/dist/modules/user_backend/screens/users-list.d.ts +17 -0
- package/dist/modules/user_backend/screens/users-list.d.ts.map +1 -0
- package/dist/modules/user_backend/screens/users-list.js +56 -0
- package/dist/modules/user_backend/screens/users-list.js.map +1 -0
- package/dist/modules/website/cms.d.ts +18 -1
- package/dist/modules/website/cms.d.ts.map +1 -1
- package/dist/modules/website/cms.js +373 -38
- package/dist/modules/website/cms.js.map +1 -1
- package/dist/modules/website/customer.d.ts.map +1 -1
- package/dist/modules/website/customer.js +249 -1
- package/dist/modules/website/customer.js.map +1 -1
- package/dist/modules/website/index.d.ts.map +1 -1
- package/dist/modules/website/index.js +26 -4
- package/dist/modules/website/index.js.map +1 -1
- package/dist/modules/website/models.d.ts.map +1 -1
- package/dist/modules/website/models.js +101 -0
- package/dist/modules/website/models.js.map +1 -1
- package/dist/modules/website/paths.d.ts +31 -0
- package/dist/modules/website/paths.d.ts.map +1 -0
- package/dist/modules/website/paths.js +48 -0
- package/dist/modules/website/paths.js.map +1 -0
- package/dist/modules/website/publication.d.ts +3 -0
- package/dist/modules/website/publication.d.ts.map +1 -0
- package/dist/modules/website/publication.js +366 -0
- package/dist/modules/website/publication.js.map +1 -0
- package/dist/modules/website/renderable.d.ts +32 -0
- package/dist/modules/website/renderable.d.ts.map +1 -0
- package/dist/modules/website/renderable.js +59 -0
- package/dist/modules/website/renderable.js.map +1 -0
- package/dist/modules/website/sections.d.ts.map +1 -1
- package/dist/modules/website/sections.js +13 -0
- package/dist/modules/website/sections.js.map +1 -1
- package/dist/modules/website_backend/csv.d.ts +23 -0
- package/dist/modules/website_backend/csv.d.ts.map +1 -0
- package/dist/modules/website_backend/csv.js +31 -0
- package/dist/modules/website_backend/csv.js.map +1 -0
- package/dist/modules/website_backend/index.js +260 -2
- package/dist/modules/website_backend/index.js.map +1 -1
- package/dist/modules/website_backend/menus.d.ts.map +1 -1
- package/dist/modules/website_backend/menus.js +28 -6
- package/dist/modules/website_backend/menus.js.map +1 -1
- package/dist/modules/website_backend/routes.d.ts.map +1 -1
- package/dist/modules/website_backend/routes.js +684 -126
- package/dist/modules/website_backend/routes.js.map +1 -1
- package/dist/modules/website_backend/screens/index.d.ts +333 -0
- package/dist/modules/website_backend/screens/index.d.ts.map +1 -0
- package/dist/modules/website_backend/screens/index.js +1332 -0
- package/dist/modules/website_backend/screens/index.js.map +1 -0
- package/dist/modules/website_backend/screens/page-frame.d.ts +14 -0
- package/dist/modules/website_backend/screens/page-frame.d.ts.map +1 -0
- package/dist/modules/website_backend/screens/page-frame.js +13 -0
- package/dist/modules/website_backend/screens/page-frame.js.map +1 -0
- package/dist/modules/website_form/audit.d.ts +27 -0
- package/dist/modules/website_form/audit.d.ts.map +1 -0
- package/dist/modules/website_form/audit.js +30 -0
- package/dist/modules/website_form/audit.js.map +1 -0
- package/dist/modules/website_form/functions.d.ts.map +1 -1
- package/dist/modules/website_form/functions.js +416 -12
- package/dist/modules/website_form/functions.js.map +1 -1
- package/dist/modules/website_form/index.js +24 -2
- package/dist/modules/website_form/index.js.map +1 -1
- package/dist/modules/website_form/jobs.d.ts +11 -0
- package/dist/modules/website_form/jobs.d.ts.map +1 -0
- package/dist/modules/website_form/jobs.js +80 -0
- package/dist/modules/website_form/jobs.js.map +1 -0
- package/dist/modules/website_form/models.d.ts.map +1 -1
- package/dist/modules/website_form/models.js +89 -0
- package/dist/modules/website_form/models.js.map +1 -1
- package/dist/modules/website_form/purge.d.ts +22 -0
- package/dist/modules/website_form/purge.d.ts.map +1 -0
- package/dist/modules/website_form/purge.js +59 -0
- package/dist/modules/website_form/purge.js.map +1 -0
- package/dist/modules/website_form/retention.d.ts +70 -0
- package/dist/modules/website_form/retention.d.ts.map +1 -0
- package/dist/modules/website_form/retention.js +145 -0
- package/dist/modules/website_form/retention.js.map +1 -0
- package/dist/modules/website_form/routes.d.ts.map +1 -1
- package/dist/modules/website_form/routes.js +37 -3
- package/dist/modules/website_form/routes.js.map +1 -1
- package/dist/modules/website_form_mail/index.d.ts +36 -0
- package/dist/modules/website_form_mail/index.d.ts.map +1 -0
- package/dist/modules/website_form_mail/index.js +137 -0
- package/dist/modules/website_form_mail/index.js.map +1 -0
- package/dist/modules/website_hospitality/channel-routes.d.ts +2 -0
- package/dist/modules/website_hospitality/channel-routes.d.ts.map +1 -0
- package/dist/modules/website_hospitality/channel-routes.js +355 -0
- package/dist/modules/website_hospitality/channel-routes.js.map +1 -0
- package/dist/modules/website_hospitality/functions.d.ts.map +1 -1
- package/dist/modules/website_hospitality/functions.js +27 -2
- package/dist/modules/website_hospitality/functions.js.map +1 -1
- package/dist/modules/website_hospitality/index.js +4 -3
- package/dist/modules/website_hospitality/index.js.map +1 -1
- package/dist/modules/website_hospitality/models.d.ts.map +1 -1
- package/dist/modules/website_hospitality/models.js +2 -0
- package/dist/modules/website_hospitality/models.js.map +1 -1
- package/dist/modules/website_menu/functions.d.ts.map +1 -1
- package/dist/modules/website_menu/functions.js +184 -9
- package/dist/modules/website_menu/functions.js.map +1 -1
- package/dist/modules/website_menu/index.js +6 -1
- package/dist/modules/website_menu/index.js.map +1 -1
- package/dist/modules/website_retail/channel-routes.d.ts +2 -0
- package/dist/modules/website_retail/channel-routes.d.ts.map +1 -0
- package/dist/modules/website_retail/channel-routes.js +305 -0
- package/dist/modules/website_retail/channel-routes.js.map +1 -0
- package/dist/modules/website_retail/functions.d.ts +14 -1
- package/dist/modules/website_retail/functions.d.ts.map +1 -1
- package/dist/modules/website_retail/functions.js +6 -6
- package/dist/modules/website_retail/functions.js.map +1 -1
- package/dist/modules/website_retail/index.js +24 -3
- package/dist/modules/website_retail/index.js.map +1 -1
- package/dist/modules/website_retail/models.d.ts.map +1 -1
- package/dist/modules/website_retail/models.js +30 -0
- package/dist/modules/website_retail/models.js.map +1 -1
- package/dist/modules/website_retail/online.d.ts +3 -0
- package/dist/modules/website_retail/online.d.ts.map +1 -0
- package/dist/modules/website_retail/online.js +710 -0
- package/dist/modules/website_retail/online.js.map +1 -0
- package/dist/modules/website_search/client/search.d.mts +16 -2
- package/dist/modules/website_search/client/search.d.mts.map +1 -1
- package/dist/modules/website_search/client/search.mjs +112 -6
- package/dist/modules/website_search/client/search.mjs.map +1 -1
- package/dist/modules/website_search/functions.d.ts +3 -0
- package/dist/modules/website_search/functions.d.ts.map +1 -0
- package/dist/modules/website_search/functions.js +239 -0
- package/dist/modules/website_search/functions.js.map +1 -0
- package/dist/modules/website_search/index.js +4 -1
- package/dist/modules/website_search/index.js.map +1 -1
- package/dist/modules/website_search/islands.d.ts +6 -0
- package/dist/modules/website_search/islands.d.ts.map +1 -1
- package/dist/modules/website_search/islands.js +8 -2
- package/dist/modules/website_search/islands.js.map +1 -1
- package/dist/modules/website_search/models.d.ts +15 -0
- package/dist/modules/website_search/models.d.ts.map +1 -0
- package/dist/modules/website_search/models.js +58 -0
- package/dist/modules/website_search/models.js.map +1 -0
- package/dist/modules/website_seo/functions.d.ts +3 -0
- package/dist/modules/website_seo/functions.d.ts.map +1 -0
- package/dist/modules/website_seo/functions.js +164 -0
- package/dist/modules/website_seo/functions.js.map +1 -0
- package/dist/modules/website_seo/index.js +15 -5
- package/dist/modules/website_seo/index.js.map +1 -1
- package/dist/modules/website_seo/projection.d.ts +52 -0
- package/dist/modules/website_seo/projection.d.ts.map +1 -0
- package/dist/modules/website_seo/projection.js +129 -0
- package/dist/modules/website_seo/projection.js.map +1 -0
- package/dist/modules/website_seo/routes.d.ts +3 -0
- package/dist/modules/website_seo/routes.d.ts.map +1 -0
- package/dist/modules/website_seo/routes.js +56 -0
- package/dist/modules/website_seo/routes.js.map +1 -0
- package/dist/permission-catalogue.d.ts +5 -0
- package/dist/permission-catalogue.d.ts.map +1 -0
- package/dist/permission-catalogue.js +1505 -0
- package/dist/permission-catalogue.js.map +1 -0
- package/dist/scaffold/index.d.ts +2 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +31 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/templates/README.md.tmpl +17 -0
- package/dist/scaffold/templates/gitignore.tmpl +2 -0
- package/dist/scaffold/templates/ket.workspace.mjs.tmpl +1 -0
- package/dist/scaffold/templates/package.json.tmpl +15 -0
- package/dist/themes/hospitality/templates/website.columns.ktl +4 -0
- package/dist/themes/paper/templates/website.columns.ktl +4 -0
- package/dist/ui/actions.d.ts +4 -0
- package/dist/ui/actions.d.ts.map +1 -1
- package/dist/ui/actions.js +1 -1
- package/dist/ui/actions.js.map +1 -1
- package/dist/ui/activity.d.ts +1 -1
- package/dist/ui/activity.d.ts.map +1 -1
- package/dist/ui/activity.js +3 -5
- package/dist/ui/activity.js.map +1 -1
- package/dist/ui/attachments.js +1 -1
- package/dist/ui/attachments.js.map +1 -1
- package/dist/ui/auth.d.ts +36 -0
- package/dist/ui/auth.d.ts.map +1 -1
- package/dist/ui/auth.js +55 -0
- package/dist/ui/auth.js.map +1 -1
- package/dist/ui/board-page.d.ts +6 -0
- package/dist/ui/board-page.d.ts.map +1 -0
- package/dist/ui/board-page.js +4 -0
- package/dist/ui/board-page.js.map +1 -0
- package/dist/ui/charts.d.ts +83 -0
- package/dist/ui/charts.d.ts.map +1 -0
- package/dist/ui/charts.js +105 -0
- package/dist/ui/charts.js.map +1 -0
- package/dist/ui/chrome.d.ts +37 -2
- package/dist/ui/chrome.d.ts.map +1 -1
- package/dist/ui/chrome.js +39 -5
- package/dist/ui/chrome.js.map +1 -1
- package/dist/ui/client/activity-view.mjs +7 -7
- package/dist/ui/client/activity-view.mjs.map +1 -1
- package/dist/ui/client/activity.css +6 -34
- package/dist/ui/client/calendar-view.d.mts.map +1 -1
- package/dist/ui/client/calendar-view.mjs +7 -6
- package/dist/ui/client/calendar-view.mjs.map +1 -1
- package/dist/ui/client/calendar.css +4 -14
- package/dist/ui/client/chart-view.d.ts +51 -0
- package/dist/ui/client/chart-view.d.ts.map +1 -0
- package/dist/ui/client/chart-view.js +192 -0
- package/dist/ui/client/chart-view.js.map +1 -0
- package/dist/ui/client/flow-app.css +387 -0
- package/dist/ui/client/flow-board-view.d.mts +8 -0
- package/dist/ui/client/flow-board-view.d.mts.map +1 -0
- package/dist/ui/client/flow-board-view.mjs +161 -0
- package/dist/ui/client/flow-board-view.mjs.map +1 -0
- package/dist/ui/client/flow-board.d.mts +3 -0
- package/dist/ui/client/flow-board.d.mts.map +1 -0
- package/dist/ui/client/flow-board.mjs +7 -0
- package/dist/ui/client/flow-board.mjs.map +1 -0
- package/dist/ui/client/flow-map-view.d.mts +2 -0
- package/dist/ui/client/flow-map-view.d.mts.map +1 -0
- package/dist/ui/client/flow-map-view.mjs +235 -0
- package/dist/ui/client/flow-map-view.mjs.map +1 -0
- package/dist/ui/client/flow-map.d.mts +3 -0
- package/dist/ui/client/flow-map.d.mts.map +1 -0
- package/dist/ui/client/flow-map.mjs +7 -0
- package/dist/ui/client/flow-map.mjs.map +1 -0
- package/dist/ui/client/live-doc-blocks.d.ts +19 -0
- package/dist/ui/client/live-doc-blocks.d.ts.map +1 -0
- package/dist/ui/client/live-doc-blocks.js +23 -0
- package/dist/ui/client/live-doc-blocks.js.map +1 -0
- package/dist/ui/client/live-doc-markdown.d.ts +18 -0
- package/dist/ui/client/live-doc-markdown.d.ts.map +1 -0
- package/dist/ui/client/live-doc-markdown.js +175 -0
- package/dist/ui/client/live-doc-markdown.js.map +1 -0
- package/dist/ui/client/live-doc-shell.d.ts +101 -0
- package/dist/ui/client/live-doc-shell.d.ts.map +1 -0
- package/dist/ui/client/live-doc-shell.js +251 -0
- package/dist/ui/client/live-doc-shell.js.map +1 -0
- package/dist/ui/client/live-doc-view.d.ts +33 -0
- package/dist/ui/client/live-doc-view.d.ts.map +1 -0
- package/dist/ui/client/live-doc-view.js +1237 -0
- package/dist/ui/client/live-doc-view.js.map +1 -0
- package/dist/ui/client/live-doc.css +243 -0
- package/dist/ui/client/live-doc.d.mts +12 -0
- package/dist/ui/client/live-doc.d.mts.map +1 -0
- package/dist/ui/client/live-doc.mjs +11 -0
- package/dist/ui/client/live-doc.mjs.map +7 -0
- package/dist/ui/client/mail-bundle.d.mts +9 -0
- package/dist/ui/client/mail-bundle.d.mts.map +1 -0
- package/dist/ui/client/mail-bundle.mjs +50 -0
- package/dist/ui/client/mail-bundle.mjs.map +7 -0
- package/dist/ui/client/mail-entry.d.mts +11 -0
- package/dist/ui/client/mail-entry.d.mts.map +1 -0
- package/dist/ui/client/mail-entry.mjs +9 -0
- package/dist/ui/client/mail-entry.mjs.map +1 -0
- package/dist/ui/client/mail-view.d.mts.map +1 -1
- package/dist/ui/client/mail-view.mjs +5 -3
- package/dist/ui/client/mail-view.mjs.map +1 -1
- package/dist/ui/client/mail.css +3 -3
- package/dist/ui/client/relation-select-view.d.ts +77 -0
- package/dist/ui/client/relation-select-view.d.ts.map +1 -0
- package/dist/ui/client/relation-select-view.js +216 -0
- package/dist/ui/client/relation-select-view.js.map +1 -0
- package/dist/ui/client/table-selection-view.d.ts +4 -0
- package/dist/ui/client/table-selection-view.d.ts.map +1 -0
- package/dist/ui/client/table-selection-view.js +283 -0
- package/dist/ui/client/table-selection-view.js.map +1 -0
- package/dist/ui/dashboard-page.d.ts +6 -0
- package/dist/ui/dashboard-page.d.ts.map +1 -0
- package/dist/ui/dashboard-page.js +4 -0
- package/dist/ui/dashboard-page.js.map +1 -0
- package/dist/ui/data.d.ts +51 -1
- package/dist/ui/data.d.ts.map +1 -1
- package/dist/ui/data.js +87 -1
- package/dist/ui/data.js.map +1 -1
- package/dist/ui/date-picker.d.ts.map +1 -1
- package/dist/ui/date-picker.js +2 -2
- package/dist/ui/date-picker.js.map +1 -1
- package/dist/ui/form-page.d.ts +6 -0
- package/dist/ui/form-page.d.ts.map +1 -0
- package/dist/ui/form-page.js +5 -0
- package/dist/ui/form-page.js.map +1 -0
- package/dist/ui/form.d.ts +4 -1
- package/dist/ui/form.d.ts.map +1 -1
- package/dist/ui/form.js +7 -5
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/format.d.ts +13 -2
- package/dist/ui/format.d.ts.map +1 -1
- package/dist/ui/format.js +28 -7
- package/dist/ui/format.js.map +1 -1
- package/dist/ui/gantt.d.ts +52 -0
- package/dist/ui/gantt.d.ts.map +1 -0
- package/dist/ui/gantt.js +92 -0
- package/dist/ui/gantt.js.map +1 -0
- package/dist/ui/hooks.d.ts.map +1 -1
- package/dist/ui/hooks.js +14 -0
- package/dist/ui/hooks.js.map +1 -1
- package/dist/ui/icons.d.ts.map +1 -1
- package/dist/ui/icons.js +6 -1
- package/dist/ui/icons.js.map +1 -1
- package/dist/ui/index.d.ts +95 -14
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +78 -13
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/layout.d.ts +43 -38
- package/dist/ui/layout.d.ts.map +1 -1
- package/dist/ui/layout.js +29 -37
- package/dist/ui/layout.js.map +1 -1
- package/dist/ui/list-page.d.ts +19 -0
- package/dist/ui/list-page.d.ts.map +1 -0
- package/dist/ui/list-page.js +21 -0
- package/dist/ui/list-page.js.map +1 -0
- package/dist/ui/media.d.ts.map +1 -1
- package/dist/ui/media.js +1 -1
- package/dist/ui/media.js.map +1 -1
- package/dist/ui/modal.d.ts +26 -1
- package/dist/ui/modal.d.ts.map +1 -1
- package/dist/ui/modal.js +18 -2
- package/dist/ui/modal.js.map +1 -1
- package/dist/ui/nav.d.ts +21 -1
- package/dist/ui/nav.d.ts.map +1 -1
- package/dist/ui/nav.js +43 -8
- package/dist/ui/nav.js.map +1 -1
- package/dist/ui/navigation.d.ts +36 -2
- package/dist/ui/navigation.d.ts.map +1 -1
- package/dist/ui/navigation.js +60 -5
- package/dist/ui/navigation.js.map +1 -1
- package/dist/ui/partner.d.ts +18 -0
- package/dist/ui/partner.d.ts.map +1 -0
- package/dist/ui/partner.js +11 -0
- package/dist/ui/partner.js.map +1 -0
- package/dist/ui/primitives.d.ts +28 -10
- package/dist/ui/primitives.d.ts.map +1 -1
- package/dist/ui/primitives.js +21 -7
- package/dist/ui/primitives.js.map +1 -1
- package/dist/ui/product-media.d.ts +47 -0
- package/dist/ui/product-media.d.ts.map +1 -0
- package/dist/ui/product-media.js +67 -0
- package/dist/ui/product-media.js.map +1 -0
- package/dist/ui/product-variants.d.ts +68 -0
- package/dist/ui/product-variants.d.ts.map +1 -0
- package/dist/ui/product-variants.js +81 -0
- package/dist/ui/product-variants.js.map +1 -0
- package/dist/ui/record-detail.d.ts +70 -0
- package/dist/ui/record-detail.d.ts.map +1 -0
- package/dist/ui/record-detail.js +35 -0
- package/dist/ui/record-detail.js.map +1 -0
- package/dist/ui/record-page.d.ts +16 -0
- package/dist/ui/record-page.d.ts.map +1 -0
- package/dist/ui/record-page.js +13 -0
- package/dist/ui/record-page.js.map +1 -0
- package/dist/ui/record.d.ts +15 -3
- package/dist/ui/record.d.ts.map +1 -1
- package/dist/ui/record.js +6 -5
- package/dist/ui/record.js.map +1 -1
- package/dist/ui/surfaces.d.ts +30 -2
- package/dist/ui/surfaces.d.ts.map +1 -1
- package/dist/ui/surfaces.js +39 -2
- package/dist/ui/surfaces.js.map +1 -1
- package/dist/ui/table.d.ts +25 -2
- package/dist/ui/table.d.ts.map +1 -1
- package/dist/ui/table.js +10 -6
- package/dist/ui/table.js.map +1 -1
- package/dist/ui/timeframe.d.ts +39 -0
- package/dist/ui/timeframe.d.ts.map +1 -0
- package/dist/ui/timeframe.js +36 -0
- package/dist/ui/timeframe.js.map +1 -0
- package/dist/ui/workspace-page.d.ts +16 -0
- package/dist/ui/workspace-page.d.ts.map +1 -0
- package/dist/ui/workspace-page.js +15 -0
- package/dist/ui/workspace-page.js.map +1 -0
- package/package.json +16 -3
- package/dist/modules/account/tt99.d.ts +0 -30
- package/dist/modules/account/tt99.d.ts.map +0 -1
- package/dist/modules/account/tt99.js +0 -1661
- package/dist/modules/account/tt99.js.map +0 -1
- package/dist/modules/account_backend/accounting-overview-screen.d.ts +0 -18
- package/dist/modules/account_backend/accounting-overview-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/accounting-overview-screen.js +0 -104
- package/dist/modules/account_backend/accounting-overview-screen.js.map +0 -1
- package/dist/modules/account_backend/accounts-screen.d.ts +0 -13
- package/dist/modules/account_backend/accounts-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/accounts-screen.js +0 -49
- package/dist/modules/account_backend/accounts-screen.js.map +0 -1
- package/dist/modules/account_backend/customer-invoices-screen.d.ts +0 -14
- package/dist/modules/account_backend/customer-invoices-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/customer-invoices-screen.js +0 -63
- package/dist/modules/account_backend/customer-invoices-screen.js.map +0 -1
- package/dist/modules/account_backend/general-ledger-screen.d.ts +0 -13
- package/dist/modules/account_backend/general-ledger-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/general-ledger-screen.js +0 -56
- package/dist/modules/account_backend/general-ledger-screen.js.map +0 -1
- package/dist/modules/account_backend/journal-entries-screen.d.ts +0 -14
- package/dist/modules/account_backend/journal-entries-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/journal-entries-screen.js +0 -45
- package/dist/modules/account_backend/journal-entries-screen.js.map +0 -1
- package/dist/modules/account_backend/journals-screen.d.ts +0 -14
- package/dist/modules/account_backend/journals-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/journals-screen.js +0 -53
- package/dist/modules/account_backend/journals-screen.js.map +0 -1
- package/dist/modules/account_backend/move-detail-screen.d.ts +0 -10
- package/dist/modules/account_backend/move-detail-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/move-detail-screen.js +0 -100
- package/dist/modules/account_backend/move-detail-screen.js.map +0 -1
- package/dist/modules/account_backend/partner-ledger-screen.d.ts +0 -14
- package/dist/modules/account_backend/partner-ledger-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/partner-ledger-screen.js +0 -69
- package/dist/modules/account_backend/partner-ledger-screen.js.map +0 -1
- package/dist/modules/account_backend/payment-terms-screen.d.ts +0 -14
- package/dist/modules/account_backend/payment-terms-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/payment-terms-screen.js +0 -40
- package/dist/modules/account_backend/payment-terms-screen.js.map +0 -1
- package/dist/modules/account_backend/payments-screen.d.ts +0 -14
- package/dist/modules/account_backend/payments-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/payments-screen.js +0 -54
- package/dist/modules/account_backend/payments-screen.js.map +0 -1
- package/dist/modules/account_backend/screens.d.ts +0 -7
- package/dist/modules/account_backend/screens.d.ts.map +0 -1
- package/dist/modules/account_backend/screens.js +0 -7
- package/dist/modules/account_backend/screens.js.map +0 -1
- package/dist/modules/account_backend/taxes-screen.d.ts +0 -15
- package/dist/modules/account_backend/taxes-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/taxes-screen.js +0 -73
- package/dist/modules/account_backend/taxes-screen.js.map +0 -1
- package/dist/modules/account_backend/trial-balance-screen.d.ts +0 -13
- package/dist/modules/account_backend/trial-balance-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/trial-balance-screen.js +0 -62
- package/dist/modules/account_backend/trial-balance-screen.js.map +0 -1
- package/dist/modules/account_backend/vendor-bills-screen.d.ts +0 -14
- package/dist/modules/account_backend/vendor-bills-screen.d.ts.map +0 -1
- package/dist/modules/account_backend/vendor-bills-screen.js +0 -59
- package/dist/modules/account_backend/vendor-bills-screen.js.map +0 -1
- package/dist/modules/account_partner_backend/screens.d.ts +0 -16
- package/dist/modules/account_partner_backend/screens.d.ts.map +0 -1
- package/dist/modules/account_partner_backend/screens.js +0 -26
- package/dist/modules/account_partner_backend/screens.js.map +0 -1
- package/dist/modules/activity_backend/screens.d.ts +0 -5
- package/dist/modules/activity_backend/screens.d.ts.map +0 -1
- package/dist/modules/activity_backend/screens.js +0 -52
- package/dist/modules/activity_backend/screens.js.map +0 -1
- package/dist/modules/address_backend/screens.d.ts +0 -31
- package/dist/modules/address_backend/screens.d.ts.map +0 -1
- package/dist/modules/address_backend/screens.js +0 -147
- package/dist/modules/address_backend/screens.js.map +0 -1
- package/dist/modules/backend/design/admin.css +0 -4229
- package/dist/modules/backend/design/client/relation-select-view.d.mts +0 -5
- package/dist/modules/backend/design/client/relation-select-view.d.mts.map +0 -1
- package/dist/modules/backend/design/client/relation-select-view.mjs +0 -335
- package/dist/modules/backend/design/client/relation-select-view.mjs.map +0 -1
- package/dist/modules/calendar_backend/screens.d.ts +0 -5
- package/dist/modules/calendar_backend/screens.d.ts.map +0 -1
- package/dist/modules/calendar_backend/screens.js +0 -4
- package/dist/modules/calendar_backend/screens.js.map +0 -1
- package/dist/modules/company_backend/screens.d.ts +0 -62
- package/dist/modules/company_backend/screens.d.ts.map +0 -1
- package/dist/modules/company_backend/screens.js +0 -268
- package/dist/modules/company_backend/screens.js.map +0 -1
- package/dist/modules/crm_backend/list-search.d.ts +0 -21
- package/dist/modules/crm_backend/list-search.d.ts.map +0 -1
- package/dist/modules/crm_backend/list-search.js +0 -220
- package/dist/modules/crm_backend/list-search.js.map +0 -1
- package/dist/modules/crm_backend/screens.d.ts +0 -32
- package/dist/modules/crm_backend/screens.d.ts.map +0 -1
- package/dist/modules/crm_backend/screens.js +0 -405
- package/dist/modules/crm_backend/screens.js.map +0 -1
- package/dist/modules/hospitality_core/screens.d.ts +0 -773
- package/dist/modules/hospitality_core/screens.d.ts.map +0 -1
- package/dist/modules/hospitality_core/screens.js +0 -4152
- package/dist/modules/hospitality_core/screens.js.map +0 -1
- package/dist/modules/hr_backend/screens.d.ts +0 -9
- package/dist/modules/hr_backend/screens.d.ts.map +0 -1
- package/dist/modules/hr_backend/screens.js +0 -144
- package/dist/modules/hr_backend/screens.js.map +0 -1
- package/dist/modules/loyalty_backend/screens.d.ts +0 -33
- package/dist/modules/loyalty_backend/screens.d.ts.map +0 -1
- package/dist/modules/loyalty_backend/screens.js +0 -562
- package/dist/modules/loyalty_backend/screens.js.map +0 -1
- package/dist/modules/mail_backend/screens.d.ts +0 -5
- package/dist/modules/mail_backend/screens.d.ts.map +0 -1
- package/dist/modules/mail_backend/screens.js +0 -11
- package/dist/modules/mail_backend/screens.js.map +0 -1
- package/dist/modules/mail_inbound_backend/screens.d.ts +0 -5
- package/dist/modules/mail_inbound_backend/screens.d.ts.map +0 -1
- package/dist/modules/mail_inbound_backend/screens.js +0 -25
- package/dist/modules/mail_inbound_backend/screens.js.map +0 -1
- package/dist/modules/mail_transport_backend/screens.d.ts +0 -5
- package/dist/modules/mail_transport_backend/screens.d.ts.map +0 -1
- package/dist/modules/mail_transport_backend/screens.js +0 -35
- package/dist/modules/mail_transport_backend/screens.js.map +0 -1
- package/dist/modules/oauth_backend/screens.d.ts +0 -66
- package/dist/modules/oauth_backend/screens.d.ts.map +0 -1
- package/dist/modules/oauth_backend/screens.js +0 -323
- package/dist/modules/oauth_backend/screens.js.map +0 -1
- package/dist/modules/odoo_collaboration_import/functions.d.ts.map +0 -1
- package/dist/modules/odoo_collaboration_import/functions.js +0 -128
- package/dist/modules/odoo_collaboration_import/functions.js.map +0 -1
- package/dist/modules/odoo_collaboration_import/index.d.ts +0 -6
- package/dist/modules/odoo_collaboration_import/index.d.ts.map +0 -1
- package/dist/modules/odoo_collaboration_import/index.js +0 -31
- package/dist/modules/odoo_collaboration_import/index.js.map +0 -1
- package/dist/modules/odoo_collaboration_import/models.d.ts.map +0 -1
- package/dist/modules/odoo_collaboration_import/models.js +0 -76
- package/dist/modules/odoo_collaboration_import/models.js.map +0 -1
- package/dist/modules/odoo_collaboration_import/operations.d.ts +0 -14
- package/dist/modules/odoo_collaboration_import/operations.d.ts.map +0 -1
- package/dist/modules/odoo_collaboration_import/operations.js +0 -1139
- package/dist/modules/odoo_collaboration_import/operations.js.map +0 -1
- package/dist/modules/odoo_collaboration_import/relations.d.ts.map +0 -1
- package/dist/modules/odoo_collaboration_import/relations.js +0 -19
- package/dist/modules/odoo_collaboration_import/relations.js.map +0 -1
- package/dist/modules/odoo_collaboration_import/types.d.ts +0 -58
- package/dist/modules/odoo_collaboration_import/types.d.ts.map +0 -1
- package/dist/modules/odoo_collaboration_import/types.js.map +0 -1
- package/dist/modules/partner_backend/screens.d.ts +0 -53
- package/dist/modules/partner_backend/screens.d.ts.map +0 -1
- package/dist/modules/partner_backend/screens.js +0 -169
- package/dist/modules/partner_backend/screens.js.map +0 -1
- package/dist/modules/pricing_backend/screens.d.ts +0 -13
- package/dist/modules/pricing_backend/screens.d.ts.map +0 -1
- package/dist/modules/pricing_backend/screens.js +0 -182
- package/dist/modules/pricing_backend/screens.js.map +0 -1
- package/dist/modules/product_backend/attributes-screen.d.ts +0 -7
- package/dist/modules/product_backend/attributes-screen.d.ts.map +0 -1
- package/dist/modules/product_backend/attributes-screen.js +0 -76
- package/dist/modules/product_backend/attributes-screen.js.map +0 -1
- package/dist/modules/product_backend/create-screen.d.ts +0 -12
- package/dist/modules/product_backend/create-screen.d.ts.map +0 -1
- package/dist/modules/product_backend/create-screen.js +0 -83
- package/dist/modules/product_backend/create-screen.js.map +0 -1
- package/dist/modules/product_backend/screens.d.ts +0 -68
- package/dist/modules/product_backend/screens.d.ts.map +0 -1
- package/dist/modules/product_backend/screens.js +0 -388
- package/dist/modules/product_backend/screens.js.map +0 -1
- package/dist/modules/purchase_backend/screens.d.ts +0 -29
- package/dist/modules/purchase_backend/screens.d.ts.map +0 -1
- package/dist/modules/purchase_backend/screens.js +0 -324
- package/dist/modules/purchase_backend/screens.js.map +0 -1
- package/dist/modules/sale_backend/invoicing-policies-screen.d.ts +0 -14
- package/dist/modules/sale_backend/invoicing-policies-screen.d.ts.map +0 -1
- package/dist/modules/sale_backend/invoicing-policies-screen.js +0 -36
- package/dist/modules/sale_backend/invoicing-policies-screen.js.map +0 -1
- package/dist/modules/sale_backend/order-detail-screen.d.ts +0 -18
- package/dist/modules/sale_backend/order-detail-screen.d.ts.map +0 -1
- package/dist/modules/sale_backend/order-detail-screen.js +0 -217
- package/dist/modules/sale_backend/order-detail-screen.js.map +0 -1
- package/dist/modules/sale_backend/quotations-screen.d.ts +0 -15
- package/dist/modules/sale_backend/quotations-screen.d.ts.map +0 -1
- package/dist/modules/sale_backend/quotations-screen.js +0 -64
- package/dist/modules/sale_backend/quotations-screen.js.map +0 -1
- package/dist/modules/sale_backend/sales-orders-screen.d.ts +0 -12
- package/dist/modules/sale_backend/sales-orders-screen.d.ts.map +0 -1
- package/dist/modules/sale_backend/sales-orders-screen.js +0 -65
- package/dist/modules/sale_backend/sales-orders-screen.js.map +0 -1
- package/dist/modules/sale_backend/screens.d.ts +0 -23
- package/dist/modules/sale_backend/screens.d.ts.map +0 -1
- package/dist/modules/sale_backend/screens.js +0 -275
- package/dist/modules/sale_backend/screens.js.map +0 -1
- package/dist/modules/stock_backend/forecast-screen.d.ts +0 -28
- package/dist/modules/stock_backend/forecast-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/forecast-screen.js +0 -108
- package/dist/modules/stock_backend/forecast-screen.js.map +0 -1
- package/dist/modules/stock_backend/inventory-screen.d.ts +0 -27
- package/dist/modules/stock_backend/inventory-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/inventory-screen.js +0 -141
- package/dist/modules/stock_backend/inventory-screen.js.map +0 -1
- package/dist/modules/stock_backend/locations-screen.d.ts +0 -18
- package/dist/modules/stock_backend/locations-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/locations-screen.js +0 -92
- package/dist/modules/stock_backend/locations-screen.js.map +0 -1
- package/dist/modules/stock_backend/lot-screen.d.ts +0 -30
- package/dist/modules/stock_backend/lot-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/lot-screen.js +0 -86
- package/dist/modules/stock_backend/lot-screen.js.map +0 -1
- package/dist/modules/stock_backend/lots-screen.d.ts +0 -21
- package/dist/modules/stock_backend/lots-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/lots-screen.js +0 -79
- package/dist/modules/stock_backend/lots-screen.js.map +0 -1
- package/dist/modules/stock_backend/picking-types-screen.d.ts +0 -21
- package/dist/modules/stock_backend/picking-types-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/picking-types-screen.js +0 -110
- package/dist/modules/stock_backend/picking-types-screen.js.map +0 -1
- package/dist/modules/stock_backend/replenishment-screen.d.ts +0 -29
- package/dist/modules/stock_backend/replenishment-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/replenishment-screen.js +0 -131
- package/dist/modules/stock_backend/replenishment-screen.js.map +0 -1
- package/dist/modules/stock_backend/screens.d.ts +0 -14
- package/dist/modules/stock_backend/screens.d.ts.map +0 -1
- package/dist/modules/stock_backend/screens.js +0 -40
- package/dist/modules/stock_backend/screens.js.map +0 -1
- package/dist/modules/stock_backend/stock-route-screen.d.ts +0 -30
- package/dist/modules/stock_backend/stock-route-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/stock-route-screen.js +0 -129
- package/dist/modules/stock_backend/stock-route-screen.js.map +0 -1
- package/dist/modules/stock_backend/stock-routes-screen.d.ts +0 -17
- package/dist/modules/stock_backend/stock-routes-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/stock-routes-screen.js +0 -60
- package/dist/modules/stock_backend/stock-routes-screen.js.map +0 -1
- package/dist/modules/stock_backend/transfer-screen.d.ts +0 -26
- package/dist/modules/stock_backend/transfer-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/transfer-screen.js +0 -95
- package/dist/modules/stock_backend/transfer-screen.js.map +0 -1
- package/dist/modules/stock_backend/transfers-screen.d.ts +0 -21
- package/dist/modules/stock_backend/transfers-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/transfers-screen.js +0 -88
- package/dist/modules/stock_backend/transfers-screen.js.map +0 -1
- package/dist/modules/stock_backend/warehouses-screen.d.ts +0 -17
- package/dist/modules/stock_backend/warehouses-screen.d.ts.map +0 -1
- package/dist/modules/stock_backend/warehouses-screen.js +0 -96
- package/dist/modules/stock_backend/warehouses-screen.js.map +0 -1
- package/dist/modules/user_backend/screens.d.ts +0 -70
- package/dist/modules/user_backend/screens.d.ts.map +0 -1
- package/dist/modules/user_backend/screens.js +0 -308
- package/dist/modules/user_backend/screens.js.map +0 -1
- package/dist/modules/website/customer-routes.d.ts +0 -3
- package/dist/modules/website/customer-routes.d.ts.map +0 -1
- package/dist/modules/website/customer-routes.js +0 -322
- package/dist/modules/website/customer-routes.js.map +0 -1
- package/dist/modules/website_backend/screens.d.ts +0 -114
- package/dist/modules/website_backend/screens.d.ts.map +0 -1
- package/dist/modules/website_backend/screens.js +0 -625
- package/dist/modules/website_backend/screens.js.map +0 -1
- package/dist/ui/client/mail.d.mts +0 -11
- package/dist/ui/client/mail.d.mts.map +0 -1
- package/dist/ui/client/mail.mjs +0 -10
- package/dist/ui/client/mail.mjs.map +0 -1
- /package/dist/modules/{odoo_collaboration_import → account_staff_channel}/functions.d.ts +0 -0
- /package/dist/modules/{odoo_collaboration_import → account_staff_channel}/models.d.ts +0 -0
- /package/dist/modules/{odoo_collaboration_import → address_backend/screens}/types.js +0 -0
- /package/dist/modules/{odoo_collaboration_import → manufacturing}/relations.d.ts +0 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { asc, defineFn, eq, from } from '@ketvietlab/ketjs';
|
|
1
|
+
import { and, asc, defineFn, deleteFrom, eq, from, ilike, inArray, or } from '@ketvietlab/ketjs';
|
|
2
|
+
import { accountingFilterDateText, accountingDateText, assertAccountingTimezone, DEFAULT_ACCOUNTING_TIMEZONE, fiscalYearKey, moveAccountingDate, } from './date.js';
|
|
3
|
+
import { canonicalDecimalText, compareDecimals, decimalSign, discountedLineMinor, divisionTaxMinor, includedDivisionBaseMinor, includedPercentBaseMinor, minorText, MONEY_POLICY_VERSION, moneyMinor, multiplyToMinor, percentOfMinor, scaleOf, sumMoneyMinor, } from './money.js';
|
|
2
4
|
import { ACCOUNT_SETUP_EFFECTS, ensureCompanyAccounting } from './setup.js';
|
|
5
|
+
import { claimPostingPeriod } from './period.js';
|
|
3
6
|
export const ACCOUNT_TYPES = [
|
|
4
7
|
'asset_receivable',
|
|
5
8
|
'asset_cash',
|
|
@@ -32,19 +35,26 @@ export const MOVE_TYPES = [
|
|
|
32
35
|
'in_receipt',
|
|
33
36
|
];
|
|
34
37
|
export const MOVE_STATES = ['draft', 'posted', 'cancel'];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The four a document can actually be in.
|
|
40
|
+
*
|
|
41
|
+
* Three more were carried over from the ERP this vocabulary came from, and
|
|
42
|
+
* nothing in this ledger ever wrote them — so a filter offering them returned an
|
|
43
|
+
* empty list however the books were kept. Same reason `group` left
|
|
44
|
+
* TAX_AMOUNT_TYPES: a choice that cannot be reached only wastes the reader's
|
|
45
|
+
* time.
|
|
46
|
+
*/
|
|
47
|
+
export const PAYMENT_STATES = ['not_paid', 'paid', 'partial', 'reversed'];
|
|
44
48
|
export const TAX_USES = ['sale', 'purchase', 'none'];
|
|
45
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Group taxes are deliberately absent: a line takes a list of taxes and applies
|
|
51
|
+
* them in sequence, which is what a group would have expressed anyway. Offering
|
|
52
|
+
* `group` as a saveable amount type only produced taxes that threw on first use.
|
|
53
|
+
*/
|
|
54
|
+
export const TAX_AMOUNT_TYPES = ['fixed', 'percent', 'division'];
|
|
46
55
|
export const PAYMENT_TYPES = ['outbound', 'inbound'];
|
|
47
56
|
export const PARTNER_TYPES = ['customer', 'supplier'];
|
|
57
|
+
export const PAYMENT_SETTLEMENT_KINDS = ['liquidity', 'stored_value'];
|
|
48
58
|
export const PAYMENT_TERM_VALUES = ['percent', 'fixed'];
|
|
49
59
|
export const PAYMENT_TERM_DELAY_TYPES = [
|
|
50
60
|
'days_after',
|
|
@@ -52,22 +62,556 @@ export const PAYMENT_TERM_DELAY_TYPES = [
|
|
|
52
62
|
'days_after_end_of_next_month',
|
|
53
63
|
'days_end_of_month_on_the',
|
|
54
64
|
];
|
|
55
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Every way this module can say no, in one place.
|
|
67
|
+
*
|
|
68
|
+
* A refusal travels as a code, because the words belong to whoever is reading:
|
|
69
|
+
* a backend screen translates it, and a ledger read in Vietnamese must not grow
|
|
70
|
+
* English prose. The sentence here is the same reason for an API client or a log
|
|
71
|
+
* that has no translator, and `{name}` placeholders are filled from `params`.
|
|
72
|
+
*/
|
|
73
|
+
const REFUSALS = {
|
|
74
|
+
moveMissing: 'journal entry does not exist',
|
|
75
|
+
moveDraftOnly: 'only a draft entry can be posted',
|
|
76
|
+
movePostedOnly: 'only a posted entry can be reversed',
|
|
77
|
+
moveNotCancellable: 'a posted entry is corrected with account.reverseMove, not cancelled',
|
|
78
|
+
moveConcurrent: 'the invoice changed concurrently; review it and retry',
|
|
79
|
+
moveIdReused: 'a different journal entry already uses this id',
|
|
80
|
+
moveTypeUnsupported: 'unsupported move type',
|
|
81
|
+
linesTooFew: 'a journal entry needs at least two lines',
|
|
82
|
+
lineSideBoth: 'each line must have a non-negative debit or credit, never both',
|
|
83
|
+
lineAmountRequired: 'each journal item needs a non-zero debit or credit',
|
|
84
|
+
lineBalanceInvalid: 'journal item balance must equal debit minus credit',
|
|
85
|
+
lineResidualInvalid: 'journal item residual is inconsistent with its account and balance',
|
|
86
|
+
entryUnbalanced: 'entry is not balanced: debit {debit}, credit {credit}',
|
|
87
|
+
moveTotalInvalid: 'document totals do not match its open-item counterparts',
|
|
88
|
+
reversalNoLines: 'the entry has no journal items to reverse',
|
|
89
|
+
reversalIdReused: 'a different reversal already uses this id',
|
|
90
|
+
moveAlreadyReversed: 'the entry already has a different reversal',
|
|
91
|
+
lineDraftOnly: 'lines can only be added to a draft entry',
|
|
92
|
+
lineIdTaken: 'a different journal item already uses this id',
|
|
93
|
+
moneyExactString: 'money values must be canonical decimal strings without exponent notation',
|
|
94
|
+
accountingDateInvalid: 'accounting and document dates must be valid civil dates',
|
|
95
|
+
moveCurrencyMismatch: 'journal entry currency must match the active company ledger',
|
|
96
|
+
periodLocked: 'the {scope} books are locked through {through}',
|
|
97
|
+
periodConcurrent: 'the accounting period policy changed; review and retry',
|
|
98
|
+
accountMissing: 'account does not exist',
|
|
99
|
+
accountInactive: 'inactive accounts cannot receive new journal items',
|
|
100
|
+
accountTypeUnsupported: 'unsupported account type',
|
|
101
|
+
accountCodeFormat: 'account code may contain only letters, numbers, and dots',
|
|
102
|
+
offBalanceReconcile: 'off-balance accounts cannot be reconciled',
|
|
103
|
+
defaultAccountMissing: 'default account does not exist',
|
|
104
|
+
journalMissing: 'journal does not exist',
|
|
105
|
+
journalInactive: 'inactive journals cannot post new entries',
|
|
106
|
+
journalTypeUnsupported: 'unsupported journal type',
|
|
107
|
+
journalCodeFormat: 'journal code must be alphanumeric',
|
|
108
|
+
journalMustBeSale: 'a customer document requires a sale journal',
|
|
109
|
+
journalMustBePurchase: 'a vendor document requires a purchase journal',
|
|
110
|
+
journalLiquidityMissing: 'payment journal needs a default liquidity account',
|
|
111
|
+
journalNotLiquidity: 'payments require a bank or cash journal',
|
|
112
|
+
journalNotStoredValue: 'stored value settlements require a general journal',
|
|
113
|
+
journalStoredValueAccount: 'stored value settlements require a liability default account',
|
|
114
|
+
taxMissing: 'tax does not exist',
|
|
115
|
+
taxUseUnsupported: 'unsupported tax use',
|
|
116
|
+
taxComputationUnsupported: 'unsupported tax computation',
|
|
117
|
+
taxScopeUnsupported: 'tax scope must be service or consu',
|
|
118
|
+
taxAccountMissing: 'tax account does not exist',
|
|
119
|
+
taxDirectionMismatch: 'tax "{name}" does not match the invoice direction',
|
|
120
|
+
taxPostingAccountMissing: 'tax "{name}" needs a valid posting account',
|
|
121
|
+
taxMixedPriceInclude: 'a line cannot mix price-included and price-excluded taxes',
|
|
122
|
+
taxManyPriceInclude: 'a line supports at most one price-included tax',
|
|
123
|
+
taxDivisionFull: 'a division tax of 100% or more has no finite base',
|
|
124
|
+
productMissing: 'product template does not exist',
|
|
125
|
+
taxFixedExceedsLine: 'a price-included fixed tax cannot be larger than the line it is inside',
|
|
126
|
+
taxQuantityPositive: 'line quantity must be positive',
|
|
127
|
+
taxPriceInvalid: 'unit price and discount are invalid',
|
|
128
|
+
partnerMissing: 'partner does not exist',
|
|
129
|
+
paymentTermMissing: 'payment term does not exist',
|
|
130
|
+
termValueUnsupported: 'value must be percent or fixed',
|
|
131
|
+
termDelayUnsupported: 'unsupported delay type',
|
|
132
|
+
termPercentRange: 'percentage must be between 0 and 100',
|
|
133
|
+
invoiceTypeRequired: 'createInvoice requires an invoice, refund, or receipt type',
|
|
134
|
+
invoiceIdReused: 'a different invoice already uses this id',
|
|
135
|
+
invoiceAccountsMissing: 'invoice accounts do not exist',
|
|
136
|
+
invoiceLinesAndSingle: 'give either lines or a single description, not both',
|
|
137
|
+
invoiceLinesEmpty: 'an invoice needs at least one line',
|
|
138
|
+
invoiceLineRequired: 'every invoice line needs a description',
|
|
139
|
+
lineAccountUndecided: 'no revenue or expense account was given, and neither the product category nor the company has a default',
|
|
140
|
+
counterpartAccountUndecided: 'no receivable or payable account was given, and neither the partner nor the company has a default',
|
|
141
|
+
categoryMissing: 'the product category does not exist',
|
|
142
|
+
defaultAccountType: 'that account type cannot serve as this default',
|
|
143
|
+
counterpartMustBeReceivable: 'the counterpart account must be a receivable account',
|
|
144
|
+
counterpartMustBePayable: 'the counterpart account must be a payable account',
|
|
145
|
+
paymentTypeUnsupported: 'payment type must be inbound or outbound',
|
|
146
|
+
paymentIdReused: 'a different payment already uses this id',
|
|
147
|
+
partnerTypeUnsupported: 'partner type must be customer or supplier',
|
|
148
|
+
paymentSettlementKindUnsupported: 'settlement kind must be liquidity or stored value',
|
|
149
|
+
storedValueOperationUnsupported: 'stored value balance operation must be issue or expire',
|
|
150
|
+
storedValueCounterpart: 'stored value issue needs an asset counterpart and expiry needs income',
|
|
151
|
+
amountPositive: 'payment amount must be positive',
|
|
152
|
+
destinationMissing: 'destination account does not exist',
|
|
153
|
+
destinationMustBeReceivable: 'a customer payment must settle a receivable account',
|
|
154
|
+
destinationMustBePayable: 'a supplier payment must settle a payable account',
|
|
155
|
+
openItemMissing: 'open item does not exist',
|
|
156
|
+
openItemAccountMismatch: 'open item uses another destination account',
|
|
157
|
+
openItemDirection: 'open item has the wrong debit or credit direction',
|
|
158
|
+
amountExceedsOpenItem: 'payment amount exceeds the selected open item',
|
|
159
|
+
invoicePaymentType: 'only a customer invoice can collect a payment',
|
|
160
|
+
invoicePaymentState: 'only a posted customer invoice can collect a payment',
|
|
161
|
+
invoicePaymentResidual: 'the customer invoice has no amount left to collect',
|
|
162
|
+
invoicePaymentAccounts: 'one mobile payment cannot settle several receivable accounts',
|
|
163
|
+
reconcileAmountPositive: 'reconciliation amount must be positive',
|
|
164
|
+
reconcileSides: 'reconciliation needs one debit and one credit line',
|
|
165
|
+
reconcileAccountMismatch: 'reconciled lines must use the same account',
|
|
166
|
+
reconcilePostedOnly: 'only posted journal items can be reconciled',
|
|
167
|
+
reconcileNotAllowed: 'this account does not allow reconciliation',
|
|
168
|
+
reconcileAmountExceeds: 'amount exceeds a residual balance',
|
|
169
|
+
reconcileConcurrent: 'residual balance changed concurrently; retry reconciliation',
|
|
170
|
+
};
|
|
171
|
+
const fill = (sentence, params) => params ? sentence.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? `{${name}}`)) : sentence;
|
|
172
|
+
const invalid = (field, code, params) => ({
|
|
173
|
+
ok: false,
|
|
174
|
+
errors: [{ field, code: `account.error.${code}`, message: fill(REFUSALS[code], params), params }],
|
|
175
|
+
});
|
|
176
|
+
/** A refusal raised from inside a helper or a transaction, carrying its code out. */
|
|
177
|
+
class Refusal extends Error {
|
|
178
|
+
code;
|
|
179
|
+
params;
|
|
180
|
+
constructor(code, params) {
|
|
181
|
+
super(fill(REFUSALS[code], params));
|
|
182
|
+
this.code = code;
|
|
183
|
+
this.params = params;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** Turn whatever a guarded block threw into a refusal the caller can act on. */
|
|
187
|
+
const refused = (field, error) => error instanceof Refusal
|
|
188
|
+
? invalid(field, error.code, error.params)
|
|
189
|
+
: { ok: false, errors: [{ field, message: error.message }] };
|
|
56
190
|
const n = (value) => Number(value ?? 0);
|
|
57
|
-
|
|
58
|
-
const
|
|
191
|
+
/** Exact numeric identity without routing ledger values through JavaScript Number. */
|
|
192
|
+
const decimalIdentity = (value) => {
|
|
193
|
+
let source = String(value).trim().replace(/^\+/, '');
|
|
194
|
+
const exponent = /^(-?)(\d+)(?:\.(\d+))?e([+-]?\d+)$/i.exec(source);
|
|
195
|
+
if (exponent) {
|
|
196
|
+
const sign = exponent[1] ?? '';
|
|
197
|
+
const whole = exponent[2] ?? '0';
|
|
198
|
+
const fraction = exponent[3] ?? '';
|
|
199
|
+
const digits = whole + fraction;
|
|
200
|
+
const shift = Number(exponent[4]);
|
|
201
|
+
if (Number.isSafeInteger(shift) && Math.abs(shift) <= 4096) {
|
|
202
|
+
const point = whole.length + shift;
|
|
203
|
+
source =
|
|
204
|
+
point <= 0
|
|
205
|
+
? `${sign}0.${'0'.repeat(-point)}${digits}`
|
|
206
|
+
: point >= digits.length
|
|
207
|
+
? `${sign}${digits}${'0'.repeat(point - digits.length)}`
|
|
208
|
+
: `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const parsed = /^(-?)(?:(\d+)(?:\.(\d*))?|\.(\d+))$/.exec(source);
|
|
212
|
+
if (!parsed)
|
|
213
|
+
return source;
|
|
214
|
+
const negative = parsed[1] === '-';
|
|
215
|
+
const whole = (parsed[2] ?? '0').replace(/^0+(?=\d)/, '');
|
|
216
|
+
const fraction = (parsed[3] ?? parsed[4] ?? '').replace(/0+$/, '');
|
|
217
|
+
if (!/[1-9]/.test(`${whole}${fraction}`))
|
|
218
|
+
return '0';
|
|
219
|
+
return `${negative ? '-' : ''}${whole}${fraction ? `.${fraction}` : ''}`;
|
|
220
|
+
};
|
|
221
|
+
const DECIMAL_CREATE_FIELDS = new Set([
|
|
222
|
+
'quantity',
|
|
223
|
+
'priceUnit',
|
|
224
|
+
'discount',
|
|
225
|
+
'debit',
|
|
226
|
+
'credit',
|
|
227
|
+
'balance',
|
|
228
|
+
'amountUntaxed',
|
|
229
|
+
'amountTax',
|
|
230
|
+
'amountTotal',
|
|
231
|
+
'amountResidual',
|
|
232
|
+
]);
|
|
233
|
+
/** Compare the values a command owns without being confused by adapter scalar types. */
|
|
234
|
+
const sameStored = (field, held, wanted) => {
|
|
235
|
+
if (held == null || wanted == null)
|
|
236
|
+
return (held ?? null) === (wanted ?? null);
|
|
237
|
+
if (DECIMAL_CREATE_FIELDS.has(field))
|
|
238
|
+
return decimalIdentity(held) === decimalIdentity(wanted);
|
|
239
|
+
return String(held) === String(wanted);
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Idempotency means equal normalized financial semantics, not byte-identical JSON:
|
|
243
|
+
* immutable fields and line structure must match, while mutable posting state does not.
|
|
244
|
+
*/
|
|
245
|
+
const rowMatches = (held, wanted, fields) => fields.every((field) => sameStored(field, held[field], wanted[field]));
|
|
246
|
+
/** Datetimes have one persisted spelling on both SQLite and PostgreSQL. */
|
|
247
|
+
const instantText = (value) => {
|
|
248
|
+
const at = value instanceof Date ? value : new Date(String(value));
|
|
249
|
+
return Number.isNaN(at.getTime()) ? String(value) : at.toISOString();
|
|
250
|
+
};
|
|
251
|
+
const MOVE_CREATE_FIELDS = [
|
|
252
|
+
'journalId',
|
|
253
|
+
'moveType',
|
|
254
|
+
'ref',
|
|
255
|
+
'partnerId',
|
|
256
|
+
'invoiceDate',
|
|
257
|
+
'invoiceDateDue',
|
|
258
|
+
'paymentTermId',
|
|
259
|
+
'currency',
|
|
260
|
+
'moneyPolicyVersion',
|
|
261
|
+
];
|
|
262
|
+
const MOVE_LINE_CREATE_FIELDS = [
|
|
263
|
+
'moveId',
|
|
264
|
+
'name',
|
|
265
|
+
'accountId',
|
|
266
|
+
'partnerId',
|
|
267
|
+
'productId',
|
|
268
|
+
'productUomId',
|
|
269
|
+
'quantity',
|
|
270
|
+
'priceUnit',
|
|
271
|
+
'discount',
|
|
272
|
+
'taxId',
|
|
273
|
+
'debit',
|
|
274
|
+
'credit',
|
|
275
|
+
'balance',
|
|
276
|
+
'dateMaturity',
|
|
277
|
+
'displayType',
|
|
278
|
+
'sequence',
|
|
279
|
+
];
|
|
280
|
+
const claimMoveRevision = async (ctx, move, expectedRevision) => {
|
|
281
|
+
const revision = n(move.revision);
|
|
282
|
+
if (expectedRevision !== undefined && revision !== n(expectedRevision))
|
|
283
|
+
return false;
|
|
284
|
+
const changed = await ctx.db.compareAndSet('account.Move', { id: move.id }, { revision: move.revision ?? null }, { revision: revision + 1 });
|
|
285
|
+
return 'dryRun' in changed || changed.matched;
|
|
286
|
+
};
|
|
59
287
|
const today = () => new Date().toISOString();
|
|
60
|
-
|
|
288
|
+
const wildcard = (value) => String(value ?? '').replace(/[\\%_]/g, '\\$&');
|
|
289
|
+
export async function ledgerOf(ctx) {
|
|
61
290
|
if (!ctx.scope.company)
|
|
62
291
|
throw new Error('accounting requires an active company');
|
|
63
292
|
const company = (await ctx.db.select('company.Company', { id: ctx.scope.company }))[0];
|
|
64
293
|
if (!company)
|
|
65
294
|
throw new Error(`company ${ctx.scope.company} does not exist`);
|
|
66
|
-
|
|
295
|
+
const currency = String(company.currency);
|
|
296
|
+
const timezone = assertAccountingTimezone(company.accountingTimezone ?? DEFAULT_ACCOUNTING_TIMEZONE);
|
|
297
|
+
return { currency, scale: scaleOf(currency), timezone };
|
|
67
298
|
}
|
|
68
299
|
async function accountOf(ctx, id) {
|
|
69
300
|
return (await ctx.db.select('account.Account', { id }))[0] ?? null;
|
|
70
301
|
}
|
|
302
|
+
export class DraftMoveBoundaryError extends Error {
|
|
303
|
+
field;
|
|
304
|
+
constructor(field, message) {
|
|
305
|
+
super(message);
|
|
306
|
+
this.field = field;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const boundaryError = (field, message) => {
|
|
310
|
+
throw new DraftMoveBoundaryError(field, message);
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* The sole transaction-level boundary for a complete draft journal entry.
|
|
314
|
+
*
|
|
315
|
+
* Sale, Purchase and POS build their domain document inside a transaction, then
|
|
316
|
+
* hand the complete move here. The boundary re-derives every monetary invariant
|
|
317
|
+
* before any ledger row is accepted. Callers must pass their transaction context;
|
|
318
|
+
* this helper deliberately does not open a nested transaction.
|
|
319
|
+
*/
|
|
320
|
+
export async function insertDraftMove(ctx, input) {
|
|
321
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
322
|
+
const moveId = String(input.move.id ?? '');
|
|
323
|
+
if (!moveId)
|
|
324
|
+
boundaryError('move.id', 'a draft move id is required');
|
|
325
|
+
if (input.move.state !== 'draft')
|
|
326
|
+
boundaryError('move.state', 'the shared boundary only accepts draft moves');
|
|
327
|
+
if (String(input.move.currency) !== currency)
|
|
328
|
+
boundaryError('move.currency', 'the move currency must match the active company ledger');
|
|
329
|
+
const journal = (await ctx.db.select('account.Journal', { id: input.move.journalId }))[0];
|
|
330
|
+
if (!journal)
|
|
331
|
+
boundaryError('move.journalId', 'the journal does not exist in the active company');
|
|
332
|
+
if (journal.active === false)
|
|
333
|
+
boundaryError('move.journalId', 'an inactive journal cannot receive a new draft move');
|
|
334
|
+
if (input.lines.length < 2)
|
|
335
|
+
boundaryError('lines', 'a draft move needs at least two lines');
|
|
336
|
+
const ids = new Set();
|
|
337
|
+
const normalizedLines = [];
|
|
338
|
+
let debitTotal = 0n;
|
|
339
|
+
let creditTotal = 0n;
|
|
340
|
+
let residualTotal = 0n;
|
|
341
|
+
const accountCache = new Map();
|
|
342
|
+
for (const given of input.lines) {
|
|
343
|
+
const id = String(given.id ?? '');
|
|
344
|
+
if (!id || ids.has(id))
|
|
345
|
+
boundaryError('lines.id', 'journal item ids must be present and unique');
|
|
346
|
+
ids.add(id);
|
|
347
|
+
if (String(given.moveId) !== moveId)
|
|
348
|
+
boundaryError('lines.moveId', 'every journal item must belong to the draft move');
|
|
349
|
+
const accountId = String(given.accountId ?? '');
|
|
350
|
+
let account = accountCache.get(accountId);
|
|
351
|
+
if (!account) {
|
|
352
|
+
const loaded = await accountOf(ctx, accountId);
|
|
353
|
+
if (!loaded)
|
|
354
|
+
throw new DraftMoveBoundaryError('lines.accountId', 'a journal item account is outside the active company');
|
|
355
|
+
account = loaded;
|
|
356
|
+
accountCache.set(accountId, loaded);
|
|
357
|
+
}
|
|
358
|
+
if (account.active === false)
|
|
359
|
+
boundaryError('lines.accountId', 'an inactive account cannot receive a new journal item');
|
|
360
|
+
const { debit, credit, balance, residual, quantity, priceUnit, discount } = (() => {
|
|
361
|
+
try {
|
|
362
|
+
return {
|
|
363
|
+
debit: moneyMinor(given.debit ?? '0', scale),
|
|
364
|
+
credit: moneyMinor(given.credit ?? '0', scale),
|
|
365
|
+
balance: moneyMinor(given.balance ?? '0', scale),
|
|
366
|
+
residual: moneyMinor(given.amountResidual ?? '0', scale),
|
|
367
|
+
quantity: canonicalDecimalText(given.quantity ?? '1'),
|
|
368
|
+
priceUnit: canonicalDecimalText(given.priceUnit ?? '0'),
|
|
369
|
+
discount: canonicalDecimalText(given.discount ?? '0'),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
throw new DraftMoveBoundaryError('lines.amount', 'journal item decimals must be canonical exact strings');
|
|
374
|
+
}
|
|
375
|
+
})();
|
|
376
|
+
if (debit < 0n || credit < 0n || (debit > 0n && credit > 0n))
|
|
377
|
+
boundaryError('lines.side', 'a journal item must use one non-negative side');
|
|
378
|
+
if (debit === 0n && credit === 0n)
|
|
379
|
+
boundaryError('lines.side', 'a journal item needs a non-zero debit or credit');
|
|
380
|
+
if (balance !== debit - credit)
|
|
381
|
+
boundaryError('lines.balance', 'journal item balance must equal debit minus credit');
|
|
382
|
+
const magnitude = balance < 0n ? -balance : balance;
|
|
383
|
+
if (residual < 0n || residual > magnitude)
|
|
384
|
+
boundaryError('lines.amountResidual', 'journal item residual must be within its balance');
|
|
385
|
+
if (account.reconcile === true) {
|
|
386
|
+
if (given.reconciled === true ? residual !== 0n : residual !== magnitude)
|
|
387
|
+
boundaryError('lines.amountResidual', 'a reconcilable draft line must carry its full residual');
|
|
388
|
+
}
|
|
389
|
+
else if (residual !== 0n)
|
|
390
|
+
boundaryError('lines.amountResidual', 'a non-reconcilable account cannot carry a residual');
|
|
391
|
+
if (given.reconciled === true)
|
|
392
|
+
boundaryError('lines.reconciled', 'a draft journal item cannot already be reconciled');
|
|
393
|
+
debitTotal += debit;
|
|
394
|
+
creditTotal += credit;
|
|
395
|
+
residualTotal += residual;
|
|
396
|
+
normalizedLines.push({
|
|
397
|
+
...given,
|
|
398
|
+
quantity,
|
|
399
|
+
priceUnit,
|
|
400
|
+
discount,
|
|
401
|
+
debit: minorText(debit, scale),
|
|
402
|
+
credit: minorText(credit, scale),
|
|
403
|
+
balance: minorText(balance, scale),
|
|
404
|
+
reconciled: false,
|
|
405
|
+
amountResidual: minorText(residual, scale),
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
if (debitTotal !== creditTotal)
|
|
409
|
+
boundaryError('lines', 'the draft move must balance exactly at company-currency scale');
|
|
410
|
+
let { untaxed, tax, total } = (() => {
|
|
411
|
+
try {
|
|
412
|
+
return {
|
|
413
|
+
untaxed: moneyMinor(input.move.amountUntaxed ?? '0', scale),
|
|
414
|
+
tax: moneyMinor(input.move.amountTax ?? '0', scale),
|
|
415
|
+
total: moneyMinor(input.move.amountTotal ?? '0', scale),
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
catch {
|
|
419
|
+
throw new DraftMoveBoundaryError('move.amountTotal', 'move totals must be canonical exact strings');
|
|
420
|
+
}
|
|
421
|
+
})();
|
|
422
|
+
if (String(input.move.moveType) === 'entry') {
|
|
423
|
+
// A journal entry's displayed total is its balanced turnover. Contra lines
|
|
424
|
+
// can make the source transaction's net amount smaller than this gross
|
|
425
|
+
// debit/credit total, so an entry does not carry invoice subtotal semantics.
|
|
426
|
+
untaxed = debitTotal;
|
|
427
|
+
tax = 0n;
|
|
428
|
+
total = debitTotal;
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
if (untaxed + tax !== total)
|
|
432
|
+
boundaryError('move.amountTotal', 'untaxed plus tax must equal the document total');
|
|
433
|
+
if (total !== residualTotal)
|
|
434
|
+
boundaryError('move.amountTotal', 'the document total must equal its open-item counterparts');
|
|
435
|
+
}
|
|
436
|
+
const move = {
|
|
437
|
+
...input.move,
|
|
438
|
+
currency,
|
|
439
|
+
accountingDate: accountingDateText(input.move.accountingDate ?? input.move.date, timezone),
|
|
440
|
+
documentDate: accountingDateText(input.move.documentDate ?? input.move.invoiceDate ?? input.move.accountingDate ?? input.move.date, timezone),
|
|
441
|
+
amountUntaxed: minorText(untaxed, scale),
|
|
442
|
+
amountTax: minorText(tax, scale),
|
|
443
|
+
amountTotal: minorText(total, scale),
|
|
444
|
+
postedAt: null,
|
|
445
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
446
|
+
revision: 0,
|
|
447
|
+
};
|
|
448
|
+
const inserted = await ctx.db.insertIfAbsent('account.Move', move);
|
|
449
|
+
if (!('dryRun' in inserted) && !inserted.inserted) {
|
|
450
|
+
const existing = (await ctx.db.select('account.Move', { id: moveId }))[0];
|
|
451
|
+
const storedLines = await ctx.db.select('account.MoveLine', { moveId });
|
|
452
|
+
const sameMove = Boolean(existing &&
|
|
453
|
+
rowMatches(existing, move, Object.keys(move).filter((field) => field !== 'companyId' && field !== 'revision')));
|
|
454
|
+
const byId = new Map(storedLines.map((row) => [String(row.id), row]));
|
|
455
|
+
const sameLines = storedLines.length === normalizedLines.length &&
|
|
456
|
+
normalizedLines.every((line) => {
|
|
457
|
+
const held = byId.get(String(line.id));
|
|
458
|
+
return Boolean(held &&
|
|
459
|
+
rowMatches(held, line, Object.keys(line).filter((field) => field !== 'companyId')));
|
|
460
|
+
});
|
|
461
|
+
if (!sameMove || !sameLines)
|
|
462
|
+
boundaryError('move.id', 'the draft move id is already used by different financial content');
|
|
463
|
+
return { id: moveId, existing: true };
|
|
464
|
+
}
|
|
465
|
+
for (const line of normalizedLines) {
|
|
466
|
+
const result = await ctx.db.insertIfAbsent('account.MoveLine', line);
|
|
467
|
+
if (!('dryRun' in result) && !result.inserted)
|
|
468
|
+
boundaryError('lines.id', 'a journal item id is already used outside this draft move');
|
|
469
|
+
}
|
|
470
|
+
return { id: moveId, existing: false };
|
|
471
|
+
}
|
|
472
|
+
/** Reads a company's fallback accounts, whether or not a row has been written yet. */
|
|
473
|
+
async function defaultsOf(ctx) {
|
|
474
|
+
return (await ctx.db.select('account.Defaults'))[0] ?? {};
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* The category a variant belongs to, through its template.
|
|
478
|
+
*
|
|
479
|
+
* An invoice line names a variant, the catalogue hangs the category off the
|
|
480
|
+
* template, and the accounts hang off the category — so reaching one from the
|
|
481
|
+
* other is two hops, not a join this query layer offers.
|
|
482
|
+
*/
|
|
483
|
+
async function categoryOfProduct(ctx, productId) {
|
|
484
|
+
if (!productId)
|
|
485
|
+
return null;
|
|
486
|
+
const variant = (await ctx.db.select('product.Product', { id: productId }))[0];
|
|
487
|
+
if (!variant)
|
|
488
|
+
return null;
|
|
489
|
+
const template = (await ctx.db.select('product.Template', { id: variant.templateId }))[0];
|
|
490
|
+
return template?.categoryId ?? null;
|
|
491
|
+
}
|
|
492
|
+
export const ACCOUNT_RESOLUTION_EFFECTS = [
|
|
493
|
+
'read:account.Account',
|
|
494
|
+
'read:account.Defaults',
|
|
495
|
+
'read:account.CategoryAccount',
|
|
496
|
+
'read:product.Product',
|
|
497
|
+
'read:product.Template',
|
|
498
|
+
'read:partner.CompanyTerms',
|
|
499
|
+
];
|
|
500
|
+
/**
|
|
501
|
+
* Decide which accounts a document posts to.
|
|
502
|
+
*
|
|
503
|
+
* Most: an explicit choice wins, then the narrowest configured default, then the
|
|
504
|
+
* company's. Asking the person writing an invoice to name a revenue account out
|
|
505
|
+
* of 216 is asking them to re-answer a question the chart already answers the
|
|
506
|
+
* same way every time — and to get it wrong occasionally.
|
|
507
|
+
*
|
|
508
|
+
* The partner's control accounts are read from `partner.CompanyTerms`, whose
|
|
509
|
+
* account fields the optional `account_partner` module adds. When it is not
|
|
510
|
+
* installed the fields are simply absent and resolution falls through to the
|
|
511
|
+
* company default, which is why this reads them rather than depending on it.
|
|
512
|
+
*/
|
|
513
|
+
async function resolveAccounts(ctx, args, explicit = {}) {
|
|
514
|
+
const customer = ['out_invoice', 'out_refund', 'out_receipt'].includes(args.moveType);
|
|
515
|
+
const defaults = await defaultsOf(ctx);
|
|
516
|
+
let lineAccountId = explicit.lineAccountId ?? null;
|
|
517
|
+
let lineAccountFrom = lineAccountId ? 'explicit' : null;
|
|
518
|
+
if (!lineAccountId) {
|
|
519
|
+
const categoryId = await categoryOfProduct(ctx, args.productId);
|
|
520
|
+
const mapped = categoryId
|
|
521
|
+
? ((await ctx.db.select('account.CategoryAccount', { categoryId }))[0] ?? null)
|
|
522
|
+
: null;
|
|
523
|
+
const fromCategory = customer ? mapped?.incomeAccountId : mapped?.expenseAccountId;
|
|
524
|
+
if (fromCategory) {
|
|
525
|
+
lineAccountId = fromCategory;
|
|
526
|
+
lineAccountFrom = 'category';
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
lineAccountId = (customer ? defaults.incomeAccountId : defaults.expenseAccountId) ?? null;
|
|
530
|
+
lineAccountFrom = lineAccountId ? 'company' : null;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
let counterpartAccountId = explicit.counterpartAccountId ?? null;
|
|
534
|
+
let counterpartAccountFrom = counterpartAccountId
|
|
535
|
+
? 'explicit'
|
|
536
|
+
: null;
|
|
537
|
+
if (!counterpartAccountId) {
|
|
538
|
+
const terms = args.partnerId
|
|
539
|
+
? ((await ctx.db.select('partner.CompanyTerms', { partnerId: args.partnerId }))[0] ?? null)
|
|
540
|
+
: null;
|
|
541
|
+
const fromPartner = customer ? terms?.receivableAccountId : terms?.payableAccountId;
|
|
542
|
+
if (fromPartner) {
|
|
543
|
+
counterpartAccountId = fromPartner;
|
|
544
|
+
counterpartAccountFrom = 'partner';
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
counterpartAccountId = (customer ? defaults.receivableAccountId : defaults.payableAccountId) ?? null;
|
|
548
|
+
counterpartAccountFrom = counterpartAccountId ? 'company' : null;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return { lineAccountId, lineAccountFrom, counterpartAccountId, counterpartAccountFrom };
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Paging is opt-in, never implicit. A screen asks for a page; an export or a
|
|
555
|
+
* report asks for everything and gets it, rather than a silently truncated list
|
|
556
|
+
* that reads as complete.
|
|
557
|
+
*/
|
|
558
|
+
const paginate = (q, limit, offset) => {
|
|
559
|
+
const size = Math.trunc(n(limit));
|
|
560
|
+
const start = Math.trunc(n(offset));
|
|
561
|
+
const limited = size > 0 ? q.limit(size) : q;
|
|
562
|
+
return start > 0 ? limited.offset(start) : limited;
|
|
563
|
+
};
|
|
564
|
+
const slice = (rows, limit, offset) => {
|
|
565
|
+
const size = Math.trunc(n(limit));
|
|
566
|
+
const start = Math.max(0, Math.trunc(n(offset)));
|
|
567
|
+
return size > 0 ? rows.slice(start, start + size) : rows.slice(start);
|
|
568
|
+
};
|
|
569
|
+
const moveTypeList = (value) => Array.isArray(value) ? value.map(String).filter((type) => MOVE_TYPES.includes(type)) : [];
|
|
570
|
+
const paymentStateList = (value) => Array.isArray(value) ? value.map(String).filter((state) => PAYMENT_STATES.includes(state)) : [];
|
|
571
|
+
/** The ids of every posted move inside an optional inclusive civil-date window. */
|
|
572
|
+
export async function postedMoves(ctx, dateFrom, dateTo) {
|
|
573
|
+
const { currency, timezone } = await ledgerOf(ctx);
|
|
574
|
+
const fromDate = accountingFilterDateText(dateFrom);
|
|
575
|
+
const toDate = accountingFilterDateText(dateTo);
|
|
576
|
+
const M = ctx.table('account.Move');
|
|
577
|
+
const moves = await ctx.db.all(from(M).where(eq(M.state, 'posted')));
|
|
578
|
+
const selected = [];
|
|
579
|
+
for (const held of moves) {
|
|
580
|
+
if (String(held.currency) !== currency)
|
|
581
|
+
throw new Refusal('moveCurrencyMismatch');
|
|
582
|
+
const accountingDate = moveAccountingDate(held, timezone);
|
|
583
|
+
if (fromDate && accountingDate < fromDate)
|
|
584
|
+
continue;
|
|
585
|
+
if (toDate && accountingDate > toDate)
|
|
586
|
+
continue;
|
|
587
|
+
selected.push([String(held.id), { ...held, accountingDate }]);
|
|
588
|
+
}
|
|
589
|
+
return new Map(selected);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Journal items belonging to the given moves. The ids go into the query so the
|
|
593
|
+
* database does the narrowing; chunking keeps a long reporting window from
|
|
594
|
+
* building a parameter list no driver will accept.
|
|
595
|
+
*/
|
|
596
|
+
export async function linesOfMoves(ctx, moveIds, accountId) {
|
|
597
|
+
if (!moveIds.length)
|
|
598
|
+
return [];
|
|
599
|
+
const L = ctx.table('account.MoveLine');
|
|
600
|
+
const rows = [];
|
|
601
|
+
for (let at = 0; at < moveIds.length; at += 400) {
|
|
602
|
+
const chunk = moveIds.slice(at, at + 400);
|
|
603
|
+
rows.push(...(await ctx.db.all(from(L).where(and(inArray(L.moveId, chunk), ...(accountId ? [eq(L.accountId, accountId)] : []))))));
|
|
604
|
+
}
|
|
605
|
+
return rows;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Every account of the active company, by id. Callers that classify a whole page
|
|
609
|
+
* of journal items need this once instead of a lookup per line — a chart of
|
|
610
|
+
* accounts is bounded by a company's configured chart while a ledger is not.
|
|
611
|
+
*/
|
|
612
|
+
export async function accountsById(ctx) {
|
|
613
|
+
return new Map((await ctx.db.select('account.Account')).map((row) => [String(row.id), row]));
|
|
614
|
+
}
|
|
71
615
|
async function dueDate(ctx, paymentTermId, date) {
|
|
72
616
|
if (!paymentTermId)
|
|
73
617
|
return date.toISOString();
|
|
@@ -95,39 +639,178 @@ async function dueDate(ctx, paymentTermId, date) {
|
|
|
95
639
|
}
|
|
96
640
|
return latest.toISOString();
|
|
97
641
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
642
|
+
const taxOrder = (a, b) => n(a.sequence) - n(b.sequence) || String(a.id).localeCompare(String(b.id));
|
|
643
|
+
/**
|
|
644
|
+
* Apply a line's taxes in sequence.
|
|
645
|
+
*
|
|
646
|
+
* A tax marked `includeBaseAmount` adds its own amount to the base every later
|
|
647
|
+
* tax is computed on — this is how import duty compounds into import VAT, which
|
|
648
|
+
* is the case for a chart installed by a localization or configured by an operator.
|
|
649
|
+
*/
|
|
650
|
+
function taxAmounts(taxes, quantity, priceUnit, discount, scale) {
|
|
651
|
+
const gross = discountedLineMinor(quantity, priceUnit, discount, scale);
|
|
652
|
+
if (!taxes.length) {
|
|
653
|
+
const amount = minorText(gross, scale);
|
|
654
|
+
return { untaxed: amount, tax: minorText(0n, scale), total: amount, shares: [] };
|
|
111
655
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
656
|
+
const ordered = [...taxes].sort(taxOrder);
|
|
657
|
+
const included = ordered.filter((tax) => tax.priceInclude === true);
|
|
658
|
+
if (included.length && included.length !== ordered.length)
|
|
659
|
+
throw new Refusal('taxMixedPriceInclude');
|
|
660
|
+
if (included.length > 1)
|
|
661
|
+
throw new Refusal('taxManyPriceInclude');
|
|
662
|
+
const share = (tax, base) => {
|
|
663
|
+
if (tax.amountType === 'fixed')
|
|
664
|
+
return multiplyToMinor([tax.amount, quantity], scale);
|
|
665
|
+
if (tax.amountType === 'percent')
|
|
666
|
+
return percentOfMinor(base, tax.amount);
|
|
667
|
+
if (tax.amountType === 'division') {
|
|
668
|
+
if (compareDecimals(tax.amount, '100') >= 0)
|
|
669
|
+
throw new Refusal('taxDivisionFull');
|
|
670
|
+
return divisionTaxMinor(base, tax.amount);
|
|
116
671
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
672
|
+
throw new Refusal('taxComputationUnsupported');
|
|
673
|
+
};
|
|
674
|
+
if (included.length === 1) {
|
|
675
|
+
const tax = ordered[0];
|
|
676
|
+
let untaxed = gross;
|
|
677
|
+
if (tax.amountType === 'fixed') {
|
|
678
|
+
untaxed = gross - share(tax, gross);
|
|
679
|
+
// A fixed tax said to be inside the price cannot be more than the price.
|
|
680
|
+
// Left alone it makes the base negative, which posts a credit to revenue
|
|
681
|
+
// as a debit and reverses the sign of the sale in the ledger.
|
|
682
|
+
if (untaxed < 0n)
|
|
683
|
+
throw new Refusal('taxFixedExceedsLine');
|
|
684
|
+
}
|
|
685
|
+
else if (tax.amountType === 'percent')
|
|
686
|
+
untaxed = includedPercentBaseMinor(gross, tax.amount);
|
|
687
|
+
else if (tax.amountType === 'division') {
|
|
688
|
+
if (compareDecimals(tax.amount, '100') >= 0)
|
|
689
|
+
throw new Refusal('taxDivisionFull');
|
|
690
|
+
untaxed = includedDivisionBaseMinor(gross, tax.amount);
|
|
124
691
|
}
|
|
125
692
|
else
|
|
126
|
-
|
|
693
|
+
throw new Refusal('taxComputationUnsupported');
|
|
694
|
+
const amount = gross - untaxed;
|
|
695
|
+
return {
|
|
696
|
+
untaxed: minorText(untaxed, scale),
|
|
697
|
+
tax: minorText(amount, scale),
|
|
698
|
+
total: minorText(untaxed + amount, scale),
|
|
699
|
+
shares: [
|
|
700
|
+
{
|
|
701
|
+
taxId: tax.id,
|
|
702
|
+
name: String(tax.name),
|
|
703
|
+
accountId: tax.accountId ?? null,
|
|
704
|
+
amount: minorText(amount, scale),
|
|
705
|
+
},
|
|
706
|
+
],
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
const shares = [];
|
|
710
|
+
let base = gross;
|
|
711
|
+
let total = 0n;
|
|
712
|
+
for (const tax of ordered) {
|
|
713
|
+
const amount = share(tax, base);
|
|
714
|
+
shares.push({
|
|
715
|
+
taxId: tax.id,
|
|
716
|
+
name: String(tax.name),
|
|
717
|
+
accountId: tax.accountId ?? null,
|
|
718
|
+
amount: minorText(amount, scale),
|
|
719
|
+
});
|
|
720
|
+
total += amount;
|
|
721
|
+
if (tax.includeBaseAmount === true)
|
|
722
|
+
base += amount;
|
|
723
|
+
}
|
|
724
|
+
return {
|
|
725
|
+
untaxed: minorText(gross, scale),
|
|
726
|
+
tax: minorText(total, scale),
|
|
727
|
+
total: minorText(gross + total, scale),
|
|
728
|
+
shares,
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
/** Canonical product line calculation shared by Sales, POS and invoices. */
|
|
732
|
+
export async function quoteTaxLineForPosting(ctx, input) {
|
|
733
|
+
let quantity;
|
|
734
|
+
let priceUnit;
|
|
735
|
+
let discount;
|
|
736
|
+
try {
|
|
737
|
+
quantity = canonicalDecimalText(input.quantity);
|
|
738
|
+
priceUnit = canonicalDecimalText(input.priceUnit);
|
|
739
|
+
discount = canonicalDecimalText(input.discount ?? '0');
|
|
740
|
+
if (decimalSign(quantity) <= 0)
|
|
741
|
+
return invalid('quantity', 'taxQuantityPositive');
|
|
742
|
+
if ((!input.allowNegativePrice && decimalSign(priceUnit) < 0) ||
|
|
743
|
+
decimalSign(discount) < 0 ||
|
|
744
|
+
compareDecimals(discount, '100') > 0)
|
|
745
|
+
return invalid('priceUnit', 'taxPriceInvalid');
|
|
127
746
|
}
|
|
128
|
-
|
|
747
|
+
catch {
|
|
748
|
+
return invalid('priceUnit', 'taxPriceInvalid');
|
|
749
|
+
}
|
|
750
|
+
let wanted;
|
|
751
|
+
if (Array.isArray(input.taxIds))
|
|
752
|
+
wanted = [...new Set(input.taxIds.map(String))];
|
|
753
|
+
else if (input.productId) {
|
|
754
|
+
const product = (await ctx.db.select('product.Product', { id: input.productId }))[0];
|
|
755
|
+
if (!product)
|
|
756
|
+
return invalid('productId', 'productMissing');
|
|
757
|
+
const mapping = (await ctx.db.select('account.ProductTax', { templateId: product.templateId }))[0];
|
|
758
|
+
wanted = mapping?.taxId ? [String(mapping.taxId)] : [];
|
|
759
|
+
}
|
|
760
|
+
else
|
|
761
|
+
wanted = [];
|
|
762
|
+
const taxes = [];
|
|
763
|
+
for (const id of wanted) {
|
|
764
|
+
const tax = (await ctx.db.select('account.Tax', { id }))[0];
|
|
765
|
+
if (!tax || tax.active === false)
|
|
766
|
+
return invalid('taxIds', 'taxMissing');
|
|
767
|
+
if (![input.taxUse ?? 'sale', 'none'].includes(String(tax.typeTaxUse)))
|
|
768
|
+
return invalid('taxIds', 'taxDirectionMismatch', { name: tax.name });
|
|
769
|
+
taxes.push(tax);
|
|
770
|
+
}
|
|
771
|
+
const { currency, scale } = await ledgerOf(ctx);
|
|
772
|
+
try {
|
|
773
|
+
const amounts = taxAmounts(taxes, quantity, priceUnit, discount, scale);
|
|
774
|
+
const shares = new Map(amounts.shares.map((share) => [String(share.taxId), share]));
|
|
775
|
+
return {
|
|
776
|
+
ok: true,
|
|
777
|
+
currency,
|
|
778
|
+
scale,
|
|
779
|
+
quantity,
|
|
780
|
+
priceUnit,
|
|
781
|
+
discount,
|
|
782
|
+
amountUntaxed: amounts.untaxed,
|
|
783
|
+
amountTax: amounts.tax,
|
|
784
|
+
amountTotal: amounts.total,
|
|
785
|
+
taxIds: taxes.sort(taxOrder).map((tax) => String(tax.id)),
|
|
786
|
+
taxes: taxes.sort(taxOrder).map((tax) => ({
|
|
787
|
+
id: String(tax.id),
|
|
788
|
+
name: String(tax.name),
|
|
789
|
+
amountType: String(tax.amountType),
|
|
790
|
+
amount: String(tax.amount),
|
|
791
|
+
priceInclude: tax.priceInclude === true,
|
|
792
|
+
includeBaseAmount: tax.includeBaseAmount === true,
|
|
793
|
+
sequence: n(tax.sequence),
|
|
794
|
+
share: shares.get(String(tax.id))?.amount ?? minorText(0n, scale),
|
|
795
|
+
})),
|
|
796
|
+
shares: amounts.shares,
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
catch (error) {
|
|
800
|
+
return refused('taxIds', error);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
/** Public calculation evidence intentionally excludes ledger account routing. */
|
|
804
|
+
export async function quoteTaxLine(ctx, input) {
|
|
805
|
+
const quote = await quoteTaxLineForPosting(ctx, input);
|
|
806
|
+
if (quote.ok !== true)
|
|
807
|
+
return quote;
|
|
808
|
+
return {
|
|
809
|
+
...quote,
|
|
810
|
+
shares: quote.shares.map(({ accountId: _accountId, ...share }) => share),
|
|
811
|
+
};
|
|
129
812
|
}
|
|
130
|
-
async function nextMoveName(ctx, journal,
|
|
813
|
+
async function nextMoveName(ctx, journal, accountingDate) {
|
|
131
814
|
for (let attempt = 0; attempt < 32; attempt += 1) {
|
|
132
815
|
const current = (await ctx.db.select('account.Journal', { id: journal.id }))[0];
|
|
133
816
|
if (!current)
|
|
@@ -135,59 +818,266 @@ async function nextMoveName(ctx, journal, date) {
|
|
|
135
818
|
const previous = n(current.sequenceNumber);
|
|
136
819
|
const changed = await ctx.db.compareAndSet('account.Journal', { id: journal.id }, { sequenceNumber: current.sequenceNumber }, { sequenceNumber: previous + 1 });
|
|
137
820
|
if ('dryRun' in changed || changed.matched)
|
|
138
|
-
return `${String(journal.code).toUpperCase()}/${
|
|
821
|
+
return `${String(journal.code).toUpperCase()}/${fiscalYearKey(accountingDate)}/${String(previous + 1).padStart(5, '0')}`;
|
|
139
822
|
}
|
|
140
823
|
throw new Error('journal sequence did not settle after concurrent updates');
|
|
141
824
|
}
|
|
142
|
-
async function
|
|
825
|
+
export async function postMoveById(ctx, id, expectedRevision) {
|
|
143
826
|
const move = (await ctx.db.select('account.Move', { id }))[0];
|
|
144
827
|
if (!move)
|
|
145
|
-
return invalid('id', '
|
|
146
|
-
if (move.state === 'posted')
|
|
828
|
+
return invalid('id', 'moveMissing');
|
|
829
|
+
if (move.state === 'posted') {
|
|
830
|
+
await ctx.db.insertIfAbsent('account.AuditEvent', {
|
|
831
|
+
id: `move:${String(move.id)}:posted`,
|
|
832
|
+
subjectType: 'move',
|
|
833
|
+
subjectId: String(move.id),
|
|
834
|
+
action: 'posted',
|
|
835
|
+
actorId: ctx.actor ?? null,
|
|
836
|
+
accountingDate: move.accountingDate,
|
|
837
|
+
reason: null,
|
|
838
|
+
relatedId: null,
|
|
839
|
+
details: { journalId: move.journalId, name: move.name, moneyPolicyVersion: move.moneyPolicyVersion },
|
|
840
|
+
createdAt: move.postedAt ?? today(),
|
|
841
|
+
});
|
|
147
842
|
return { ok: true, id: move.id, name: move.name };
|
|
843
|
+
}
|
|
148
844
|
if (move.state !== 'draft')
|
|
149
|
-
return invalid('state', '
|
|
845
|
+
return invalid('state', 'moveDraftOnly');
|
|
846
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
847
|
+
if (String(move.currency) !== currency)
|
|
848
|
+
return invalid('currency', 'moveCurrencyMismatch');
|
|
849
|
+
const journal = (await ctx.db.select('account.Journal', { id: move.journalId }))[0];
|
|
850
|
+
if (!journal)
|
|
851
|
+
return invalid('journalId', 'journalMissing');
|
|
852
|
+
if (journal.active === false)
|
|
853
|
+
return invalid('journalId', 'journalInactive');
|
|
150
854
|
const lines = await ctx.db.select('account.MoveLine', { moveId: id });
|
|
151
855
|
if (lines.length < 2)
|
|
152
|
-
return invalid('lines', '
|
|
153
|
-
let debit =
|
|
154
|
-
let credit =
|
|
856
|
+
return invalid('lines', 'linesTooFew');
|
|
857
|
+
let debit = 0n;
|
|
858
|
+
let credit = 0n;
|
|
859
|
+
let residualTotal = 0n;
|
|
860
|
+
const accounts = new Map();
|
|
155
861
|
for (const line of lines) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
862
|
+
let lineDebit;
|
|
863
|
+
let lineCredit;
|
|
864
|
+
let balance;
|
|
865
|
+
let residual;
|
|
866
|
+
try {
|
|
867
|
+
lineDebit = moneyMinor(line.debit, scale);
|
|
868
|
+
lineCredit = moneyMinor(line.credit, scale);
|
|
869
|
+
balance = moneyMinor(line.balance, scale);
|
|
870
|
+
residual = moneyMinor(line.amountResidual, scale);
|
|
871
|
+
}
|
|
872
|
+
catch {
|
|
873
|
+
return invalid('lines', 'moneyExactString');
|
|
874
|
+
}
|
|
875
|
+
if (lineDebit < 0n || lineCredit < 0n || (lineDebit > 0n && lineCredit > 0n))
|
|
876
|
+
return invalid('lines', 'lineSideBoth');
|
|
877
|
+
if (lineDebit === 0n && lineCredit === 0n)
|
|
878
|
+
return invalid('lines', 'lineAmountRequired');
|
|
879
|
+
if (balance !== lineDebit - lineCredit)
|
|
880
|
+
return invalid('lines', 'lineBalanceInvalid');
|
|
881
|
+
const accountId = String(line.accountId);
|
|
882
|
+
let account = accounts.get(accountId);
|
|
883
|
+
if (!account) {
|
|
884
|
+
account = (await accountOf(ctx, accountId)) ?? undefined;
|
|
885
|
+
if (!account)
|
|
886
|
+
return invalid('lines.accountId', 'accountMissing');
|
|
887
|
+
accounts.set(accountId, account);
|
|
888
|
+
}
|
|
889
|
+
if (account.active === false)
|
|
890
|
+
return invalid('lines.accountId', 'accountInactive');
|
|
891
|
+
const magnitude = balance < 0n ? -balance : balance;
|
|
892
|
+
if (line.reconciled === true ||
|
|
893
|
+
residual < 0n ||
|
|
894
|
+
residual > magnitude ||
|
|
895
|
+
(account.reconcile === true ? residual !== magnitude : residual !== 0n))
|
|
896
|
+
return invalid('lines.amountResidual', 'lineResidualInvalid');
|
|
897
|
+
debit += lineDebit;
|
|
898
|
+
credit += lineCredit;
|
|
899
|
+
residualTotal += residual;
|
|
900
|
+
}
|
|
901
|
+
if (debit !== credit)
|
|
902
|
+
return invalid('lines', 'entryUnbalanced', {
|
|
903
|
+
debit: minorText(debit, scale),
|
|
904
|
+
credit: minorText(credit, scale),
|
|
905
|
+
});
|
|
906
|
+
if (move.moveType !== 'entry') {
|
|
907
|
+
let untaxed;
|
|
908
|
+
let tax;
|
|
909
|
+
let total;
|
|
910
|
+
try {
|
|
911
|
+
untaxed = moneyMinor(move.amountUntaxed, scale);
|
|
912
|
+
tax = moneyMinor(move.amountTax, scale);
|
|
913
|
+
total = moneyMinor(move.amountTotal, scale);
|
|
914
|
+
}
|
|
915
|
+
catch {
|
|
916
|
+
return invalid('amountTotal', 'moneyExactString');
|
|
917
|
+
}
|
|
918
|
+
if (untaxed + tax !== total || total !== residualTotal)
|
|
919
|
+
return invalid('amountTotal', 'moveTotalInvalid');
|
|
160
920
|
}
|
|
161
|
-
if (Math.abs(debit - credit) > 0.000001)
|
|
162
|
-
return invalid('lines', `entry is not balanced: debit ${debit}, credit ${credit}`);
|
|
163
|
-
const journal = (await ctx.db.select('account.Journal', { id: move.journalId }))[0];
|
|
164
|
-
if (!journal)
|
|
165
|
-
return invalid('journalId', 'journal does not exist');
|
|
166
921
|
const postedAt = today();
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
922
|
+
// An invoice already carries the totals its own line builder computed. A manual
|
|
923
|
+
// entry has none, and a ledger that shows every entry as 0 is not a ledger.
|
|
924
|
+
const totals = move.moveType === 'entry'
|
|
925
|
+
? {
|
|
926
|
+
amountUntaxed: minorText(debit, scale),
|
|
927
|
+
amountTax: minorText(0n, scale),
|
|
928
|
+
amountTotal: minorText(debit, scale),
|
|
929
|
+
}
|
|
930
|
+
: {};
|
|
931
|
+
let assigned;
|
|
932
|
+
try {
|
|
933
|
+
assigned = await ctx.tx(async (tx) => {
|
|
934
|
+
const current = (await tx.db.select('account.Move', { id }))[0];
|
|
935
|
+
if (!current)
|
|
936
|
+
throw new Refusal('moveMissing');
|
|
937
|
+
if (current.state === 'posted')
|
|
938
|
+
return String(current.name);
|
|
939
|
+
if (current.state !== 'draft')
|
|
940
|
+
throw new Refusal('moveDraftOnly');
|
|
941
|
+
// The validated line snapshot belongs to the revision read above. Claim that
|
|
942
|
+
// exact revision even when the caller did not supply a token: if a line was
|
|
943
|
+
// added after validation, posting must retry and validate the new set.
|
|
944
|
+
const validatedRevision = expectedRevision ?? move.revision ?? null;
|
|
945
|
+
if (!(await claimMoveRevision(tx, current, validatedRevision)))
|
|
946
|
+
throw new Refusal('moveConcurrent');
|
|
947
|
+
let accountingDate;
|
|
948
|
+
let documentDate;
|
|
949
|
+
try {
|
|
950
|
+
accountingDate = accountingDateText(current.accountingDate ?? current.date, timezone);
|
|
951
|
+
documentDate = accountingDateText(current.documentDate ?? current.invoiceDate ?? current.accountingDate ?? current.date, timezone);
|
|
952
|
+
}
|
|
953
|
+
catch {
|
|
954
|
+
throw new Refusal('accountingDateInvalid');
|
|
955
|
+
}
|
|
956
|
+
let locked;
|
|
957
|
+
try {
|
|
958
|
+
locked = await claimPostingPeriod(tx, {
|
|
959
|
+
accountingDate,
|
|
960
|
+
moveType: current.moveType,
|
|
961
|
+
journalType: journal.type,
|
|
962
|
+
hasTax: lines.some((line) => line.taxId != null),
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
catch {
|
|
966
|
+
throw new Refusal('periodConcurrent');
|
|
967
|
+
}
|
|
968
|
+
if (locked)
|
|
969
|
+
throw new Refusal('periodLocked', locked);
|
|
970
|
+
const name = await nextMoveName(tx, journal, accountingDate);
|
|
971
|
+
await tx.db.update('account.Move', { id }, {
|
|
972
|
+
name,
|
|
973
|
+
state: 'posted',
|
|
974
|
+
accountingDate,
|
|
975
|
+
documentDate,
|
|
976
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
977
|
+
postedAt,
|
|
978
|
+
...totals,
|
|
979
|
+
});
|
|
980
|
+
await tx.db.insertIfAbsent('account.AuditEvent', {
|
|
981
|
+
id: `move:${String(id)}:posted`,
|
|
982
|
+
subjectType: 'move',
|
|
983
|
+
subjectId: String(id),
|
|
984
|
+
action: 'posted',
|
|
985
|
+
actorId: tx.actor ?? null,
|
|
986
|
+
accountingDate,
|
|
987
|
+
reason: null,
|
|
988
|
+
relatedId: null,
|
|
989
|
+
details: { journalId: journal.id, name, moneyPolicyVersion: MONEY_POLICY_VERSION },
|
|
990
|
+
createdAt: postedAt,
|
|
991
|
+
});
|
|
992
|
+
return name;
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
catch (error) {
|
|
996
|
+
// Two replicas may both validate the same draft and one may lose the CAS only
|
|
997
|
+
// because the other already posted it. That retry has reached its requested
|
|
998
|
+
// state and is therefore an idempotent success, not a conflict.
|
|
999
|
+
if (error instanceof Refusal && error.code === 'moveConcurrent') {
|
|
1000
|
+
const settled = (await ctx.db.select('account.Move', { id }))[0];
|
|
1001
|
+
if (settled?.state === 'posted')
|
|
1002
|
+
return { ok: true, id: settled.id, name: settled.name };
|
|
1003
|
+
}
|
|
1004
|
+
return refused(error instanceof Refusal && error.code === 'accountingDateInvalid'
|
|
1005
|
+
? 'accountingDate'
|
|
1006
|
+
: error instanceof Refusal && error.code === 'periodLocked'
|
|
1007
|
+
? 'accountingDate'
|
|
1008
|
+
: 'expectedRevision', error);
|
|
1009
|
+
}
|
|
172
1010
|
return { ok: true, id: move.id, name: assigned };
|
|
173
1011
|
}
|
|
174
|
-
|
|
1012
|
+
const OPEN_ITEM_TYPES = ['asset_receivable', 'liability_payable'];
|
|
1013
|
+
async function updatePaymentState(ctx, moveId, accounts) {
|
|
175
1014
|
const move = (await ctx.db.select('account.Move', { id: moveId }))[0];
|
|
176
1015
|
if (!move || move.moveType === 'entry')
|
|
177
1016
|
return;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
1017
|
+
// A reversal settles the document; it must not be relabelled by the residual math.
|
|
1018
|
+
if (move.paymentState === 'reversed')
|
|
1019
|
+
return;
|
|
1020
|
+
const byId = accounts ?? (await accountsById(ctx));
|
|
1021
|
+
const candidates = (await ctx.db.select('account.MoveLine', { moveId })).filter((line) => OPEN_ITEM_TYPES.includes(String(byId.get(String(line.accountId))?.accountType)));
|
|
1022
|
+
const scale = scaleOf(move.currency);
|
|
1023
|
+
const original = candidates.reduce((sum, line) => {
|
|
1024
|
+
const amount = moneyMinor(line.balance, scale);
|
|
1025
|
+
return sum + (amount < 0n ? -amount : amount);
|
|
1026
|
+
}, 0n);
|
|
1027
|
+
const residual = candidates.reduce((sum, line) => {
|
|
1028
|
+
const amount = moneyMinor(line.amountResidual, scale);
|
|
1029
|
+
return sum + (amount < 0n ? -amount : amount);
|
|
1030
|
+
}, 0n);
|
|
1031
|
+
const paymentState = residual === 0n ? 'paid' : residual < original ? 'partial' : 'not_paid';
|
|
188
1032
|
await ctx.db.update('account.Move', { id: moveId }, { paymentState });
|
|
189
1033
|
}
|
|
1034
|
+
/**
|
|
1035
|
+
* The slice of a list a picker actually needs.
|
|
1036
|
+
*
|
|
1037
|
+
* A relation picker sends `search` on every keystroke and `limit` to keep the
|
|
1038
|
+
* response small; `validateInput` rejects inputs a function does not declare, so
|
|
1039
|
+
* a list without them cannot back a picker at all. `product` and `uom` carry the
|
|
1040
|
+
* same helper for the same reason.
|
|
1041
|
+
*/
|
|
1042
|
+
const narrow = (rows, args, fields) => {
|
|
1043
|
+
const needle = String(args.search ?? '')
|
|
1044
|
+
.trim()
|
|
1045
|
+
.toLocaleLowerCase();
|
|
1046
|
+
const matched = needle
|
|
1047
|
+
? rows.filter((row) => fields.some((field) => String(row[field] ?? '')
|
|
1048
|
+
.toLocaleLowerCase()
|
|
1049
|
+
.includes(needle)))
|
|
1050
|
+
: rows;
|
|
1051
|
+
const limit = Number(args.limit);
|
|
1052
|
+
return Number.isInteger(limit) && limit > 0 ? matched.slice(0, limit) : matched;
|
|
1053
|
+
};
|
|
190
1054
|
export const functions = {
|
|
1055
|
+
quoteLine: defineFn({
|
|
1056
|
+
input: {
|
|
1057
|
+
productId: 'id?',
|
|
1058
|
+
taxIds: 'json?',
|
|
1059
|
+
quantity: 'decimal',
|
|
1060
|
+
priceUnit: 'decimal',
|
|
1061
|
+
discount: 'decimal?',
|
|
1062
|
+
},
|
|
1063
|
+
output: {
|
|
1064
|
+
ok: 'bool',
|
|
1065
|
+
currency: 'text?',
|
|
1066
|
+
scale: 'int?',
|
|
1067
|
+
quantity: 'decimal?',
|
|
1068
|
+
priceUnit: 'decimal?',
|
|
1069
|
+
discount: 'decimal?',
|
|
1070
|
+
amountUntaxed: 'decimal?',
|
|
1071
|
+
amountTax: 'decimal?',
|
|
1072
|
+
amountTotal: 'decimal?',
|
|
1073
|
+
taxIds: 'json?',
|
|
1074
|
+
taxes: 'json?',
|
|
1075
|
+
errors: 'json?',
|
|
1076
|
+
},
|
|
1077
|
+
effects: ['read:company.Company', 'read:product.Product', 'read:account.ProductTax', 'read:account.Tax'],
|
|
1078
|
+
agent: true,
|
|
1079
|
+
handler: (ctx, args) => quoteTaxLine(ctx, args),
|
|
1080
|
+
}),
|
|
191
1081
|
initializeCompany: defineFn({
|
|
192
1082
|
input: {},
|
|
193
1083
|
output: {
|
|
@@ -209,15 +1099,41 @@ export const functions = {
|
|
|
209
1099
|
agent: true,
|
|
210
1100
|
handler: async (ctx) => (await ctx.db.select('account.Setup'))[0] ?? null,
|
|
211
1101
|
}),
|
|
1102
|
+
/**
|
|
1103
|
+
* The chart of accounts, narrowed the way a picker asks for it.
|
|
1104
|
+
*
|
|
1105
|
+
* `search` and `limit` are what a relation picker sends on every keystroke, and
|
|
1106
|
+
* an unknown input is a hard error — so a chart of two hundred accounts is only
|
|
1107
|
+
* reachable through a search dialog once they are part of the signature.
|
|
1108
|
+
* `accountTypes` moves a restriction the forms were applying after the fact
|
|
1109
|
+
* into the query, so the dialog offers nothing the field would reject.
|
|
1110
|
+
*/
|
|
212
1111
|
listAccounts: defineFn({
|
|
213
|
-
input: { includeArchived: 'bool?' },
|
|
1112
|
+
input: { includeArchived: 'bool?', accountTypes: 'json?', search: 'text?', limit: 'int?' },
|
|
214
1113
|
effects: ['read:account.Account', ...ACCOUNT_SETUP_EFFECTS],
|
|
215
1114
|
agent: true,
|
|
216
1115
|
handler: async (ctx, args) => {
|
|
217
1116
|
await ensureCompanyAccounting(ctx);
|
|
218
1117
|
const A = ctx.table('account.Account');
|
|
219
1118
|
const q = from(A).orderBy(asc(A.code));
|
|
220
|
-
|
|
1119
|
+
const rows = await ctx.db.all(args.includeArchived ? q : q.where(eq(A.active, true)));
|
|
1120
|
+
const types = Array.isArray(args.accountTypes) ? args.accountTypes.map(String) : [];
|
|
1121
|
+
const wanted = types.length
|
|
1122
|
+
? rows.filter((row) => types.some((type) =>
|
|
1123
|
+
// A prefix so a field can ask for every income account without
|
|
1124
|
+
// naming income_other alongside income.
|
|
1125
|
+
type.endsWith('*')
|
|
1126
|
+
? String(row.accountType).startsWith(type.slice(0, -1))
|
|
1127
|
+
: String(row.accountType) === type))
|
|
1128
|
+
: rows;
|
|
1129
|
+
const needle = String(args.search ?? '')
|
|
1130
|
+
.trim()
|
|
1131
|
+
.toLocaleLowerCase();
|
|
1132
|
+
const matched = needle
|
|
1133
|
+
? wanted.filter((row) => `${String(row.code)} ${String(row.name)}`.toLocaleLowerCase().includes(needle))
|
|
1134
|
+
: wanted;
|
|
1135
|
+
const limit = Number(args.limit);
|
|
1136
|
+
return Number.isInteger(limit) && limit > 0 ? matched.slice(0, limit) : matched;
|
|
221
1137
|
},
|
|
222
1138
|
}),
|
|
223
1139
|
saveAccount: defineFn({
|
|
@@ -228,13 +1144,13 @@ export const functions = {
|
|
|
228
1144
|
agent: true,
|
|
229
1145
|
handler: async (ctx, args) => {
|
|
230
1146
|
if (!ACCOUNT_TYPES.includes(args.accountType))
|
|
231
|
-
return invalid('accountType', '
|
|
1147
|
+
return invalid('accountType', 'accountTypeUnsupported');
|
|
232
1148
|
if (!/^[A-Za-z0-9.]+$/.test(String(args.code)))
|
|
233
|
-
return invalid('code', '
|
|
1149
|
+
return invalid('code', 'accountCodeFormat');
|
|
234
1150
|
const forced = ['asset_receivable', 'liability_payable'].includes(String(args.accountType));
|
|
235
1151
|
const reconcile = forced || args.reconcile === true;
|
|
236
1152
|
if (args.accountType === 'off_balance' && reconcile)
|
|
237
|
-
return invalid('reconcile', '
|
|
1153
|
+
return invalid('reconcile', 'offBalanceReconcile');
|
|
238
1154
|
const existing = (await ctx.db.select('account.Account', { id: args.id }))[0];
|
|
239
1155
|
const values = { ...args, reconcile, active: args.active ?? true };
|
|
240
1156
|
const cs = ctx
|
|
@@ -248,12 +1164,15 @@ export const functions = {
|
|
|
248
1164
|
},
|
|
249
1165
|
}),
|
|
250
1166
|
listJournals: defineFn({
|
|
251
|
-
input: { type: 'text?' },
|
|
1167
|
+
input: { type: 'text?', includeArchived: 'bool?' },
|
|
252
1168
|
effects: ['read:account.Journal', ...ACCOUNT_SETUP_EFFECTS],
|
|
253
1169
|
agent: true,
|
|
254
1170
|
handler: async (ctx, args) => {
|
|
255
1171
|
await ensureCompanyAccounting(ctx);
|
|
256
|
-
return ctx.db.select('account.Journal',
|
|
1172
|
+
return ctx.db.select('account.Journal', {
|
|
1173
|
+
...(args.type ? { type: args.type } : {}),
|
|
1174
|
+
...(args.includeArchived ? {} : { active: true }),
|
|
1175
|
+
});
|
|
257
1176
|
},
|
|
258
1177
|
}),
|
|
259
1178
|
saveJournal: defineFn({
|
|
@@ -264,11 +1183,11 @@ export const functions = {
|
|
|
264
1183
|
agent: true,
|
|
265
1184
|
handler: async (ctx, args) => {
|
|
266
1185
|
if (!JOURNAL_TYPES.includes(args.type))
|
|
267
|
-
return invalid('type', '
|
|
1186
|
+
return invalid('type', 'journalTypeUnsupported');
|
|
268
1187
|
if (!/^[A-Za-z0-9]+$/.test(String(args.code)))
|
|
269
|
-
return invalid('code', '
|
|
1188
|
+
return invalid('code', 'journalCodeFormat');
|
|
270
1189
|
if (args.defaultAccountId && !(await accountOf(ctx, args.defaultAccountId)))
|
|
271
|
-
return invalid('defaultAccountId', '
|
|
1190
|
+
return invalid('defaultAccountId', 'defaultAccountMissing');
|
|
272
1191
|
const existing = (await ctx.db.select('account.Journal', { id: args.id }))[0];
|
|
273
1192
|
const values = {
|
|
274
1193
|
...args,
|
|
@@ -287,12 +1206,63 @@ export const functions = {
|
|
|
287
1206
|
},
|
|
288
1207
|
}),
|
|
289
1208
|
listTaxes: defineFn({
|
|
290
|
-
input: { typeTaxUse: 'text?' },
|
|
1209
|
+
input: { typeTaxUse: 'text?', includeArchived: 'bool?', search: 'text?', limit: 'int?' },
|
|
291
1210
|
effects: ['read:account.Tax', ...ACCOUNT_SETUP_EFFECTS],
|
|
292
1211
|
agent: true,
|
|
293
1212
|
handler: async (ctx, args) => {
|
|
294
1213
|
await ensureCompanyAccounting(ctx);
|
|
295
|
-
|
|
1214
|
+
const rows = await ctx.db.select('account.Tax', {
|
|
1215
|
+
...(args.typeTaxUse ? { typeTaxUse: args.typeTaxUse } : {}),
|
|
1216
|
+
...(args.includeArchived ? {} : { active: true }),
|
|
1217
|
+
});
|
|
1218
|
+
return narrow(rows.sort(taxOrder), args, ['name']);
|
|
1219
|
+
},
|
|
1220
|
+
}),
|
|
1221
|
+
getProductTax: defineFn({
|
|
1222
|
+
input: { templateId: 'id' },
|
|
1223
|
+
output: { id: 'id', templateId: 'id', taxId: 'id' },
|
|
1224
|
+
effects: ['read:account.ProductTax'],
|
|
1225
|
+
agent: true,
|
|
1226
|
+
handler: async (ctx, args) => (await ctx.db.select('account.ProductTax', { templateId: args.templateId }))[0] ?? null,
|
|
1227
|
+
}),
|
|
1228
|
+
setProductTax: defineFn({
|
|
1229
|
+
input: { templateId: 'id', taxId: 'id?' },
|
|
1230
|
+
output: { ok: 'bool', id: 'id?', errors: 'json?' },
|
|
1231
|
+
effects: [
|
|
1232
|
+
'read:product.Template',
|
|
1233
|
+
'read:account.Tax',
|
|
1234
|
+
'read:account.ProductTax',
|
|
1235
|
+
'write:account.ProductTax',
|
|
1236
|
+
],
|
|
1237
|
+
idempotent: true,
|
|
1238
|
+
agent: true,
|
|
1239
|
+
handler: async (ctx, args) => {
|
|
1240
|
+
if (!(await ctx.db.select('product.Template', { id: args.templateId }))[0])
|
|
1241
|
+
return invalid('templateId', 'productMissing');
|
|
1242
|
+
const held = (await ctx.db.select('account.ProductTax', { templateId: args.templateId }))[0];
|
|
1243
|
+
if (!args.taxId) {
|
|
1244
|
+
if (held) {
|
|
1245
|
+
const ProductTax = ctx.table('account.ProductTax');
|
|
1246
|
+
await ctx.db.del(deleteFrom(ProductTax).where(eq(ProductTax.id, held.id)));
|
|
1247
|
+
}
|
|
1248
|
+
return { ok: true };
|
|
1249
|
+
}
|
|
1250
|
+
const tax = (await ctx.db.select('account.Tax', { id: args.taxId }))[0];
|
|
1251
|
+
if (!tax)
|
|
1252
|
+
return invalid('taxId', 'taxMissing');
|
|
1253
|
+
if (!['sale', 'none'].includes(String(tax.typeTaxUse)))
|
|
1254
|
+
return invalid('taxId', 'taxDirectionMismatch', { name: tax.name });
|
|
1255
|
+
if (held) {
|
|
1256
|
+
await ctx.db.update('account.ProductTax', { id: held.id }, { taxId: args.taxId });
|
|
1257
|
+
return { ok: true, id: held.id };
|
|
1258
|
+
}
|
|
1259
|
+
const id = `product-tax:${String(ctx.scope.company ?? '')}:${String(args.templateId)}`;
|
|
1260
|
+
await ctx.db.insert('account.ProductTax', {
|
|
1261
|
+
id,
|
|
1262
|
+
templateId: args.templateId,
|
|
1263
|
+
taxId: args.taxId,
|
|
1264
|
+
});
|
|
1265
|
+
return { ok: true, id };
|
|
296
1266
|
},
|
|
297
1267
|
}),
|
|
298
1268
|
saveTax: defineFn({
|
|
@@ -301,7 +1271,6 @@ export const functions = {
|
|
|
301
1271
|
name: 'text',
|
|
302
1272
|
description: 'text?',
|
|
303
1273
|
typeTaxUse: 'text',
|
|
304
|
-
taxScope: 'text?',
|
|
305
1274
|
amountType: 'text',
|
|
306
1275
|
amount: 'decimal',
|
|
307
1276
|
priceInclude: 'bool?',
|
|
@@ -316,16 +1285,24 @@ export const functions = {
|
|
|
316
1285
|
agent: true,
|
|
317
1286
|
handler: async (ctx, args) => {
|
|
318
1287
|
if (!TAX_USES.includes(args.typeTaxUse))
|
|
319
|
-
return invalid('typeTaxUse', '
|
|
1288
|
+
return invalid('typeTaxUse', 'taxUseUnsupported');
|
|
320
1289
|
if (!TAX_AMOUNT_TYPES.includes(args.amountType))
|
|
321
|
-
return invalid('amountType', '
|
|
1290
|
+
return invalid('amountType', 'taxComputationUnsupported');
|
|
322
1291
|
if (args.taxScope && !['service', 'consu'].includes(String(args.taxScope)))
|
|
323
|
-
return invalid('taxScope', '
|
|
1292
|
+
return invalid('taxScope', 'taxScopeUnsupported');
|
|
324
1293
|
if (args.accountId && !(await accountOf(ctx, args.accountId)))
|
|
325
|
-
return invalid('accountId', '
|
|
1294
|
+
return invalid('accountId', 'taxAccountMissing');
|
|
1295
|
+
let amount;
|
|
1296
|
+
try {
|
|
1297
|
+
amount = canonicalDecimalText(args.amount);
|
|
1298
|
+
}
|
|
1299
|
+
catch {
|
|
1300
|
+
return invalid('amount', 'moneyExactString');
|
|
1301
|
+
}
|
|
326
1302
|
const existing = (await ctx.db.select('account.Tax', { id: args.id }))[0];
|
|
327
1303
|
const values = {
|
|
328
1304
|
...args,
|
|
1305
|
+
amount,
|
|
329
1306
|
priceInclude: args.priceInclude === true,
|
|
330
1307
|
includeBaseAmount: args.includeBaseAmount === true,
|
|
331
1308
|
sequence: args.sequence ?? 10,
|
|
@@ -338,7 +1315,6 @@ export const functions = {
|
|
|
338
1315
|
'name',
|
|
339
1316
|
'description',
|
|
340
1317
|
'typeTaxUse',
|
|
341
|
-
'taxScope',
|
|
342
1318
|
'amountType',
|
|
343
1319
|
'amount',
|
|
344
1320
|
'priceInclude',
|
|
@@ -354,14 +1330,152 @@ export const functions = {
|
|
|
354
1330
|
return { ok: true, id: args.id };
|
|
355
1331
|
},
|
|
356
1332
|
}),
|
|
357
|
-
|
|
1333
|
+
getDefaults: defineFn({
|
|
358
1334
|
input: {},
|
|
359
|
-
|
|
1335
|
+
output: {
|
|
1336
|
+
id: 'id?',
|
|
1337
|
+
incomeAccountId: 'id?',
|
|
1338
|
+
expenseAccountId: 'id?',
|
|
1339
|
+
receivableAccountId: 'id?',
|
|
1340
|
+
payableAccountId: 'id?',
|
|
1341
|
+
},
|
|
1342
|
+
effects: ['read:account.Defaults', ...ACCOUNT_SETUP_EFFECTS],
|
|
1343
|
+
agent: true,
|
|
1344
|
+
handler: async (ctx) => {
|
|
1345
|
+
await ensureCompanyAccounting(ctx);
|
|
1346
|
+
return (await ctx.db.select('account.Defaults'))[0] ?? {};
|
|
1347
|
+
},
|
|
1348
|
+
}),
|
|
1349
|
+
saveDefaults: defineFn({
|
|
1350
|
+
input: {
|
|
1351
|
+
incomeAccountId: 'id?',
|
|
1352
|
+
expenseAccountId: 'id?',
|
|
1353
|
+
receivableAccountId: 'id?',
|
|
1354
|
+
payableAccountId: 'id?',
|
|
1355
|
+
},
|
|
1356
|
+
output: { ok: 'bool', id: 'id?', errors: 'json?' },
|
|
1357
|
+
effects: ['read:account.Account', 'read:account.Defaults', 'write:account.Defaults'],
|
|
1358
|
+
idempotent: true,
|
|
1359
|
+
agent: true,
|
|
1360
|
+
handler: async (ctx, args) => {
|
|
1361
|
+
// Each default has a type the ledger will insist on later; refusing here
|
|
1362
|
+
// means the invoice that would have used it never fails in the first place.
|
|
1363
|
+
for (const [field, wanted] of [
|
|
1364
|
+
['incomeAccountId', ['income', 'income_other']],
|
|
1365
|
+
['expenseAccountId', ['expense', 'expense_other', 'expense_depreciation', 'expense_direct_cost']],
|
|
1366
|
+
['receivableAccountId', ['asset_receivable']],
|
|
1367
|
+
['payableAccountId', ['liability_payable']],
|
|
1368
|
+
]) {
|
|
1369
|
+
const id = args[field];
|
|
1370
|
+
if (!id)
|
|
1371
|
+
continue;
|
|
1372
|
+
const account = await accountOf(ctx, id);
|
|
1373
|
+
if (!account)
|
|
1374
|
+
return invalid(field, 'accountMissing');
|
|
1375
|
+
if (!wanted.includes(String(account.accountType)))
|
|
1376
|
+
return invalid(field, field === 'receivableAccountId'
|
|
1377
|
+
? 'counterpartMustBeReceivable'
|
|
1378
|
+
: field === 'payableAccountId'
|
|
1379
|
+
? 'counterpartMustBePayable'
|
|
1380
|
+
: 'defaultAccountType');
|
|
1381
|
+
}
|
|
1382
|
+
const held = (await ctx.db.select('account.Defaults'))[0];
|
|
1383
|
+
const values = {
|
|
1384
|
+
incomeAccountId: args.incomeAccountId ?? null,
|
|
1385
|
+
expenseAccountId: args.expenseAccountId ?? null,
|
|
1386
|
+
receivableAccountId: args.receivableAccountId ?? null,
|
|
1387
|
+
payableAccountId: args.payableAccountId ?? null,
|
|
1388
|
+
};
|
|
1389
|
+
if (held) {
|
|
1390
|
+
await ctx.db.update('account.Defaults', { id: held.id }, values);
|
|
1391
|
+
return { ok: true, id: held.id };
|
|
1392
|
+
}
|
|
1393
|
+
const id = `account-defaults:${String(ctx.scope.company ?? '')}`;
|
|
1394
|
+
await ctx.db.insert('account.Defaults', { id, ...values });
|
|
1395
|
+
return { ok: true, id };
|
|
1396
|
+
},
|
|
1397
|
+
}),
|
|
1398
|
+
listCategoryAccounts: defineFn({
|
|
1399
|
+
input: {},
|
|
1400
|
+
effects: ['read:account.CategoryAccount', 'read:product.Category'],
|
|
360
1401
|
agent: true,
|
|
361
1402
|
handler: async (ctx) => {
|
|
1403
|
+
const categories = new Map((await ctx.db.select('product.Category')).map((row) => [String(row.id), row]));
|
|
1404
|
+
return (await ctx.db.select('account.CategoryAccount')).map((row) => ({
|
|
1405
|
+
...row,
|
|
1406
|
+
categoryName: categories.get(String(row.categoryId))?.name ?? null,
|
|
1407
|
+
}));
|
|
1408
|
+
},
|
|
1409
|
+
}),
|
|
1410
|
+
saveCategoryAccount: defineFn({
|
|
1411
|
+
input: { categoryId: 'id', incomeAccountId: 'id?', expenseAccountId: 'id?' },
|
|
1412
|
+
output: { ok: 'bool', id: 'id?', errors: 'json?' },
|
|
1413
|
+
effects: [
|
|
1414
|
+
'read:account.Account',
|
|
1415
|
+
'read:account.CategoryAccount',
|
|
1416
|
+
'read:product.Category',
|
|
1417
|
+
'write:account.CategoryAccount',
|
|
1418
|
+
],
|
|
1419
|
+
idempotent: true,
|
|
1420
|
+
agent: true,
|
|
1421
|
+
handler: async (ctx, args) => {
|
|
1422
|
+
if (!(await ctx.db.select('product.Category', { id: args.categoryId }))[0])
|
|
1423
|
+
return invalid('categoryId', 'categoryMissing');
|
|
1424
|
+
for (const [field, wanted] of [
|
|
1425
|
+
['incomeAccountId', ['income', 'income_other']],
|
|
1426
|
+
['expenseAccountId', ['expense', 'expense_other', 'expense_depreciation', 'expense_direct_cost']],
|
|
1427
|
+
]) {
|
|
1428
|
+
const id = args[field];
|
|
1429
|
+
if (!id)
|
|
1430
|
+
continue;
|
|
1431
|
+
const account = await accountOf(ctx, id);
|
|
1432
|
+
if (!account)
|
|
1433
|
+
return invalid(field, 'accountMissing');
|
|
1434
|
+
if (!wanted.includes(String(account.accountType)))
|
|
1435
|
+
return invalid(field, 'defaultAccountType');
|
|
1436
|
+
}
|
|
1437
|
+
const values = {
|
|
1438
|
+
incomeAccountId: args.incomeAccountId ?? null,
|
|
1439
|
+
expenseAccountId: args.expenseAccountId ?? null,
|
|
1440
|
+
};
|
|
1441
|
+
const held = (await ctx.db.select('account.CategoryAccount', { categoryId: args.categoryId }))[0];
|
|
1442
|
+
if (held) {
|
|
1443
|
+
await ctx.db.update('account.CategoryAccount', { id: held.id }, values);
|
|
1444
|
+
return { ok: true, id: held.id };
|
|
1445
|
+
}
|
|
1446
|
+
// One row per company and category, so the id can be derived rather than
|
|
1447
|
+
// generated: a second save corrects the first instead of racing it.
|
|
1448
|
+
const id = `category-account:${String(ctx.scope.company ?? '')}:${String(args.categoryId)}`;
|
|
1449
|
+
await ctx.db.insert('account.CategoryAccount', { id, categoryId: args.categoryId, ...values });
|
|
1450
|
+
return { ok: true, id };
|
|
1451
|
+
},
|
|
1452
|
+
}),
|
|
1453
|
+
/** What a document would post to, and what decided it. The forms use this to explain themselves. */
|
|
1454
|
+
previewAccounts: defineFn({
|
|
1455
|
+
input: { moveType: 'text', partnerId: 'id?', productId: 'id?' },
|
|
1456
|
+
output: {
|
|
1457
|
+
lineAccountId: 'id?',
|
|
1458
|
+
lineAccountFrom: 'text?',
|
|
1459
|
+
counterpartAccountId: 'id?',
|
|
1460
|
+
counterpartAccountFrom: 'text?',
|
|
1461
|
+
},
|
|
1462
|
+
effects: [...ACCOUNT_RESOLUTION_EFFECTS],
|
|
1463
|
+
agent: true,
|
|
1464
|
+
handler: (ctx, args) => resolveAccounts(ctx, {
|
|
1465
|
+
moveType: String(args.moveType),
|
|
1466
|
+
partnerId: args.partnerId,
|
|
1467
|
+
productId: args.productId,
|
|
1468
|
+
}),
|
|
1469
|
+
}),
|
|
1470
|
+
listPaymentTerms: defineFn({
|
|
1471
|
+
input: { includeArchived: 'bool?' },
|
|
1472
|
+
effects: ['read:account.PaymentTerm', 'read:account.PaymentTermLine', ...ACCOUNT_SETUP_EFFECTS],
|
|
1473
|
+
agent: true,
|
|
1474
|
+
handler: async (ctx, args) => {
|
|
362
1475
|
await ensureCompanyAccounting(ctx);
|
|
363
1476
|
const T = ctx.table('account.PaymentTerm');
|
|
364
|
-
|
|
1477
|
+
const q = from(T).orderBy(asc(T.name)).preload('lines');
|
|
1478
|
+
return ctx.db.all(args.includeArchived ? q : q.where(eq(T.active, true)));
|
|
365
1479
|
},
|
|
366
1480
|
}),
|
|
367
1481
|
savePaymentTerm: defineFn({
|
|
@@ -400,15 +1514,23 @@ export const functions = {
|
|
|
400
1514
|
agent: true,
|
|
401
1515
|
handler: async (ctx, args) => {
|
|
402
1516
|
if (!(await ctx.db.select('account.PaymentTerm', { id: args.paymentId }))[0])
|
|
403
|
-
return invalid('paymentId', '
|
|
1517
|
+
return invalid('paymentId', 'paymentTermMissing');
|
|
404
1518
|
if (!PAYMENT_TERM_VALUES.includes(args.value))
|
|
405
|
-
return invalid('value', '
|
|
1519
|
+
return invalid('value', 'termValueUnsupported');
|
|
406
1520
|
if (!PAYMENT_TERM_DELAY_TYPES.includes(args.delayType))
|
|
407
|
-
return invalid('delayType', '
|
|
408
|
-
|
|
409
|
-
|
|
1521
|
+
return invalid('delayType', 'termDelayUnsupported');
|
|
1522
|
+
let valueAmount;
|
|
1523
|
+
try {
|
|
1524
|
+
valueAmount = canonicalDecimalText(args.valueAmount);
|
|
1525
|
+
}
|
|
1526
|
+
catch {
|
|
1527
|
+
return invalid('valueAmount', 'moneyExactString');
|
|
1528
|
+
}
|
|
1529
|
+
if (args.value === 'percent' &&
|
|
1530
|
+
(decimalSign(valueAmount) < 0 || compareDecimals(valueAmount, '100') > 0))
|
|
1531
|
+
return invalid('valueAmount', 'termPercentRange');
|
|
410
1532
|
const existing = (await ctx.db.select('account.PaymentTermLine', { id: args.id }))[0];
|
|
411
|
-
const values = { ...args, sequence: args.sequence ?? 10 };
|
|
1533
|
+
const values = { ...args, valueAmount, sequence: args.sequence ?? 10 };
|
|
412
1534
|
const cs = ctx
|
|
413
1535
|
.change('account.PaymentTermLine', values, existing ?? null)
|
|
414
1536
|
.cast(['id', 'paymentId', 'value', 'valueAmount', 'delayType', 'nbDays', 'daysNextMonth', 'sequence'])
|
|
@@ -420,35 +1542,125 @@ export const functions = {
|
|
|
420
1542
|
},
|
|
421
1543
|
}),
|
|
422
1544
|
listMoves: defineFn({
|
|
423
|
-
input: {
|
|
1545
|
+
input: {
|
|
1546
|
+
moveType: 'text?',
|
|
1547
|
+
moveTypes: 'json?',
|
|
1548
|
+
state: 'text?',
|
|
1549
|
+
paymentState: 'text?',
|
|
1550
|
+
paymentStates: 'json?',
|
|
1551
|
+
partnerId: 'id?',
|
|
1552
|
+
search: 'text?',
|
|
1553
|
+
dateFrom: 'date?',
|
|
1554
|
+
dateTo: 'date?',
|
|
1555
|
+
order: 'text?',
|
|
1556
|
+
limit: 'int?',
|
|
1557
|
+
offset: 'int?',
|
|
1558
|
+
},
|
|
1559
|
+
effects: ['read:account.Move', 'read:company.Company'],
|
|
1560
|
+
agent: true,
|
|
1561
|
+
handler: async (ctx, args) => {
|
|
1562
|
+
const M = ctx.table('account.Move');
|
|
1563
|
+
const where = [
|
|
1564
|
+
...(args.moveType ? [eq(M.moveType, args.moveType)] : []),
|
|
1565
|
+
...(moveTypeList(args.moveTypes).length ? [inArray(M.moveType, moveTypeList(args.moveTypes))] : []),
|
|
1566
|
+
...(args.state ? [eq(M.state, args.state)] : []),
|
|
1567
|
+
...(args.paymentState ? [eq(M.paymentState, args.paymentState)] : []),
|
|
1568
|
+
...(paymentStateList(args.paymentStates).length
|
|
1569
|
+
? [inArray(M.paymentState, paymentStateList(args.paymentStates))]
|
|
1570
|
+
: []),
|
|
1571
|
+
...(args.partnerId ? [eq(M.partnerId, args.partnerId)] : []),
|
|
1572
|
+
...(args.search
|
|
1573
|
+
? [
|
|
1574
|
+
or(ilike(M.name, `%${wildcard(args.search)}%`, true), ilike(M.ref, `%${wildcard(args.search)}%`, true)),
|
|
1575
|
+
]
|
|
1576
|
+
: []),
|
|
1577
|
+
];
|
|
1578
|
+
const { timezone } = await ledgerOf(ctx);
|
|
1579
|
+
const dateFrom = accountingFilterDateText(args.dateFrom);
|
|
1580
|
+
const dateTo = accountingFilterDateText(args.dateTo);
|
|
1581
|
+
const loaded = (await ctx.db.all(where.length ? from(M).where(and(...where)) : from(M)));
|
|
1582
|
+
const rows = loaded
|
|
1583
|
+
.map((move) => ({ ...move, accountingDate: moveAccountingDate(move, timezone) }))
|
|
1584
|
+
.filter((move) => (!dateFrom || String(move.accountingDate) >= dateFrom) &&
|
|
1585
|
+
(!dateTo || String(move.accountingDate) <= dateTo))
|
|
1586
|
+
.sort((left, right) => {
|
|
1587
|
+
const held = String(left.accountingDate).localeCompare(String(right.accountingDate)) ||
|
|
1588
|
+
String(left.id).localeCompare(String(right.id));
|
|
1589
|
+
return args.order === 'desc' ? -held : held;
|
|
1590
|
+
});
|
|
1591
|
+
return slice(rows, args.limit, args.offset);
|
|
1592
|
+
},
|
|
1593
|
+
}),
|
|
1594
|
+
countMoves: defineFn({
|
|
1595
|
+
input: {
|
|
1596
|
+
moveType: 'text?',
|
|
1597
|
+
moveTypes: 'json?',
|
|
1598
|
+
state: 'text?',
|
|
1599
|
+
paymentState: 'text?',
|
|
1600
|
+
partnerId: 'id?',
|
|
1601
|
+
},
|
|
1602
|
+
output: { count: 'int' },
|
|
424
1603
|
effects: ['read:account.Move'],
|
|
425
1604
|
agent: true,
|
|
426
|
-
handler: (ctx, args) =>
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
1605
|
+
handler: async (ctx, args) => {
|
|
1606
|
+
const M = ctx.table('account.Move');
|
|
1607
|
+
const where = [
|
|
1608
|
+
...(args.moveType ? [eq(M.moveType, args.moveType)] : []),
|
|
1609
|
+
...(moveTypeList(args.moveTypes).length ? [inArray(M.moveType, moveTypeList(args.moveTypes))] : []),
|
|
1610
|
+
...(args.state ? [eq(M.state, args.state)] : []),
|
|
1611
|
+
...(args.paymentState ? [eq(M.paymentState, args.paymentState)] : []),
|
|
1612
|
+
...(args.partnerId ? [eq(M.partnerId, args.partnerId)] : []),
|
|
1613
|
+
];
|
|
1614
|
+
return { count: await ctx.db.count(where.length ? from(M).where(and(...where)) : from(M)) };
|
|
1615
|
+
},
|
|
431
1616
|
}),
|
|
432
|
-
|
|
433
|
-
input: {
|
|
434
|
-
effects: ['read:account.
|
|
1617
|
+
listMoveResiduals: defineFn({
|
|
1618
|
+
input: { moveIds: 'json' },
|
|
1619
|
+
effects: ['read:account.MoveLine', 'read:company.Company'],
|
|
435
1620
|
agent: true,
|
|
436
1621
|
handler: async (ctx, args) => {
|
|
437
|
-
const
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
continue;
|
|
449
|
-
rows.push({ ...line, move });
|
|
1622
|
+
const { scale } = await ledgerOf(ctx);
|
|
1623
|
+
const ids = Array.isArray(args.moveIds) ? [...new Set(args.moveIds.map(String).filter(Boolean))] : [];
|
|
1624
|
+
const totals = new Map(ids.map((id) => [id, 0n]));
|
|
1625
|
+
const L = ctx.table('account.MoveLine');
|
|
1626
|
+
for (let at = 0; at < ids.length; at += 400) {
|
|
1627
|
+
const chunk = ids.slice(at, at + 400);
|
|
1628
|
+
for (const line of await ctx.db.all(from(L).where(inArray(L.moveId, chunk)))) {
|
|
1629
|
+
const residual = moneyMinor(line.amountResidual, scale);
|
|
1630
|
+
if (residual > 0n)
|
|
1631
|
+
totals.set(String(line.moveId), (totals.get(String(line.moveId)) ?? 0n) + residual);
|
|
1632
|
+
}
|
|
450
1633
|
}
|
|
451
|
-
return
|
|
1634
|
+
return ids.map((moveId) => ({
|
|
1635
|
+
moveId,
|
|
1636
|
+
amountResidual: minorText(totals.get(moveId) ?? 0n, scale),
|
|
1637
|
+
}));
|
|
1638
|
+
},
|
|
1639
|
+
}),
|
|
1640
|
+
listOpenItems: defineFn({
|
|
1641
|
+
input: { partnerId: 'id?', accountId: 'id?', limit: 'int?', offset: 'int?' },
|
|
1642
|
+
effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine', 'read:company.Company'],
|
|
1643
|
+
agent: true,
|
|
1644
|
+
handler: async (ctx, args) => {
|
|
1645
|
+
const { scale, timezone } = await ledgerOf(ctx);
|
|
1646
|
+
const byId = await accountsById(ctx);
|
|
1647
|
+
const reconcilable = [...byId.values()].filter((row) => row.reconcile === true).map((row) => row.id);
|
|
1648
|
+
if (!reconcilable.length)
|
|
1649
|
+
return [];
|
|
1650
|
+
const posted = new Map((await ctx.db.select('account.Move', { state: 'posted' })).map((move) => [
|
|
1651
|
+
String(move.id),
|
|
1652
|
+
{ ...move, accountingDate: moveAccountingDate(move, timezone) },
|
|
1653
|
+
]));
|
|
1654
|
+
if (!posted.size)
|
|
1655
|
+
return [];
|
|
1656
|
+
const L = ctx.table('account.MoveLine');
|
|
1657
|
+
const lines = await ctx.db.all(from(L).where(and(eq(L.reconciled, false), inArray(L.accountId, args.accountId ? [args.accountId] : reconcilable), ...(args.partnerId ? [eq(L.partnerId, args.partnerId)] : []))));
|
|
1658
|
+
const rows = lines
|
|
1659
|
+
.filter((line) => posted.has(String(line.moveId)) && moneyMinor(line.amountResidual, scale) > 0n)
|
|
1660
|
+
.map((line) => ({ ...line, move: posted.get(String(line.moveId)) }))
|
|
1661
|
+
.sort((a, b) => String(a.move.accountingDate).localeCompare(String(b.move.accountingDate)) ||
|
|
1662
|
+
String(a.id).localeCompare(String(b.id)));
|
|
1663
|
+
return slice(rows, args.limit, args.offset);
|
|
452
1664
|
},
|
|
453
1665
|
}),
|
|
454
1666
|
getMove: defineFn({
|
|
@@ -466,6 +1678,8 @@ export const functions = {
|
|
|
466
1678
|
journalId: 'id',
|
|
467
1679
|
moveType: 'text?',
|
|
468
1680
|
date: 'datetime?',
|
|
1681
|
+
accountingDate: 'date?',
|
|
1682
|
+
documentDate: 'date?',
|
|
469
1683
|
ref: 'text?',
|
|
470
1684
|
partnerId: 'id?',
|
|
471
1685
|
invoiceDate: 'datetime?',
|
|
@@ -476,7 +1690,9 @@ export const functions = {
|
|
|
476
1690
|
effects: [
|
|
477
1691
|
'read:account.Journal',
|
|
478
1692
|
'read:account.Move',
|
|
1693
|
+
'read:account.PaymentTerm',
|
|
479
1694
|
'read:account.PaymentTermLine',
|
|
1695
|
+
'read:partner.Partner',
|
|
480
1696
|
'read:company.Company',
|
|
481
1697
|
'write:account.Move',
|
|
482
1698
|
],
|
|
@@ -485,36 +1701,64 @@ export const functions = {
|
|
|
485
1701
|
handler: async (ctx, args) => {
|
|
486
1702
|
const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
|
|
487
1703
|
if (!journal)
|
|
488
|
-
return invalid('journalId', '
|
|
1704
|
+
return invalid('journalId', 'journalMissing');
|
|
489
1705
|
const moveType = String(args.moveType ?? 'entry');
|
|
490
1706
|
if (!MOVE_TYPES.includes(moveType))
|
|
491
|
-
return invalid('moveType', '
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
await ctx
|
|
1707
|
+
return invalid('moveType', 'moveTypeUnsupported');
|
|
1708
|
+
if (args.partnerId && !(await ctx.db.select('partner.Partner', { id: args.partnerId }))[0])
|
|
1709
|
+
return invalid('partnerId', 'partnerMissing');
|
|
1710
|
+
if (args.paymentTermId && !(await ctx.db.select('account.PaymentTerm', { id: args.paymentTermId }))[0])
|
|
1711
|
+
return invalid('paymentTermId', 'paymentTermMissing');
|
|
1712
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
1713
|
+
const date = instantText(args.date ?? today());
|
|
1714
|
+
const invoiceDate = args.invoiceDate == null ? null : instantText(args.invoiceDate);
|
|
1715
|
+
const accountingDate = accountingDateText(args.accountingDate ?? date, timezone);
|
|
1716
|
+
const documentDate = accountingDateText(args.documentDate ?? invoiceDate ?? args.accountingDate ?? date, timezone);
|
|
1717
|
+
const invoiceDateDue = args.invoiceDateDue != null
|
|
1718
|
+
? instantText(args.invoiceDateDue)
|
|
1719
|
+
: invoiceDate
|
|
1720
|
+
? await dueDate(ctx, args.paymentTermId, new Date(invoiceDate))
|
|
1721
|
+
: null;
|
|
1722
|
+
const row = {
|
|
497
1723
|
id: args.id,
|
|
498
1724
|
name: String(args.id),
|
|
499
1725
|
ref: args.ref ?? null,
|
|
500
1726
|
date,
|
|
1727
|
+
accountingDate,
|
|
1728
|
+
documentDate,
|
|
501
1729
|
moveType,
|
|
502
1730
|
state: 'draft',
|
|
503
1731
|
journalId: args.journalId,
|
|
504
1732
|
partnerId: args.partnerId ?? null,
|
|
505
|
-
invoiceDate
|
|
506
|
-
invoiceDateDue
|
|
507
|
-
(args.invoiceDate
|
|
508
|
-
? await dueDate(ctx, args.paymentTermId, new Date(String(args.invoiceDate)))
|
|
509
|
-
: null),
|
|
1733
|
+
invoiceDate,
|
|
1734
|
+
invoiceDateDue,
|
|
510
1735
|
paymentTermId: args.paymentTermId ?? null,
|
|
511
1736
|
paymentState: moveType === 'entry' ? 'paid' : 'not_paid',
|
|
512
|
-
currency
|
|
513
|
-
amountUntaxed:
|
|
514
|
-
amountTax:
|
|
515
|
-
amountTotal:
|
|
1737
|
+
currency,
|
|
1738
|
+
amountUntaxed: minorText(0n, scale),
|
|
1739
|
+
amountTax: minorText(0n, scale),
|
|
1740
|
+
amountTotal: minorText(0n, scale),
|
|
1741
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
516
1742
|
postedAt: null,
|
|
517
|
-
|
|
1743
|
+
revision: 0,
|
|
1744
|
+
};
|
|
1745
|
+
const inserted = await ctx.db.insertIfAbsent('account.Move', row);
|
|
1746
|
+
if ('dryRun' in inserted || inserted.inserted)
|
|
1747
|
+
return { ok: true, id: args.id };
|
|
1748
|
+
const existing = (await ctx.db.select('account.Move', { id: args.id }))[0];
|
|
1749
|
+
const fields = [
|
|
1750
|
+
...MOVE_CREATE_FIELDS,
|
|
1751
|
+
...(args.date == null ? [] : ['date']),
|
|
1752
|
+
...(args.accountingDate == null && args.date == null ? [] : ['accountingDate']),
|
|
1753
|
+
...(args.documentDate == null &&
|
|
1754
|
+
args.invoiceDate == null &&
|
|
1755
|
+
args.accountingDate == null &&
|
|
1756
|
+
args.date == null
|
|
1757
|
+
? []
|
|
1758
|
+
: ['documentDate']),
|
|
1759
|
+
];
|
|
1760
|
+
if (!existing || !rowMatches(existing, row, fields))
|
|
1761
|
+
return invalid('id', 'moveIdReused');
|
|
518
1762
|
return { ok: true, id: args.id };
|
|
519
1763
|
},
|
|
520
1764
|
}),
|
|
@@ -536,22 +1780,47 @@ export const functions = {
|
|
|
536
1780
|
dateMaturity: 'datetime?',
|
|
537
1781
|
displayType: 'text?',
|
|
538
1782
|
sequence: 'int?',
|
|
1783
|
+
expectedRevision: 'int?',
|
|
539
1784
|
},
|
|
540
|
-
output: { ok: 'bool', id: 'id?', errors: 'json?' },
|
|
541
|
-
effects: [
|
|
1785
|
+
output: { ok: 'bool', id: 'id?', existing: 'bool?', errors: 'json?' },
|
|
1786
|
+
effects: [
|
|
1787
|
+
'read:account.Move',
|
|
1788
|
+
'read:account.MoveLine',
|
|
1789
|
+
'read:account.Account',
|
|
1790
|
+
'read:account.Tax',
|
|
1791
|
+
'write:account.Move',
|
|
1792
|
+
'write:account.MoveLine',
|
|
1793
|
+
],
|
|
542
1794
|
idempotent: true,
|
|
543
1795
|
agent: true,
|
|
544
1796
|
handler: async (ctx, args) => {
|
|
545
1797
|
const move = (await ctx.db.select('account.Move', { id: args.moveId }))[0];
|
|
546
|
-
if (move
|
|
547
|
-
return invalid('moveId', '
|
|
1798
|
+
if (!move)
|
|
1799
|
+
return invalid('moveId', 'lineDraftOnly');
|
|
548
1800
|
const account = await accountOf(ctx, args.accountId);
|
|
549
1801
|
if (!account)
|
|
550
|
-
return invalid('accountId', '
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
1802
|
+
return invalid('accountId', 'accountMissing');
|
|
1803
|
+
if (args.taxId && !(await ctx.db.select('account.Tax', { id: args.taxId }))[0])
|
|
1804
|
+
return invalid('taxId', 'taxMissing');
|
|
1805
|
+
const scale = scaleOf(move.currency);
|
|
1806
|
+
let debit;
|
|
1807
|
+
let credit;
|
|
1808
|
+
let quantity;
|
|
1809
|
+
let priceUnit;
|
|
1810
|
+
let discount;
|
|
1811
|
+
try {
|
|
1812
|
+
debit = moneyMinor(args.debit ?? '0', scale);
|
|
1813
|
+
credit = moneyMinor(args.credit ?? '0', scale);
|
|
1814
|
+
quantity = canonicalDecimalText(args.quantity ?? '1');
|
|
1815
|
+
priceUnit = canonicalDecimalText(args.priceUnit ?? '0');
|
|
1816
|
+
discount = canonicalDecimalText(args.discount ?? '0');
|
|
1817
|
+
}
|
|
1818
|
+
catch {
|
|
1819
|
+
return invalid('debit', 'moneyExactString');
|
|
1820
|
+
}
|
|
1821
|
+
if (debit < 0n || credit < 0n || (debit > 0n && credit > 0n))
|
|
1822
|
+
return invalid('debit', 'lineSideBoth');
|
|
1823
|
+
const row = {
|
|
555
1824
|
id: args.id,
|
|
556
1825
|
moveId: args.moveId,
|
|
557
1826
|
name: args.name,
|
|
@@ -559,22 +1828,80 @@ export const functions = {
|
|
|
559
1828
|
partnerId: args.partnerId ?? move.partnerId ?? null,
|
|
560
1829
|
productId: args.productId ?? null,
|
|
561
1830
|
productUomId: args.productUomId ?? null,
|
|
562
|
-
quantity
|
|
563
|
-
priceUnit
|
|
564
|
-
discount
|
|
1831
|
+
quantity,
|
|
1832
|
+
priceUnit,
|
|
1833
|
+
discount,
|
|
565
1834
|
taxId: args.taxId ?? null,
|
|
566
|
-
debit:
|
|
567
|
-
credit:
|
|
568
|
-
balance:
|
|
569
|
-
dateMaturity: args.dateMaturity
|
|
1835
|
+
debit: minorText(debit, scale),
|
|
1836
|
+
credit: minorText(credit, scale),
|
|
1837
|
+
balance: minorText(debit - credit, scale),
|
|
1838
|
+
dateMaturity: args.dateMaturity == null ? null : instantText(args.dateMaturity),
|
|
570
1839
|
displayType: args.displayType ?? null,
|
|
571
1840
|
reconciled: false,
|
|
572
|
-
amountResidual: account.reconcile
|
|
1841
|
+
amountResidual: account.reconcile
|
|
1842
|
+
? minorText(debit >= credit ? debit - credit : credit - debit, scale)
|
|
1843
|
+
: minorText(0n, scale),
|
|
573
1844
|
sequence: args.sequence ?? 10,
|
|
574
|
-
}
|
|
575
|
-
|
|
1845
|
+
};
|
|
1846
|
+
const sameLine = (held) => Boolean(held && rowMatches(held, row, MOVE_LINE_CREATE_FIELDS));
|
|
1847
|
+
try {
|
|
1848
|
+
return await ctx.tx(async (tx) => {
|
|
1849
|
+
const current = (await tx.db.select('account.Move', { id: args.moveId }))[0];
|
|
1850
|
+
if (!current)
|
|
1851
|
+
throw new Refusal('lineDraftOnly');
|
|
1852
|
+
// A retry remains successful after the move was posted. Only a genuinely
|
|
1853
|
+
// new line is subject to the draft-state gate.
|
|
1854
|
+
const existing = (await tx.db.select('account.MoveLine', { id: args.id }))[0];
|
|
1855
|
+
if (existing) {
|
|
1856
|
+
if (!sameLine(existing))
|
|
1857
|
+
throw new Refusal('lineIdTaken');
|
|
1858
|
+
return { ok: true, id: args.id, existing: true };
|
|
1859
|
+
}
|
|
1860
|
+
if (current.state !== 'draft')
|
|
1861
|
+
throw new Refusal('lineDraftOnly');
|
|
1862
|
+
if (!(await claimMoveRevision(tx, current, args.expectedRevision)))
|
|
1863
|
+
throw new Refusal('moveConcurrent');
|
|
1864
|
+
const inserted = await tx.db.insertIfAbsent('account.MoveLine', row);
|
|
1865
|
+
if ('dryRun' in inserted || inserted.inserted)
|
|
1866
|
+
return { ok: true, id: args.id, existing: false };
|
|
1867
|
+
const held = (await tx.db.select('account.MoveLine', { id: args.id }))[0];
|
|
1868
|
+
if (!sameLine(held))
|
|
1869
|
+
throw new Refusal('lineIdTaken');
|
|
1870
|
+
return { ok: true, id: args.id, existing: true };
|
|
1871
|
+
});
|
|
1872
|
+
}
|
|
1873
|
+
catch (error) {
|
|
1874
|
+
if (error instanceof Refusal && error.code === 'moveConcurrent') {
|
|
1875
|
+
const held = (await ctx.db.select('account.MoveLine', { id: args.id }))[0];
|
|
1876
|
+
if (sameLine(held))
|
|
1877
|
+
return { ok: true, id: args.id, existing: true };
|
|
1878
|
+
const settled = (await ctx.db.select('account.Move', { id: args.moveId }))[0];
|
|
1879
|
+
if (settled?.state !== 'draft')
|
|
1880
|
+
return invalid('moveId', 'lineDraftOnly');
|
|
1881
|
+
}
|
|
1882
|
+
const field = error instanceof Refusal && error.code === 'lineIdTaken'
|
|
1883
|
+
? 'id'
|
|
1884
|
+
: error instanceof Refusal && error.code === 'lineDraftOnly'
|
|
1885
|
+
? 'moveId'
|
|
1886
|
+
: 'expectedRevision';
|
|
1887
|
+
return refused(field, error);
|
|
1888
|
+
}
|
|
576
1889
|
},
|
|
577
1890
|
}),
|
|
1891
|
+
/**
|
|
1892
|
+
* An invoice, in one call, with one line or many.
|
|
1893
|
+
*
|
|
1894
|
+
* A document with several lines cannot be assembled out of `createMove` and
|
|
1895
|
+
* `addMoveLine`: those write exactly what they are given, and the tax a line
|
|
1896
|
+
* carries has to become a posting of its own, computed in the order taxes
|
|
1897
|
+
* compound. Leaving that to callers means every caller re-derives VAT, and
|
|
1898
|
+
* they will not all round it the same way.
|
|
1899
|
+
*
|
|
1900
|
+
* So `lines` is the general form and the flat `description`/`quantity`/
|
|
1901
|
+
* `priceUnit` arguments are the one-line shorthand. A single-line document
|
|
1902
|
+
* built either way lands on the same rows with the same ids, which is what
|
|
1903
|
+
* lets an existing caller keep its `${id}:base` and `${id}:tax` identifiers.
|
|
1904
|
+
*/
|
|
578
1905
|
createInvoice: defineFn({
|
|
579
1906
|
input: {
|
|
580
1907
|
id: 'id',
|
|
@@ -582,27 +1909,42 @@ export const functions = {
|
|
|
582
1909
|
moveType: 'text',
|
|
583
1910
|
partnerId: 'id',
|
|
584
1911
|
invoiceDate: 'datetime?',
|
|
1912
|
+
accountingDate: 'date?',
|
|
1913
|
+
documentDate: 'date?',
|
|
585
1914
|
paymentTermId: 'id?',
|
|
586
1915
|
ref: 'text?',
|
|
587
|
-
|
|
1916
|
+
/**
|
|
1917
|
+
* The lines of the document, when there is more than one.
|
|
1918
|
+
*
|
|
1919
|
+
* `{ description, quantity, priceUnit, productId?, productUomId?,
|
|
1920
|
+
* discount?, taxId?, taxIds?, lineAccountId?, taxAccountId? }` — the same
|
|
1921
|
+
* fields as the shorthand below, per line. Give this or the shorthand,
|
|
1922
|
+
* never both.
|
|
1923
|
+
*/
|
|
1924
|
+
lines: 'json?',
|
|
1925
|
+
description: 'text?',
|
|
588
1926
|
productId: 'id?',
|
|
589
1927
|
productUomId: 'id?',
|
|
590
|
-
quantity: 'decimal',
|
|
591
|
-
priceUnit: 'decimal',
|
|
1928
|
+
quantity: 'decimal?',
|
|
1929
|
+
priceUnit: 'decimal?',
|
|
592
1930
|
discount: 'decimal?',
|
|
593
|
-
|
|
594
|
-
|
|
1931
|
+
// Optional: left out, they come from the product's category, the partner,
|
|
1932
|
+
// and the company's defaults, in that order.
|
|
1933
|
+
lineAccountId: 'id?',
|
|
1934
|
+
counterpartAccountId: 'id?',
|
|
595
1935
|
taxId: 'id?',
|
|
1936
|
+
taxIds: 'json?',
|
|
596
1937
|
taxAccountId: 'id?',
|
|
597
1938
|
},
|
|
598
1939
|
output: { ok: 'bool', id: 'id?', amountTotal: 'decimal?', errors: 'json?' },
|
|
599
1940
|
effects: [
|
|
600
1941
|
'read:account.Journal',
|
|
601
|
-
'read:account.Account',
|
|
602
1942
|
'read:account.Tax',
|
|
603
1943
|
'read:account.Move',
|
|
1944
|
+
'read:account.MoveLine',
|
|
604
1945
|
'read:account.PaymentTermLine',
|
|
605
1946
|
'read:company.Company',
|
|
1947
|
+
...ACCOUNT_RESOLUTION_EFFECTS,
|
|
606
1948
|
'write:account.Move',
|
|
607
1949
|
'write:account.MoveLine',
|
|
608
1950
|
],
|
|
@@ -610,60 +1952,141 @@ export const functions = {
|
|
|
610
1952
|
agent: true,
|
|
611
1953
|
handler: async (ctx, args) => {
|
|
612
1954
|
if (!['out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'].includes(String(args.moveType)))
|
|
613
|
-
return invalid('moveType', '
|
|
1955
|
+
return invalid('moveType', 'invoiceTypeRequired');
|
|
614
1956
|
const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
|
|
615
1957
|
if (!journal)
|
|
616
|
-
return invalid('journalId', '
|
|
1958
|
+
return invalid('journalId', 'journalMissing');
|
|
617
1959
|
const customerDocument = ['out_invoice', 'out_refund', 'out_receipt'].includes(String(args.moveType));
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
1960
|
+
if (journal.type !== (customerDocument ? 'sale' : 'purchase'))
|
|
1961
|
+
return invalid('journalId', customerDocument ? 'journalMustBeSale' : 'journalMustBePurchase');
|
|
1962
|
+
// One shape or the other. Accepting both would leave the shorthand's line
|
|
1963
|
+
// either silently dropped or silently appended, and neither is obvious
|
|
1964
|
+
// from the call site.
|
|
1965
|
+
const many = args.lines !== undefined && args.lines !== null;
|
|
1966
|
+
if (many && args.description !== undefined)
|
|
1967
|
+
return invalid('lines', 'invoiceLinesAndSingle');
|
|
1968
|
+
const given = many ? (Array.isArray(args.lines) ? args.lines : []) : [args];
|
|
1969
|
+
if (many && !given.length)
|
|
1970
|
+
return invalid('lines', 'invoiceLinesEmpty');
|
|
1971
|
+
if (!many && (args.description === undefined || args.description === null))
|
|
1972
|
+
return invalid('description', 'invoiceLineRequired');
|
|
1973
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
1974
|
+
const priced = [];
|
|
1975
|
+
// Tax shares are accumulated across the whole document: two lines at the
|
|
1976
|
+
// same rate post one tax line, as a paper invoice shows one VAT figure per
|
|
1977
|
+
// rate rather than one per row.
|
|
1978
|
+
const shares = new Map();
|
|
1979
|
+
for (const [at, entry] of given.entries()) {
|
|
1980
|
+
const spec = (entry ?? {});
|
|
1981
|
+
const where = many ? `lines.${at}` : 'description';
|
|
1982
|
+
if (spec.description === undefined || spec.description === null)
|
|
1983
|
+
return invalid(where, 'invoiceLineRequired');
|
|
1984
|
+
const resolved = await resolveAccounts(ctx, { moveType: String(args.moveType), partnerId: args.partnerId, productId: spec.productId }, { lineAccountId: spec.lineAccountId });
|
|
1985
|
+
if (!resolved.lineAccountId)
|
|
1986
|
+
return invalid(many ? where : 'lineAccountId', 'lineAccountUndecided');
|
|
1987
|
+
if (!(await accountOf(ctx, resolved.lineAccountId)))
|
|
1988
|
+
return invalid(many ? where : 'lineAccountId', 'invoiceAccountsMissing');
|
|
1989
|
+
// `taxId` stays accepted so existing callers keep working; `taxIds` is how a
|
|
1990
|
+
// line carries the sequence of taxes that compound into one another.
|
|
1991
|
+
const wanted = [
|
|
1992
|
+
...(Array.isArray(spec.taxIds) ? spec.taxIds.map(String) : []),
|
|
1993
|
+
...(spec.taxId ? [String(spec.taxId)] : []),
|
|
1994
|
+
].filter((id, index, all) => all.indexOf(id) === index);
|
|
1995
|
+
const taxes = [];
|
|
1996
|
+
for (const id of wanted) {
|
|
1997
|
+
const tax = (await ctx.db.select('account.Tax', { id }))[0];
|
|
1998
|
+
if (!tax)
|
|
1999
|
+
return invalid(many ? where : 'taxIds', 'taxMissing');
|
|
2000
|
+
if (![customerDocument ? 'sale' : 'purchase', 'none'].includes(String(tax.typeTaxUse)))
|
|
2001
|
+
return invalid(many ? where : 'taxIds', 'taxDirectionMismatch', { name: tax.name });
|
|
2002
|
+
taxes.push(tax);
|
|
2003
|
+
}
|
|
2004
|
+
let amounts;
|
|
2005
|
+
try {
|
|
2006
|
+
const quantity = canonicalDecimalText(spec.quantity ?? '1');
|
|
2007
|
+
const priceUnit = canonicalDecimalText(spec.priceUnit ?? '0');
|
|
2008
|
+
const discount = canonicalDecimalText(spec.discount ?? '0');
|
|
2009
|
+
if (decimalSign(quantity) <= 0 ||
|
|
2010
|
+
decimalSign(priceUnit) < 0 ||
|
|
2011
|
+
decimalSign(discount) < 0 ||
|
|
2012
|
+
compareDecimals(discount, '100') > 0)
|
|
2013
|
+
return invalid(where, 'taxPriceInvalid');
|
|
2014
|
+
amounts = taxAmounts(taxes, quantity, priceUnit, discount, scale);
|
|
2015
|
+
spec.quantity = quantity;
|
|
2016
|
+
spec.priceUnit = priceUnit;
|
|
2017
|
+
spec.discount = discount;
|
|
2018
|
+
}
|
|
2019
|
+
catch (error) {
|
|
2020
|
+
return refused(many ? where : 'taxIds', error);
|
|
2021
|
+
}
|
|
2022
|
+
// Each tax posts to its own account. A single override stays meaningful only
|
|
2023
|
+
// while there is one tax to override.
|
|
2024
|
+
for (const held of amounts.shares) {
|
|
2025
|
+
if (moneyMinor(held.amount, scale) === 0n)
|
|
2026
|
+
continue;
|
|
2027
|
+
const accountId = (amounts.shares.length === 1 ? spec.taxAccountId : null) ?? held.accountId;
|
|
2028
|
+
if (!accountId || !(await accountOf(ctx, accountId)))
|
|
2029
|
+
return invalid(many ? where : 'taxAccountId', 'taxPostingAccountMissing', { name: held.name });
|
|
2030
|
+
const key = `${String(held.taxId)}:${String(accountId)}`;
|
|
2031
|
+
const running = shares.get(key);
|
|
2032
|
+
if (running)
|
|
2033
|
+
running.amount = minorText(moneyMinor(running.amount, scale) + moneyMinor(held.amount, scale), scale);
|
|
2034
|
+
else
|
|
2035
|
+
shares.set(key, { ...held, accountId });
|
|
2036
|
+
}
|
|
2037
|
+
priced.push({
|
|
2038
|
+
spec,
|
|
2039
|
+
accountId: resolved.lineAccountId,
|
|
2040
|
+
amounts,
|
|
2041
|
+
firstTaxId: taxes[0]?.id ?? null,
|
|
2042
|
+
});
|
|
636
2043
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
2044
|
+
// After the lines, so a document with nothing to post still reports the
|
|
2045
|
+
// revenue account it could not decide before the receivable one.
|
|
2046
|
+
const resolvedCounterpart = await resolveAccounts(ctx, { moveType: String(args.moveType), partnerId: args.partnerId }, { counterpartAccountId: args.counterpartAccountId });
|
|
2047
|
+
if (!resolvedCounterpart.counterpartAccountId)
|
|
2048
|
+
return invalid('counterpartAccountId', 'counterpartAccountUndecided');
|
|
2049
|
+
const counterpart = await accountOf(ctx, resolvedCounterpart.counterpartAccountId);
|
|
2050
|
+
if (!counterpart)
|
|
2051
|
+
return invalid('counterpartAccountId', 'invoiceAccountsMissing');
|
|
2052
|
+
if (counterpart.accountType !== (customerDocument ? 'asset_receivable' : 'liability_payable'))
|
|
2053
|
+
return invalid('counterpartAccountId', customerDocument ? 'counterpartMustBeReceivable' : 'counterpartMustBePayable');
|
|
2054
|
+
const untaxed = sumMoneyMinor(priced.map((line) => line.amounts.untaxed), scale);
|
|
2055
|
+
const tax = sumMoneyMinor([...shares.values()].map((held) => held.amount), scale);
|
|
2056
|
+
const total = untaxed + tax;
|
|
2057
|
+
const posting = [...shares.values()];
|
|
2058
|
+
const invoiceDate = instantText(args.invoiceDate ?? today());
|
|
2059
|
+
const accountingDate = accountingDateText(args.accountingDate ?? invoiceDate, timezone);
|
|
2060
|
+
const documentDate = accountingDateText(args.documentDate ?? invoiceDate, timezone);
|
|
2061
|
+
const due = await dueDate(ctx, args.paymentTermId, new Date(invoiceDate));
|
|
645
2062
|
const mainDebit = ['in_invoice', 'in_receipt', 'out_refund'].includes(String(args.moveType));
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
2063
|
+
const moveRow = {
|
|
2064
|
+
id: args.id,
|
|
2065
|
+
name: String(args.id),
|
|
2066
|
+
ref: args.ref ?? null,
|
|
2067
|
+
date: invoiceDate,
|
|
2068
|
+
accountingDate,
|
|
2069
|
+
documentDate,
|
|
2070
|
+
moveType: args.moveType,
|
|
2071
|
+
state: 'draft',
|
|
2072
|
+
journalId: args.journalId,
|
|
2073
|
+
partnerId: args.partnerId,
|
|
2074
|
+
invoiceDate,
|
|
2075
|
+
invoiceDateDue: due,
|
|
2076
|
+
paymentTermId: args.paymentTermId ?? null,
|
|
2077
|
+
paymentState: 'not_paid',
|
|
2078
|
+
currency,
|
|
2079
|
+
amountUntaxed: minorText(untaxed, scale),
|
|
2080
|
+
amountTax: minorText(tax, scale),
|
|
2081
|
+
amountTotal: minorText(total, scale),
|
|
2082
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
2083
|
+
postedAt: null,
|
|
2084
|
+
revision: 0,
|
|
2085
|
+
};
|
|
2086
|
+
const lineRows = [];
|
|
2087
|
+
const line = (id, accountId, amount, debitSide, name, reconcilable, extra = {}) => {
|
|
2088
|
+
const minor = typeof amount === 'bigint' ? amount : moneyMinor(amount, scale);
|
|
2089
|
+
lineRows.push({
|
|
667
2090
|
id,
|
|
668
2091
|
moveId: args.id,
|
|
669
2092
|
name,
|
|
@@ -672,50 +2095,105 @@ export const functions = {
|
|
|
672
2095
|
productId: null,
|
|
673
2096
|
productUomId: null,
|
|
674
2097
|
quantity: '1',
|
|
675
|
-
priceUnit:
|
|
2098
|
+
priceUnit: minorText(minor, scale),
|
|
676
2099
|
discount: '0',
|
|
677
2100
|
taxId: null,
|
|
678
|
-
debit: debitSide ?
|
|
679
|
-
credit: debitSide ?
|
|
680
|
-
balance:
|
|
2101
|
+
debit: debitSide ? minorText(minor, scale) : minorText(0n, scale),
|
|
2102
|
+
credit: debitSide ? minorText(0n, scale) : minorText(minor, scale),
|
|
2103
|
+
balance: minorText(debitSide ? minor : -minor, scale),
|
|
681
2104
|
dateMaturity: null,
|
|
682
2105
|
displayType: null,
|
|
683
2106
|
reconciled: false,
|
|
684
|
-
amountResidual: reconcilable ?
|
|
2107
|
+
amountResidual: minorText(reconcilable ? minor : 0n, scale),
|
|
685
2108
|
sequence: 10,
|
|
686
2109
|
...extra,
|
|
687
2110
|
});
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
2111
|
+
};
|
|
2112
|
+
for (const [at, held] of priced.entries())
|
|
2113
|
+
line(
|
|
2114
|
+
// The first line keeps the historical id, so a single-line document
|
|
2115
|
+
// written through either shape lands on exactly the same row.
|
|
2116
|
+
at === 0 ? `${String(args.id)}:base` : `${String(args.id)}:base:${at}`, held.accountId, held.amounts.untaxed, mainDebit, String(held.spec.description), false, {
|
|
2117
|
+
productId: held.spec.productId ?? null,
|
|
2118
|
+
productUomId: held.spec.productUomId ?? null,
|
|
2119
|
+
quantity: held.spec.quantity,
|
|
2120
|
+
priceUnit: held.spec.priceUnit,
|
|
2121
|
+
discount: held.spec.discount,
|
|
2122
|
+
taxId: held.firstTaxId,
|
|
2123
|
+
sequence: 10 + at,
|
|
695
2124
|
});
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
2125
|
+
for (const [at, held] of posting.entries())
|
|
2126
|
+
line(
|
|
2127
|
+
// The first tax line keeps the historical id so an existing document
|
|
2128
|
+
// reprocessed by id lands on the same rows.
|
|
2129
|
+
at === 0 ? `${String(args.id)}:tax` : `${String(args.id)}:tax:${String(held.taxId)}`, held.accountId, held.amount, mainDebit, held.name, false, { taxId: held.taxId, sequence: 10 + priced.length + at });
|
|
2130
|
+
line(`${String(args.id)}:counterpart`, resolvedCounterpart.counterpartAccountId, total, !mainDebit, String(args.ref ?? priced[0]?.spec.description ?? args.id), true, { dateMaturity: due, sequence: 10 + priced.length + posting.length });
|
|
2131
|
+
try {
|
|
2132
|
+
const amountTotal = await ctx.tx(async (tx) => {
|
|
2133
|
+
const inserted = await tx.db.insertIfAbsent('account.Move', moveRow);
|
|
2134
|
+
if (!('dryRun' in inserted) && !inserted.inserted) {
|
|
2135
|
+
const existing = (await tx.db.select('account.Move', { id: args.id }))[0];
|
|
2136
|
+
const moveFields = [
|
|
2137
|
+
'journalId',
|
|
2138
|
+
'moveType',
|
|
2139
|
+
'ref',
|
|
2140
|
+
'partnerId',
|
|
2141
|
+
'paymentTermId',
|
|
2142
|
+
'currency',
|
|
2143
|
+
'amountUntaxed',
|
|
2144
|
+
'amountTax',
|
|
2145
|
+
'amountTotal',
|
|
2146
|
+
'moneyPolicyVersion',
|
|
2147
|
+
...(args.invoiceDate == null ? [] : ['date', 'invoiceDate', 'invoiceDateDue']),
|
|
2148
|
+
...(args.accountingDate == null && args.invoiceDate == null ? [] : ['accountingDate']),
|
|
2149
|
+
...(args.documentDate == null && args.invoiceDate == null ? [] : ['documentDate']),
|
|
2150
|
+
];
|
|
2151
|
+
const storedLines = await tx.db.select('account.MoveLine', { moveId: args.id });
|
|
2152
|
+
const lineFields = args.invoiceDate == null
|
|
2153
|
+
? MOVE_LINE_CREATE_FIELDS.filter((field) => field !== 'dateMaturity')
|
|
2154
|
+
: MOVE_LINE_CREATE_FIELDS;
|
|
2155
|
+
const byLineId = new Map(storedLines.map((held) => [String(held.id), held]));
|
|
2156
|
+
const sameLines = storedLines.length === lineRows.length &&
|
|
2157
|
+
lineRows.every((wanted) => {
|
|
2158
|
+
const held = byLineId.get(String(wanted.id));
|
|
2159
|
+
return Boolean(held && rowMatches(held, wanted, lineFields));
|
|
2160
|
+
});
|
|
2161
|
+
if (!existing || !rowMatches(existing, moveRow, moveFields) || !sameLines)
|
|
2162
|
+
throw new Refusal('invoiceIdReused');
|
|
2163
|
+
return String(existing.amountTotal);
|
|
2164
|
+
}
|
|
2165
|
+
for (const row of lineRows)
|
|
2166
|
+
await tx.db.insert('account.MoveLine', row);
|
|
2167
|
+
return minorText(total, scale);
|
|
2168
|
+
});
|
|
2169
|
+
return { ok: true, id: args.id, amountTotal };
|
|
2170
|
+
}
|
|
2171
|
+
catch (error) {
|
|
2172
|
+
return refused('id', error);
|
|
2173
|
+
}
|
|
701
2174
|
},
|
|
702
2175
|
}),
|
|
703
2176
|
postMove: defineFn({
|
|
704
|
-
input: { id: 'id' },
|
|
2177
|
+
input: { id: 'id', expectedRevision: 'int?' },
|
|
705
2178
|
output: { ok: 'bool', id: 'id?', name: 'text?', errors: 'json?' },
|
|
706
2179
|
effects: [
|
|
707
2180
|
'read:account.Move',
|
|
708
2181
|
'read:account.MoveLine',
|
|
709
2182
|
'read:account.Journal',
|
|
2183
|
+
'read:account.Account',
|
|
2184
|
+
'read:account.PeriodPolicy',
|
|
2185
|
+
'read:company.Company',
|
|
710
2186
|
'write:account.Journal',
|
|
711
2187
|
'write:account.Move',
|
|
2188
|
+
'write:account.PeriodPolicy',
|
|
2189
|
+
'write:account.AuditEvent',
|
|
712
2190
|
],
|
|
713
2191
|
idempotent: true,
|
|
714
2192
|
agent: true,
|
|
715
|
-
handler: (ctx, args) =>
|
|
2193
|
+
handler: (ctx, args) => postMoveById(ctx, args.id, args.expectedRevision),
|
|
716
2194
|
}),
|
|
717
2195
|
cancelMove: defineFn({
|
|
718
|
-
input: { id: 'id' },
|
|
2196
|
+
input: { id: 'id', expectedRevision: 'int?' },
|
|
719
2197
|
output: { ok: 'bool', id: 'id?', errors: 'json?' },
|
|
720
2198
|
effects: ['read:account.Move', 'write:account.Move'],
|
|
721
2199
|
idempotent: true,
|
|
@@ -723,18 +2201,438 @@ export const functions = {
|
|
|
723
2201
|
handler: async (ctx, args) => {
|
|
724
2202
|
const move = (await ctx.db.select('account.Move', { id: args.id }))[0];
|
|
725
2203
|
if (!move)
|
|
726
|
-
return invalid('id', '
|
|
2204
|
+
return invalid('id', 'moveMissing');
|
|
2205
|
+
if (move.state === 'cancel')
|
|
2206
|
+
return { ok: true, id: args.id };
|
|
727
2207
|
if (move.state === 'posted')
|
|
728
|
-
return invalid('state', '
|
|
729
|
-
|
|
730
|
-
|
|
2208
|
+
return invalid('state', 'moveNotCancellable');
|
|
2209
|
+
try {
|
|
2210
|
+
await ctx.tx(async (tx) => {
|
|
2211
|
+
const current = (await tx.db.select('account.Move', { id: args.id }))[0];
|
|
2212
|
+
if (!current)
|
|
2213
|
+
throw new Refusal('moveMissing');
|
|
2214
|
+
if (current.state === 'cancel')
|
|
2215
|
+
return;
|
|
2216
|
+
if (current.state === 'posted')
|
|
2217
|
+
throw new Refusal('moveNotCancellable');
|
|
2218
|
+
if (!(await claimMoveRevision(tx, current, args.expectedRevision)))
|
|
2219
|
+
throw new Refusal('moveConcurrent');
|
|
2220
|
+
await tx.db.update('account.Move', { id: args.id }, { state: 'cancel' });
|
|
2221
|
+
});
|
|
2222
|
+
return { ok: true, id: args.id };
|
|
2223
|
+
}
|
|
2224
|
+
catch (error) {
|
|
2225
|
+
return refused('expectedRevision', error);
|
|
2226
|
+
}
|
|
2227
|
+
},
|
|
2228
|
+
}),
|
|
2229
|
+
/**
|
|
2230
|
+
* Post the mirror image of an entry that is already in the books.
|
|
2231
|
+
*
|
|
2232
|
+
* A posted entry is never edited or deleted — the correction is a second entry
|
|
2233
|
+
* whose debits and credits are the first one's, swapped. Where the original
|
|
2234
|
+
* opened an item on a reconcilable account, the reversal closes it against the
|
|
2235
|
+
* original, so the document stops showing up as owed.
|
|
2236
|
+
*/
|
|
2237
|
+
reverseMove: defineFn({
|
|
2238
|
+
input: {
|
|
2239
|
+
id: 'id',
|
|
2240
|
+
reversalId: 'id',
|
|
2241
|
+
date: 'datetime?',
|
|
2242
|
+
accountingDate: 'date?',
|
|
2243
|
+
documentDate: 'date?',
|
|
2244
|
+
ref: 'text?',
|
|
2245
|
+
reason: 'text?',
|
|
2246
|
+
journalId: 'id?',
|
|
2247
|
+
},
|
|
2248
|
+
output: { ok: 'bool', id: 'id?', reversalId: 'id?', name: 'text?', errors: 'json?' },
|
|
2249
|
+
effects: [
|
|
2250
|
+
'read:account.Move',
|
|
2251
|
+
'read:account.MoveLine',
|
|
2252
|
+
'read:account.Account',
|
|
2253
|
+
'read:account.Journal',
|
|
2254
|
+
'read:account.PartialReconcile',
|
|
2255
|
+
'read:account.Payment',
|
|
2256
|
+
'read:account.PeriodPolicy',
|
|
2257
|
+
'read:company.Company',
|
|
2258
|
+
'write:account.Journal',
|
|
2259
|
+
'write:account.Move',
|
|
2260
|
+
'write:account.MoveLine',
|
|
2261
|
+
'write:account.PartialReconcile',
|
|
2262
|
+
'write:account.Payment',
|
|
2263
|
+
'write:account.PeriodPolicy',
|
|
2264
|
+
'write:account.AuditEvent',
|
|
2265
|
+
],
|
|
2266
|
+
idempotent: true,
|
|
2267
|
+
agent: true,
|
|
2268
|
+
handler: async (ctx, args) => {
|
|
2269
|
+
const move = (await ctx.db.select('account.Move', { id: args.id }))[0];
|
|
2270
|
+
if (!move)
|
|
2271
|
+
return invalid('id', 'moveMissing');
|
|
2272
|
+
if (move.state !== 'posted')
|
|
2273
|
+
return invalid('state', 'movePostedOnly');
|
|
2274
|
+
const reversalId = String(args.reversalId);
|
|
2275
|
+
if (move.reversedById && String(move.reversedById) !== reversalId)
|
|
2276
|
+
return invalid('reversalId', 'moveAlreadyReversed');
|
|
2277
|
+
const already = (await ctx.db.select('account.Move', { id: args.reversalId }))[0];
|
|
2278
|
+
const lines = (await ctx.db.select('account.MoveLine', { moveId: args.id })).sort((a, b) => n(a.sequence) - n(b.sequence) || String(a.id).localeCompare(String(b.id)));
|
|
2279
|
+
if (!lines.length)
|
|
2280
|
+
return invalid('lines', 'reversalNoLines');
|
|
2281
|
+
const journalId = args.journalId ?? already?.journalId ?? move.journalId;
|
|
2282
|
+
if (!(await ctx.db.select('account.Journal', { id: journalId }))[0])
|
|
2283
|
+
return invalid('journalId', 'journalMissing');
|
|
2284
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
2285
|
+
if (String(move.currency) !== currency)
|
|
2286
|
+
return invalid('currency', 'moveCurrencyMismatch');
|
|
2287
|
+
const byId = await accountsById(ctx);
|
|
2288
|
+
let date = instantText(args.date ?? already?.date ?? today());
|
|
2289
|
+
let accountingDate;
|
|
2290
|
+
let documentDate;
|
|
2291
|
+
try {
|
|
2292
|
+
accountingDate = accountingDateText(args.accountingDate ?? already?.accountingDate ?? date, timezone);
|
|
2293
|
+
documentDate = accountingDateText(args.documentDate ?? already?.documentDate ?? accountingDate, timezone);
|
|
2294
|
+
}
|
|
2295
|
+
catch {
|
|
2296
|
+
return invalid('accountingDate', 'accountingDateInvalid');
|
|
2297
|
+
}
|
|
2298
|
+
const reversalRow = {
|
|
2299
|
+
id: reversalId,
|
|
2300
|
+
name: reversalId,
|
|
2301
|
+
// The reference is the document being corrected, not a sentence about it:
|
|
2302
|
+
// this module has no translator, and a ledger read in Vietnamese must not
|
|
2303
|
+
// grow English prose.
|
|
2304
|
+
ref: args.ref ?? already?.ref ?? move.name,
|
|
2305
|
+
date,
|
|
2306
|
+
accountingDate,
|
|
2307
|
+
documentDate,
|
|
2308
|
+
moveType: 'entry',
|
|
2309
|
+
state: 'draft',
|
|
2310
|
+
journalId,
|
|
2311
|
+
partnerId: move.partnerId ?? null,
|
|
2312
|
+
invoiceDate: null,
|
|
2313
|
+
invoiceDateDue: null,
|
|
2314
|
+
paymentTermId: null,
|
|
2315
|
+
paymentState: 'paid',
|
|
2316
|
+
currency: move.currency,
|
|
2317
|
+
amountUntaxed: move.amountUntaxed,
|
|
2318
|
+
amountTax: move.amountTax,
|
|
2319
|
+
amountTotal: move.amountTotal,
|
|
2320
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
2321
|
+
postedAt: null,
|
|
2322
|
+
reversalOfId: move.id,
|
|
2323
|
+
reversedById: null,
|
|
2324
|
+
reversalStatus: 'creating',
|
|
2325
|
+
revision: 0,
|
|
2326
|
+
};
|
|
2327
|
+
const mirrorRows = lines.map((line) => {
|
|
2328
|
+
const debit = moneyMinor(line.credit, scale);
|
|
2329
|
+
const credit = moneyMinor(line.debit, scale);
|
|
2330
|
+
const reconcilable = byId.get(String(line.accountId))?.reconcile === true;
|
|
2331
|
+
return {
|
|
2332
|
+
id: `${reversalId}:${String(line.id)}`,
|
|
2333
|
+
moveId: reversalId,
|
|
2334
|
+
name: line.name,
|
|
2335
|
+
accountId: line.accountId,
|
|
2336
|
+
partnerId: line.partnerId ?? null,
|
|
2337
|
+
productId: line.productId ?? null,
|
|
2338
|
+
productUomId: line.productUomId ?? null,
|
|
2339
|
+
quantity: line.quantity,
|
|
2340
|
+
priceUnit: line.priceUnit,
|
|
2341
|
+
discount: line.discount,
|
|
2342
|
+
taxId: line.taxId ?? null,
|
|
2343
|
+
debit: minorText(debit, scale),
|
|
2344
|
+
credit: minorText(credit, scale),
|
|
2345
|
+
balance: minorText(debit - credit, scale),
|
|
2346
|
+
dateMaturity: null,
|
|
2347
|
+
displayType: line.displayType ?? null,
|
|
2348
|
+
reconciled: false,
|
|
2349
|
+
amountResidual: minorText(reconcilable ? (debit >= credit ? debit - credit : credit - debit) : 0n, scale),
|
|
2350
|
+
sequence: line.sequence,
|
|
2351
|
+
};
|
|
2352
|
+
});
|
|
2353
|
+
try {
|
|
2354
|
+
const settled = await ctx.tx(async (tx) => {
|
|
2355
|
+
const source = (await tx.db.select('account.Move', { id: args.id }))[0];
|
|
2356
|
+
if (!source)
|
|
2357
|
+
throw new Refusal('moveMissing');
|
|
2358
|
+
if (source.state !== 'posted')
|
|
2359
|
+
throw new Refusal('movePostedOnly');
|
|
2360
|
+
if (source.reversedById && String(source.reversedById) !== reversalId)
|
|
2361
|
+
throw new Refusal('moveAlreadyReversed');
|
|
2362
|
+
if (!source.reversedById) {
|
|
2363
|
+
const claimed = await tx.db.compareAndSet('account.Move', { id: args.id }, { reversedById: source.reversedById ?? null }, { reversedById: reversalId });
|
|
2364
|
+
if (!('dryRun' in claimed) && !claimed.matched) {
|
|
2365
|
+
const current = (await tx.db.select('account.Move', { id: args.id }))[0];
|
|
2366
|
+
if (String(current?.reversedById ?? '') !== reversalId)
|
|
2367
|
+
throw new Refusal('moveAlreadyReversed');
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
const inserted = await tx.db.insertIfAbsent('account.Move', reversalRow);
|
|
2371
|
+
if (!('dryRun' in inserted) && !inserted.inserted) {
|
|
2372
|
+
const existing = (await tx.db.select('account.Move', { id: reversalId }))[0];
|
|
2373
|
+
const moveFields = [
|
|
2374
|
+
'ref',
|
|
2375
|
+
'moveType',
|
|
2376
|
+
'journalId',
|
|
2377
|
+
'partnerId',
|
|
2378
|
+
'invoiceDate',
|
|
2379
|
+
'paymentTermId',
|
|
2380
|
+
'currency',
|
|
2381
|
+
'moneyPolicyVersion',
|
|
2382
|
+
'reversalOfId',
|
|
2383
|
+
...(args.date == null ? [] : ['date']),
|
|
2384
|
+
...(args.accountingDate == null ? [] : ['accountingDate']),
|
|
2385
|
+
...(args.documentDate == null ? [] : ['documentDate']),
|
|
2386
|
+
];
|
|
2387
|
+
const storedLines = await tx.db.select('account.MoveLine', { moveId: reversalId });
|
|
2388
|
+
const byLineId = new Map(storedLines.map((held) => [String(held.id), held]));
|
|
2389
|
+
const sameLines = storedLines.length === mirrorRows.length &&
|
|
2390
|
+
mirrorRows.every((wanted) => {
|
|
2391
|
+
const held = byLineId.get(String(wanted.id));
|
|
2392
|
+
return Boolean(held && rowMatches(held, wanted, MOVE_LINE_CREATE_FIELDS));
|
|
2393
|
+
});
|
|
2394
|
+
if (!existing ||
|
|
2395
|
+
!['draft', 'posted'].includes(String(existing.state)) ||
|
|
2396
|
+
!rowMatches(existing, reversalRow, moveFields) ||
|
|
2397
|
+
!sameLines)
|
|
2398
|
+
throw new Refusal('reversalIdReused');
|
|
2399
|
+
return existing;
|
|
2400
|
+
}
|
|
2401
|
+
for (const row of mirrorRows)
|
|
2402
|
+
await tx.db.insert('account.MoveLine', row);
|
|
2403
|
+
return reversalRow;
|
|
2404
|
+
});
|
|
2405
|
+
date = String(settled.date);
|
|
2406
|
+
}
|
|
2407
|
+
catch (error) {
|
|
2408
|
+
return refused('reversalId', error);
|
|
2409
|
+
}
|
|
2410
|
+
const posted = await postMoveById(ctx, reversalId);
|
|
2411
|
+
if (posted.ok !== true)
|
|
2412
|
+
return posted;
|
|
2413
|
+
const postedReversal = (await ctx.db.select('account.Move', { id: reversalId }))[0];
|
|
2414
|
+
if (postedReversal?.reversalStatus === 'creating' || !postedReversal?.reversalStatus)
|
|
2415
|
+
await ctx.db.update('account.Move', { id: reversalId }, { reversalStatus: 'posted' });
|
|
2416
|
+
if (postedReversal?.reversalStatus !== 'completed')
|
|
2417
|
+
await ctx.db.update('account.Move', { id: reversalId }, { reversalStatus: 'reconciling' });
|
|
2418
|
+
// Close what the original left open, as far as each side still allows.
|
|
2419
|
+
for (const line of lines) {
|
|
2420
|
+
if (byId.get(String(line.accountId))?.reconcile !== true)
|
|
2421
|
+
continue;
|
|
2422
|
+
const mirror = (await ctx.db.select('account.MoveLine', { id: `${reversalId}:${String(line.id)}` }))[0];
|
|
2423
|
+
const fresh = (await ctx.db.select('account.MoveLine', { id: line.id }))[0];
|
|
2424
|
+
if (!mirror || !fresh)
|
|
2425
|
+
continue;
|
|
2426
|
+
const freshResidual = moneyMinor(fresh.amountResidual, scale);
|
|
2427
|
+
const mirrorResidual = moneyMinor(mirror.amountResidual, scale);
|
|
2428
|
+
const amount = freshResidual < mirrorResidual ? freshResidual : mirrorResidual;
|
|
2429
|
+
if (amount <= 0n)
|
|
2430
|
+
continue;
|
|
2431
|
+
const debitFirst = moneyMinor(fresh.balance, scale) > 0n;
|
|
2432
|
+
const result = await functions.reconcile.handler(ctx, {
|
|
2433
|
+
id: `${reversalId}:reconcile:${String(line.id)}`,
|
|
2434
|
+
debitMoveId: debitFirst ? fresh.id : mirror.id,
|
|
2435
|
+
creditMoveId: debitFirst ? mirror.id : fresh.id,
|
|
2436
|
+
amount: minorText(amount, scale),
|
|
2437
|
+
date,
|
|
2438
|
+
});
|
|
2439
|
+
if (result.ok !== true)
|
|
2440
|
+
return result;
|
|
2441
|
+
}
|
|
2442
|
+
try {
|
|
2443
|
+
await ctx.tx(async (tx) => {
|
|
2444
|
+
const source = (await tx.db.select('account.Move', { id: args.id }))[0];
|
|
2445
|
+
const reversal = (await tx.db.select('account.Move', { id: reversalId }))[0];
|
|
2446
|
+
if (!source || String(source.reversedById ?? '') !== reversalId)
|
|
2447
|
+
throw new Refusal('moveAlreadyReversed');
|
|
2448
|
+
if (!reversal || String(reversal.reversalOfId ?? '') !== String(source.id))
|
|
2449
|
+
throw new Refusal('reversalIdReused');
|
|
2450
|
+
if (source.moveType !== 'entry')
|
|
2451
|
+
await tx.db.update('account.Move', { id: args.id }, { paymentState: 'reversed' });
|
|
2452
|
+
// A payment's own move is an `entry`, so the line above never reaches it
|
|
2453
|
+
// and the payment kept reading `paid` after the money had been reversed
|
|
2454
|
+
// out of the books — the ledger and the payments list disagreeing about
|
|
2455
|
+
// whether a customer had paid.
|
|
2456
|
+
for (const payment of await tx.db.select('account.Payment', { moveId: args.id }))
|
|
2457
|
+
await tx.db.update('account.Payment', { id: payment.id }, { state: 'reversed' });
|
|
2458
|
+
await tx.db.update('account.Move', { id: reversalId }, { reversalStatus: 'completed' });
|
|
2459
|
+
await tx.db.insertIfAbsent('account.AuditEvent', {
|
|
2460
|
+
id: `move:${String(args.id)}:reversed:${reversalId}`,
|
|
2461
|
+
subjectType: 'move',
|
|
2462
|
+
subjectId: String(args.id),
|
|
2463
|
+
action: 'reversed',
|
|
2464
|
+
actorId: tx.actor ?? null,
|
|
2465
|
+
accountingDate: reversal.accountingDate,
|
|
2466
|
+
reason: args.reason ?? args.ref ?? source.name,
|
|
2467
|
+
relatedId: reversalId,
|
|
2468
|
+
details: { originalId: source.id, reversalId, replacementId: null },
|
|
2469
|
+
createdAt: today(),
|
|
2470
|
+
});
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
catch (error) {
|
|
2474
|
+
return refused('reversalId', error);
|
|
2475
|
+
}
|
|
2476
|
+
return { ok: true, id: args.id, reversalId, name: posted.name };
|
|
731
2477
|
},
|
|
732
2478
|
}),
|
|
733
2479
|
listPayments: defineFn({
|
|
734
|
-
input: {},
|
|
2480
|
+
input: { partnerId: 'id?', state: 'text?', limit: 'int?', offset: 'int?' },
|
|
735
2481
|
effects: ['read:account.Payment'],
|
|
736
2482
|
agent: true,
|
|
737
|
-
handler: (ctx) =>
|
|
2483
|
+
handler: (ctx, args) => {
|
|
2484
|
+
const P = ctx.table('account.Payment');
|
|
2485
|
+
const where = [
|
|
2486
|
+
...(args.partnerId ? [eq(P.partnerId, args.partnerId)] : []),
|
|
2487
|
+
...(args.state ? [eq(P.state, args.state)] : []),
|
|
2488
|
+
];
|
|
2489
|
+
const q = (where.length ? from(P).where(and(...where)) : from(P)).orderBy(asc(P.accountingDate), asc(P.date), asc(P.id));
|
|
2490
|
+
return ctx.db.all(paginate(q, args.limit, args.offset));
|
|
2491
|
+
},
|
|
2492
|
+
}),
|
|
2493
|
+
/**
|
|
2494
|
+
* Post the two ledger events that change stored-value liability without a sale.
|
|
2495
|
+
*
|
|
2496
|
+
* Issuing value increases the liability against an asset/clearing account;
|
|
2497
|
+
* expiry releases it to income. Redemption and customer refund are settlements
|
|
2498
|
+
* of a receivable and therefore use `registerPayment` with `stored_value`.
|
|
2499
|
+
*/
|
|
2500
|
+
postStoredValueBalance: defineFn({
|
|
2501
|
+
input: {
|
|
2502
|
+
id: 'id',
|
|
2503
|
+
operation: 'text',
|
|
2504
|
+
journalId: 'id',
|
|
2505
|
+
liabilityAccountId: 'id',
|
|
2506
|
+
counterpartAccountId: 'id',
|
|
2507
|
+
amount: 'decimal',
|
|
2508
|
+
partnerId: 'id?',
|
|
2509
|
+
date: 'datetime?',
|
|
2510
|
+
accountingDate: 'date?',
|
|
2511
|
+
documentDate: 'date?',
|
|
2512
|
+
reference: 'text?',
|
|
2513
|
+
},
|
|
2514
|
+
output: { ok: 'bool', id: 'id?', moveId: 'id?', operation: 'text?', amount: 'decimal?', errors: 'json?' },
|
|
2515
|
+
effects: [
|
|
2516
|
+
'read:account.Journal',
|
|
2517
|
+
'read:account.Account',
|
|
2518
|
+
'read:account.Move',
|
|
2519
|
+
'read:account.MoveLine',
|
|
2520
|
+
'read:account.PeriodPolicy',
|
|
2521
|
+
'read:company.Company',
|
|
2522
|
+
'read:partner.Partner',
|
|
2523
|
+
'write:account.Journal',
|
|
2524
|
+
'write:account.Move',
|
|
2525
|
+
'write:account.MoveLine',
|
|
2526
|
+
'write:account.PeriodPolicy',
|
|
2527
|
+
'write:account.AuditEvent',
|
|
2528
|
+
],
|
|
2529
|
+
idempotent: true,
|
|
2530
|
+
agent: true,
|
|
2531
|
+
handler: async (ctx, args) => {
|
|
2532
|
+
const operation = String(args.operation);
|
|
2533
|
+
if (!['issue', 'expire'].includes(operation))
|
|
2534
|
+
return invalid('operation', 'storedValueOperationUnsupported');
|
|
2535
|
+
const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
|
|
2536
|
+
if (!journal || String(journal.type) !== 'general')
|
|
2537
|
+
return invalid('journalId', 'journalNotStoredValue');
|
|
2538
|
+
const [liability, counterpart] = await Promise.all([
|
|
2539
|
+
accountOf(ctx, args.liabilityAccountId),
|
|
2540
|
+
accountOf(ctx, args.counterpartAccountId),
|
|
2541
|
+
]);
|
|
2542
|
+
if (!liability || !String(liability.accountType).startsWith('liability'))
|
|
2543
|
+
return invalid('liabilityAccountId', 'journalStoredValueAccount');
|
|
2544
|
+
const counterpartType = String(counterpart?.accountType ?? '');
|
|
2545
|
+
if (!counterpart ||
|
|
2546
|
+
(operation === 'issue' && !counterpartType.startsWith('asset')) ||
|
|
2547
|
+
(operation === 'expire' && !counterpartType.startsWith('income')))
|
|
2548
|
+
return invalid('counterpartAccountId', 'storedValueCounterpart');
|
|
2549
|
+
if (args.partnerId && !(await ctx.db.select('partner.Partner', { id: args.partnerId }))[0])
|
|
2550
|
+
return invalid('partnerId', 'partnerMissing');
|
|
2551
|
+
const existing = (await ctx.db.select('account.Move', { id: args.id }))[0];
|
|
2552
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
2553
|
+
let amount;
|
|
2554
|
+
try {
|
|
2555
|
+
amount = moneyMinor(args.amount, scale);
|
|
2556
|
+
}
|
|
2557
|
+
catch {
|
|
2558
|
+
return invalid('amount', 'moneyExactString');
|
|
2559
|
+
}
|
|
2560
|
+
if (amount <= 0n)
|
|
2561
|
+
return invalid('amount', 'amountPositive');
|
|
2562
|
+
const amountText = minorText(amount, scale);
|
|
2563
|
+
const zero = minorText(0n, scale);
|
|
2564
|
+
const date = instantText(args.date ?? existing?.date ?? today());
|
|
2565
|
+
let accountingDate;
|
|
2566
|
+
let documentDate;
|
|
2567
|
+
try {
|
|
2568
|
+
accountingDate = accountingDateText(args.accountingDate ?? existing?.accountingDate ?? date, timezone);
|
|
2569
|
+
documentDate = accountingDateText(args.documentDate ?? existing?.documentDate ?? accountingDate, timezone);
|
|
2570
|
+
}
|
|
2571
|
+
catch {
|
|
2572
|
+
return invalid('accountingDate', 'accountingDateInvalid');
|
|
2573
|
+
}
|
|
2574
|
+
const increasing = operation === 'issue';
|
|
2575
|
+
const line = (id, account, debitSide, sequence) => ({
|
|
2576
|
+
id,
|
|
2577
|
+
moveId: args.id,
|
|
2578
|
+
name: `account.stored_value.${operation}`,
|
|
2579
|
+
accountId: account.id,
|
|
2580
|
+
partnerId: args.partnerId ?? null,
|
|
2581
|
+
productId: null,
|
|
2582
|
+
productUomId: null,
|
|
2583
|
+
quantity: '1',
|
|
2584
|
+
priceUnit: amountText,
|
|
2585
|
+
discount: '0',
|
|
2586
|
+
taxId: null,
|
|
2587
|
+
debit: debitSide ? amountText : zero,
|
|
2588
|
+
credit: debitSide ? zero : amountText,
|
|
2589
|
+
balance: debitSide ? amountText : minorText(-amount, scale),
|
|
2590
|
+
dateMaturity: null,
|
|
2591
|
+
displayType: null,
|
|
2592
|
+
reconciled: false,
|
|
2593
|
+
amountResidual: account.reconcile === true ? amountText : zero,
|
|
2594
|
+
sequence,
|
|
2595
|
+
});
|
|
2596
|
+
try {
|
|
2597
|
+
await ctx.tx(async (tx) => {
|
|
2598
|
+
await insertDraftMove(tx, {
|
|
2599
|
+
move: {
|
|
2600
|
+
id: args.id,
|
|
2601
|
+
name: String(args.id),
|
|
2602
|
+
ref: args.reference ?? null,
|
|
2603
|
+
date,
|
|
2604
|
+
accountingDate,
|
|
2605
|
+
documentDate,
|
|
2606
|
+
moveType: 'entry',
|
|
2607
|
+
state: 'draft',
|
|
2608
|
+
journalId: args.journalId,
|
|
2609
|
+
partnerId: args.partnerId ?? null,
|
|
2610
|
+
invoiceDate: null,
|
|
2611
|
+
invoiceDateDue: null,
|
|
2612
|
+
paymentTermId: null,
|
|
2613
|
+
paymentState: 'paid',
|
|
2614
|
+
currency,
|
|
2615
|
+
amountUntaxed: amountText,
|
|
2616
|
+
amountTax: zero,
|
|
2617
|
+
amountTotal: amountText,
|
|
2618
|
+
postedAt: null,
|
|
2619
|
+
revision: 0,
|
|
2620
|
+
},
|
|
2621
|
+
lines: [
|
|
2622
|
+
line(`${String(args.id)}:counterpart`, counterpart, increasing, 10),
|
|
2623
|
+
line(`${String(args.id)}:liability`, liability, !increasing, 20),
|
|
2624
|
+
],
|
|
2625
|
+
});
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
catch (error) {
|
|
2629
|
+
return refused('id', error);
|
|
2630
|
+
}
|
|
2631
|
+
const posted = await postMoveById(ctx, args.id);
|
|
2632
|
+
if (posted.ok !== true)
|
|
2633
|
+
return posted;
|
|
2634
|
+
return { ok: true, id: args.id, moveId: args.id, operation, amount: amountText };
|
|
2635
|
+
},
|
|
738
2636
|
}),
|
|
739
2637
|
registerPayment: defineFn({
|
|
740
2638
|
input: {
|
|
@@ -747,9 +2645,14 @@ export const functions = {
|
|
|
747
2645
|
destinationAccountId: 'id',
|
|
748
2646
|
amount: 'decimal',
|
|
749
2647
|
date: 'datetime?',
|
|
2648
|
+
accountingDate: 'date?',
|
|
2649
|
+
documentDate: 'date?',
|
|
750
2650
|
memo: 'text?',
|
|
751
2651
|
paymentReference: 'text?',
|
|
2652
|
+
settlementKind: 'text?',
|
|
752
2653
|
reconcileLineId: 'id?',
|
|
2654
|
+
invoiceId: 'id?',
|
|
2655
|
+
expectedRevision: 'int?',
|
|
753
2656
|
},
|
|
754
2657
|
output: { ok: 'bool', id: 'id?', moveId: 'id?', errors: 'json?' },
|
|
755
2658
|
effects: [
|
|
@@ -759,53 +2662,112 @@ export const functions = {
|
|
|
759
2662
|
'read:account.Move',
|
|
760
2663
|
'read:account.MoveLine',
|
|
761
2664
|
'read:account.PartialReconcile',
|
|
2665
|
+
'read:account.PeriodPolicy',
|
|
762
2666
|
'read:company.Company',
|
|
763
2667
|
'write:account.Payment',
|
|
764
2668
|
'write:account.Journal',
|
|
765
2669
|
'write:account.Move',
|
|
766
2670
|
'write:account.MoveLine',
|
|
767
2671
|
'write:account.PartialReconcile',
|
|
2672
|
+
'write:account.PeriodPolicy',
|
|
2673
|
+
'write:account.AuditEvent',
|
|
768
2674
|
],
|
|
769
2675
|
idempotent: true,
|
|
770
2676
|
agent: true,
|
|
771
2677
|
handler: async (ctx, args) => {
|
|
772
2678
|
if (!PAYMENT_TYPES.includes(args.paymentType))
|
|
773
|
-
return invalid('paymentType', '
|
|
2679
|
+
return invalid('paymentType', 'paymentTypeUnsupported');
|
|
774
2680
|
if (!PARTNER_TYPES.includes(args.partnerType))
|
|
775
|
-
return invalid('partnerType', '
|
|
776
|
-
|
|
777
|
-
|
|
2681
|
+
return invalid('partnerType', 'partnerTypeUnsupported');
|
|
2682
|
+
const settlementKind = String(args.settlementKind ?? 'liquidity');
|
|
2683
|
+
if (!PAYMENT_SETTLEMENT_KINDS.includes(settlementKind))
|
|
2684
|
+
return invalid('settlementKind', 'paymentSettlementKindUnsupported');
|
|
2685
|
+
const { currency, scale, timezone } = await ledgerOf(ctx);
|
|
2686
|
+
let amount;
|
|
2687
|
+
try {
|
|
2688
|
+
amount = moneyMinor(args.amount, scale);
|
|
2689
|
+
}
|
|
2690
|
+
catch {
|
|
2691
|
+
return invalid('amount', 'moneyExactString');
|
|
2692
|
+
}
|
|
2693
|
+
if (amount <= 0n)
|
|
2694
|
+
return invalid('amount', 'amountPositive');
|
|
778
2695
|
const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
|
|
779
2696
|
if (!journal?.defaultAccountId)
|
|
780
|
-
return invalid('journalId', '
|
|
781
|
-
|
|
782
|
-
|
|
2697
|
+
return invalid('journalId', 'journalLiquidityMissing');
|
|
2698
|
+
const settlementAccount = await accountOf(ctx, journal.defaultAccountId);
|
|
2699
|
+
if (settlementKind === 'liquidity') {
|
|
2700
|
+
if (!['bank', 'cash'].includes(String(journal.type)))
|
|
2701
|
+
return invalid('journalId', 'journalNotLiquidity');
|
|
2702
|
+
}
|
|
2703
|
+
else {
|
|
2704
|
+
if (String(journal.type) !== 'general')
|
|
2705
|
+
return invalid('journalId', 'journalNotStoredValue');
|
|
2706
|
+
if (!String(settlementAccount?.accountType ?? '').startsWith('liability'))
|
|
2707
|
+
return invalid('journalId', 'journalStoredValueAccount');
|
|
2708
|
+
}
|
|
783
2709
|
const destination = await accountOf(ctx, args.destinationAccountId);
|
|
784
2710
|
if (!destination)
|
|
785
|
-
return invalid('destinationAccountId', '
|
|
786
|
-
const
|
|
787
|
-
if (destination.accountType !==
|
|
788
|
-
return invalid('destinationAccountId',
|
|
2711
|
+
return invalid('destinationAccountId', 'destinationMissing');
|
|
2712
|
+
const forCustomer = args.partnerType === 'customer';
|
|
2713
|
+
if (destination.accountType !== (forCustomer ? 'asset_receivable' : 'liability_payable'))
|
|
2714
|
+
return invalid('destinationAccountId', forCustomer ? 'destinationMustBeReceivable' : 'destinationMustBePayable');
|
|
789
2715
|
const existing = (await ctx.db.select('account.Payment', { id: args.id }))[0];
|
|
2716
|
+
const date = instantText(args.date ?? existing?.date ?? today());
|
|
2717
|
+
let accountingDate;
|
|
2718
|
+
let documentDate;
|
|
2719
|
+
try {
|
|
2720
|
+
accountingDate = accountingDateText(args.accountingDate ?? existing?.accountingDate ?? date, timezone);
|
|
2721
|
+
documentDate = accountingDateText(args.documentDate ?? existing?.documentDate ?? accountingDate, timezone);
|
|
2722
|
+
}
|
|
2723
|
+
catch {
|
|
2724
|
+
return invalid('accountingDate', 'accountingDateInvalid');
|
|
2725
|
+
}
|
|
2726
|
+
if (existing &&
|
|
2727
|
+
(moneyMinor(existing.amount, scale) !== amount ||
|
|
2728
|
+
String(existing.name) !== String(args.name) ||
|
|
2729
|
+
String(existing.paymentType) !== String(args.paymentType) ||
|
|
2730
|
+
String(existing.partnerType) !== String(args.partnerType) ||
|
|
2731
|
+
String(existing.partnerId ?? '') !== String(args.partnerId ?? '') ||
|
|
2732
|
+
String(existing.journalId) !== String(args.journalId) ||
|
|
2733
|
+
String(existing.destinationAccountId) !== String(args.destinationAccountId) ||
|
|
2734
|
+
String(existing.reconcileLineId ?? '') !== String(args.reconcileLineId ?? '') ||
|
|
2735
|
+
String(existing.invoiceId ?? '') !== String(args.invoiceId ?? '') ||
|
|
2736
|
+
instantText(existing.date) !== date ||
|
|
2737
|
+
moveAccountingDate(existing, timezone) !== accountingDate ||
|
|
2738
|
+
String(existing.documentDate ?? accountingDate) !== documentDate ||
|
|
2739
|
+
String(existing.memo ?? '') !== String(args.memo ?? '') ||
|
|
2740
|
+
String(existing.paymentReference ?? '') !== String(args.paymentReference ?? '') ||
|
|
2741
|
+
String(existing.settlementKind ?? 'liquidity') !== settlementKind ||
|
|
2742
|
+
String(existing.currency) !== currency))
|
|
2743
|
+
return invalid('id', 'paymentIdReused');
|
|
2744
|
+
if (existing?.state === 'reversed')
|
|
2745
|
+
return { ok: true, id: args.id, moveId: existing.moveId };
|
|
790
2746
|
if (existing &&
|
|
791
2747
|
args.reconcileLineId &&
|
|
792
2748
|
(await ctx.db.select('account.PartialReconcile', {
|
|
793
2749
|
id: `${String(args.id)}:reconcile:${String(args.reconcileLineId)}`,
|
|
794
|
-
}))[0])
|
|
2750
|
+
}))[0]) {
|
|
2751
|
+
const posted = await postMoveById(ctx, existing.moveId);
|
|
2752
|
+
if (posted.ok !== true)
|
|
2753
|
+
return posted;
|
|
2754
|
+
if (existing.state !== 'paid')
|
|
2755
|
+
await ctx.db.update('account.Payment', { id: args.id }, { state: 'paid' });
|
|
795
2756
|
return { ok: true, id: args.id, moveId: existing.moveId };
|
|
2757
|
+
}
|
|
796
2758
|
let reconcileTarget = null;
|
|
797
2759
|
if (args.reconcileLineId) {
|
|
798
2760
|
reconcileTarget = (await ctx.db.select('account.MoveLine', { id: args.reconcileLineId }))[0] ?? null;
|
|
799
2761
|
if (!reconcileTarget)
|
|
800
|
-
return invalid('reconcileLineId', '
|
|
2762
|
+
return invalid('reconcileLineId', 'openItemMissing');
|
|
801
2763
|
if (reconcileTarget.accountId !== args.destinationAccountId)
|
|
802
|
-
return invalid('reconcileLineId', '
|
|
2764
|
+
return invalid('reconcileLineId', 'openItemAccountMismatch');
|
|
803
2765
|
const expectedDebit = args.paymentType === 'inbound';
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
return invalid('reconcileLineId', '
|
|
807
|
-
if (
|
|
808
|
-
return invalid('amount', '
|
|
2766
|
+
const targetBalance = moneyMinor(reconcileTarget.balance, scale);
|
|
2767
|
+
if ((expectedDebit && targetBalance <= 0n) || (!expectedDebit && targetBalance >= 0n))
|
|
2768
|
+
return invalid('reconcileLineId', 'openItemDirection');
|
|
2769
|
+
if (amount > moneyMinor(reconcileTarget.amountResidual, scale))
|
|
2770
|
+
return invalid('amount', 'amountExceedsOpenItem');
|
|
809
2771
|
}
|
|
810
2772
|
const reconcilePayment = async (paymentMoveId) => {
|
|
811
2773
|
if (!reconcileTarget)
|
|
@@ -815,77 +2777,144 @@ export const functions = {
|
|
|
815
2777
|
id: `${String(args.id)}:reconcile:${String(reconcileTarget.id)}`,
|
|
816
2778
|
debitMoveId: args.paymentType === 'inbound' ? reconcileTarget.id : counterpartId,
|
|
817
2779
|
creditMoveId: args.paymentType === 'inbound' ? counterpartId : reconcileTarget.id,
|
|
818
|
-
amount:
|
|
819
|
-
date
|
|
2780
|
+
amount: minorText(amount, scale),
|
|
2781
|
+
date,
|
|
820
2782
|
});
|
|
821
2783
|
return result.ok === true ? null : result;
|
|
822
2784
|
};
|
|
823
2785
|
if (existing) {
|
|
2786
|
+
// A retry of the same call is a success. A different payment under an id
|
|
2787
|
+
// that is already taken is not: the stored move is left as it was, and
|
|
2788
|
+
// reconciling it for a newly supplied amount would settle an open item
|
|
2789
|
+
// against money the ledger never recorded.
|
|
2790
|
+
const posted = await postMoveById(ctx, existing.moveId);
|
|
2791
|
+
if (posted.ok !== true)
|
|
2792
|
+
return posted;
|
|
2793
|
+
if (existing.state !== 'paid')
|
|
2794
|
+
await ctx.db.update('account.Payment', { id: args.id }, { state: 'paid' });
|
|
824
2795
|
const failed = await reconcilePayment(String(existing.moveId));
|
|
825
2796
|
return failed ?? { ok: true, id: args.id, moveId: existing.moveId };
|
|
826
2797
|
}
|
|
827
|
-
const moveId = `${String(args.id)}:move`,
|
|
828
|
-
|
|
829
|
-
await tx
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
2798
|
+
const moveId = `${String(args.id)}:move`, inbound = args.paymentType === 'inbound';
|
|
2799
|
+
try {
|
|
2800
|
+
await ctx.tx(async (tx) => {
|
|
2801
|
+
if (args.invoiceId) {
|
|
2802
|
+
const invoice = (await tx.db.select('account.Move', { id: args.invoiceId }))[0];
|
|
2803
|
+
if (!invoice)
|
|
2804
|
+
throw new Refusal('moveMissing');
|
|
2805
|
+
if (!(await claimMoveRevision(tx, invoice, args.expectedRevision)))
|
|
2806
|
+
throw new Refusal('moveConcurrent');
|
|
2807
|
+
}
|
|
2808
|
+
const paymentMove = {
|
|
2809
|
+
id: moveId,
|
|
2810
|
+
name: moveId,
|
|
2811
|
+
ref: args.paymentReference ?? args.memo ?? null,
|
|
2812
|
+
date,
|
|
2813
|
+
accountingDate,
|
|
2814
|
+
documentDate,
|
|
2815
|
+
moveType: 'entry',
|
|
2816
|
+
state: 'draft',
|
|
2817
|
+
journalId: args.journalId,
|
|
2818
|
+
partnerId: args.partnerId ?? null,
|
|
2819
|
+
invoiceDate: null,
|
|
2820
|
+
invoiceDateDue: null,
|
|
2821
|
+
paymentTermId: null,
|
|
2822
|
+
paymentState: 'paid',
|
|
2823
|
+
currency,
|
|
2824
|
+
amountUntaxed: minorText(amount, scale),
|
|
2825
|
+
amountTax: minorText(0n, scale),
|
|
2826
|
+
amountTotal: minorText(amount, scale),
|
|
2827
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
2828
|
+
postedAt: null,
|
|
2829
|
+
revision: 0,
|
|
2830
|
+
};
|
|
2831
|
+
const line = (id, accountId, debitSide, reconcilable) => ({
|
|
2832
|
+
id,
|
|
2833
|
+
moveId,
|
|
2834
|
+
name: args.memo ?? args.name,
|
|
2835
|
+
accountId,
|
|
2836
|
+
partnerId: args.partnerId ?? null,
|
|
2837
|
+
productId: null,
|
|
2838
|
+
productUomId: null,
|
|
2839
|
+
quantity: '1',
|
|
2840
|
+
priceUnit: minorText(amount, scale),
|
|
2841
|
+
discount: '0',
|
|
2842
|
+
taxId: null,
|
|
2843
|
+
debit: minorText(debitSide ? amount : 0n, scale),
|
|
2844
|
+
credit: minorText(debitSide ? 0n : amount, scale),
|
|
2845
|
+
balance: minorText(debitSide ? amount : -amount, scale),
|
|
2846
|
+
dateMaturity: null,
|
|
2847
|
+
displayType: null,
|
|
2848
|
+
reconciled: false,
|
|
2849
|
+
amountResidual: minorText(reconcilable ? amount : 0n, scale),
|
|
2850
|
+
sequence: debitSide ? 10 : 20,
|
|
2851
|
+
});
|
|
2852
|
+
await insertDraftMove(tx, {
|
|
2853
|
+
move: paymentMove,
|
|
2854
|
+
lines: [
|
|
2855
|
+
line(`${moveId}:liquidity`, journal.defaultAccountId, inbound, false),
|
|
2856
|
+
line(`${moveId}:counterpart`, args.destinationAccountId, !inbound, true),
|
|
2857
|
+
],
|
|
2858
|
+
});
|
|
2859
|
+
const paymentRow = {
|
|
2860
|
+
id: args.id,
|
|
2861
|
+
name: args.name,
|
|
2862
|
+
paymentType: args.paymentType,
|
|
2863
|
+
partnerType: args.partnerType,
|
|
2864
|
+
partnerId: args.partnerId ?? null,
|
|
2865
|
+
journalId: args.journalId,
|
|
2866
|
+
destinationAccountId: args.destinationAccountId,
|
|
2867
|
+
amount: minorText(amount, scale),
|
|
2868
|
+
date,
|
|
2869
|
+
accountingDate,
|
|
2870
|
+
documentDate,
|
|
2871
|
+
memo: args.memo ?? null,
|
|
2872
|
+
paymentReference: args.paymentReference ?? null,
|
|
2873
|
+
settlementKind,
|
|
2874
|
+
state: 'in_process',
|
|
2875
|
+
currency,
|
|
2876
|
+
moneyPolicyVersion: MONEY_POLICY_VERSION,
|
|
2877
|
+
moveId,
|
|
2878
|
+
reconcileLineId: args.reconcileLineId ?? null,
|
|
2879
|
+
invoiceId: args.invoiceId ?? null,
|
|
2880
|
+
};
|
|
2881
|
+
const inserted = await tx.db.insertIfAbsent('account.Payment', paymentRow);
|
|
2882
|
+
if (!('dryRun' in inserted) && !inserted.inserted) {
|
|
2883
|
+
const held = (await tx.db.select('account.Payment', { id: args.id }))[0];
|
|
2884
|
+
if (!held ||
|
|
2885
|
+
!rowMatches(held, paymentRow, [
|
|
2886
|
+
'name',
|
|
2887
|
+
'paymentType',
|
|
2888
|
+
'partnerType',
|
|
2889
|
+
'partnerId',
|
|
2890
|
+
'journalId',
|
|
2891
|
+
'destinationAccountId',
|
|
2892
|
+
'amount',
|
|
2893
|
+
'date',
|
|
2894
|
+
'accountingDate',
|
|
2895
|
+
'documentDate',
|
|
2896
|
+
'memo',
|
|
2897
|
+
'paymentReference',
|
|
2898
|
+
'settlementKind',
|
|
2899
|
+
'currency',
|
|
2900
|
+
'moneyPolicyVersion',
|
|
2901
|
+
'moveId',
|
|
2902
|
+
'reconcileLineId',
|
|
2903
|
+
'invoiceId',
|
|
2904
|
+
]))
|
|
2905
|
+
throw new Refusal('paymentIdReused');
|
|
2906
|
+
}
|
|
886
2907
|
});
|
|
887
|
-
}
|
|
888
|
-
|
|
2908
|
+
}
|
|
2909
|
+
catch (error) {
|
|
2910
|
+
if (error instanceof Refusal && error.code === 'moveConcurrent') {
|
|
2911
|
+
const settled = (await ctx.db.select('account.Payment', { id: args.id }))[0];
|
|
2912
|
+
if (settled)
|
|
2913
|
+
return (await functions.registerPayment.handler(ctx, args));
|
|
2914
|
+
}
|
|
2915
|
+
return refused('expectedRevision', error);
|
|
2916
|
+
}
|
|
2917
|
+
const posted = await postMoveById(ctx, moveId);
|
|
889
2918
|
if (posted.ok !== true)
|
|
890
2919
|
return posted;
|
|
891
2920
|
await ctx.db.update('account.Payment', { id: args.id }, { state: 'paid' });
|
|
@@ -895,14 +2924,135 @@ export const functions = {
|
|
|
895
2924
|
return { ok: true, id: args.id, moveId };
|
|
896
2925
|
},
|
|
897
2926
|
}),
|
|
2927
|
+
/**
|
|
2928
|
+
* Collect the complete residual of one posted customer invoice.
|
|
2929
|
+
*
|
|
2930
|
+
* A payment can settle several due-date lines. The lower-level payment
|
|
2931
|
+
* primitive intentionally accepts one open item, so this aggregate creates a
|
|
2932
|
+
* single deterministic payment and reconciles its counterpart across every
|
|
2933
|
+
* receivable line. Retries resume unfinished reconciliations from the same
|
|
2934
|
+
* payment id; the invoice revision is claimed in the transaction that first
|
|
2935
|
+
* creates that payment, preventing two collectors from recording the same
|
|
2936
|
+
* money concurrently.
|
|
2937
|
+
*/
|
|
2938
|
+
registerInvoicePayment: defineFn({
|
|
2939
|
+
input: {
|
|
2940
|
+
id: 'id',
|
|
2941
|
+
invoiceId: 'id',
|
|
2942
|
+
journalId: 'id',
|
|
2943
|
+
expectedRevision: 'int?',
|
|
2944
|
+
date: 'datetime?',
|
|
2945
|
+
accountingDate: 'date?',
|
|
2946
|
+
documentDate: 'date?',
|
|
2947
|
+
},
|
|
2948
|
+
output: { ok: 'bool', id: 'id?', moveId: 'id?', amount: 'decimal?', errors: 'json?' },
|
|
2949
|
+
effects: [
|
|
2950
|
+
'read:account.Payment',
|
|
2951
|
+
'read:account.Journal',
|
|
2952
|
+
'read:account.Account',
|
|
2953
|
+
'read:account.Move',
|
|
2954
|
+
'read:account.MoveLine',
|
|
2955
|
+
'read:account.PartialReconcile',
|
|
2956
|
+
'read:account.PeriodPolicy',
|
|
2957
|
+
'read:company.Company',
|
|
2958
|
+
'write:account.Payment',
|
|
2959
|
+
'write:account.Journal',
|
|
2960
|
+
'write:account.Move',
|
|
2961
|
+
'write:account.MoveLine',
|
|
2962
|
+
'write:account.PartialReconcile',
|
|
2963
|
+
'write:account.PeriodPolicy',
|
|
2964
|
+
'write:account.AuditEvent',
|
|
2965
|
+
],
|
|
2966
|
+
idempotent: true,
|
|
2967
|
+
agent: true,
|
|
2968
|
+
handler: async (ctx, args) => {
|
|
2969
|
+
const invoice = (await ctx.db.select('account.Move', { id: args.invoiceId }))[0];
|
|
2970
|
+
if (!invoice)
|
|
2971
|
+
return invalid('invoiceId', 'moveMissing');
|
|
2972
|
+
if (invoice.moveType !== 'out_invoice')
|
|
2973
|
+
return invalid('invoiceId', 'invoicePaymentType');
|
|
2974
|
+
if (invoice.state !== 'posted')
|
|
2975
|
+
return invalid('state', 'invoicePaymentState');
|
|
2976
|
+
const existing = (await ctx.db.select('account.Payment', { id: args.id }))[0];
|
|
2977
|
+
if (existing && String(existing.invoiceId ?? '') !== String(args.invoiceId))
|
|
2978
|
+
return invalid('id', 'paymentIdReused');
|
|
2979
|
+
const { scale } = await ledgerOf(ctx);
|
|
2980
|
+
const accounts = await accountsById(ctx);
|
|
2981
|
+
const receivables = (await ctx.db.select('account.MoveLine', { moveId: args.invoiceId }))
|
|
2982
|
+
.filter((line) => accounts.get(String(line.accountId))?.accountType === 'asset_receivable' &&
|
|
2983
|
+
moneyMinor(line.amountResidual, scale) > 0n)
|
|
2984
|
+
.sort((left, right) => String(left.id).localeCompare(String(right.id)));
|
|
2985
|
+
if (!receivables.length) {
|
|
2986
|
+
if (existing)
|
|
2987
|
+
return { ok: true, id: args.id, moveId: existing.moveId, amount: String(existing.amount) };
|
|
2988
|
+
return invalid('invoiceId', 'invoicePaymentResidual');
|
|
2989
|
+
}
|
|
2990
|
+
const destinationIds = [...new Set(receivables.map((line) => String(line.accountId)))];
|
|
2991
|
+
if (destinationIds.length !== 1)
|
|
2992
|
+
return invalid('invoiceId', 'invoicePaymentAccounts');
|
|
2993
|
+
const amount = existing
|
|
2994
|
+
? moneyMinor(existing.amount, scale)
|
|
2995
|
+
: sumMoneyMinor(receivables.map((line) => line.amountResidual), scale);
|
|
2996
|
+
const registered = (await functions.registerPayment.handler(ctx, {
|
|
2997
|
+
id: args.id,
|
|
2998
|
+
name: `Payment ${String(invoice.name)}`,
|
|
2999
|
+
paymentType: 'inbound',
|
|
3000
|
+
partnerType: 'customer',
|
|
3001
|
+
partnerId: invoice.partnerId,
|
|
3002
|
+
journalId: args.journalId,
|
|
3003
|
+
destinationAccountId: destinationIds[0],
|
|
3004
|
+
amount: minorText(amount, scale),
|
|
3005
|
+
date: args.date ?? today(),
|
|
3006
|
+
...(args.accountingDate ? { accountingDate: args.accountingDate } : {}),
|
|
3007
|
+
...(args.documentDate ? { documentDate: args.documentDate } : {}),
|
|
3008
|
+
memo: String(invoice.name),
|
|
3009
|
+
paymentReference: String(invoice.name),
|
|
3010
|
+
invoiceId: args.invoiceId,
|
|
3011
|
+
expectedRevision: args.expectedRevision,
|
|
3012
|
+
}));
|
|
3013
|
+
if (registered.ok !== true)
|
|
3014
|
+
return registered;
|
|
3015
|
+
const counterpartId = `${String(registered.moveId)}:counterpart`;
|
|
3016
|
+
for (const line of receivables) {
|
|
3017
|
+
const current = (await ctx.db.select('account.MoveLine', { id: line.id }))[0];
|
|
3018
|
+
const residual = moneyMinor(current?.amountResidual ?? '0', scale);
|
|
3019
|
+
if (residual <= 0n)
|
|
3020
|
+
continue;
|
|
3021
|
+
const reconciled = (await functions.reconcile.handler(ctx, {
|
|
3022
|
+
id: `${String(args.id)}:invoice:${String(line.id)}`,
|
|
3023
|
+
debitMoveId: line.id,
|
|
3024
|
+
creditMoveId: counterpartId,
|
|
3025
|
+
amount: minorText(residual, scale),
|
|
3026
|
+
date: args.date ?? today(),
|
|
3027
|
+
}));
|
|
3028
|
+
if (reconciled.ok !== true)
|
|
3029
|
+
return reconciled;
|
|
3030
|
+
}
|
|
3031
|
+
return {
|
|
3032
|
+
ok: true,
|
|
3033
|
+
id: args.id,
|
|
3034
|
+
moveId: registered.moveId,
|
|
3035
|
+
amount: minorText(amount, scale),
|
|
3036
|
+
};
|
|
3037
|
+
},
|
|
3038
|
+
}),
|
|
898
3039
|
reconcile: defineFn({
|
|
899
|
-
input: {
|
|
3040
|
+
input: {
|
|
3041
|
+
id: 'id',
|
|
3042
|
+
debitMoveId: 'id',
|
|
3043
|
+
creditMoveId: 'id',
|
|
3044
|
+
amount: 'decimal',
|
|
3045
|
+
date: 'datetime?',
|
|
3046
|
+
actorId: 'text?',
|
|
3047
|
+
reason: 'text?',
|
|
3048
|
+
},
|
|
900
3049
|
output: { ok: 'bool', id: 'id?', errors: 'json?' },
|
|
901
3050
|
effects: [
|
|
902
3051
|
'read:account.Move',
|
|
903
3052
|
'read:account.MoveLine',
|
|
904
3053
|
'read:account.Account',
|
|
905
3054
|
'read:account.PartialReconcile',
|
|
3055
|
+
'read:company.Company',
|
|
906
3056
|
'write:account.Move',
|
|
907
3057
|
'write:account.MoveLine',
|
|
908
3058
|
'write:account.PartialReconcile',
|
|
@@ -910,9 +3060,16 @@ export const functions = {
|
|
|
910
3060
|
idempotent: true,
|
|
911
3061
|
agent: true,
|
|
912
3062
|
handler: async (ctx, args) => {
|
|
913
|
-
const
|
|
914
|
-
|
|
915
|
-
|
|
3063
|
+
const { scale } = await ledgerOf(ctx);
|
|
3064
|
+
let amount;
|
|
3065
|
+
try {
|
|
3066
|
+
amount = moneyMinor(args.amount, scale);
|
|
3067
|
+
}
|
|
3068
|
+
catch {
|
|
3069
|
+
return invalid('amount', 'moneyExactString');
|
|
3070
|
+
}
|
|
3071
|
+
if (amount <= 0n)
|
|
3072
|
+
return invalid('amount', 'reconcileAmountPositive');
|
|
916
3073
|
if ((await ctx.db.select('account.PartialReconcile', { id: args.id }))[0])
|
|
917
3074
|
return { ok: true, id: args.id };
|
|
918
3075
|
let moveIds = null;
|
|
@@ -920,118 +3077,142 @@ export const functions = {
|
|
|
920
3077
|
moveIds = await ctx.tx(async (tx) => {
|
|
921
3078
|
const debit = (await tx.db.select('account.MoveLine', { id: args.debitMoveId }))[0];
|
|
922
3079
|
const credit = (await tx.db.select('account.MoveLine', { id: args.creditMoveId }))[0];
|
|
923
|
-
if (!debit ||
|
|
924
|
-
|
|
3080
|
+
if (!debit ||
|
|
3081
|
+
!credit ||
|
|
3082
|
+
moneyMinor(debit.balance, scale) <= 0n ||
|
|
3083
|
+
moneyMinor(credit.balance, scale) >= 0n)
|
|
3084
|
+
throw new Refusal('reconcileSides');
|
|
925
3085
|
if (debit.accountId !== credit.accountId)
|
|
926
|
-
throw new
|
|
3086
|
+
throw new Refusal('reconcileAccountMismatch');
|
|
927
3087
|
const [debitMove, creditMove] = await Promise.all([
|
|
928
3088
|
tx.db.select('account.Move', { id: debit.moveId }),
|
|
929
3089
|
tx.db.select('account.Move', { id: credit.moveId }),
|
|
930
3090
|
]);
|
|
931
3091
|
if (debitMove[0]?.state !== 'posted' || creditMove[0]?.state !== 'posted')
|
|
932
|
-
throw new
|
|
3092
|
+
throw new Refusal('reconcilePostedOnly');
|
|
933
3093
|
const account = await accountOf(tx, debit.accountId);
|
|
934
3094
|
if (!account?.reconcile)
|
|
935
|
-
throw new
|
|
936
|
-
|
|
937
|
-
|
|
3095
|
+
throw new Refusal('reconcileNotAllowed');
|
|
3096
|
+
const debitHeld = moneyMinor(debit.amountResidual, scale);
|
|
3097
|
+
const creditHeld = moneyMinor(credit.amountResidual, scale);
|
|
3098
|
+
if (amount > debitHeld || amount > creditHeld)
|
|
3099
|
+
throw new Refusal('reconcileAmountExceeds');
|
|
938
3100
|
const held = await tx.db.insertIfAbsent('account.PartialReconcile', {
|
|
939
3101
|
id: args.id,
|
|
940
3102
|
debitMoveId: args.debitMoveId,
|
|
941
3103
|
creditMoveId: args.creditMoveId,
|
|
942
|
-
amount:
|
|
3104
|
+
amount: minorText(amount, scale),
|
|
943
3105
|
date: args.date ?? today(),
|
|
3106
|
+
state: 'active',
|
|
3107
|
+
actorId: args.actorId ?? null,
|
|
3108
|
+
reason: args.reason ?? null,
|
|
3109
|
+
reversedAt: null,
|
|
3110
|
+
reversedBy: null,
|
|
3111
|
+
reversalReason: null,
|
|
944
3112
|
});
|
|
945
3113
|
if (!('dryRun' in held) && !held.inserted)
|
|
946
3114
|
return [debit.moveId, credit.moveId];
|
|
947
|
-
const debitResidual =
|
|
948
|
-
const creditResidual =
|
|
949
|
-
const debitWrite = await tx.db.compareAndSet('account.MoveLine', { id: debit.id }, { amountResidual: debit.amountResidual }, { amountResidual:
|
|
950
|
-
const creditWrite = await tx.db.compareAndSet('account.MoveLine', { id: credit.id }, { amountResidual: credit.amountResidual }, { amountResidual:
|
|
3115
|
+
const debitResidual = debitHeld - amount;
|
|
3116
|
+
const creditResidual = creditHeld - amount;
|
|
3117
|
+
const debitWrite = await tx.db.compareAndSet('account.MoveLine', { id: debit.id }, { amountResidual: debit.amountResidual }, { amountResidual: minorText(debitResidual, scale), reconciled: debitResidual === 0n });
|
|
3118
|
+
const creditWrite = await tx.db.compareAndSet('account.MoveLine', { id: credit.id }, { amountResidual: credit.amountResidual }, { amountResidual: minorText(creditResidual, scale), reconciled: creditResidual === 0n });
|
|
951
3119
|
if ((!('dryRun' in debitWrite) && !debitWrite.matched) ||
|
|
952
3120
|
(!('dryRun' in creditWrite) && !creditWrite.matched))
|
|
953
|
-
throw new
|
|
3121
|
+
throw new Refusal('reconcileConcurrent');
|
|
954
3122
|
return [debit.moveId, credit.moveId];
|
|
955
3123
|
});
|
|
956
3124
|
}
|
|
957
3125
|
catch (error) {
|
|
958
|
-
return
|
|
3126
|
+
return refused('lines', error);
|
|
959
3127
|
}
|
|
960
3128
|
if (moveIds) {
|
|
961
|
-
await
|
|
962
|
-
await updatePaymentState(ctx, moveIds[
|
|
3129
|
+
const accounts = await accountsById(ctx);
|
|
3130
|
+
await updatePaymentState(ctx, moveIds[0], accounts);
|
|
3131
|
+
await updatePaymentState(ctx, moveIds[1], accounts);
|
|
963
3132
|
}
|
|
964
3133
|
return { ok: true, id: args.id };
|
|
965
3134
|
},
|
|
966
3135
|
}),
|
|
967
3136
|
trialBalance: defineFn({
|
|
968
|
-
input: { dateFrom: '
|
|
969
|
-
effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine'],
|
|
3137
|
+
input: { dateFrom: 'date?', dateTo: 'date?' },
|
|
3138
|
+
effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine', 'read:company.Company'],
|
|
970
3139
|
agent: true,
|
|
971
3140
|
handler: async (ctx, args) => {
|
|
972
|
-
const
|
|
3141
|
+
const { scale } = await ledgerOf(ctx);
|
|
3142
|
+
const accounts = await ctx.db.select('account.Account');
|
|
3143
|
+
// The date window belongs to the move, so it narrows the move query and the
|
|
3144
|
+
// journal items are then fetched for those moves alone.
|
|
3145
|
+
const moves = await postedMoves(ctx, args.dateFrom, args.dateTo);
|
|
973
3146
|
const result = new Map();
|
|
974
|
-
for (const line of await ctx.
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const at = new Date(String(move.date)).getTime(), from = args.dateFrom ? new Date(String(args.dateFrom)).getTime() : -Infinity, to = args.dateTo ? new Date(String(args.dateTo)).getTime() : Infinity;
|
|
979
|
-
if (at < from || at > to)
|
|
980
|
-
continue;
|
|
981
|
-
const held = result.get(String(line.accountId)) ?? { debit: 0, credit: 0 };
|
|
982
|
-
held.debit = money(held.debit + n(line.debit));
|
|
983
|
-
held.credit = money(held.credit + n(line.credit));
|
|
3147
|
+
for (const line of await linesOfMoves(ctx, [...moves.keys()])) {
|
|
3148
|
+
const held = result.get(String(line.accountId)) ?? { debit: 0n, credit: 0n };
|
|
3149
|
+
held.debit += moneyMinor(line.debit, scale);
|
|
3150
|
+
held.credit += moneyMinor(line.credit, scale);
|
|
984
3151
|
result.set(String(line.accountId), held);
|
|
985
3152
|
}
|
|
986
3153
|
return accounts
|
|
987
3154
|
.map((account) => {
|
|
988
|
-
const held = result.get(String(account.id)) ?? { debit:
|
|
3155
|
+
const held = result.get(String(account.id)) ?? { debit: 0n, credit: 0n };
|
|
989
3156
|
return {
|
|
990
3157
|
accountId: account.id,
|
|
991
3158
|
code: account.code,
|
|
992
3159
|
name: account.name,
|
|
993
|
-
debit:
|
|
994
|
-
credit:
|
|
995
|
-
balance:
|
|
3160
|
+
debit: minorText(held.debit, scale),
|
|
3161
|
+
credit: minorText(held.credit, scale),
|
|
3162
|
+
balance: minorText(held.debit - held.credit, scale),
|
|
996
3163
|
};
|
|
997
3164
|
})
|
|
998
|
-
.filter((row) =>
|
|
3165
|
+
.filter((row) => moneyMinor(row.debit, scale) !== 0n || moneyMinor(row.credit, scale) !== 0n);
|
|
999
3166
|
},
|
|
1000
3167
|
}),
|
|
1001
3168
|
generalLedger: defineFn({
|
|
1002
|
-
input: {
|
|
1003
|
-
|
|
3169
|
+
input: {
|
|
3170
|
+
accountId: 'id?',
|
|
3171
|
+
dateFrom: 'date?',
|
|
3172
|
+
dateTo: 'date?',
|
|
3173
|
+
limit: 'int?',
|
|
3174
|
+
offset: 'int?',
|
|
3175
|
+
},
|
|
3176
|
+
effects: ['read:account.Move', 'read:account.MoveLine', 'read:company.Company'],
|
|
1004
3177
|
agent: true,
|
|
1005
3178
|
handler: async (ctx, args) => {
|
|
1006
|
-
const moves =
|
|
1007
|
-
const rows = []
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
if (at < (args.dateFrom ? new Date(String(args.dateFrom)).getTime() : -Infinity))
|
|
1014
|
-
continue;
|
|
1015
|
-
if (at > (args.dateTo ? new Date(String(args.dateTo)).getTime() : Infinity))
|
|
1016
|
-
continue;
|
|
1017
|
-
rows.push({ ...line, move });
|
|
1018
|
-
}
|
|
1019
|
-
return rows.sort((a, b) => String(a.move.date).localeCompare(String(b.move.date)) || n(a.sequence) - n(b.sequence));
|
|
3179
|
+
const moves = await postedMoves(ctx, args.dateFrom, args.dateTo);
|
|
3180
|
+
const rows = (await linesOfMoves(ctx, [...moves.keys()], args.accountId))
|
|
3181
|
+
.map((line) => ({ ...line, move: moves.get(String(line.moveId)) }))
|
|
3182
|
+
.sort((a, b) => String(a.move.accountingDate).localeCompare(String(b.move.accountingDate)) ||
|
|
3183
|
+
String(a.moveId).localeCompare(String(b.moveId)) ||
|
|
3184
|
+
n(a.sequence) - n(b.sequence));
|
|
3185
|
+
return slice(rows, args.limit, args.offset);
|
|
1020
3186
|
},
|
|
1021
3187
|
}),
|
|
1022
3188
|
partnerStatement: defineFn({
|
|
1023
|
-
input: {
|
|
1024
|
-
|
|
3189
|
+
input: {
|
|
3190
|
+
partnerId: 'id',
|
|
3191
|
+
dateFrom: 'date?',
|
|
3192
|
+
dateTo: 'date?',
|
|
3193
|
+
limit: 'int?',
|
|
3194
|
+
offset: 'int?',
|
|
3195
|
+
},
|
|
3196
|
+
effects: ['read:account.Move', 'read:account.MoveLine', 'read:account.Account', 'read:company.Company'],
|
|
1025
3197
|
agent: true,
|
|
1026
3198
|
handler: async (ctx, args) => {
|
|
1027
|
-
const
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
3199
|
+
const byId = await accountsById(ctx);
|
|
3200
|
+
const control = [...byId.values()]
|
|
3201
|
+
.filter((row) => OPEN_ITEM_TYPES.includes(String(row.accountType)))
|
|
3202
|
+
.map((row) => row.id);
|
|
3203
|
+
if (!control.length)
|
|
3204
|
+
return [];
|
|
3205
|
+
const moves = new Map([...(await postedMoves(ctx, args.dateFrom, args.dateTo))].filter(([, move]) => String(move.partnerId) === String(args.partnerId)));
|
|
3206
|
+
if (!moves.size)
|
|
3207
|
+
return [];
|
|
3208
|
+
const L = ctx.table('account.MoveLine');
|
|
3209
|
+
const lines = await ctx.db.all(from(L).where(and(eq(L.partnerId, args.partnerId), inArray(L.accountId, control))));
|
|
3210
|
+
const rows = lines
|
|
3211
|
+
.filter((line) => moves.has(String(line.moveId)))
|
|
3212
|
+
.map((line) => ({ ...line, move: moves.get(String(line.moveId)) }))
|
|
3213
|
+
.sort((a, b) => String(a.move.accountingDate).localeCompare(String(b.move.accountingDate)) ||
|
|
3214
|
+
String(a.id).localeCompare(String(b.id)));
|
|
3215
|
+
return slice(rows, args.limit, args.offset);
|
|
1035
3216
|
},
|
|
1036
3217
|
}),
|
|
1037
3218
|
};
|