shutro-erp 0.3.6 → 0.3.7
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.js +1 -1
- package/dist/account_asset/.kosh/schema.d.ts +530 -8
- package/dist/account_asset/i18n/bn.d.ts +2 -0
- package/dist/account_asset/i18n/bn.js +97 -0
- package/dist/account_asset/index.js +2 -0
- package/dist/account_asset/module.d.ts +4899 -1445
- package/dist/account_budget/.kosh/bindings.js +1 -1
- package/dist/account_budget/.kosh/schema.d.ts +1130 -56
- package/dist/account_budget/i18n/bn.d.ts +2 -0
- package/dist/account_budget/i18n/bn.js +63 -0
- package/dist/account_budget/index.js +14 -0
- package/dist/account_budget/module.d.ts +17958 -4532
- package/dist/account_budget/module.js +15 -0
- package/dist/account_portal/.kosh/bindings.js +1 -1
- package/dist/account_portal/.kosh/schema.d.ts +530 -8
- package/dist/account_portal/i18n/bn.d.ts +2 -0
- package/dist/account_portal/i18n/bn.js +6 -0
- package/dist/account_portal/index.js +2 -0
- package/dist/account_portal/module.d.ts +5167 -1693
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +530 -8
- package/dist/accounting/closing.js +1 -0
- package/dist/accounting/fiscal.d.ts +578 -0
- package/dist/accounting/fiscal.js +401 -0
- package/dist/accounting/followups.d.ts +618 -0
- package/dist/accounting/followups.js +420 -0
- package/dist/accounting/i18n/bn.d.ts +2 -0
- package/dist/accounting/i18n/bn.js +425 -0
- package/dist/accounting/index.d.ts +2 -0
- package/dist/accounting/index.js +649 -2
- package/dist/accounting/module.d.ts +4998 -1451
- package/dist/accounting/module.js +124 -18
- package/dist/accounting/statements.d.ts +878 -0
- package/dist/accounting/statements.js +728 -0
- package/dist/accounting/web/BankReconcilePage.d.ts +9 -0
- package/dist/accounting/web/BankReconcilePage.js +138 -0
- package/dist/accounting/web/FollowupsPage.d.ts +8 -0
- package/dist/accounting/web/FollowupsPage.js +54 -0
- package/dist/accounting/web/PostingPreview.d.ts +8 -0
- package/dist/accounting/web/PostingPreview.js +26 -0
- package/dist/accounting/web/index.d.ts +3 -0
- package/dist/accounting/web/index.js +9 -0
- package/dist/accounting/web/messages.js +140 -0
- package/dist/approvals/.kosh/bindings.js +1 -1
- package/dist/approvals/.kosh/schema.d.ts +272 -4
- package/dist/approvals/demo.d.ts +7 -0
- package/dist/approvals/demo.js +41 -0
- package/dist/approvals/i18n/bn.d.ts +2 -0
- package/dist/approvals/i18n/bn.js +133 -0
- package/dist/approvals/index.d.ts +19 -1
- package/dist/approvals/index.js +477 -7
- package/dist/approvals/mails.d.ts +7 -2
- package/dist/approvals/mails.js +8 -3
- package/dist/approvals/module.d.ts +2930 -1
- package/dist/approvals/module.js +468 -7
- package/dist/approvals/web/Config.d.ts +12 -0
- package/dist/approvals/web/Config.js +60 -0
- package/dist/approvals/web/Matrix.d.ts +9 -0
- package/dist/approvals/web/Matrix.js +26 -0
- package/dist/approvals/web/index.d.ts +3 -1
- package/dist/approvals/web/index.js +8 -1
- package/dist/approvals/web/messages.js +92 -0
- package/dist/approvals_purchase/.kosh/bindings.js +15 -0
- package/dist/approvals_purchase/.kosh/schema.d.ts +1997 -0
- package/dist/approvals_purchase/i18n/bn.d.ts +2 -0
- package/dist/approvals_purchase/i18n/bn.js +5 -0
- package/dist/approvals_purchase/index.d.ts +3 -0
- package/dist/approvals_purchase/index.js +47 -0
- package/dist/approvals_purchase/module.d.ts +12670 -0
- package/dist/approvals_purchase/module.js +84 -0
- package/dist/attendance/.kosh/bindings.js +1 -1
- package/dist/attendance/.kosh/schema.d.ts +59 -1
- package/dist/attendance/i18n/bn.d.ts +2 -0
- package/dist/attendance/i18n/bn.js +147 -0
- package/dist/attendance/index.js +3 -1
- package/dist/attendance/module.d.ts +452 -8
- package/dist/automation/engine.js +1 -1
- package/dist/calendar/.kosh/bindings.js +1 -1
- package/dist/calendar/.kosh/schema.d.ts +2 -1
- package/dist/calendar/i18n/bn.d.ts +2 -0
- package/dist/calendar/i18n/bn.js +80 -0
- package/dist/calendar/index.js +77 -0
- package/dist/calendar/module.d.ts +26 -0
- package/dist/calendar/module.js +14 -4
- package/dist/cli/apps.js +25 -5
- package/dist/cli/init.js +14 -4
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +34 -5
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +2 -1
- package/dist/contacts/i18n/bn.d.ts +2 -0
- package/dist/contacts/i18n/bn.js +67 -0
- package/dist/contacts/index.js +3 -0
- package/dist/contacts/module.d.ts +42 -0
- package/dist/contacts/module.js +6 -1
- package/dist/crm/.kosh/bindings.js +1 -1
- package/dist/crm/.kosh/schema.d.ts +2 -1
- package/dist/crm/i18n/bn.d.ts +2 -0
- package/dist/crm/i18n/bn.js +80 -0
- package/dist/crm/index.js +22 -0
- package/dist/crm/module.d.ts +20 -0
- package/dist/crm/module.js +4 -2
- package/dist/documents/.kosh/bindings.js +1 -1
- package/dist/documents/.kosh/schema.d.ts +2 -1
- package/dist/documents/i18n/bn.d.ts +2 -0
- package/dist/documents/i18n/bn.js +83 -0
- package/dist/documents/index.js +128 -1
- package/dist/documents/module.d.ts +20 -0
- package/dist/documents/module.js +1 -0
- package/dist/event/.kosh/bindings.js +1 -1
- package/dist/event/.kosh/schema.d.ts +2 -1
- package/dist/event/i18n/bn.d.ts +2 -0
- package/dist/event/i18n/bn.js +101 -0
- package/dist/event/index.js +66 -0
- package/dist/event/module.d.ts +20 -0
- package/dist/event/module.js +8 -1
- package/dist/event_account/.kosh/bindings.js +1 -1
- package/dist/event_account/.kosh/schema.d.ts +530 -8
- package/dist/event_account/i18n/bn.d.ts +2 -0
- package/dist/event_account/i18n/bn.js +5 -0
- package/dist/event_account/index.js +2 -0
- package/dist/event_account/module.d.ts +4905 -1431
- package/dist/expense/.kosh/bindings.js +1 -1
- package/dist/expense/.kosh/schema.d.ts +323 -2
- package/dist/expense/i18n/bn.d.ts +2 -0
- package/dist/expense/i18n/bn.js +155 -0
- package/dist/expense/index.js +8 -1
- package/dist/expense/module.d.ts +2715 -694
- package/dist/expense/module.js +3 -1
- package/dist/expense_account/.kosh/bindings.js +1 -1
- package/dist/expense_account/.kosh/schema.d.ts +587 -8
- package/dist/expense_account/i18n/bn.d.ts +2 -0
- package/dist/expense_account/i18n/bn.js +15 -0
- package/dist/expense_account/index.js +2 -0
- package/dist/expense_account/module.d.ts +8094 -2619
- package/dist/helpdesk/.kosh/bindings.js +1 -1
- package/dist/helpdesk/.kosh/schema.d.ts +2 -1
- package/dist/helpdesk/i18n/bn.d.ts +2 -0
- package/dist/helpdesk/i18n/bn.js +127 -0
- package/dist/helpdesk/index.js +2 -0
- package/dist/helpdesk/module.d.ts +20 -0
- package/dist/hr/.kosh/bindings.js +1 -1
- package/dist/hr/.kosh/schema.d.ts +59 -1
- package/dist/hr/demo.js +11 -1
- package/dist/hr/i18n/bn.d.ts +2 -0
- package/dist/hr/i18n/bn.js +126 -0
- package/dist/hr/index.d.ts +1 -1
- package/dist/hr/index.js +158 -12
- package/dist/hr/module.d.ts +932 -59
- package/dist/hr/module.js +114 -17
- package/dist/{mrp → indent}/.kosh/bindings.js +2 -2
- package/dist/indent/.kosh/schema.d.ts +2084 -0
- package/dist/indent/demo.d.ts +7 -0
- package/dist/indent/demo.js +48 -0
- package/dist/indent/i18n/bn.d.ts +2 -0
- package/dist/indent/i18n/bn.js +143 -0
- package/dist/indent/index.d.ts +3 -0
- package/dist/indent/index.js +450 -0
- package/dist/{mrp → indent}/module.d.ts +7164 -3075
- package/dist/indent/module.js +792 -0
- package/dist/indent_purchase/.kosh/bindings.d.ts +22 -0
- package/dist/indent_purchase/.kosh/bindings.js +15 -0
- package/dist/indent_purchase/.kosh/schema.d.ts +2710 -0
- package/dist/indent_purchase/i18n/bn.d.ts +2 -0
- package/dist/indent_purchase/i18n/bn.js +13 -0
- package/dist/indent_purchase/index.d.ts +3 -0
- package/dist/indent_purchase/index.js +61 -0
- package/dist/indent_purchase/module.d.ts +27950 -0
- package/dist/indent_purchase/module.js +163 -0
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +530 -8
- package/dist/l10n_bd/i18n/bn.d.ts +2 -0
- package/dist/l10n_bd/i18n/bn.js +69 -0
- package/dist/l10n_bd/index.js +2 -0
- package/dist/l10n_bd/module.d.ts +5167 -1693
- package/dist/l10n_bd_payroll/.kosh/bindings.js +1 -1
- package/dist/l10n_bd_payroll/.kosh/schema.d.ts +587 -8
- package/dist/l10n_bd_payroll/i18n/bn.d.ts +2 -0
- package/dist/l10n_bd_payroll/i18n/bn.js +4 -0
- package/dist/l10n_bd_payroll/index.js +2 -0
- package/dist/l10n_bd_payroll/module.d.ts +5910 -1548
- package/dist/l10n_bd_pos/.kosh/bindings.d.ts +22 -0
- package/dist/{mrp_account → l10n_bd_pos}/.kosh/bindings.js +2 -2
- package/dist/{mrp_account → l10n_bd_pos}/.kosh/schema.d.ts +693 -651
- package/dist/l10n_bd_pos/i18n/bn.d.ts +2 -0
- package/dist/l10n_bd_pos/i18n/bn.js +32 -0
- package/dist/l10n_bd_pos/index.d.ts +3 -0
- package/dist/l10n_bd_pos/index.js +111 -0
- package/dist/{mrp_account → l10n_bd_pos}/module.d.ts +7402 -7647
- package/dist/l10n_bd_pos/module.js +43 -0
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +530 -8
- package/dist/l10n_in/i18n/bn.d.ts +2 -0
- package/dist/l10n_in/i18n/bn.js +95 -0
- package/dist/l10n_in/index.js +2 -0
- package/dist/l10n_in/module.d.ts +6703 -1652
- package/dist/l10n_in/module.js +25 -5
- package/dist/l10n_in/web/GstSettings.js +2 -2
- package/dist/mail/inbound/handle.js +2 -4
- package/dist/mail/inbound/models.js +5 -3
- package/dist/mail/index.d.ts +12 -1
- package/dist/mail/index.js +139 -2
- package/dist/mail/send.d.ts +56 -0
- package/dist/mail/send.js +394 -0
- package/dist/mail/web/SendButton.d.ts +9 -0
- package/dist/mail/web/SendButton.js +71 -0
- package/dist/mail/web/SendSelected.d.ts +8 -0
- package/dist/mail/web/SendSelected.js +33 -0
- package/dist/mail/web/index.d.ts +2 -0
- package/dist/mail/web/index.js +6 -0
- package/dist/mail/web/messages.js +36 -0
- package/dist/maintenance/.kosh/bindings.js +1 -1
- package/dist/maintenance/.kosh/schema.d.ts +2 -1
- package/dist/maintenance/i18n/bn.d.ts +2 -0
- package/dist/maintenance/i18n/bn.js +132 -0
- package/dist/maintenance/index.js +85 -0
- package/dist/maintenance/module.d.ts +25 -0
- package/dist/maintenance/module.js +27 -9
- package/dist/maintenance_stock/.kosh/bindings.js +1 -1
- package/dist/maintenance_stock/.kosh/schema.d.ts +298 -2
- package/dist/maintenance_stock/i18n/bn.d.ts +2 -0
- package/dist/maintenance_stock/i18n/bn.js +21 -0
- package/dist/maintenance_stock/index.js +2 -0
- package/dist/maintenance_stock/module.d.ts +5302 -1256
- package/dist/maintenance_stock/module.js +1 -0
- package/dist/modules-sdk/apps.d.ts +10 -0
- package/dist/modules-sdk/apps.js +32 -0
- package/dist/modules-sdk/index.d.ts +1 -1
- package/dist/modules-sdk/manifest.d.ts +68 -2
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +530 -8
- package/dist/payment/i18n/bn.d.ts +2 -0
- package/dist/payment/i18n/bn.js +59 -0
- package/dist/payment/index.js +85 -0
- package/dist/payment/module.d.ts +5134 -1660
- package/dist/payment/module.js +17 -3
- package/dist/payment/settle.js +1 -0
- package/dist/payroll/.kosh/bindings.js +1 -1
- package/dist/payroll/.kosh/schema.d.ts +59 -1
- package/dist/payroll/i18n/bn.d.ts +2 -0
- package/dist/payroll/i18n/bn.js +206 -0
- package/dist/payroll/index.js +2 -0
- package/dist/payroll/module.d.ts +936 -48
- package/dist/payroll_account/.kosh/bindings.js +1 -1
- package/dist/payroll_account/.kosh/schema.d.ts +587 -8
- package/dist/payroll_account/i18n/bn.d.ts +2 -0
- package/dist/payroll_account/i18n/bn.js +10 -0
- package/dist/payroll_account/index.js +2 -0
- package/dist/payroll_account/module.d.ts +7534 -3192
- package/dist/permissions/approvals.d.ts +97 -4
- package/dist/permissions/approvals.js +780 -31
- package/dist/permissions/index.d.ts +1 -1
- package/dist/permissions/index.js +2 -2
- package/dist/permissions/models.js +177 -5
- package/dist/permissions/routes.d.ts +3 -0
- package/dist/permissions/routes.js +36 -2
- package/dist/permissions/web/ApprovalPanel.js +43 -5
- package/dist/permissions/web/messages.js +52 -0
- package/dist/portal/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +2 -1
- package/dist/portal/documents.d.ts +3 -0
- package/dist/portal/documents.js +21 -1
- package/dist/portal/i18n/bn.d.ts +2 -0
- package/dist/portal/i18n/bn.js +33 -0
- package/dist/portal/index.js +2 -0
- package/dist/portal/module.d.ts +20 -0
- package/dist/portal/routes-documents.js +76 -0
- package/dist/pos/.kosh/bindings.js +1 -1
- package/dist/pos/.kosh/schema.d.ts +531 -8
- package/dist/pos/i18n/bn.d.ts +2 -0
- package/dist/pos/i18n/bn.js +133 -0
- package/dist/pos/index.js +83 -1
- package/dist/pos/module.d.ts +6888 -1777
- package/dist/pos/module.js +49 -5
- package/dist/pos/routes.js +80 -7
- package/dist/pos/web/Register.js +2 -5
- package/dist/pos_stock/.kosh/bindings.js +1 -1
- package/dist/pos_stock/.kosh/schema.d.ts +626 -9
- package/dist/pos_stock/i18n/bn.d.ts +2 -0
- package/dist/pos_stock/i18n/bn.js +6 -0
- package/dist/pos_stock/index.js +2 -0
- package/dist/pos_stock/module.d.ts +10798 -3276
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +202 -1
- package/dist/product/i18n/bn.d.ts +2 -0
- package/dist/product/i18n/bn.js +175 -0
- package/dist/product/index.d.ts +1 -0
- package/dist/product/index.js +288 -1
- package/dist/product/module.d.ts +1725 -0
- package/dist/product/module.js +66 -6
- package/dist/product/pricelist.d.ts +575 -0
- package/dist/product/pricelist.js +257 -0
- package/dist/product/variants.d.ts +908 -0
- package/dist/product/variants.js +251 -0
- package/dist/production/.kosh/bindings.d.ts +22 -0
- package/dist/production/.kosh/bindings.js +15 -0
- package/dist/production/.kosh/schema.d.ts +2345 -0
- package/dist/{mrp → production}/demo.d.ts +1 -1
- package/dist/{mrp → production}/demo.js +5 -5
- package/dist/production/depth.d.ts +790 -0
- package/dist/production/depth.js +262 -0
- package/dist/production/i18n/bn.d.ts +2 -0
- package/dist/production/i18n/bn.js +350 -0
- package/dist/production/index.d.ts +6 -0
- package/dist/production/index.js +1256 -0
- package/dist/production/module.d.ts +17327 -0
- package/dist/production/module.js +1333 -0
- package/dist/production/plan.d.ts +921 -0
- package/dist/production/plan.js +511 -0
- package/dist/production/schedule.d.ts +656 -0
- package/dist/production/schedule.js +309 -0
- package/dist/production_account/.kosh/bindings.d.ts +22 -0
- package/dist/production_account/.kosh/bindings.js +15 -0
- package/dist/production_account/.kosh/schema.d.ts +3496 -0
- package/dist/production_account/i18n/bn.d.ts +2 -0
- package/dist/production_account/i18n/bn.js +93 -0
- package/dist/production_account/index.d.ts +4 -0
- package/dist/production_account/index.js +246 -0
- package/dist/production_account/module.d.ts +1192 -0
- package/dist/{mrp_account → production_account}/module.js +72 -18
- package/dist/production_account/overhead.d.ts +1195 -0
- package/dist/production_account/overhead.js +554 -0
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +65 -2
- package/dist/project/i18n/bn.d.ts +2 -0
- package/dist/project/i18n/bn.js +383 -0
- package/dist/project/index.js +123 -0
- package/dist/project/module.d.ts +20 -0
- package/dist/project/module.js +73 -14
- package/dist/project_account/.kosh/bindings.js +1 -1
- package/dist/project_account/.kosh/schema.d.ts +530 -8
- package/dist/project_account/i18n/bn.d.ts +2 -0
- package/dist/project_account/i18n/bn.js +6 -0
- package/dist/project_account/index.js +2 -0
- package/dist/project_account/module.d.ts +4926 -1452
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +65 -2
- package/dist/project_portal/i18n/bn.d.ts +2 -0
- package/dist/project_portal/i18n/bn.js +6 -0
- package/dist/project_portal/index.js +2 -0
- package/dist/project_portal/module.d.ts +40 -0
- package/dist/project_purchase/.kosh/bindings.js +1 -1
- package/dist/project_purchase/.kosh/schema.d.ts +1126 -53
- package/dist/project_purchase/i18n/bn.d.ts +2 -0
- package/dist/project_purchase/i18n/bn.js +4 -0
- package/dist/project_purchase/index.js +2 -0
- package/dist/project_purchase/module.d.ts +17912 -4446
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +813 -3
- package/dist/purchase/comparison.d.ts +993 -0
- package/dist/purchase/comparison.js +415 -0
- package/dist/purchase/extras.d.ts +1509 -0
- package/dist/purchase/extras.js +445 -0
- package/dist/purchase/i18n/bn.d.ts +2 -0
- package/dist/purchase/i18n/bn.js +413 -0
- package/dist/purchase/index.d.ts +5 -0
- package/dist/purchase/index.js +1280 -4
- package/dist/purchase/module.d.ts +7139 -398
- package/dist/purchase/module.js +295 -11
- package/dist/purchase/request.d.ts +696 -0
- package/dist/purchase/request.js +446 -0
- package/dist/purchase/tender.d.ts +1208 -0
- package/dist/purchase/tender.js +507 -0
- package/dist/purchase/vendorprice.d.ts +340 -0
- package/dist/purchase/vendorprice.js +153 -0
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +1130 -57
- package/dist/purchase_account/i18n/bn.d.ts +2 -0
- package/dist/purchase_account/i18n/bn.js +22 -0
- package/dist/purchase_account/index.js +19 -0
- package/dist/purchase_account/module.d.ts +12276 -2247
- package/dist/purchase_account/module.js +241 -9
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +813 -3
- package/dist/purchase_portal/i18n/bn.d.ts +2 -0
- package/dist/purchase_portal/i18n/bn.js +5 -0
- package/dist/purchase_portal/index.js +2 -0
- package/dist/purchase_portal/module.d.ts +6849 -353
- package/dist/purchase_stock/.kosh/bindings.js +1 -1
- package/dist/purchase_stock/.kosh/schema.d.ts +910 -4
- package/dist/purchase_stock/i18n/bn.d.ts +2 -0
- package/dist/purchase_stock/i18n/bn.js +19 -0
- package/dist/purchase_stock/index.d.ts +1 -1
- package/dist/purchase_stock/index.js +29 -0
- package/dist/purchase_stock/module.d.ts +12410 -1864
- package/dist/purchase_stock/module.js +81 -9
- package/dist/purchase_stock/scorecard.d.ts +22 -0
- package/dist/purchase_stock/scorecard.js +77 -0
- package/dist/purchase_stock/web/Scorecard.d.ts +7 -0
- package/dist/purchase_stock/web/Scorecard.js +22 -0
- package/dist/purchase_stock/web/index.d.ts +11 -0
- package/dist/purchase_stock/web/index.js +16 -0
- package/dist/purchase_stock/web/messages.d.ts +2 -0
- package/dist/purchase_stock/web/messages.js +27 -0
- package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
- package/dist/purchase_stock_account/.kosh/schema.d.ts +1286 -58
- package/dist/purchase_stock_account/i18n/bn.d.ts +2 -0
- package/dist/purchase_stock_account/i18n/bn.js +8 -0
- package/dist/purchase_stock_account/index.js +18 -0
- package/dist/purchase_stock_account/module.d.ts +7 -37995
- package/dist/purchase_stock_account/module.js +24 -3
- package/dist/recruitment/.kosh/bindings.js +1 -1
- package/dist/recruitment/.kosh/schema.d.ts +59 -1
- package/dist/recruitment/i18n/bn.d.ts +2 -0
- package/dist/recruitment/i18n/bn.js +93 -0
- package/dist/recruitment/index.js +64 -0
- package/dist/recruitment/module.d.ts +458 -8
- package/dist/recruitment/module.js +11 -3
- package/dist/reporting/documents.d.ts +5 -0
- package/dist/reporting/documents.js +11 -1
- package/dist/reporting/index.d.ts +1 -1
- package/dist/reporting/index.js +1 -1
- package/dist/reporting/web/CalendarView.d.ts +18 -5
- package/dist/reporting/web/CalendarView.js +163 -29
- package/dist/reporting/web/messages.js +18 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +642 -16
- package/dist/sale_account/i18n/bn.d.ts +2 -0
- package/dist/sale_account/i18n/bn.js +48 -0
- package/dist/sale_account/index.d.ts +1 -1
- package/dist/sale_account/index.js +102 -4
- package/dist/sale_account/module.d.ts +8254 -2212
- package/dist/sale_account/module.js +535 -46
- package/dist/sale_crm/.kosh/bindings.d.ts +22 -0
- package/dist/sale_crm/.kosh/bindings.js +15 -0
- package/dist/{mrp → sale_crm}/.kosh/schema.d.ts +389 -567
- package/dist/sale_crm/i18n/bn.d.ts +2 -0
- package/dist/sale_crm/i18n/bn.js +9 -0
- package/dist/sale_crm/index.d.ts +7 -0
- package/dist/sale_crm/index.js +104 -0
- package/dist/sale_crm/module.d.ts +5609 -0
- package/dist/sale_crm/module.js +73 -0
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +291 -4
- package/dist/sale_portal/i18n/bn.d.ts +2 -0
- package/dist/sale_portal/i18n/bn.js +7 -0
- package/dist/sale_portal/index.js +10 -0
- package/dist/sale_portal/module.d.ts +2564 -294
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +354 -5
- package/dist/sale_project/i18n/bn.d.ts +2 -0
- package/dist/sale_project/i18n/bn.js +12 -0
- package/dist/sale_project/index.js +2 -0
- package/dist/sale_project/module.d.ts +6249 -2402
- package/dist/sale_stock/.kosh/bindings.js +1 -1
- package/dist/sale_stock/.kosh/schema.d.ts +387 -5
- package/dist/sale_stock/i18n/bn.d.ts +2 -0
- package/dist/sale_stock/i18n/bn.js +15 -0
- package/dist/sale_stock/index.js +2 -0
- package/dist/sale_stock/module.d.ts +8057 -1759
- package/dist/sale_stock/module.js +20 -3
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +291 -4
- package/dist/sales/i18n/bn.d.ts +2 -0
- package/dist/sales/i18n/bn.js +128 -0
- package/dist/sales/index.js +120 -5
- package/dist/sales/module.d.ts +3567 -633
- package/dist/sales/module.js +306 -11
- package/dist/server/api/duplicate.d.ts +14 -0
- package/dist/server/api/duplicate.js +75 -0
- package/dist/server/api/explain.d.ts +70 -0
- package/dist/server/api/explain.js +111 -0
- package/dist/server/api/metadata.d.ts +2 -0
- package/dist/server/api/metadata.js +9 -0
- package/dist/server/api/openapi.js +15 -0
- package/dist/server/api/rest.d.ts +1 -0
- package/dist/server/api/rest.js +76 -12
- package/dist/server/api/views.js +1 -1
- package/dist/server/apps.d.ts +16 -1
- package/dist/server/apps.js +164 -2
- package/dist/server/auth/base.js +2 -0
- package/dist/server/auth/service.d.ts +8 -0
- package/dist/server/auth/service.js +19 -0
- package/dist/server/events.d.ts +13 -0
- package/dist/server/events.js +22 -0
- package/dist/server/i18n.d.ts +27 -0
- package/dist/server/i18n.js +143 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/server.js +6 -0
- package/dist/settings/company.d.ts +3 -1
- package/dist/settings/company.js +26 -5
- package/dist/settings/routes.d.ts +10 -0
- package/dist/settings/routes.js +19 -3
- package/dist/settings/web/AppsPage.d.ts +3 -2
- package/dist/settings/web/AppsPage.js +26 -8
- package/dist/settings/web/CompaniesPage.js +91 -6
- package/dist/settings/web/messages.js +64 -0
- package/dist/sign/.kosh/bindings.js +1 -1
- package/dist/sign/.kosh/schema.d.ts +2 -1
- package/dist/sign/i18n/bn.d.ts +2 -0
- package/dist/sign/i18n/bn.js +97 -0
- package/dist/sign/index.d.ts +15 -0
- package/dist/sign/index.js +129 -1
- package/dist/sign/module.d.ts +40 -0
- package/dist/sign/module.js +11 -2
- package/dist/stock/.kosh/bindings.js +1 -1
- package/dist/stock/.kosh/schema.d.ts +298 -2
- package/dist/stock/i18n/bn.d.ts +2 -0
- package/dist/stock/i18n/bn.js +311 -0
- package/dist/stock/index.d.ts +3 -1
- package/dist/stock/index.js +442 -3
- package/dist/stock/ledger.d.ts +78 -0
- package/dist/stock/ledger.js +582 -0
- package/dist/stock/module.d.ts +5280 -2044
- package/dist/stock/module.js +222 -23
- package/dist/stock/replenish.js +16 -1
- package/dist/stock/returns.d.ts +157 -0
- package/dist/stock/returns.js +163 -0
- package/dist/stock/web/Ledger.d.ts +9 -0
- package/dist/stock/web/Ledger.js +108 -0
- package/dist/stock/web/Operations.d.ts +8 -0
- package/dist/stock/web/Operations.js +33 -0
- package/dist/stock/web/ReturnButton.d.ts +7 -0
- package/dist/stock/web/ReturnButton.js +62 -0
- package/dist/stock/web/index.d.ts +3 -0
- package/dist/stock/web/index.js +9 -0
- package/dist/stock/web/messages.js +154 -0
- package/dist/stock_account/.kosh/bindings.js +1 -1
- package/dist/stock_account/.kosh/schema.d.ts +682 -9
- package/dist/stock_account/i18n/bn.d.ts +2 -0
- package/dist/stock_account/i18n/bn.js +73 -0
- package/dist/stock_account/index.d.ts +1 -0
- package/dist/stock_account/index.js +131 -3
- package/dist/stock_account/landed.d.ts +429 -0
- package/dist/stock_account/landed.js +335 -0
- package/dist/stock_account/module.d.ts +11247 -3363
- package/dist/stock_account/module.js +135 -6
- package/dist/stock_account/web/LandedPreview.d.ts +7 -0
- package/dist/stock_account/web/LandedPreview.js +23 -0
- package/dist/stock_account/web/index.d.ts +11 -0
- package/dist/stock_account/web/index.js +16 -0
- package/dist/stock_account/web/messages.d.ts +2 -0
- package/dist/stock_account/web/messages.js +27 -0
- package/dist/todo/i18n/bn.d.ts +2 -0
- package/dist/todo/i18n/bn.js +66 -0
- package/dist/todo/index.js +59 -0
- package/dist/todo/module.d.ts +5 -0
- package/dist/todo/module.js +5 -3
- package/dist/trade_finance/.kosh/bindings.js +1 -1
- package/dist/trade_finance/.kosh/schema.d.ts +2 -1
- package/dist/trade_finance/i18n/bn.d.ts +2 -0
- package/dist/trade_finance/i18n/bn.js +162 -0
- package/dist/trade_finance/index.js +93 -0
- package/dist/trade_finance/module.d.ts +26 -0
- package/dist/trade_finance/module.js +27 -8
- package/dist/trade_finance_account/.kosh/bindings.js +1 -1
- package/dist/trade_finance_account/.kosh/schema.d.ts +530 -8
- package/dist/trade_finance_account/i18n/bn.d.ts +2 -0
- package/dist/trade_finance_account/i18n/bn.js +27 -0
- package/dist/trade_finance_account/index.js +2 -0
- package/dist/trade_finance_account/module.d.ts +4906 -1432
- 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 +813 -3
- package/dist/trade_finance_purchase/i18n/bn.d.ts +2 -0
- package/dist/trade_finance_purchase/i18n/bn.js +6 -0
- package/dist/trade_finance_purchase/index.js +2 -0
- package/dist/trade_finance_purchase/module.d.ts +6909 -413
- package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
- package/dist/trade_finance_sale/.kosh/schema.d.ts +291 -4
- package/dist/trade_finance_sale/i18n/bn.d.ts +2 -0
- package/dist/trade_finance_sale/i18n/bn.js +6 -0
- package/dist/trade_finance_sale/index.js +2 -0
- package/dist/trade_finance_sale/module.d.ts +2601 -331
- package/dist/ui/api.d.ts +2 -0
- package/dist/ui/app.d.ts +9 -0
- package/dist/ui/app.js +24 -4
- package/dist/ui/components/AppIcon.js +2 -2
- package/dist/ui/components/Explain.d.ts +69 -0
- package/dist/ui/components/Explain.js +62 -0
- package/dist/ui/context.d.ts +8 -1
- package/dist/ui/context.js +34 -1
- package/dist/ui/i18n/messages.d.ts +36 -0
- package/dist/ui/i18n/messages.js +72 -0
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.js +1 -0
- package/dist/ui/registry.d.ts +14 -0
- package/dist/ui/registry.js +10 -0
- package/dist/ui/views/FormView.d.ts +6 -0
- package/dist/ui/views/FormView.js +47 -10
- package/dist/ui/views/ListView.d.ts +8 -0
- package/dist/ui/views/ListView.js +10 -3
- package/dist/ui/views/StatsRow.js +2 -1
- package/dist/views/extend.js +12 -0
- package/dist/views/types.d.ts +13 -2
- package/dist/views/validate.js +8 -1
- package/dist/website/.kosh/bindings.js +1 -1
- package/dist/website/.kosh/schema.d.ts +2 -1
- package/dist/website/i18n/bn.d.ts +2 -0
- package/dist/website/i18n/bn.js +113 -0
- package/dist/website/index.js +36 -0
- package/dist/website/module.d.ts +20 -0
- package/dist/website/module.js +29 -5
- package/dist/website_crm/.kosh/bindings.js +1 -1
- package/dist/website_crm/.kosh/schema.d.ts +2 -1
- package/dist/website_crm/i18n/bn.d.ts +2 -0
- package/dist/website_crm/i18n/bn.js +5 -0
- package/dist/website_crm/index.js +2 -0
- package/dist/website_crm/module.d.ts +40 -0
- package/dist/website_sale/.kosh/bindings.js +1 -1
- package/dist/website_sale/.kosh/schema.d.ts +642 -17
- package/dist/website_sale/i18n/bn.d.ts +2 -0
- package/dist/website_sale/i18n/bn.js +132 -0
- package/dist/website_sale/index.js +83 -1
- package/dist/website_sale/module.d.ts +18705 -5550
- package/dist/website_sale/module.js +32 -10
- package/dist/website_sale/shop.js +22 -9
- package/dist/website_sale_stock/.kosh/bindings.js +1 -1
- package/dist/website_sale_stock/.kosh/schema.d.ts +737 -18
- package/dist/website_sale_stock/i18n/bn.d.ts +2 -0
- package/dist/website_sale_stock/i18n/bn.js +4 -0
- package/dist/website_sale_stock/index.js +2 -0
- package/dist/website_sale_stock/module.d.ts +10 -24997
- package/dist/website_sale_stock/module.js +7 -3
- package/package.json +36 -8
- package/dist/mrp/index.d.ts +0 -3
- package/dist/mrp/index.js +0 -393
- package/dist/mrp/module.js +0 -757
- package/dist/mrp_account/index.d.ts +0 -3
- package/dist/mrp_account/index.js +0 -22
- /package/dist/{mrp → approvals_purchase}/.kosh/bindings.d.ts +0 -0
- /package/dist/{mrp_account → indent}/.kosh/bindings.d.ts +0 -0
package/dist/sales/module.js
CHANGED
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { contactsShutro } from '../contacts/index.js';
|
|
7
7
|
import { messagingShutro } from '../messaging/index.js';
|
|
8
|
-
import { computeTaxes, productShutro, taxRule } from '../product/index.js';
|
|
8
|
+
import { computeTaxes, priceFor, productShutro, taxRule } from '../product/index.js';
|
|
9
9
|
import { orm } from '../server/orm.js';
|
|
10
|
-
import { check, compute, defineModel, defineModule, extendModel, f, onchange, records, } from './.kosh/bindings.js';
|
|
10
|
+
import { check, compute, defineModel, defineModule, extendModel, f, method, onchange, records, } from './.kosh/bindings.js';
|
|
11
11
|
/** A line's taxes through the engine (RFC 0016): its amount after discount, its taxes in order. */
|
|
12
12
|
function taxesOf(l) {
|
|
13
|
-
const amount = l.quantity
|
|
13
|
+
const amount = l.quantity
|
|
14
|
+
.times(l.priceUnit ?? orm.toDecimal('0'))
|
|
15
|
+
.times(orm.toDecimal(100).minus(l.discount))
|
|
16
|
+
.div(100);
|
|
14
17
|
return computeTaxes(amount, l.quantity, [...l.taxes].map(taxRule));
|
|
15
18
|
}
|
|
16
19
|
/** A monetary value's amount (a Money object or a plain Decimal), or null. */
|
|
@@ -63,20 +66,64 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
63
66
|
label: 'Salesperson',
|
|
64
67
|
}),
|
|
65
68
|
partner: f.many2one('res.partner', { required: true, checkCompany: true, label: 'Customer' }),
|
|
69
|
+
/** Where the invoice goes and where the goods go (RFC 0028 §3.2); empty: the customer's own address. */
|
|
70
|
+
partnerInvoice: f.many2one('res.partner', {
|
|
71
|
+
checkCompany: true,
|
|
72
|
+
label: 'Invoice to',
|
|
73
|
+
help: 'The contact the invoice is addressed to; empty: the customer.',
|
|
74
|
+
}),
|
|
75
|
+
partnerShipping: f.many2one('res.partner', {
|
|
76
|
+
checkCompany: true,
|
|
77
|
+
label: 'Deliver to',
|
|
78
|
+
help: 'Where the goods go; empty: the customer’s address.',
|
|
79
|
+
}),
|
|
80
|
+
/** The price list its lines are priced by (RFC 0028 §3.1); from the customer, else none (list prices). */
|
|
81
|
+
pricelist: f.many2one('product.pricelist', {
|
|
82
|
+
ondelete: 'restrict',
|
|
83
|
+
label: 'Price list',
|
|
84
|
+
help: 'Lines without a price typed in are priced by this list; each line says why.',
|
|
85
|
+
}),
|
|
66
86
|
currency: f.many2one('res.currency', { required: true }),
|
|
67
87
|
dateOrder: f.date({ required: true, default: (env) => env.today(), label: 'Order date' }),
|
|
68
88
|
validityDate: f.date({ label: 'Valid until' }),
|
|
69
89
|
clientReference: f.char({ label: 'Customer reference' }),
|
|
70
90
|
note: f.text({ label: 'Terms and conditions' }),
|
|
71
91
|
lines: f.one2many('sale.order.line', 'order'),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
92
|
+
/** The quotation template it started from (RFC 0028 §3.5). */
|
|
93
|
+
template: f.many2one('sale.order.template', {
|
|
94
|
+
ondelete: 'set null',
|
|
95
|
+
label: 'Quotation template',
|
|
96
|
+
help: '“Fill from template” fills the quotation’s lines, options, validity and terms from it.',
|
|
97
|
+
}),
|
|
98
|
+
/** Optional products offered with the quotation; added as lines when the customer wants them. */
|
|
99
|
+
options: f.one2many('sale.order.option', 'order', { label: 'Optional products' }),
|
|
100
|
+
amountUntaxed: f.monetary({
|
|
101
|
+
currency: 'currency',
|
|
102
|
+
store: true,
|
|
103
|
+
label: 'Untaxed',
|
|
104
|
+
help: 'The sum of the lines’ amounts before taxes.',
|
|
105
|
+
...amounts,
|
|
106
|
+
}),
|
|
107
|
+
amountTax: f.monetary({
|
|
108
|
+
currency: 'currency',
|
|
109
|
+
store: true,
|
|
110
|
+
label: 'Taxes',
|
|
111
|
+
help: 'The sum of the taxes on the lines.',
|
|
112
|
+
...amounts,
|
|
113
|
+
}),
|
|
114
|
+
amountTotal: f.monetary({
|
|
115
|
+
currency: 'currency',
|
|
116
|
+
store: true,
|
|
117
|
+
label: 'Total',
|
|
118
|
+
help: 'What the customer pays: the untaxed amount plus the taxes.',
|
|
119
|
+
...amounts,
|
|
120
|
+
}),
|
|
75
121
|
/** RFC 0022 step 2: what the order earns — the lines' untaxed amounts less their products' cost. */
|
|
76
122
|
margin: f.monetary({
|
|
77
123
|
currency: 'currency',
|
|
78
124
|
store: true,
|
|
79
125
|
label: 'Margin',
|
|
126
|
+
help: 'What the order earns: its lines’ untaxed amounts less their products’ cost.',
|
|
80
127
|
...compute('sale.order', 'margin', ['lines.margin', 'currency'], (orders) => {
|
|
81
128
|
for (const o of orders)
|
|
82
129
|
o.margin = o.currency === null ? null : o.lines.sum('margin', o.currency);
|
|
@@ -86,6 +133,7 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
86
133
|
scale: 1,
|
|
87
134
|
store: true,
|
|
88
135
|
label: 'Margin (%)',
|
|
136
|
+
help: 'The margin as a percentage of the untaxed amount.',
|
|
89
137
|
...compute('sale.order', 'marginPercent', ['margin', 'amountUntaxed'], (orders) => {
|
|
90
138
|
for (const o of orders) {
|
|
91
139
|
const untaxed = amountOf(o.amountUntaxed);
|
|
@@ -98,6 +146,7 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
98
146
|
}),
|
|
99
147
|
}),
|
|
100
148
|
state: f.state({
|
|
149
|
+
help: 'A quotation until it is confirmed as a sales order, which can then be locked or cancelled.',
|
|
101
150
|
states: {
|
|
102
151
|
draft: 'Quotation',
|
|
103
152
|
sent: 'Quotation sent',
|
|
@@ -108,6 +157,54 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
108
157
|
initial: 'draft',
|
|
109
158
|
transitions: {
|
|
110
159
|
send: { from: ['draft'], to: 'sent' },
|
|
160
|
+
// A quotation filled from its template (RFC 0028 §3.5): lines, options, validity, terms.
|
|
161
|
+
fill: {
|
|
162
|
+
from: ['draft'],
|
|
163
|
+
to: 'draft',
|
|
164
|
+
guard: records('sale.order', async (orders) => (await orders.load({ template: true })).filter((o) => o.template === null)),
|
|
165
|
+
message: 'Choose a quotation template first.',
|
|
166
|
+
after: records('sale.order', async (orders) => {
|
|
167
|
+
const env = orders.env;
|
|
168
|
+
for (const o of await orders.load({ template: { lines: { product: true } } })) {
|
|
169
|
+
const t = o.template;
|
|
170
|
+
if (t === null)
|
|
171
|
+
continue;
|
|
172
|
+
const rows = [...t.lines].sort((a, b) => (a.sequence ?? 10) - (b.sequence ?? 10));
|
|
173
|
+
const lines = rows.filter((r) => r.optional !== true);
|
|
174
|
+
const options = rows.filter((r) => r.optional === true);
|
|
175
|
+
if (lines.length > 0)
|
|
176
|
+
await env.model('sale.order.line').create(lines.map((r) => ({
|
|
177
|
+
order: o.id,
|
|
178
|
+
product: r.product.id,
|
|
179
|
+
name: r.name,
|
|
180
|
+
quantity: r.quantity,
|
|
181
|
+
})));
|
|
182
|
+
if (options.length > 0)
|
|
183
|
+
await env.model('sale.order.option').create(options.map((r) => ({
|
|
184
|
+
order: o.id,
|
|
185
|
+
product: r.product.id,
|
|
186
|
+
name: r.name,
|
|
187
|
+
quantity: r.quantity,
|
|
188
|
+
})));
|
|
189
|
+
const days = t.validityDays ?? 0;
|
|
190
|
+
const date = String(o.dateOrder).slice(0, 10);
|
|
191
|
+
const [y, m, day] = date.split('-').map(Number);
|
|
192
|
+
await env
|
|
193
|
+
.model('sale.order')
|
|
194
|
+
.browse([o.id])
|
|
195
|
+
.write({
|
|
196
|
+
...(days > 0
|
|
197
|
+
? {
|
|
198
|
+
validityDate: new Date(Date.UTC(y, m - 1, day + days))
|
|
199
|
+
.toISOString()
|
|
200
|
+
.slice(0, 10),
|
|
201
|
+
}
|
|
202
|
+
: {}),
|
|
203
|
+
...(t.note !== null && t.note !== '' ? { note: t.note } : {}),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}),
|
|
207
|
+
},
|
|
111
208
|
confirm: {
|
|
112
209
|
from: ['draft', 'sent'],
|
|
113
210
|
to: 'sale',
|
|
@@ -116,6 +213,11 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
116
213
|
return loaded.filter((o) => o.lines.length === 0);
|
|
117
214
|
}),
|
|
118
215
|
message: 'Add at least one line before confirming the order.',
|
|
216
|
+
// Other apps check the order first (sale_account: the customer's credit).
|
|
217
|
+
before: records('sale.order', async (orders) => {
|
|
218
|
+
const env = orders.env;
|
|
219
|
+
await env.model('sale.order').browse(orders.ids).confirming();
|
|
220
|
+
}),
|
|
119
221
|
// Other apps act on a confirmation through the outbox (sale_project creates the tasks).
|
|
120
222
|
after: records('sale.order', async (orders) => {
|
|
121
223
|
for (const o of await orders.load({}))
|
|
@@ -124,17 +226,40 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
124
226
|
},
|
|
125
227
|
lock: { from: ['sale'], to: 'done' },
|
|
126
228
|
unlock: { from: ['done'], to: 'sale' },
|
|
127
|
-
cancel: {
|
|
229
|
+
cancel: {
|
|
230
|
+
from: ['draft', 'sent', 'sale'],
|
|
231
|
+
to: 'cancel',
|
|
232
|
+
// Other apps follow a cancellation through the outbox (sale_crm: a deal with every quotation cancelled).
|
|
233
|
+
after: records('sale.order', async (orders) => {
|
|
234
|
+
for (const o of await orders.load({}))
|
|
235
|
+
await orders.env.emit('sale.order.cancelled', { id: o.id });
|
|
236
|
+
}),
|
|
237
|
+
},
|
|
128
238
|
redraft: { from: ['cancel'], to: 'draft' },
|
|
129
239
|
},
|
|
130
240
|
extensible: true, // Accounting adds invoicing states through its bridge
|
|
131
241
|
}),
|
|
132
242
|
},
|
|
243
|
+
methods: {
|
|
244
|
+
/** Before a confirmation: nothing here; sale_account checks the customer's credit (RFC 0028 §3.2). */
|
|
245
|
+
confirming: method('sale.order', async () => undefined),
|
|
246
|
+
},
|
|
133
247
|
onchange: {
|
|
134
248
|
// The customer's currency, else the company's; an empty validity and terms from the company's settings.
|
|
135
249
|
partner: onchange('sale.order', async (d, env) => {
|
|
136
250
|
await quotationDefaults(d, env);
|
|
137
251
|
const p = await d.record('partner');
|
|
252
|
+
const [priced] = p === null
|
|
253
|
+
? []
|
|
254
|
+
: await env
|
|
255
|
+
.model('res.partner')
|
|
256
|
+
.browse([p.id])
|
|
257
|
+
.load({ pricelist: { currency: true } });
|
|
258
|
+
d.set('pricelist', priced?.pricelist?.id ?? null);
|
|
259
|
+
if (priced?.pricelist?.currency) {
|
|
260
|
+
d.set('currency', priced.pricelist.currency.id);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
138
263
|
if (p?.currency) {
|
|
139
264
|
d.set('currency', p.currency.id);
|
|
140
265
|
return;
|
|
@@ -146,6 +271,12 @@ export const SaleOrder = defineModel('sale.order', {
|
|
|
146
271
|
if (company !== undefined)
|
|
147
272
|
d.set('currency', company.currency.id);
|
|
148
273
|
}),
|
|
274
|
+
// A price list in another currency puts the order in it.
|
|
275
|
+
pricelist: onchange('sale.order', async (d) => {
|
|
276
|
+
const list = await d.record('pricelist');
|
|
277
|
+
if (list?.currency)
|
|
278
|
+
d.set('currency', list.currency.id);
|
|
279
|
+
}),
|
|
149
280
|
// A new order date moves the validity with it.
|
|
150
281
|
dateOrder: onchange('sale.order', async (d, env) => {
|
|
151
282
|
d.set('validityDate', null);
|
|
@@ -173,6 +304,16 @@ async function quotationDefaults(d, env) {
|
|
|
173
304
|
if ((d.get('note') ?? '') === '' && typeof terms === 'string' && terms !== '')
|
|
174
305
|
d.set('note', terms);
|
|
175
306
|
}
|
|
307
|
+
/** A line's price and why (RFC 0028 §3.1): typed in, else its order's price list, else the list price. */
|
|
308
|
+
async function linePrice(l) {
|
|
309
|
+
if (l.manualPrice !== null)
|
|
310
|
+
return { price: l.manualPrice, reason: 'Typed in.' };
|
|
311
|
+
if (l.product === null)
|
|
312
|
+
return { price: orm.toDecimal('0'), reason: null };
|
|
313
|
+
const env = l.env;
|
|
314
|
+
const found = await priceFor(l.env, l.order?.pricelist?.id ?? null, l.product.id, l.quantity, String(l.order?.dateOrder ?? env.today()).slice(0, 10));
|
|
315
|
+
return { price: found.price, reason: found.explanation };
|
|
316
|
+
}
|
|
176
317
|
export const SaleOrderLine = defineModel('sale.order.line', {
|
|
177
318
|
label: 'Order line',
|
|
178
319
|
access: {
|
|
@@ -185,7 +326,43 @@ export const SaleOrderLine = defineModel('sale.order.line', {
|
|
|
185
326
|
name: f.char({ required: true, label: 'Description' }),
|
|
186
327
|
quantity: f.decimal({ scale: 3, required: true, default: '1' }),
|
|
187
328
|
uom: f.many2one('uom.uom', { label: 'Unit' }),
|
|
188
|
-
|
|
329
|
+
/**
|
|
330
|
+
* The unit price: the one typed in, else the order's price list's (RFC 0028 §3.1). Typing a price keeps it
|
|
331
|
+
* (`manualPrice`); changing the product, the quantity or the list reprices the lines without one.
|
|
332
|
+
*/
|
|
333
|
+
priceUnit: f.decimal({
|
|
334
|
+
scale: 2,
|
|
335
|
+
store: true,
|
|
336
|
+
label: 'Unit price',
|
|
337
|
+
help: 'The price typed in, else the order’s price list’s (see why on the line), else the product’s list price.',
|
|
338
|
+
...compute('sale.order.line', 'priceUnit', ['product', 'quantity', 'manualPrice', 'order.pricelist', 'order.dateOrder'], async (lines) => {
|
|
339
|
+
for (const l of lines)
|
|
340
|
+
l.priceUnit = (await linePrice(l)).price;
|
|
341
|
+
}),
|
|
342
|
+
inverse: async (records) => {
|
|
343
|
+
const lines = records;
|
|
344
|
+
const env = records.env;
|
|
345
|
+
// Who may set prices by hand (RFC 0028 §3.1): the server decides.
|
|
346
|
+
if (!env.su && !env.access.has('sales.price_override'))
|
|
347
|
+
throw new orm.ValidationError('sale.order.line', ['priceUnit'], 'You may not change prices.', 'Prices come from the price list; ask a Sales manager.');
|
|
348
|
+
for (const l of lines)
|
|
349
|
+
await env
|
|
350
|
+
.model('sale.order.line')
|
|
351
|
+
.browse([l.id])
|
|
352
|
+
.write({ manualPrice: l.priceUnit });
|
|
353
|
+
},
|
|
354
|
+
}),
|
|
355
|
+
/** The price typed in, kept when the product, the quantity or the list changes (empty: the list's price). */
|
|
356
|
+
manualPrice: f.decimal({ scale: 2, label: 'Price typed in' }),
|
|
357
|
+
/** Why the line has its price: the list and rule, or "typed in". */
|
|
358
|
+
priceReason: f.char({
|
|
359
|
+
store: true,
|
|
360
|
+
label: 'Why this price',
|
|
361
|
+
...compute('sale.order.line', 'priceReason', ['product', 'quantity', 'manualPrice', 'order.pricelist', 'order.dateOrder'], async (lines) => {
|
|
362
|
+
for (const l of lines)
|
|
363
|
+
l.priceReason = (await linePrice(l)).reason;
|
|
364
|
+
}),
|
|
365
|
+
}),
|
|
189
366
|
/** Percent off the unit price (0–100). */
|
|
190
367
|
discount: f.decimal({ scale: 2, required: true, default: '0', label: 'Discount %' }),
|
|
191
368
|
/** The line's taxes, applied in order (RFC 0016). */
|
|
@@ -203,6 +380,7 @@ export const SaleOrderLine = defineModel('sale.order.line', {
|
|
|
203
380
|
subtotal: f.monetary({
|
|
204
381
|
currency: 'currency',
|
|
205
382
|
store: true,
|
|
383
|
+
help: 'The line’s amount before taxes: the quantity times the unit price, less the discount and any tax included in the price.',
|
|
206
384
|
...compute('sale.order.line', 'subtotal', [
|
|
207
385
|
'quantity',
|
|
208
386
|
'priceUnit',
|
|
@@ -224,6 +402,7 @@ export const SaleOrderLine = defineModel('sale.order.line', {
|
|
|
224
402
|
currency: 'currency',
|
|
225
403
|
store: true,
|
|
226
404
|
label: 'Margin',
|
|
405
|
+
help: 'What the line earns: its untaxed amount less its product’s cost for the quantity.',
|
|
227
406
|
...compute('sale.order.line', 'margin', ['subtotal', 'quantity', 'product.standardPrice'], (lines) => {
|
|
228
407
|
for (const l of lines) {
|
|
229
408
|
const untaxed = amountOf(l.subtotal);
|
|
@@ -238,6 +417,7 @@ export const SaleOrderLine = defineModel('sale.order.line', {
|
|
|
238
417
|
currency: 'currency',
|
|
239
418
|
store: true,
|
|
240
419
|
label: 'Tax',
|
|
420
|
+
help: 'The taxes on this line, computed from its amount and its taxes.',
|
|
241
421
|
...compute('sale.order.line', 'taxAmount', [
|
|
242
422
|
'quantity',
|
|
243
423
|
'priceUnit',
|
|
@@ -279,10 +459,118 @@ export const SaleOrderLine = defineModel('sale.order.line', {
|
|
|
279
459
|
},
|
|
280
460
|
},
|
|
281
461
|
});
|
|
462
|
+
/** A quotation template (RFC 0028 §3.5): lines and optional products, validity and terms. */
|
|
463
|
+
export const SaleOrderTemplate = defineModel('sale.order.template', {
|
|
464
|
+
label: 'Quotation template',
|
|
465
|
+
archivable: true,
|
|
466
|
+
order: ['name asc'],
|
|
467
|
+
access: {
|
|
468
|
+
'sales.user': ['read'],
|
|
469
|
+
'sales.manager': ['read', 'write', 'create', 'unlink', 'export', 'import'],
|
|
470
|
+
},
|
|
471
|
+
fields: {
|
|
472
|
+
name: f.char({ required: true, translate: true }),
|
|
473
|
+
validityDays: f.integer({
|
|
474
|
+
default: 0,
|
|
475
|
+
label: 'Valid for (days)',
|
|
476
|
+
help: 'The quotation is valid until its date plus these days; 0 keeps the quotation’s own.',
|
|
477
|
+
}),
|
|
478
|
+
note: f.text({ label: 'Terms and conditions' }),
|
|
479
|
+
lines: f.one2many('sale.order.template.line', 'template', { label: 'Lines' }),
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
export const SaleOrderTemplateLine = defineModel('sale.order.template.line', {
|
|
483
|
+
label: 'Template line',
|
|
484
|
+
order: ['template asc', 'sequence asc', 'id asc'],
|
|
485
|
+
access: {
|
|
486
|
+
'sales.user': ['read'],
|
|
487
|
+
'sales.manager': ['read', 'write', 'create', 'unlink'],
|
|
488
|
+
},
|
|
489
|
+
fields: {
|
|
490
|
+
template: f.many2one('sale.order.template', { required: true, ondelete: 'cascade' }),
|
|
491
|
+
sequence: f.integer({ default: 10 }),
|
|
492
|
+
product: f.many2one('product.product', { required: true }),
|
|
493
|
+
name: f.char({ required: true, label: 'Description' }),
|
|
494
|
+
quantity: f.decimal({ scale: 3, required: true, default: '1' }),
|
|
495
|
+
optional: f.boolean({
|
|
496
|
+
default: false,
|
|
497
|
+
label: 'Optional',
|
|
498
|
+
help: 'Offered with the quotation; the customer adds it, or not.',
|
|
499
|
+
}),
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
/** An optional product offered with a quotation (RFC 0028 §3.5); added, it becomes a line, once. */
|
|
503
|
+
export const SaleOrderOption = defineModel('sale.order.option', {
|
|
504
|
+
label: 'Optional product',
|
|
505
|
+
order: ['order asc', 'id asc'],
|
|
506
|
+
access: {
|
|
507
|
+
'sales.user': ['read', 'write', 'create', 'unlink'],
|
|
508
|
+
'sales.manager': ['read', 'write', 'create', 'unlink'],
|
|
509
|
+
},
|
|
510
|
+
fields: {
|
|
511
|
+
order: f.many2one('sale.order', { required: true, ondelete: 'cascade' }),
|
|
512
|
+
product: f.many2one('product.product', { required: true }),
|
|
513
|
+
name: f.char({ required: true, label: 'Description' }),
|
|
514
|
+
quantity: f.decimal({ scale: 3, required: true, default: '1' }),
|
|
515
|
+
/** Empty: the order's price list prices the line. */
|
|
516
|
+
priceUnit: f.decimal({ scale: 2, label: 'Unit price' }),
|
|
517
|
+
line: f.many2one('sale.order.line', { ondelete: 'set null', label: 'Added as' }),
|
|
518
|
+
state: f.state({
|
|
519
|
+
help: 'Offered until it is added to the quotation as a line.',
|
|
520
|
+
states: { offered: 'Offered', added: 'Added' },
|
|
521
|
+
initial: 'offered',
|
|
522
|
+
transitions: {
|
|
523
|
+
// Added while the quotation is open: a line, priced by the list unless the option has a price.
|
|
524
|
+
add: {
|
|
525
|
+
from: ['offered'],
|
|
526
|
+
to: 'added',
|
|
527
|
+
guard: records('sale.order.option', async (options) => (await options.load({ order: true })).filter((o) => o.order.state !== 'draft' && o.order.state !== 'sent')),
|
|
528
|
+
message: 'Options are added while the quotation is open.',
|
|
529
|
+
after: records('sale.order.option', async (options) => {
|
|
530
|
+
const env = options.env;
|
|
531
|
+
for (const o of await options.load({})) {
|
|
532
|
+
const made = await env.asSuperuser({ reason: 'option added' }, (su) => su.model('sale.order.line').create([
|
|
533
|
+
{
|
|
534
|
+
order: o.order.id,
|
|
535
|
+
product: o.product.id,
|
|
536
|
+
name: o.name,
|
|
537
|
+
quantity: o.quantity,
|
|
538
|
+
...(o.priceUnit === null ? {} : { priceUnit: o.priceUnit }),
|
|
539
|
+
},
|
|
540
|
+
]));
|
|
541
|
+
await env
|
|
542
|
+
.model('sale.order.option')
|
|
543
|
+
.browse([o.id])
|
|
544
|
+
.write({ line: made.ids[0] });
|
|
545
|
+
}
|
|
546
|
+
}),
|
|
547
|
+
},
|
|
548
|
+
},
|
|
549
|
+
}),
|
|
550
|
+
},
|
|
551
|
+
});
|
|
552
|
+
/** The customer's price list (RFC 0028 §3.1): their orders start on it. */
|
|
553
|
+
export const PartnerPricelist = extendModel('res.partner', {
|
|
554
|
+
fields: {
|
|
555
|
+
pricelist: f.many2one('product.pricelist', {
|
|
556
|
+
ondelete: 'set null',
|
|
557
|
+
label: 'Price list',
|
|
558
|
+
help: 'Orders for this customer start on this price list.',
|
|
559
|
+
}),
|
|
560
|
+
},
|
|
561
|
+
});
|
|
282
562
|
export const salesShutro = defineModule({
|
|
283
563
|
name: 'sales',
|
|
284
|
-
version: '0.
|
|
564
|
+
version: '0.5.0',
|
|
285
565
|
migrations: [
|
|
566
|
+
{
|
|
567
|
+
version: '0.4.0',
|
|
568
|
+
description: 'Price lists: existing lines keep the price they have, as typed in (no order is repriced)',
|
|
569
|
+
up: async (ctx) => {
|
|
570
|
+
await ctx.sql `UPDATE sale_order_line SET manual_price = price_unit WHERE manual_price IS NULL`;
|
|
571
|
+
await ctx.sql `UPDATE sale_order_line SET price_reason = 'Typed in.' WHERE price_reason IS NULL`;
|
|
572
|
+
},
|
|
573
|
+
},
|
|
286
574
|
{
|
|
287
575
|
version: '0.2.0',
|
|
288
576
|
description: 'Several taxes per line: the single tax of each line becomes its first',
|
|
@@ -301,9 +589,16 @@ export const salesShutro = defineModule({
|
|
|
301
589
|
}),
|
|
302
590
|
orm.defineGroup({ code: 'sales.manager', label: 'Sales manager', implies: ['sales.user'] }),
|
|
303
591
|
],
|
|
592
|
+
permissions: [
|
|
593
|
+
orm.definePermission({
|
|
594
|
+
code: 'sales.price_override',
|
|
595
|
+
label: 'Type in prices on order lines (instead of the price list)',
|
|
596
|
+
groups: ['sales.user'],
|
|
597
|
+
}),
|
|
598
|
+
],
|
|
304
599
|
sequences: [
|
|
305
600
|
orm.defineSequence({ code: 'sale.order', prefix: 'SO/{year}/', padding: 5, reset: 'yearly' }),
|
|
306
601
|
],
|
|
307
|
-
models: [SaleOrder, SaleOrderLine],
|
|
308
|
-
extensions: [CompanySales],
|
|
602
|
+
models: [SaleOrder, SaleOrderLine, SaleOrderTemplate, SaleOrderTemplateLine, SaleOrderOption],
|
|
603
|
+
extensions: [CompanySales, PartnerPricelist],
|
|
309
604
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duplicate (RFC 0023 R1, §3.2): a copy of a record made **as the user** (ACL, record rules and field groups decide)
|
|
3
|
+
* from the model's metadata — Shutro has no `copy()` yet (docs/shutro-requests.md #32):
|
|
4
|
+
* - stored, writable fields are copied; many2one kept, many2many as the same set;
|
|
5
|
+
* - states, sequences and computed fields start again (they are read-only, so not copied);
|
|
6
|
+
* - a field in a unique constraint (beside the company) is left out, or for a required text gets " (copy)";
|
|
7
|
+
* - one2many lines are copied with the record, each line by the same rules, without the link back.
|
|
8
|
+
*/
|
|
9
|
+
import type { Env } from '../orm.js';
|
|
10
|
+
import type { ApiModel } from './metadata.js';
|
|
11
|
+
type Row = Record<string, unknown>;
|
|
12
|
+
/** The record's copy (as the API takes values), with its lines. */
|
|
13
|
+
export declare function duplicateValues(env: Env, models: ReadonlyMap<string, ApiModel>, model: ApiModel, id: number): Promise<Row>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const ref = (env, name) => env.model(name);
|
|
2
|
+
/** Whether a field's value is copied as such. */
|
|
3
|
+
const copied = (env, model, f) => f.stored &&
|
|
4
|
+
!f.readonly &&
|
|
5
|
+
f.kind !== 'one2many' &&
|
|
6
|
+
f.kind !== 'binary' &&
|
|
7
|
+
env.access.canField(model.name, f.key, 'read') &&
|
|
8
|
+
env.access.canField(model.name, f.key, 'write');
|
|
9
|
+
/** The fields of the model's unique constraints, the company aside. */
|
|
10
|
+
const uniqueKeys = (model) => new Set(model.unique.flat().filter((k) => k !== 'company'));
|
|
11
|
+
async function valuesOf(env, model, id, skip, rename) {
|
|
12
|
+
const fields = model.fields.filter((f) => copied(env, model, f) && f.key !== skip);
|
|
13
|
+
const scalar = fields.filter((f) => f.kind !== 'many2many').map((f) => f.key);
|
|
14
|
+
const sets = fields.filter((f) => f.kind === 'many2many').map((f) => f.key);
|
|
15
|
+
let loaded = await ref(env, model.name)
|
|
16
|
+
.browse([id])
|
|
17
|
+
.load(['id', ...scalar]);
|
|
18
|
+
if (sets.length > 0)
|
|
19
|
+
loaded = await loaded.load(Object.fromEntries(sets.map((k) => [k, true])));
|
|
20
|
+
const [row] = loaded.read(['id', ...fields.map((f) => f.key)]);
|
|
21
|
+
if (row === undefined)
|
|
22
|
+
return {};
|
|
23
|
+
const unique = uniqueKeys(model);
|
|
24
|
+
const out = {};
|
|
25
|
+
for (const f of fields) {
|
|
26
|
+
const value = row[f.key];
|
|
27
|
+
if (value === null || value === undefined)
|
|
28
|
+
continue;
|
|
29
|
+
if (unique.has(f.key)) {
|
|
30
|
+
if (rename &&
|
|
31
|
+
f.required &&
|
|
32
|
+
(f.kind === 'char' || f.kind === 'text') &&
|
|
33
|
+
typeof value === 'string')
|
|
34
|
+
out[f.key] = `${value} (copy)`;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (f.kind === 'many2one')
|
|
38
|
+
out[f.key] = typeof value === 'object' ? value.id : value;
|
|
39
|
+
else if (f.kind === 'many2many')
|
|
40
|
+
out[f.key] = {
|
|
41
|
+
set: value.map((v) => typeof v === 'object' && v !== null ? v.id : v),
|
|
42
|
+
};
|
|
43
|
+
else
|
|
44
|
+
out[f.key] = value;
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
/** The record's copy (as the API takes values), with its lines. */
|
|
49
|
+
export async function duplicateValues(env, models, model, id) {
|
|
50
|
+
const values = await valuesOf(env, model, id, null, true);
|
|
51
|
+
for (const f of model.fields) {
|
|
52
|
+
if (f.kind !== 'one2many' || f.readonly || f.target === null)
|
|
53
|
+
continue;
|
|
54
|
+
if (!env.access.canField(model.name, f.key, 'write'))
|
|
55
|
+
continue;
|
|
56
|
+
const lines = models.get(f.target);
|
|
57
|
+
if (lines === undefined || !env.access.can(f.target, 'create'))
|
|
58
|
+
continue;
|
|
59
|
+
// The lines' link back: their many2one to this model that is required.
|
|
60
|
+
const back = lines.fields.find((x) => x.kind === 'many2one' && x.target === model.name && x.required);
|
|
61
|
+
if (back === undefined)
|
|
62
|
+
continue;
|
|
63
|
+
const [parent] = (await ref(env, model.name)
|
|
64
|
+
.browse([id])
|
|
65
|
+
.load({ [f.key]: true })).read([f.key]);
|
|
66
|
+
const lineIds = (parent?.[f.key] ?? []).map((v) => typeof v === 'object' && v !== null ? Number(v.id) : Number(v));
|
|
67
|
+
if (lineIds.length === 0)
|
|
68
|
+
continue;
|
|
69
|
+
const create = [];
|
|
70
|
+
for (const lineId of lineIds)
|
|
71
|
+
create.push(await valuesOf(env, lines, lineId, back.key, false));
|
|
72
|
+
values[f.key] = { create };
|
|
73
|
+
}
|
|
74
|
+
return values;
|
|
75
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explain (RFC 0031 §3.1): what a model, its fields and its buttons are, for developers and administrators — the
|
|
3
|
+
* facts behind the dark popovers of Developer mode. Where each field comes from (the module that defined the model,
|
|
4
|
+
* or the one that extended it), what it points to (and, for a one-to-many, through which field), whether it is
|
|
5
|
+
* stored or computed and from what, its default, its rules; each transition's states and guard; and every relation
|
|
6
|
+
* into the model from the other served models.
|
|
7
|
+
*
|
|
8
|
+
* - `GET /api/v1/meta/explain/:model` administrators and `base.developer` only
|
|
9
|
+
*/
|
|
10
|
+
import type { FastifyInstance } from 'fastify';
|
|
11
|
+
import type { KoshRegistry } from '../registry.js';
|
|
12
|
+
import type { ApiModel } from './metadata.js';
|
|
13
|
+
/** One field, explained. */
|
|
14
|
+
export interface ExplainedField {
|
|
15
|
+
readonly key: string;
|
|
16
|
+
readonly label: string;
|
|
17
|
+
readonly kind: string;
|
|
18
|
+
readonly help: string | null;
|
|
19
|
+
readonly target: string | null;
|
|
20
|
+
/** For a one-to-many: the field of the target that points back. */
|
|
21
|
+
readonly inverse: string | null;
|
|
22
|
+
readonly required: boolean;
|
|
23
|
+
readonly readonly: boolean;
|
|
24
|
+
readonly stored: boolean;
|
|
25
|
+
readonly computed: boolean;
|
|
26
|
+
/** What a computed field is computed from. */
|
|
27
|
+
readonly depends: readonly string[];
|
|
28
|
+
readonly hasDefault: boolean;
|
|
29
|
+
readonly default: string | null;
|
|
30
|
+
readonly ondelete: string | null;
|
|
31
|
+
readonly translate: boolean;
|
|
32
|
+
readonly index: boolean;
|
|
33
|
+
readonly options: readonly (readonly [string, string])[] | null;
|
|
34
|
+
/** The module whose model or extension declares it. */
|
|
35
|
+
readonly module: string | null;
|
|
36
|
+
}
|
|
37
|
+
/** One transition, explained. */
|
|
38
|
+
export interface ExplainedTransition {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly field: string;
|
|
41
|
+
readonly from: readonly string[];
|
|
42
|
+
readonly to: string;
|
|
43
|
+
readonly guarded: boolean;
|
|
44
|
+
readonly message: string | null;
|
|
45
|
+
readonly requires: string | null;
|
|
46
|
+
}
|
|
47
|
+
/** A model, explained. */
|
|
48
|
+
export interface Explained {
|
|
49
|
+
readonly model: string;
|
|
50
|
+
readonly label: string;
|
|
51
|
+
readonly module: string | null;
|
|
52
|
+
readonly extendedBy: readonly string[];
|
|
53
|
+
readonly fields: readonly ExplainedField[];
|
|
54
|
+
readonly transitions: readonly ExplainedTransition[];
|
|
55
|
+
/** The relations of other models into this one. */
|
|
56
|
+
readonly incoming: readonly {
|
|
57
|
+
readonly model: string;
|
|
58
|
+
readonly field: string;
|
|
59
|
+
readonly label: string;
|
|
60
|
+
readonly kind: string;
|
|
61
|
+
}[];
|
|
62
|
+
}
|
|
63
|
+
/** A model explained, from the registry and the API metadata. */
|
|
64
|
+
export declare function explainModel(registry: KoshRegistry, models: ReadonlyMap<string, ApiModel>, name: string): Explained | null;
|
|
65
|
+
/** The group that may read explanations besides administrators. */
|
|
66
|
+
export declare const DEVELOPER_GROUP = "base.developer";
|
|
67
|
+
export declare function registerExplain(app: FastifyInstance, options: {
|
|
68
|
+
readonly registry: KoshRegistry;
|
|
69
|
+
readonly models: ReadonlyMap<string, ApiModel>;
|
|
70
|
+
}): void;
|