shutro-erp 0.3.5 → 0.3.6
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/dist/account_asset/.kosh/bindings.d.ts +22 -0
- package/dist/account_asset/.kosh/bindings.js +15 -0
- package/dist/account_asset/.kosh/schema.d.ts +1755 -0
- package/dist/account_asset/board.d.ts +61 -0
- package/dist/account_asset/board.js +86 -0
- package/dist/account_asset/books.d.ts +42 -0
- package/dist/account_asset/books.js +398 -0
- package/dist/account_asset/demo.d.ts +7 -0
- package/dist/account_asset/demo.js +72 -0
- package/dist/account_asset/index.d.ts +9 -0
- package/dist/account_asset/index.js +335 -0
- package/dist/account_asset/module.d.ts +7622 -0
- package/dist/account_asset/module.js +230 -0
- package/dist/account_budget/.kosh/bindings.d.ts +22 -0
- package/dist/account_budget/.kosh/bindings.js +15 -0
- package/dist/account_budget/.kosh/schema.d.ts +1767 -0
- package/dist/account_budget/budget.d.ts +5 -0
- package/dist/account_budget/budget.js +142 -0
- package/dist/account_budget/demo.d.ts +6 -0
- package/dist/account_budget/demo.js +30 -0
- package/dist/account_budget/index.d.ts +4 -0
- package/dist/account_budget/index.js +223 -0
- package/dist/account_budget/module.d.ts +13863 -0
- package/dist/account_budget/module.js +167 -0
- package/dist/account_portal/.kosh/bindings.js +1 -1
- package/dist/account_portal/.kosh/schema.d.ts +123 -4
- package/dist/account_portal/module.d.ts +146 -0
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +123 -4
- package/dist/accounting/index.d.ts +1 -1
- package/dist/accounting/index.js +131 -3
- package/dist/accounting/module.d.ts +296 -0
- package/dist/accounting/module.js +32 -1
- package/dist/approvals/.kosh/bindings.d.ts +22 -0
- package/dist/approvals/.kosh/bindings.js +15 -0
- package/dist/approvals/.kosh/schema.d.ts +611 -0
- package/dist/approvals/index.d.ts +18 -0
- package/dist/approvals/index.js +302 -0
- package/dist/approvals/mails.d.ts +25 -0
- package/dist/approvals/mails.js +82 -0
- package/dist/approvals/module.d.ts +1 -0
- package/dist/approvals/module.js +12 -0
- package/dist/approvals/web/History.d.ts +4 -0
- package/dist/approvals/web/History.js +13 -0
- package/dist/approvals/web/Inbox.d.ts +9 -0
- package/dist/approvals/web/Inbox.js +114 -0
- package/dist/approvals/web/Mine.d.ts +7 -0
- package/dist/approvals/web/Mine.js +27 -0
- package/dist/approvals/web/index.d.ts +13 -0
- package/dist/approvals/web/index.js +22 -0
- package/dist/approvals/web/messages.d.ts +2 -0
- package/dist/approvals/web/messages.js +119 -0
- package/dist/approvals/web/shared.d.ts +59 -0
- package/dist/approvals/web/shared.js +46 -0
- package/dist/attendance/.kosh/bindings.d.ts +22 -0
- package/dist/attendance/.kosh/bindings.js +15 -0
- package/dist/attendance/.kosh/schema.d.ts +1048 -0
- package/dist/attendance/days.d.ts +96 -0
- package/dist/attendance/days.js +430 -0
- package/dist/attendance/demo.d.ts +7 -0
- package/dist/attendance/demo.js +58 -0
- package/dist/attendance/index.d.ts +4 -0
- package/dist/attendance/index.js +513 -0
- package/dist/attendance/module.d.ts +3969 -0
- package/dist/attendance/module.js +412 -0
- package/dist/attendance/routes.d.ts +16 -0
- package/dist/attendance/routes.js +266 -0
- package/dist/attendance/web/Check.d.ts +8 -0
- package/dist/attendance/web/Check.js +40 -0
- package/dist/attendance/web/Kiosk.d.ts +8 -0
- package/dist/attendance/web/Kiosk.js +62 -0
- package/dist/attendance/web/PinButton.d.ts +7 -0
- package/dist/attendance/web/PinButton.js +29 -0
- package/dist/attendance/web/index.d.ts +13 -0
- package/dist/attendance/web/index.js +22 -0
- package/dist/attendance/web/messages.d.ts +2 -0
- package/dist/attendance/web/messages.js +61 -0
- package/dist/cli/init.js +32 -0
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +89 -0
- package/dist/contacts/module.js +13 -2
- package/dist/crm/.kosh/bindings.js +1 -1
- package/dist/crm/.kosh/schema.d.ts +2 -1
- package/dist/crm/module.d.ts +2 -0
- package/dist/crm/module.js +2 -1
- package/dist/documents/.kosh/bindings.d.ts +22 -0
- package/dist/documents/.kosh/bindings.js +15 -0
- package/dist/documents/.kosh/schema.d.ts +862 -0
- package/dist/documents/demo.d.ts +6 -0
- package/dist/documents/demo.js +22 -0
- package/dist/documents/documents.d.ts +98 -0
- package/dist/documents/documents.js +318 -0
- package/dist/documents/index.d.ts +30 -0
- package/dist/documents/index.js +442 -0
- package/dist/documents/module.d.ts +2781 -0
- package/dist/documents/module.js +214 -0
- package/dist/documents/web/Versions.d.ts +7 -0
- package/dist/documents/web/Versions.js +45 -0
- package/dist/documents/web/index.d.ts +11 -0
- package/dist/documents/web/index.js +16 -0
- package/dist/documents/web/messages.d.ts +2 -0
- package/dist/documents/web/messages.js +21 -0
- package/dist/event_account/.kosh/bindings.js +1 -1
- package/dist/event_account/.kosh/schema.d.ts +123 -4
- package/dist/event_account/module.d.ts +146 -0
- package/dist/expense/.kosh/bindings.d.ts +22 -0
- package/dist/expense/.kosh/bindings.js +15 -0
- package/dist/expense/.kosh/schema.d.ts +1299 -0
- package/dist/expense/demo.d.ts +7 -0
- package/dist/expense/demo.js +69 -0
- package/dist/expense/index.d.ts +3 -0
- package/dist/expense/index.js +495 -0
- package/dist/expense/module.d.ts +4747 -0
- package/dist/expense/module.js +647 -0
- package/dist/expense_account/.kosh/bindings.d.ts +22 -0
- package/dist/expense_account/.kosh/bindings.js +15 -0
- package/dist/expense_account/.kosh/schema.d.ts +1936 -0
- package/dist/expense_account/index.d.ts +3 -0
- package/dist/expense_account/index.js +74 -0
- package/dist/expense_account/module.d.ts +9153 -0
- package/dist/expense_account/module.js +318 -0
- package/dist/helpdesk/.kosh/bindings.d.ts +22 -0
- package/dist/helpdesk/.kosh/bindings.js +15 -0
- package/dist/helpdesk/.kosh/schema.d.ts +885 -0
- package/dist/helpdesk/demo.d.ts +7 -0
- package/dist/helpdesk/demo.js +65 -0
- package/dist/helpdesk/hours.d.ts +17 -0
- package/dist/helpdesk/hours.js +94 -0
- package/dist/helpdesk/index.d.ts +10 -0
- package/dist/helpdesk/index.js +461 -0
- package/dist/helpdesk/module.d.ts +2940 -0
- package/dist/helpdesk/module.js +326 -0
- package/dist/helpdesk/routes.d.ts +12 -0
- package/dist/helpdesk/routes.js +132 -0
- package/dist/helpdesk/sla.d.ts +37 -0
- package/dist/helpdesk/sla.js +226 -0
- package/dist/hr/index.d.ts +1 -1
- package/dist/hr/index.js +1 -1
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +123 -4
- package/dist/l10n_bd/module.d.ts +146 -0
- package/dist/l10n_bd_payroll/.kosh/bindings.d.ts +22 -0
- package/dist/l10n_bd_payroll/.kosh/bindings.js +15 -0
- package/dist/l10n_bd_payroll/.kosh/schema.d.ts +2312 -0
- package/dist/l10n_bd_payroll/data.d.ts +47 -0
- package/dist/l10n_bd_payroll/data.js +347 -0
- package/dist/l10n_bd_payroll/index.d.ts +4 -0
- package/dist/l10n_bd_payroll/index.js +24 -0
- package/dist/l10n_bd_payroll/module.d.ts +12932 -0
- package/dist/l10n_bd_payroll/module.js +86 -0
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +123 -4
- package/dist/l10n_in/module.d.ts +147 -0
- package/dist/mail/inbound/handle.js +6 -1
- package/dist/maintenance_stock/.kosh/bindings.js +1 -1
- package/dist/maintenance_stock/.kosh/schema.d.ts +77 -2
- package/dist/maintenance_stock/module.d.ts +788 -66
- package/dist/modules-sdk/index.d.ts +1 -1
- package/dist/modules-sdk/manifest.d.ts +39 -2
- package/dist/mrp/.kosh/bindings.js +1 -1
- package/dist/mrp/.kosh/schema.d.ts +77 -2
- package/dist/mrp/index.d.ts +1 -1
- package/dist/mrp/index.js +2 -1
- package/dist/mrp/module.d.ts +781 -54
- package/dist/mrp/module.js +64 -2
- package/dist/mrp_account/.kosh/bindings.js +1 -1
- package/dist/mrp_account/.kosh/schema.d.ts +198 -5
- package/dist/mrp_account/module.d.ts +4852 -2541
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +125 -5
- package/dist/payment/index.d.ts +41 -0
- package/dist/payment/index.js +131 -74
- package/dist/payment/module.d.ts +210 -6
- package/dist/payment/module.js +19 -3
- package/dist/payment/settle.js +10 -1
- package/dist/payroll/.kosh/bindings.d.ts +22 -0
- package/dist/payroll/.kosh/bindings.js +15 -0
- package/dist/payroll/.kosh/schema.d.ts +1390 -0
- package/dist/payroll/compute.d.ts +35 -0
- package/dist/payroll/compute.js +398 -0
- package/dist/payroll/demo.d.ts +55 -0
- package/dist/payroll/demo.js +121 -0
- package/dist/payroll/formula.d.ts +62 -0
- package/dist/payroll/formula.js +320 -0
- package/dist/payroll/index.d.ts +230 -0
- package/dist/payroll/index.js +713 -0
- package/dist/payroll/module.d.ts +9390 -0
- package/dist/payroll/module.js +606 -0
- package/dist/payroll/routes.d.ts +10 -0
- package/dist/payroll/routes.js +112 -0
- package/dist/payroll_account/.kosh/bindings.d.ts +22 -0
- package/dist/payroll_account/.kosh/bindings.js +15 -0
- package/dist/payroll_account/.kosh/schema.d.ts +2308 -0
- package/dist/payroll_account/index.d.ts +3 -0
- package/dist/payroll_account/index.js +40 -0
- package/dist/payroll_account/module.d.ts +12396 -0
- package/dist/payroll_account/module.js +256 -0
- package/dist/permissions/approvals.d.ts +131 -9
- package/dist/permissions/approvals.js +662 -57
- package/dist/permissions/index.d.ts +1 -1
- package/dist/permissions/index.js +2 -2
- package/dist/permissions/models.js +191 -12
- package/dist/permissions/routes.d.ts +6 -1
- package/dist/permissions/routes.js +37 -4
- package/dist/permissions/web/ApprovalPanel.d.ts +5 -4
- package/dist/permissions/web/ApprovalPanel.js +39 -13
- package/dist/permissions/web/index.d.ts +6 -4
- package/dist/permissions/web/index.js +13 -4
- package/dist/permissions/web/messages.d.ts +2 -0
- package/dist/permissions/web/messages.js +43 -0
- package/dist/portal/index.js +1 -1
- package/dist/pos/.kosh/bindings.js +1 -1
- package/dist/pos/.kosh/schema.d.ts +123 -4
- package/dist/pos/index.js +4 -0
- package/dist/pos/module.d.ts +147 -0
- package/dist/pos_stock/.kosh/bindings.js +1 -1
- package/dist/pos_stock/.kosh/schema.d.ts +198 -5
- package/dist/pos_stock/module.d.ts +914 -46
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +2 -1
- package/dist/product/index.js +13 -0
- package/dist/product/module.d.ts +2 -0
- package/dist/product/module.js +2 -1
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +672 -1
- package/dist/project/index.d.ts +3 -1
- package/dist/project/index.js +901 -14
- package/dist/project/module.d.ts +9892 -390
- package/dist/project/module.js +1530 -13
- package/dist/project/routes.d.ts +44 -0
- package/dist/project/routes.js +314 -0
- package/dist/project/schedule.d.ts +72 -0
- package/dist/project/schedule.js +192 -0
- package/dist/project/web/Refresh.d.ts +8 -0
- package/dist/project/web/Refresh.js +29 -0
- package/dist/project/web/Schedule.d.ts +9 -0
- package/dist/project/web/Schedule.js +93 -0
- package/dist/project/web/Structure.d.ts +8 -0
- package/dist/project/web/Structure.js +86 -0
- package/dist/project/web/Workload.d.ts +8 -0
- package/dist/project/web/Workload.js +43 -0
- package/dist/project/web/index.d.ts +14 -0
- package/dist/project/web/index.js +25 -0
- package/dist/project/web/messages.d.ts +2 -0
- package/dist/project/web/messages.js +85 -0
- package/dist/project_account/.kosh/bindings.d.ts +22 -0
- package/dist/project_account/.kosh/bindings.js +15 -0
- package/dist/project_account/.kosh/schema.d.ts +2241 -0
- package/dist/project_account/index.d.ts +3 -0
- package/dist/project_account/index.js +27 -0
- package/dist/project_account/module.d.ts +11539 -0
- package/dist/project_account/module.js +76 -0
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +672 -1
- package/dist/project_portal/module.d.ts +4798 -129
- package/dist/project_purchase/.kosh/bindings.d.ts +22 -0
- package/dist/project_purchase/.kosh/bindings.js +15 -0
- package/dist/project_purchase/.kosh/schema.d.ts +2320 -0
- package/dist/project_purchase/index.d.ts +9 -0
- package/dist/project_purchase/index.js +22 -0
- package/dist/project_purchase/module.d.ts +25147 -0
- package/dist/project_purchase/module.js +56 -0
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +97 -4
- package/dist/purchase/module.d.ts +13 -2
- package/dist/purchase/module.js +10 -1
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +126 -6
- package/dist/purchase_account/index.js +1 -0
- package/dist/purchase_account/module.d.ts +176 -1
- package/dist/purchase_account/module.js +13 -2
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +97 -4
- package/dist/purchase_portal/module.d.ts +6 -1
- package/dist/purchase_stock/.kosh/bindings.js +1 -1
- package/dist/purchase_stock/.kosh/schema.d.ts +174 -5
- package/dist/purchase_stock/index.d.ts +1 -1
- package/dist/purchase_stock/index.js +9 -2
- package/dist/purchase_stock/module.d.ts +840 -68
- package/dist/purchase_stock/module.js +242 -6
- package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
- package/dist/purchase_stock_account/.kosh/schema.d.ts +203 -7
- package/dist/purchase_stock_account/module.d.ts +8163 -5514
- package/dist/purchase_stock_account/module.js +11 -5
- package/dist/recruitment/.kosh/bindings.js +1 -1
- package/dist/recruitment/.kosh/schema.d.ts +2 -1
- package/dist/recruitment/module.d.ts +2 -0
- package/dist/recruitment/module.js +2 -1
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +123 -4
- package/dist/sale_account/module.d.ts +147 -0
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +2 -1
- package/dist/sale_portal/module.d.ts +1 -0
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +673 -1
- package/dist/sale_project/module.d.ts +4800 -129
- package/dist/sale_project/module.js +17 -1
- package/dist/sale_stock/.kosh/bindings.js +1 -1
- package/dist/sale_stock/.kosh/schema.d.ts +77 -2
- package/dist/sale_stock/module.d.ts +789 -66
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +2 -1
- package/dist/sales/index.js +4 -0
- package/dist/sales/module.d.ts +1 -0
- package/dist/sign/.kosh/bindings.d.ts +22 -0
- package/dist/sign/.kosh/bindings.js +15 -0
- package/dist/sign/.kosh/schema.d.ts +990 -0
- package/dist/sign/index.d.ts +14 -0
- package/dist/sign/index.js +350 -0
- package/dist/sign/module.d.ts +4478 -0
- package/dist/sign/module.js +158 -0
- package/dist/sign/sign.d.ts +82 -0
- package/dist/sign/sign.js +474 -0
- package/dist/stock/.kosh/bindings.js +1 -1
- package/dist/stock/.kosh/schema.d.ts +77 -2
- package/dist/stock/demo.d.ts +2 -1
- package/dist/stock/demo.js +28 -1
- package/dist/stock/index.d.ts +2 -1
- package/dist/stock/index.js +233 -4
- package/dist/stock/module.d.ts +2363 -837
- package/dist/stock/module.js +569 -14
- package/dist/stock/replenish.d.ts +38 -0
- package/dist/stock/replenish.js +176 -0
- package/dist/stock/web/Replenishment.d.ts +8 -0
- package/dist/stock/web/Replenishment.js +84 -0
- package/dist/stock/web/index.d.ts +4 -2
- package/dist/stock/web/index.js +6 -2
- package/dist/stock/web/messages.js +52 -0
- package/dist/stock_account/.kosh/bindings.js +1 -1
- package/dist/stock_account/.kosh/schema.d.ts +198 -5
- package/dist/stock_account/index.js +10 -0
- package/dist/stock_account/module.d.ts +969 -101
- package/dist/trade_finance/index.js +2 -0
- package/dist/trade_finance/module.js +2 -0
- package/dist/trade_finance_account/.kosh/bindings.js +1 -1
- package/dist/trade_finance_account/.kosh/schema.d.ts +123 -4
- package/dist/trade_finance_account/index.js +1 -0
- package/dist/trade_finance_account/module.d.ts +146 -0
- package/dist/trade_finance_account/module.js +1 -0
- package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
- package/dist/trade_finance_purchase/.kosh/schema.d.ts +97 -4
- package/dist/trade_finance_purchase/module.d.ts +6 -1
- package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
- package/dist/trade_finance_sale/.kosh/schema.d.ts +2 -1
- package/dist/trade_finance_sale/module.d.ts +1 -0
- package/dist/ui/app.js +24 -12
- package/dist/ui/components/AppIcon.js +8 -1
- package/dist/ui/i18n/messages.d.ts +4 -0
- package/dist/ui/i18n/messages.js +8 -0
- package/dist/ui/views/FormView.js +4 -2
- package/dist/ui/views/KanbanView.js +9 -1
- package/dist/ui/views/ListView.js +4 -2
- package/dist/ui/views/widgets.js +7 -1
- package/dist/website/index.js +1 -0
- package/dist/website/module.js +1 -0
- package/dist/website_crm/.kosh/bindings.js +1 -1
- package/dist/website_crm/.kosh/schema.d.ts +2 -1
- package/dist/website_crm/module.d.ts +1 -0
- package/dist/website_sale/.kosh/bindings.d.ts +22 -0
- package/dist/website_sale/.kosh/bindings.js +15 -0
- package/dist/website_sale/.kosh/schema.d.ts +2284 -0
- package/dist/website_sale/couriers.d.ts +50 -0
- package/dist/website_sale/couriers.js +59 -0
- package/dist/website_sale/demo.d.ts +7 -0
- package/dist/website_sale/demo.js +90 -0
- package/dist/website_sale/growth.d.ts +31 -0
- package/dist/website_sale/growth.js +163 -0
- package/dist/website_sale/index.d.ts +49 -0
- package/dist/website_sale/index.js +538 -0
- package/dist/website_sale/module.d.ts +22027 -0
- package/dist/website_sale/module.js +397 -0
- package/dist/website_sale/shipments.d.ts +16 -0
- package/dist/website_sale/shipments.js +113 -0
- package/dist/website_sale/shop.d.ts +81 -0
- package/dist/website_sale/shop.js +649 -0
- package/dist/website_sale_stock/.kosh/bindings.d.ts +22 -0
- package/dist/website_sale_stock/.kosh/bindings.js +15 -0
- package/dist/website_sale_stock/.kosh/schema.d.ts +2681 -0
- package/dist/website_sale_stock/index.d.ts +9 -0
- package/dist/website_sale_stock/index.js +20 -0
- package/dist/website_sale_stock/module.d.ts +24998 -0
- package/dist/website_sale_stock/module.js +28 -0
- package/package.json +83 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c50b4a215467041d
|
|
2
2
|
// Bindings of module `payment`: import the definition API from here to get types scoped to what it can see.
|
|
3
3
|
export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
|
|
4
4
|
import { definitions } from '../../server/orm.js';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c50b4a215467041d
|
|
2
2
|
// Schema view of module `payment` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
|
|
3
3
|
import type { F } from '../../server/orm.js';
|
|
4
4
|
|
|
5
5
|
/** Model name → model type (RFC 0002 §7.7). */
|
|
6
6
|
export interface SchemaView {
|
|
7
7
|
readonly 'account.account': AccountAccount;
|
|
8
|
+
readonly 'account.analytic': AccountAnalytic;
|
|
8
9
|
readonly 'account.fiscal.year': AccountFiscalYear;
|
|
9
10
|
readonly 'account.full.reconcile': AccountFullReconcile;
|
|
10
11
|
readonly 'account.journal': AccountJournal;
|
|
@@ -18,9 +19,12 @@ export interface SchemaView {
|
|
|
18
19
|
readonly 'account.tax': AccountTax;
|
|
19
20
|
readonly 'account.tax.component': AccountTaxComponent;
|
|
20
21
|
readonly 'account.withholding': AccountWithholding;
|
|
22
|
+
readonly 'approval.delegation': ApprovalDelegation;
|
|
21
23
|
readonly 'approval.level': ApprovalLevel;
|
|
24
|
+
readonly 'approval.link': ApprovalLink;
|
|
22
25
|
readonly 'approval.policy': ApprovalPolicy;
|
|
23
26
|
readonly 'approval.request': ApprovalRequest;
|
|
27
|
+
readonly 'approval.vote': ApprovalVote;
|
|
24
28
|
readonly 'audit.event': AuditEvent;
|
|
25
29
|
readonly 'auth.api_key': AuthApiKey;
|
|
26
30
|
readonly 'auth.credential': AuthCredential;
|
|
@@ -95,6 +99,30 @@ export interface AccountAccount {
|
|
|
95
99
|
export interface AccountAccountMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'account.account'> {
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
/** `account.analytic` (owner: accounting). */
|
|
103
|
+
export interface AccountAnalytic {
|
|
104
|
+
readonly name: 'account.analytic';
|
|
105
|
+
readonly fields: {
|
|
106
|
+
readonly id: F.Id<'account.analytic'>;
|
|
107
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
108
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
109
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
110
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
111
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
112
|
+
readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
113
|
+
readonly company: F.Many2one<'res.company', { readonly required: true; readonly default: true }>;
|
|
114
|
+
readonly code: F.Char;
|
|
115
|
+
readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
|
|
116
|
+
readonly parent: F.Many2one<'account.analytic'>;
|
|
117
|
+
readonly note: F.Text;
|
|
118
|
+
};
|
|
119
|
+
readonly methods: AccountAnalyticMethods;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Methods of `account.analytic`: declared ones and transitions. */
|
|
123
|
+
export interface AccountAnalyticMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'account.analytic'> {
|
|
124
|
+
}
|
|
125
|
+
|
|
98
126
|
/** `account.fiscal.year` (owner: accounting). */
|
|
99
127
|
export interface AccountFiscalYear {
|
|
100
128
|
readonly name: 'account.fiscal.year';
|
|
@@ -250,6 +278,7 @@ export interface AccountMoveLine {
|
|
|
250
278
|
readonly lineKind: F.Selection<'entry' | 'product' | 'tax' | 'counterpart', { readonly required: true; readonly default: true }>;
|
|
251
279
|
readonly invoice: F.Many2one<'account.move', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
252
280
|
readonly product: F.Many2one<'product.product'>;
|
|
281
|
+
readonly analytic: F.Many2one<'account.analytic'>;
|
|
253
282
|
readonly quantity: F.Decimal<{ readonly default: true }>;
|
|
254
283
|
readonly priceUnit: F.Decimal<{ readonly default: true }>;
|
|
255
284
|
readonly discount: F.Decimal<{ readonly default: true }>;
|
|
@@ -491,6 +520,29 @@ export interface AccountWithholding {
|
|
|
491
520
|
export interface AccountWithholdingMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'account.withholding'> {
|
|
492
521
|
}
|
|
493
522
|
|
|
523
|
+
/** `approval.delegation` (owner: permissions). */
|
|
524
|
+
export interface ApprovalDelegation {
|
|
525
|
+
readonly name: 'approval.delegation';
|
|
526
|
+
readonly fields: {
|
|
527
|
+
readonly id: F.Id<'approval.delegation'>;
|
|
528
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
529
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
530
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
531
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
532
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
533
|
+
readonly user: F.Many2one<'res.users', { readonly required: true; readonly default: true }>;
|
|
534
|
+
readonly delegate: F.Many2one<'res.users', { readonly required: true }>;
|
|
535
|
+
readonly dateFrom: F.DateOnly<{ readonly required: true }>;
|
|
536
|
+
readonly dateTo: F.DateOnly<{ readonly required: true }>;
|
|
537
|
+
readonly note: F.Char;
|
|
538
|
+
};
|
|
539
|
+
readonly methods: ApprovalDelegationMethods;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/** Methods of `approval.delegation`: declared ones and transitions. */
|
|
543
|
+
export interface ApprovalDelegationMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.delegation'> {
|
|
544
|
+
}
|
|
545
|
+
|
|
494
546
|
/** `approval.level` (owner: permissions). */
|
|
495
547
|
export interface ApprovalLevel {
|
|
496
548
|
readonly name: 'approval.level';
|
|
@@ -505,7 +557,14 @@ export interface ApprovalLevel {
|
|
|
505
557
|
readonly sequence: F.Integer<{ readonly default: true }>;
|
|
506
558
|
readonly name: F.Char<{ readonly required: true }>;
|
|
507
559
|
readonly condition: F.Json;
|
|
508
|
-
readonly
|
|
560
|
+
readonly approverKind: F.Selection<'role' | 'users' | 'manager' | 'field', { readonly required: true; readonly default: true }>;
|
|
561
|
+
readonly approverRole: F.Char;
|
|
562
|
+
readonly approverUsers: F.Many2many<'res.users', { readonly required: true }>;
|
|
563
|
+
readonly approverField: F.Char;
|
|
564
|
+
readonly quorum: F.Selection<'any' | 'all' | 'count', { readonly required: true; readonly default: true }>;
|
|
565
|
+
readonly quorumCount: F.Integer;
|
|
566
|
+
readonly deadlineHours: F.Integer;
|
|
567
|
+
readonly escalateRole: F.Char;
|
|
509
568
|
};
|
|
510
569
|
readonly methods: ApprovalLevelMethods;
|
|
511
570
|
}
|
|
@@ -514,6 +573,29 @@ export interface ApprovalLevel {
|
|
|
514
573
|
export interface ApprovalLevelMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.level'> {
|
|
515
574
|
}
|
|
516
575
|
|
|
576
|
+
/** `approval.link` (owner: permissions). */
|
|
577
|
+
export interface ApprovalLink {
|
|
578
|
+
readonly name: 'approval.link';
|
|
579
|
+
readonly fields: {
|
|
580
|
+
readonly id: F.Id<'approval.link'>;
|
|
581
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
582
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
583
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
584
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
585
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
586
|
+
readonly request: F.Many2one<'approval.request', { readonly required: true }>;
|
|
587
|
+
readonly user: F.Many2one<'res.users', { readonly required: true }>;
|
|
588
|
+
readonly tokenHash: F.Char<{ readonly required: true }>;
|
|
589
|
+
readonly expiresAt: F.Datetime<{ readonly required: true }>;
|
|
590
|
+
readonly usedAt: F.Datetime;
|
|
591
|
+
};
|
|
592
|
+
readonly methods: ApprovalLinkMethods;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/** Methods of `approval.link`: declared ones and transitions. */
|
|
596
|
+
export interface ApprovalLinkMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.link'> {
|
|
597
|
+
}
|
|
598
|
+
|
|
517
599
|
/** `approval.policy` (owner: permissions). */
|
|
518
600
|
export interface ApprovalPolicy {
|
|
519
601
|
readonly name: 'approval.policy';
|
|
@@ -531,6 +613,9 @@ export interface ApprovalPolicy {
|
|
|
531
613
|
readonly company: F.Many2one<'res.company'>;
|
|
532
614
|
readonly onApproved: F.Char;
|
|
533
615
|
readonly onRejected: F.Char;
|
|
616
|
+
readonly onSentBack: F.Char;
|
|
617
|
+
readonly onWithdrawn: F.Char;
|
|
618
|
+
readonly reasonRequired: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
534
619
|
readonly levels: F.One2many<'approval.level', { readonly required: true }>;
|
|
535
620
|
};
|
|
536
621
|
readonly methods: ApprovalPolicyMethods;
|
|
@@ -557,8 +642,16 @@ export interface ApprovalRequest {
|
|
|
557
642
|
readonly targetModel: F.Char<{ readonly required: true }>;
|
|
558
643
|
readonly targetId: F.Integer<{ readonly required: true }>;
|
|
559
644
|
readonly company: F.Many2one<'res.company'>;
|
|
560
|
-
readonly approverRole: F.Char
|
|
561
|
-
readonly
|
|
645
|
+
readonly approverRole: F.Char;
|
|
646
|
+
readonly approvers: F.Many2many<'res.users', { readonly required: true }>;
|
|
647
|
+
readonly required: F.Integer<{ readonly required: true; readonly default: true }>;
|
|
648
|
+
readonly round: F.Integer<{ readonly required: true; readonly default: true }>;
|
|
649
|
+
readonly votes: F.One2many<'approval.vote', { readonly required: true }>;
|
|
650
|
+
readonly dueAt: F.Datetime;
|
|
651
|
+
readonly remindedAt: F.Datetime;
|
|
652
|
+
readonly escalatedTo: F.Char;
|
|
653
|
+
readonly escalatedAt: F.Datetime;
|
|
654
|
+
readonly state: F.Selection<'pending' | 'approved' | 'rejected' | 'sent_back' | 'cancelled', { readonly required: true; readonly default: true }>;
|
|
562
655
|
readonly requestedBy: F.Many2one<'res.users'>;
|
|
563
656
|
readonly decidedBy: F.Many2one<'res.users'>;
|
|
564
657
|
readonly decidedAt: F.Datetime;
|
|
@@ -571,6 +664,31 @@ export interface ApprovalRequest {
|
|
|
571
664
|
export interface ApprovalRequestMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.request'> {
|
|
572
665
|
}
|
|
573
666
|
|
|
667
|
+
/** `approval.vote` (owner: permissions). */
|
|
668
|
+
export interface ApprovalVote {
|
|
669
|
+
readonly name: 'approval.vote';
|
|
670
|
+
readonly fields: {
|
|
671
|
+
readonly id: F.Id<'approval.vote'>;
|
|
672
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
673
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
674
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
675
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
676
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
677
|
+
readonly request: F.Many2one<'approval.request', { readonly required: true }>;
|
|
678
|
+
readonly user: F.Many2one<'res.users', { readonly required: true }>;
|
|
679
|
+
readonly decision: F.Selection<'approve' | 'reject' | 'send_back', { readonly required: true }>;
|
|
680
|
+
readonly comment: F.Text;
|
|
681
|
+
readonly at: F.Datetime<{ readonly required: true }>;
|
|
682
|
+
readonly onBehalfOf: F.Many2one<'res.users'>;
|
|
683
|
+
readonly ip: F.Char;
|
|
684
|
+
};
|
|
685
|
+
readonly methods: ApprovalVoteMethods;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/** Methods of `approval.vote`: declared ones and transitions. */
|
|
689
|
+
export interface ApprovalVoteMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.vote'> {
|
|
690
|
+
}
|
|
691
|
+
|
|
574
692
|
/** `audit.event` (owner: base). */
|
|
575
693
|
export interface AuditEvent {
|
|
576
694
|
readonly name: 'audit.event';
|
|
@@ -1122,7 +1240,7 @@ export interface PaymentTransaction {
|
|
|
1122
1240
|
readonly company: F.Many2one<'res.company', { readonly required: true; readonly default: true }>;
|
|
1123
1241
|
readonly reference: F.Char<{ readonly required: true; readonly default: true }>;
|
|
1124
1242
|
readonly provider: F.Many2one<'payment.provider', { readonly required: true }>;
|
|
1125
|
-
readonly move: F.Many2one<'account.move'
|
|
1243
|
+
readonly move: F.Many2one<'account.move'>;
|
|
1126
1244
|
readonly partner: F.Many2one<'res.partner'>;
|
|
1127
1245
|
readonly currency: F.Many2one<'res.currency', { readonly required: true }>;
|
|
1128
1246
|
readonly amount: F.Monetary<'currency', { readonly required: true }>;
|
|
@@ -1131,6 +1249,7 @@ export interface PaymentTransaction {
|
|
|
1131
1249
|
readonly payment: F.Many2one<'account.payment'>;
|
|
1132
1250
|
readonly error: F.Text;
|
|
1133
1251
|
readonly doneAt: F.Datetime;
|
|
1252
|
+
readonly returnUrl: F.Char;
|
|
1134
1253
|
};
|
|
1135
1254
|
readonly methods: PaymentTransactionMethods;
|
|
1136
1255
|
}
|
|
@@ -1221,6 +1340,7 @@ export interface ProductCategory {
|
|
|
1221
1340
|
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
1222
1341
|
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
1223
1342
|
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
1343
|
+
readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
1224
1344
|
readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
|
|
1225
1345
|
readonly parent: F.Many2one<'product.category'>;
|
|
1226
1346
|
};
|
package/dist/payment/index.d.ts
CHANGED
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
* - `GET|POST /api/v1/payment/return/:reference` back from the provider: on to the portal
|
|
14
14
|
*
|
|
15
15
|
* The callbacks arrive at `POST /api/v1/hooks/<token>` (the provider's endpoint, made with its first payment).
|
|
16
|
+
* Other apps start payments with `startPayment` (`website_sale`: a shop's checkout) and say what a transaction pays by
|
|
17
|
+
* overriding `payable()` on `payment.transaction`.
|
|
16
18
|
*/
|
|
17
19
|
import { type KoshModule } from '../modules-sdk/index.js';
|
|
20
|
+
import { type Decimal } from '../server/orm.js';
|
|
21
|
+
import type { Env } from './.kosh/bindings.js';
|
|
18
22
|
import { type PaymentAdapter } from './providers.js';
|
|
19
23
|
export { type BkashOptions, bkashAdapter, bkashFromEnvironment } from './bkash.js';
|
|
20
24
|
export { newReference, PaymentProvider, PaymentTransaction, PROVIDERS, paymentShutro, } from './module.js';
|
|
@@ -32,6 +36,43 @@ export interface PaymentOptions {
|
|
|
32
36
|
/** The API's public address: where providers call back (`SHUTRO_ERP_API_URL`). */
|
|
33
37
|
readonly apiUrl?: string;
|
|
34
38
|
}
|
|
39
|
+
export interface StartPayment {
|
|
40
|
+
/** A provider of the company, enabled. */
|
|
41
|
+
readonly provider: number;
|
|
42
|
+
/** The invoice paid; null when another app's document waits for it (its link in `values`). */
|
|
43
|
+
readonly move?: number | null;
|
|
44
|
+
readonly partner: {
|
|
45
|
+
readonly id: number;
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly email?: string | null;
|
|
48
|
+
readonly phone?: string | null;
|
|
49
|
+
readonly mobile?: string | null;
|
|
50
|
+
readonly street?: string | null;
|
|
51
|
+
readonly city?: string | null;
|
|
52
|
+
readonly zip?: string | null;
|
|
53
|
+
readonly country?: unknown;
|
|
54
|
+
} | null;
|
|
55
|
+
readonly currency: {
|
|
56
|
+
readonly id: number;
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly decimalPlaces?: number | null;
|
|
59
|
+
};
|
|
60
|
+
readonly amount: Decimal;
|
|
61
|
+
readonly company: number;
|
|
62
|
+
readonly description: string;
|
|
63
|
+
/** Where the customer goes back to (the portal's document when absent). */
|
|
64
|
+
readonly returnUrl?: string;
|
|
65
|
+
/** More fields of the transaction (another app's link: `saleOrder`). */
|
|
66
|
+
readonly values?: Readonly<Record<string, unknown>>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Starts a payment as the system: a pending transaction for `amount` with the provider, and where to send the
|
|
70
|
+
* customer. The provider must be enabled, configured on this server, and the fake never live.
|
|
71
|
+
*/
|
|
72
|
+
export declare function startPayment(su: Env, input: StartPayment): Promise<{
|
|
73
|
+
reference: string;
|
|
74
|
+
redirectUrl: string;
|
|
75
|
+
}>;
|
|
35
76
|
/** Online payments with explicit options (tests, installations wiring their own adapters). */
|
|
36
77
|
export declare function paymentModule(options?: PaymentOptions): KoshModule;
|
|
37
78
|
/** Online payments (the fake adapter; addresses from the environment). */
|
package/dist/payment/index.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* - `GET|POST /api/v1/payment/return/:reference` back from the provider: on to the portal
|
|
14
14
|
*
|
|
15
15
|
* The callbacks arrive at `POST /api/v1/hooks/<token>` (the provider's endpoint, made with its first payment).
|
|
16
|
+
* Other apps start payments with `startPayment` (`website_sale`: a shop's checkout) and say what a transaction pays by
|
|
17
|
+
* overriding `payable()` on `payment.transaction`.
|
|
16
18
|
*/
|
|
17
19
|
import { accountPortal } from '../account_portal/index.js';
|
|
18
20
|
import { accounting } from '../accounting/index.js';
|
|
@@ -21,7 +23,7 @@ import { defineModule } from '../modules-sdk/index.js';
|
|
|
21
23
|
import { portalDocuments } from '../portal/index.js';
|
|
22
24
|
import { HttpProblem } from '../server/index.js';
|
|
23
25
|
import { orm } from '../server/orm.js';
|
|
24
|
-
import { action, form, list } from '../views/index.js';
|
|
26
|
+
import { action, form, list, search } from '../views/index.js';
|
|
25
27
|
import { bkashFromEnvironment } from './bkash.js';
|
|
26
28
|
import { PaymentProvider, PaymentTransaction, paymentShutro } from './module.js';
|
|
27
29
|
import { ADAPTERS, FAKE_SIGNATURE, fakeAdapter } from './providers.js';
|
|
@@ -56,6 +58,102 @@ function callbackHooks(adapters) {
|
|
|
56
58
|
},
|
|
57
59
|
}));
|
|
58
60
|
}
|
|
61
|
+
/** The adapters and addresses of the running server (set when the routes are registered). */
|
|
62
|
+
let current = null;
|
|
63
|
+
const adapterOf = (code) => {
|
|
64
|
+
const adapter = current?.adapters.get(code);
|
|
65
|
+
if (adapter === undefined)
|
|
66
|
+
throw new HttpProblem(409, 'no-adapter', 'Provider unavailable', `The ${code} adapter is not installed.`);
|
|
67
|
+
return adapter;
|
|
68
|
+
};
|
|
69
|
+
/** The provider's callback endpoint (made on first use), with its token. */
|
|
70
|
+
async function endpointOf(su, provider) {
|
|
71
|
+
const [p] = await su
|
|
72
|
+
.model('payment.provider')
|
|
73
|
+
.browse([provider.id])
|
|
74
|
+
.load({ endpoint: true });
|
|
75
|
+
if (p?.endpoint !== null && p?.endpoint !== undefined)
|
|
76
|
+
return p.endpoint.token;
|
|
77
|
+
const made = await su
|
|
78
|
+
.model('webhook.endpoint')
|
|
79
|
+
.create([{ name: `${provider.name} callbacks`, hook: `payment.${provider.code}` }]);
|
|
80
|
+
await su
|
|
81
|
+
.model('payment.provider')
|
|
82
|
+
.browse([provider.id])
|
|
83
|
+
.write({ endpoint: made.ids[0] });
|
|
84
|
+
const [e] = await made.load({});
|
|
85
|
+
return e?.token ?? '';
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Starts a payment as the system: a pending transaction for `amount` with the provider, and where to send the
|
|
89
|
+
* customer. The provider must be enabled, configured on this server, and the fake never live.
|
|
90
|
+
*/
|
|
91
|
+
export async function startPayment(su, input) {
|
|
92
|
+
if (current === null)
|
|
93
|
+
throw new HttpProblem(503, 'no-payments', 'Payments unavailable', 'Payments are not set up.');
|
|
94
|
+
const urls = current.urls;
|
|
95
|
+
const [provider] = await (await su.model('payment.provider').search({
|
|
96
|
+
where: {
|
|
97
|
+
id: orm.asId(input.provider, 'payment.provider'),
|
|
98
|
+
state: { in: ['test', 'live'] },
|
|
99
|
+
company: orm.asId(input.company, 'res.company'),
|
|
100
|
+
},
|
|
101
|
+
limit: 1,
|
|
102
|
+
})).load({});
|
|
103
|
+
if (provider === undefined)
|
|
104
|
+
throw new HttpProblem(422, 'invalid-provider', 'No such provider', 'Choose one of the providers offered.');
|
|
105
|
+
const adapter = adapterOf(provider.code);
|
|
106
|
+
if (provider.code === 'fake' && provider.state === 'live')
|
|
107
|
+
throw new HttpProblem(409, 'fake-live', 'Test provider', 'The test provider moves no money: it cannot be live.');
|
|
108
|
+
if (!adapter.configured(provider.state === 'live' ? 'live' : 'test'))
|
|
109
|
+
throw new HttpProblem(409, 'not-configured', 'Provider not set up', `The ${provider.name} provider has no credentials for ${provider.state} payments on this server.`);
|
|
110
|
+
const token = await endpointOf(su, provider);
|
|
111
|
+
const created = await su.model('payment.transaction').create([
|
|
112
|
+
{
|
|
113
|
+
...input.values,
|
|
114
|
+
provider: provider.id,
|
|
115
|
+
move: input.move ?? null,
|
|
116
|
+
partner: input.partner?.id ?? null,
|
|
117
|
+
currency: input.currency.id,
|
|
118
|
+
amount: input.amount.toFixed(),
|
|
119
|
+
company: input.company,
|
|
120
|
+
returnUrl: input.returnUrl ?? null,
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
await su.flush(); // company checks run in this superuser scope, not at commit (Shutro request #11)
|
|
124
|
+
const tx = su.model('payment.transaction').browse(created.ids);
|
|
125
|
+
const [t] = await tx.load({});
|
|
126
|
+
const reference = t?.reference ?? '';
|
|
127
|
+
const p = input.partner;
|
|
128
|
+
let started;
|
|
129
|
+
try {
|
|
130
|
+
started = await adapter.createPayment({
|
|
131
|
+
reference,
|
|
132
|
+
amount: input.amount.toFixed(input.currency.decimalPlaces ?? 2),
|
|
133
|
+
currency: input.currency.name,
|
|
134
|
+
description: input.description,
|
|
135
|
+
customer: {
|
|
136
|
+
name: p?.name ?? '',
|
|
137
|
+
email: p?.email ?? null,
|
|
138
|
+
phone: p?.phone ?? p?.mobile ?? null,
|
|
139
|
+
street: p?.street ?? null,
|
|
140
|
+
city: p?.city ?? null,
|
|
141
|
+
zip: p?.zip ?? null,
|
|
142
|
+
country: (p?.country ?? null),
|
|
143
|
+
},
|
|
144
|
+
returnUrl: `${urls.api}/api/v1/payment/return/${encodeURIComponent(reference)}`,
|
|
145
|
+
callbackUrl: `${urls.api}/api/v1/hooks/${token}`,
|
|
146
|
+
mode: provider.state === 'live' ? 'live' : 'test',
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
throw new HttpProblem(502, 'provider-error', 'The payment could not start', error instanceof Error ? error.message : String(error));
|
|
151
|
+
}
|
|
152
|
+
if (started.providerReference !== undefined)
|
|
153
|
+
await tx.write({ providerReference: started.providerReference });
|
|
154
|
+
await su.flush();
|
|
155
|
+
return { reference, redirectUrl: started.redirectUrl };
|
|
156
|
+
}
|
|
59
157
|
function registerPaymentRoutes(context, adapters, urls) {
|
|
60
158
|
const { app } = context;
|
|
61
159
|
const documents = portalDocuments(context.registry);
|
|
@@ -63,30 +161,7 @@ function registerPaymentRoutes(context, adapters, urls) {
|
|
|
63
161
|
if (!env.groups.has('portal.user') || env.groups.has('base.user'))
|
|
64
162
|
throw new HttpProblem(403, 'portal-only', 'Portal users only', 'This is the portal’s API.');
|
|
65
163
|
};
|
|
66
|
-
|
|
67
|
-
const adapter = adapters.get(code);
|
|
68
|
-
if (adapter === undefined)
|
|
69
|
-
throw new HttpProblem(409, 'no-adapter', 'Provider unavailable', `The ${code} adapter is not installed.`);
|
|
70
|
-
return adapter;
|
|
71
|
-
};
|
|
72
|
-
/** The provider's callback endpoint (made on first use), with its token. */
|
|
73
|
-
const endpointOf = async (su, provider) => {
|
|
74
|
-
const [p] = await su
|
|
75
|
-
.model('payment.provider')
|
|
76
|
-
.browse([provider.id])
|
|
77
|
-
.load({ endpoint: true });
|
|
78
|
-
if (p?.endpoint !== null && p?.endpoint !== undefined)
|
|
79
|
-
return p.endpoint.token;
|
|
80
|
-
const made = await su
|
|
81
|
-
.model('webhook.endpoint')
|
|
82
|
-
.create([{ name: `${provider.name} callbacks`, hook: `payment.${provider.code}` }]);
|
|
83
|
-
await su
|
|
84
|
-
.model('payment.provider')
|
|
85
|
-
.browse([provider.id])
|
|
86
|
-
.write({ endpoint: made.ids[0] });
|
|
87
|
-
const [e] = await made.load({});
|
|
88
|
-
return e?.token ?? '';
|
|
89
|
-
};
|
|
164
|
+
current = { adapters, urls };
|
|
90
165
|
app.get('/api/portal/v1/payments/providers', async (request) => request.env((env) => {
|
|
91
166
|
portalOnly(env);
|
|
92
167
|
return env.asSuperuser({ reason: 'portal: payment providers' }, async (su) => {
|
|
@@ -137,11 +212,6 @@ function registerPaymentRoutes(context, adapters, urls) {
|
|
|
137
212
|
})).load({});
|
|
138
213
|
if (provider === undefined)
|
|
139
214
|
throw new HttpProblem(422, 'invalid-provider', 'No such provider', 'Choose one of the providers offered.');
|
|
140
|
-
const adapter = adapterOf(provider.code);
|
|
141
|
-
if (provider.code === 'fake' && provider.state === 'live')
|
|
142
|
-
throw new HttpProblem(409, 'fake-live', 'Test provider', 'The test provider moves no money: it cannot be live.');
|
|
143
|
-
if (!adapter.configured(provider.state === 'live' ? 'live' : 'test'))
|
|
144
|
-
throw new HttpProblem(409, 'not-configured', 'Provider not set up', `The ${provider.name} provider has no credentials for ${provider.state} payments on this server.`);
|
|
145
215
|
const [move] = await su
|
|
146
216
|
.model('account.move')
|
|
147
217
|
.browse([id])
|
|
@@ -151,48 +221,15 @@ function registerPaymentRoutes(context, adapters, urls) {
|
|
|
151
221
|
const due = move.amountResidual?.amount;
|
|
152
222
|
if (due === undefined || !due.gt(0))
|
|
153
223
|
throw new HttpProblem(409, 'not-payable', 'Nothing to pay', 'Nothing is due on this document.');
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
},
|
|
164
|
-
]);
|
|
165
|
-
await su.flush(); // company checks run in this superuser scope, not at commit (Shutro request #11)
|
|
166
|
-
const [tx] = await created.load({});
|
|
167
|
-
const reference = tx?.reference ?? '';
|
|
168
|
-
let started;
|
|
169
|
-
try {
|
|
170
|
-
started = await adapter.createPayment({
|
|
171
|
-
reference,
|
|
172
|
-
amount: due.toFixed(move.currency.decimalPlaces ?? 2),
|
|
173
|
-
currency: move.currency.name,
|
|
174
|
-
description: `${d.spec.label} ${move.name}`,
|
|
175
|
-
customer: {
|
|
176
|
-
name: move.partner?.name ?? '',
|
|
177
|
-
email: move.partner?.email ?? null,
|
|
178
|
-
phone: move.partner?.phone ?? move.partner?.mobile ?? null,
|
|
179
|
-
street: move.partner?.street ?? null,
|
|
180
|
-
city: move.partner?.city ?? null,
|
|
181
|
-
zip: move.partner?.zip ?? null,
|
|
182
|
-
country: move.partner?.country ?? null,
|
|
183
|
-
},
|
|
184
|
-
returnUrl: `${urls.api}/api/v1/payment/return/${encodeURIComponent(reference)}`,
|
|
185
|
-
callbackUrl: `${urls.api}/api/v1/hooks/${token}`,
|
|
186
|
-
mode: provider.state === 'live' ? 'live' : 'test',
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
throw new HttpProblem(502, 'provider-error', 'The payment could not start', error instanceof Error ? error.message : String(error));
|
|
191
|
-
}
|
|
192
|
-
if (started.providerReference !== undefined)
|
|
193
|
-
await created.write({ providerReference: started.providerReference });
|
|
194
|
-
await su.flush();
|
|
195
|
-
return { reference, redirectUrl: started.redirectUrl };
|
|
224
|
+
return startPayment(su, {
|
|
225
|
+
provider: provider.id,
|
|
226
|
+
move: move.id,
|
|
227
|
+
partner: move.partner,
|
|
228
|
+
currency: move.currency,
|
|
229
|
+
amount: due,
|
|
230
|
+
company,
|
|
231
|
+
description: `${d.spec.label} ${move.name}`,
|
|
232
|
+
});
|
|
196
233
|
});
|
|
197
234
|
return reply.status(201).send(started);
|
|
198
235
|
});
|
|
@@ -210,7 +247,7 @@ function registerPaymentRoutes(context, adapters, urls) {
|
|
|
210
247
|
return t === undefined
|
|
211
248
|
? null
|
|
212
249
|
: {
|
|
213
|
-
move: t.move
|
|
250
|
+
move: t.move?.id ?? 0,
|
|
214
251
|
state: t.state,
|
|
215
252
|
amount: t.amount.amount.toFixed(t.currency.decimalPlaces ?? 2),
|
|
216
253
|
currency: t.currency.name,
|
|
@@ -294,7 +331,8 @@ function registerPaymentRoutes(context, adapters, urls) {
|
|
|
294
331
|
return t === undefined
|
|
295
332
|
? null
|
|
296
333
|
: {
|
|
297
|
-
move: t.move
|
|
334
|
+
move: t.move?.id ?? null,
|
|
335
|
+
returnUrl: t.returnUrl,
|
|
298
336
|
company: t.company.id,
|
|
299
337
|
state: t.state,
|
|
300
338
|
code: t.provider.code,
|
|
@@ -322,6 +360,8 @@ function registerPaymentRoutes(context, adapters, urls) {
|
|
|
322
360
|
}
|
|
323
361
|
}
|
|
324
362
|
const move = tx?.move ?? null;
|
|
363
|
+
if (tx?.returnUrl !== null && tx?.returnUrl !== undefined && tx.returnUrl !== '')
|
|
364
|
+
return reply.redirect(`${tx.returnUrl}${tx.returnUrl.includes('?') ? '&' : '?'}payment=${encodeURIComponent(reference)}`, 303);
|
|
325
365
|
return reply.redirect(move === null
|
|
326
366
|
? `${urls.portal}/`
|
|
327
367
|
: `${urls.portal}/d/${encodeURIComponent(payable)}/${move}?payment=${encodeURIComponent(reference)}`, 303);
|
|
@@ -391,11 +431,27 @@ export function paymentModule(options = {}) {
|
|
|
391
431
|
sequence: 3.7,
|
|
392
432
|
},
|
|
393
433
|
],
|
|
434
|
+
search: {
|
|
435
|
+
'payment.provider': search(PaymentProvider, {
|
|
436
|
+
fields: ['name'],
|
|
437
|
+
groupBy: ['code', 'state'],
|
|
438
|
+
}),
|
|
439
|
+
'payment.transaction': search(PaymentTransaction, {
|
|
440
|
+
fields: ['reference', 'providerReference', 'partner.name'],
|
|
441
|
+
filters: {
|
|
442
|
+
done: { label: 'Done', domain: { state: 'done' }, group: 'state' },
|
|
443
|
+
pending: { label: 'Pending', domain: { state: 'pending' }, group: 'state' },
|
|
444
|
+
failed: { label: 'Failed', domain: { state: 'failed' }, group: 'state' },
|
|
445
|
+
},
|
|
446
|
+
groupBy: ['provider', 'state', 'doneAt:month'],
|
|
447
|
+
}),
|
|
448
|
+
},
|
|
394
449
|
views: {
|
|
395
450
|
'payment.provider.list': list(PaymentProvider, {
|
|
396
451
|
columns: ['name', 'code', 'state', 'journal'],
|
|
397
452
|
}),
|
|
398
453
|
'payment.provider.form': form(PaymentProvider, (k) => ({
|
|
454
|
+
chatter: true,
|
|
399
455
|
sheet: [
|
|
400
456
|
k.group('main', ['name', 'code', 'state']),
|
|
401
457
|
k.group('accounting', ['journal', 'sequence', 'endpoint']),
|
|
@@ -405,6 +461,7 @@ export function paymentModule(options = {}) {
|
|
|
405
461
|
columns: ['reference', 'move', 'partner', 'provider', 'amount', 'state', 'doneAt'],
|
|
406
462
|
}),
|
|
407
463
|
'payment.transaction.form': form(PaymentTransaction, (k) => ({
|
|
464
|
+
chatter: true,
|
|
408
465
|
sheet: [
|
|
409
466
|
k.group('main', ['reference', 'move', 'partner', 'provider']),
|
|
410
467
|
k.group('outcome', [
|