shutro-erp 0.3.4 → 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 +176 -6
- package/dist/account_portal/module.d.ts +505 -6
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +176 -6
- package/dist/accounting/index.d.ts +1 -1
- package/dist/accounting/index.js +344 -4
- package/dist/accounting/module.d.ts +513 -5
- package/dist/accounting/module.js +55 -3
- 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/calendar/.kosh/bindings.d.ts +22 -0
- package/dist/calendar/.kosh/bindings.js +15 -0
- package/dist/calendar/.kosh/schema.d.ts +795 -0
- package/dist/calendar/demo.d.ts +6 -0
- package/dist/calendar/demo.js +24 -0
- package/dist/calendar/index.d.ts +3 -0
- package/dist/calendar/index.js +291 -0
- package/dist/calendar/module.d.ts +1705 -0
- package/dist/calendar/module.js +180 -0
- package/dist/cli/init.js +80 -0
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +226 -0
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +78 -3
- package/dist/contacts/demo.js +30 -1
- package/dist/contacts/index.d.ts +1 -1
- package/dist/contacts/index.js +155 -9
- package/dist/contacts/module.d.ts +338 -2
- package/dist/contacts/module.js +93 -5
- package/dist/crm/.kosh/bindings.d.ts +22 -0
- package/dist/crm/.kosh/bindings.js +15 -0
- package/dist/crm/.kosh/schema.d.ts +800 -0
- package/dist/crm/demo.d.ts +6 -0
- package/dist/crm/demo.js +45 -0
- package/dist/crm/index.d.ts +3 -0
- package/dist/crm/index.js +361 -0
- package/dist/crm/module.d.ts +1845 -0
- package/dist/crm/module.js +208 -0
- 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/.kosh/bindings.d.ts +22 -0
- package/dist/event/.kosh/bindings.js +15 -0
- package/dist/event/.kosh/schema.d.ts +843 -0
- package/dist/event/demo.d.ts +6 -0
- package/dist/event/demo.js +65 -0
- package/dist/event/index.d.ts +14 -0
- package/dist/event/index.js +333 -0
- package/dist/event/mails.d.ts +15 -0
- package/dist/event/mails.js +112 -0
- package/dist/event/module.d.ts +2800 -0
- package/dist/event/module.js +323 -0
- package/dist/event/web/CheckInBox.d.ts +9 -0
- package/dist/event/web/CheckInBox.js +87 -0
- package/dist/event/web/index.d.ts +11 -0
- package/dist/event/web/index.js +16 -0
- package/dist/event/web/messages.d.ts +2 -0
- package/dist/event/web/messages.js +23 -0
- package/dist/event_account/.kosh/bindings.d.ts +22 -0
- package/dist/event_account/.kosh/bindings.js +15 -0
- package/dist/event_account/.kosh/schema.d.ts +1758 -0
- package/dist/event_account/index.d.ts +3 -0
- package/dist/event_account/index.js +28 -0
- package/dist/event_account/module.d.ts +7114 -0
- package/dist/event_account/module.js +90 -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/.kosh/bindings.d.ts +22 -0
- package/dist/hr/.kosh/bindings.js +15 -0
- package/dist/hr/.kosh/schema.d.ts +878 -0
- package/dist/hr/demo.d.ts +6 -0
- package/dist/hr/demo.js +60 -0
- package/dist/hr/index.d.ts +3 -0
- package/dist/hr/index.js +483 -0
- package/dist/hr/module.d.ts +2611 -0
- package/dist/hr/module.js +350 -0
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +176 -6
- package/dist/l10n_bd/module.d.ts +505 -6
- 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 +176 -6
- package/dist/l10n_in/module.d.ts +527 -7
- package/dist/mail/inbound/handle.js +6 -1
- package/dist/maintenance/.kosh/bindings.d.ts +22 -0
- package/dist/maintenance/.kosh/bindings.js +15 -0
- package/dist/maintenance/.kosh/schema.d.ts +911 -0
- package/dist/maintenance/demo.d.ts +6 -0
- package/dist/maintenance/demo.js +60 -0
- package/dist/maintenance/index.d.ts +3 -0
- package/dist/maintenance/index.js +422 -0
- package/dist/maintenance/module.d.ts +3545 -0
- package/dist/maintenance/module.js +446 -0
- package/dist/maintenance_stock/.kosh/bindings.d.ts +22 -0
- package/dist/maintenance_stock/.kosh/bindings.js +15 -0
- package/dist/maintenance_stock/.kosh/schema.d.ts +1446 -0
- package/dist/maintenance_stock/index.d.ts +9 -0
- package/dist/maintenance_stock/index.js +52 -0
- package/dist/maintenance_stock/module.d.ts +7675 -0
- package/dist/maintenance_stock/module.js +192 -0
- package/dist/modules-sdk/index.d.ts +1 -1
- package/dist/modules-sdk/manifest.d.ts +109 -2
- package/dist/modules-sdk/manifest.js +35 -1
- package/dist/mrp/.kosh/bindings.d.ts +22 -0
- package/dist/mrp/.kosh/bindings.js +15 -0
- package/dist/mrp/.kosh/schema.d.ts +1453 -0
- package/dist/mrp/demo.d.ts +7 -0
- package/dist/mrp/demo.js +42 -0
- package/dist/mrp/index.d.ts +3 -0
- package/dist/mrp/index.js +393 -0
- package/dist/mrp/module.d.ts +9335 -0
- package/dist/mrp/module.js +757 -0
- package/dist/mrp_account/.kosh/bindings.d.ts +22 -0
- package/dist/mrp_account/.kosh/bindings.js +15 -0
- package/dist/mrp_account/.kosh/schema.d.ts +2299 -0
- package/dist/mrp_account/index.d.ts +3 -0
- package/dist/mrp_account/index.js +22 -0
- package/dist/mrp_account/module.d.ts +23151 -0
- package/dist/mrp_account/module.js +123 -0
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +178 -7
- package/dist/payment/index.d.ts +41 -0
- package/dist/payment/index.js +131 -74
- package/dist/payment/module.d.ts +569 -12
- 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/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +78 -3
- package/dist/portal/index.js +1 -1
- package/dist/portal/module.d.ts +166 -2
- package/dist/pos/.kosh/bindings.d.ts +22 -0
- package/dist/pos/.kosh/bindings.js +15 -0
- package/dist/pos/.kosh/schema.d.ts +1809 -0
- package/dist/pos/accounting.d.ts +10 -0
- package/dist/pos/accounting.js +149 -0
- package/dist/pos/demo.d.ts +6 -0
- package/dist/pos/demo.js +90 -0
- package/dist/pos/index.d.ts +9 -0
- package/dist/pos/index.js +353 -0
- package/dist/pos/module.d.ts +9783 -0
- package/dist/pos/module.js +423 -0
- package/dist/pos/routes.d.ts +39 -0
- package/dist/pos/routes.js +368 -0
- package/dist/pos/web/Register.d.ts +9 -0
- package/dist/pos/web/Register.js +252 -0
- package/dist/pos/web/index.d.ts +11 -0
- package/dist/pos/web/index.js +16 -0
- package/dist/pos/web/messages.d.ts +2 -0
- package/dist/pos/web/messages.js +87 -0
- package/dist/pos_stock/.kosh/bindings.d.ts +22 -0
- package/dist/pos_stock/.kosh/bindings.js +15 -0
- package/dist/pos_stock/.kosh/schema.d.ts +2208 -0
- package/dist/pos_stock/index.d.ts +9 -0
- package/dist/pos_stock/index.js +35 -0
- package/dist/pos_stock/module.d.ts +12803 -0
- package/dist/pos_stock/module.js +115 -0
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +52 -1
- package/dist/product/index.js +94 -4
- package/dist/product/module.d.ts +45 -1
- package/dist/product/module.js +11 -3
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +725 -3
- package/dist/project/index.d.ts +3 -1
- package/dist/project/index.js +1045 -18
- package/dist/project/module.d.ts +10168 -458
- package/dist/project/module.js +1578 -14
- 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 +725 -3
- package/dist/project_portal/module.d.ts +5137 -119
- 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 +150 -6
- package/dist/purchase/index.js +163 -3
- package/dist/purchase/module.d.ts +228 -5
- package/dist/purchase/module.js +30 -3
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +180 -8
- package/dist/purchase_account/index.js +27 -1
- package/dist/purchase_account/module.d.ts +591 -30
- 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 +150 -6
- package/dist/purchase_portal/module.d.ts +372 -6
- package/dist/purchase_stock/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_stock/.kosh/bindings.js +15 -0
- package/dist/purchase_stock/.kosh/schema.d.ts +1479 -0
- package/dist/purchase_stock/index.d.ts +7 -0
- package/dist/purchase_stock/index.js +98 -0
- package/dist/purchase_stock/module.d.ts +7535 -0
- package/dist/purchase_stock/module.js +380 -0
- package/dist/purchase_stock_account/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_stock_account/.kosh/bindings.js +15 -0
- package/dist/purchase_stock_account/.kosh/schema.d.ts +2155 -0
- package/dist/purchase_stock_account/index.d.ts +3 -0
- package/dist/purchase_stock_account/index.js +24 -0
- package/dist/purchase_stock_account/module.d.ts +38015 -0
- package/dist/purchase_stock_account/module.js +168 -0
- package/dist/recruitment/.kosh/bindings.d.ts +22 -0
- package/dist/recruitment/.kosh/bindings.js +15 -0
- package/dist/recruitment/.kosh/schema.d.ts +991 -0
- package/dist/recruitment/demo.d.ts +6 -0
- package/dist/recruitment/demo.js +45 -0
- package/dist/recruitment/index.d.ts +3 -0
- package/dist/recruitment/index.js +385 -0
- package/dist/recruitment/module.d.ts +3249 -0
- package/dist/recruitment/module.js +194 -0
- package/dist/recruitment/web/HireButton.d.ts +9 -0
- package/dist/recruitment/web/HireButton.js +32 -0
- package/dist/recruitment/web/index.d.ts +11 -0
- package/dist/recruitment/web/index.js +16 -0
- package/dist/recruitment/web/messages.d.ts +2 -0
- package/dist/recruitment/web/messages.js +19 -0
- package/dist/reporting/documents.d.ts +5 -0
- package/dist/reporting/documents.js +28 -1
- package/dist/reporting/index.d.ts +1 -1
- package/dist/reporting/index.js +4 -2
- package/dist/reporting/models.js +9 -0
- package/dist/reporting/overviews.d.ts +16 -0
- package/dist/reporting/overviews.js +56 -0
- package/dist/reporting/routes-documents.js +1 -1
- package/dist/reporting/routes.js +138 -80
- package/dist/reporting/web/DashboardView.d.ts +11 -0
- package/dist/reporting/web/DashboardView.js +2 -2
- package/dist/reporting/web/DesignerView.js +5 -0
- package/dist/reporting/web/Overview.d.ts +9 -0
- package/dist/reporting/web/Overview.js +53 -0
- package/dist/reporting/web/index.d.ts +1 -0
- package/dist/reporting/web/index.js +4 -1
- package/dist/reporting/web/messages.js +9 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +181 -6
- package/dist/sale_account/index.js +22 -1
- package/dist/sale_account/module.d.ts +639 -38
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +59 -3
- package/dist/sale_portal/module.d.ts +435 -5
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +732 -3
- package/dist/sale_project/module.d.ts +5349 -208
- package/dist/sale_project/module.js +17 -1
- package/dist/sale_stock/.kosh/bindings.d.ts +22 -0
- package/dist/sale_stock/.kosh/bindings.js +15 -0
- package/dist/sale_stock/.kosh/schema.d.ts +1303 -0
- package/dist/sale_stock/index.d.ts +7 -0
- package/dist/sale_stock/index.js +84 -0
- package/dist/sale_stock/module.d.ts +7514 -0
- package/dist/sale_stock/module.js +146 -0
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +59 -3
- package/dist/sales/index.js +195 -4
- package/dist/sales/module.d.ts +356 -3
- package/dist/sales/module.js +78 -3
- package/dist/server/api/metadata.d.ts +5 -0
- package/dist/server/api/metadata.js +5 -0
- package/dist/server/api/rest.js +64 -1
- package/dist/server/api/views.js +1 -0
- package/dist/server/app-settings.d.ts +7 -0
- package/dist/server/app-settings.js +10 -0
- package/dist/server/auth/base.js +9 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/settings/app-settings.d.ts +2 -0
- package/dist/settings/app-settings.js +518 -0
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/people.js +29 -5
- package/dist/settings/web/AppSettingsPage.d.ts +11 -0
- package/dist/settings/web/AppSettingsPage.js +210 -0
- package/dist/settings/web/OverviewPage.js +16 -3
- package/dist/settings/web/PeoplePage.js +20 -6
- package/dist/settings/web/index.d.ts +1 -0
- package/dist/settings/web/index.js +3 -0
- package/dist/settings/web/messages.js +118 -2
- 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.d.ts +22 -0
- package/dist/stock/.kosh/bindings.js +15 -0
- package/dist/stock/.kosh/schema.d.ts +1222 -0
- package/dist/stock/demo.d.ts +8 -0
- package/dist/stock/demo.js +82 -0
- package/dist/stock/index.d.ts +4 -0
- package/dist/stock/index.js +903 -0
- package/dist/stock/module.d.ts +7856 -0
- package/dist/stock/module.js +1880 -0
- 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/ScanBox.d.ts +8 -0
- package/dist/stock/web/ScanBox.js +90 -0
- package/dist/stock/web/index.d.ts +13 -0
- package/dist/stock/web/index.js +20 -0
- package/dist/stock/web/messages.d.ts +2 -0
- package/dist/stock/web/messages.js +77 -0
- package/dist/stock_account/.kosh/bindings.d.ts +22 -0
- package/dist/stock_account/.kosh/bindings.js +15 -0
- package/dist/stock_account/.kosh/schema.d.ts +2068 -0
- package/dist/stock_account/index.d.ts +3 -0
- package/dist/stock_account/index.js +140 -0
- package/dist/stock_account/module.d.ts +11523 -0
- package/dist/stock_account/module.js +339 -0
- package/dist/storage/attachments.d.ts +5 -0
- package/dist/storage/attachments.js +12 -1
- package/dist/storage/models.js +3 -0
- package/dist/storage/routes.js +13 -2
- package/dist/todo/.kosh/bindings.d.ts +22 -0
- package/dist/todo/.kosh/bindings.js +15 -0
- package/dist/todo/.kosh/schema.d.ts +732 -0
- package/dist/todo/demo.d.ts +6 -0
- package/dist/todo/demo.js +35 -0
- package/dist/todo/index.d.ts +3 -0
- package/dist/todo/index.js +187 -0
- package/dist/todo/module.d.ts +1180 -0
- package/dist/todo/module.js +130 -0
- package/dist/trade_finance/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance/.kosh/bindings.js +15 -0
- package/dist/trade_finance/.kosh/schema.d.ts +884 -0
- package/dist/trade_finance/demo.d.ts +6 -0
- package/dist/trade_finance/demo.js +63 -0
- package/dist/trade_finance/index.d.ts +3 -0
- package/dist/trade_finance/index.js +415 -0
- package/dist/trade_finance/module.d.ts +3779 -0
- package/dist/trade_finance/module.js +507 -0
- package/dist/trade_finance_account/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_account/.kosh/bindings.js +15 -0
- package/dist/trade_finance_account/.kosh/schema.d.ts +1830 -0
- package/dist/trade_finance_account/index.d.ts +3 -0
- package/dist/trade_finance_account/index.js +93 -0
- package/dist/trade_finance_account/module.d.ts +8074 -0
- package/dist/trade_finance_account/module.js +245 -0
- package/dist/trade_finance_purchase/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_purchase/.kosh/bindings.js +15 -0
- package/dist/trade_finance_purchase/.kosh/schema.d.ts +1246 -0
- package/dist/trade_finance_purchase/index.d.ts +8 -0
- package/dist/trade_finance_purchase/index.js +50 -0
- package/dist/trade_finance_purchase/module.d.ts +4257 -0
- package/dist/trade_finance_purchase/module.js +44 -0
- package/dist/trade_finance_sale/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_sale/.kosh/bindings.js +15 -0
- package/dist/trade_finance_sale/.kosh/schema.d.ts +1072 -0
- package/dist/trade_finance_sale/index.d.ts +8 -0
- package/dist/trade_finance_sale/index.js +50 -0
- package/dist/trade_finance_sale/module.d.ts +4281 -0
- package/dist/trade_finance_sale/module.js +44 -0
- package/dist/ui/api.d.ts +2 -1
- package/dist/ui/api.js +2 -1
- package/dist/ui/app.js +26 -13
- package/dist/ui/components/AppIcon.js +30 -1
- package/dist/ui/components/primitives.d.ts +2 -0
- package/dist/ui/components/primitives.js +7 -1
- package/dist/ui/i18n/messages.d.ts +27 -0
- package/dist/ui/i18n/messages.js +46 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +1 -0
- package/dist/ui/offline/queue.d.ts +5 -1
- package/dist/ui/offline/queue.js +2 -0
- package/dist/ui/registry.d.ts +5 -0
- package/dist/ui/shell/Home.js +55 -4
- package/dist/ui/views/FormView.js +102 -19
- package/dist/ui/views/KanbanView.d.ts +2 -0
- package/dist/ui/views/KanbanView.js +40 -3
- package/dist/ui/views/ListView.js +110 -11
- package/dist/ui/views/StatsRow.d.ts +14 -0
- package/dist/ui/views/StatsRow.js +88 -0
- package/dist/ui/views/widgets.d.ts +2 -1
- package/dist/ui/views/widgets.js +200 -1
- package/dist/views/builders.d.ts +19 -2
- package/dist/views/builders.js +21 -1
- package/dist/views/condition.d.ts +6 -0
- package/dist/views/condition.js +20 -0
- package/dist/views/documents.d.ts +8 -0
- package/dist/views/extend.d.ts +2 -2
- package/dist/views/extend.js +11 -1
- package/dist/views/index.d.ts +2 -2
- package/dist/views/index.js +2 -2
- package/dist/views/types.d.ts +52 -5
- package/dist/views/validate.js +39 -1
- package/dist/website/.kosh/bindings.d.ts +22 -0
- package/dist/website/.kosh/bindings.js +15 -0
- package/dist/website/.kosh/schema.d.ts +881 -0
- package/dist/website/demo.d.ts +6 -0
- package/dist/website/demo.js +115 -0
- package/dist/website/index.d.ts +9 -0
- package/dist/website/index.js +251 -0
- package/dist/website/module.d.ts +2987 -0
- package/dist/website/module.js +282 -0
- package/dist/website/render.d.ts +45 -0
- package/dist/website/render.js +102 -0
- package/dist/website/routes.d.ts +12 -0
- package/dist/website/routes.js +246 -0
- package/dist/website/web/PagePreview.d.ts +7 -0
- package/dist/website/web/PagePreview.js +33 -0
- package/dist/website/web/index.d.ts +11 -0
- package/dist/website/web/index.js +16 -0
- package/dist/website/web/messages.d.ts +2 -0
- package/dist/website/web/messages.js +15 -0
- package/dist/website_crm/.kosh/bindings.d.ts +22 -0
- package/dist/website_crm/.kosh/bindings.js +15 -0
- package/dist/website_crm/.kosh/schema.d.ts +967 -0
- package/dist/website_crm/index.d.ts +3 -0
- package/dist/website_crm/index.js +39 -0
- package/dist/website_crm/module.d.ts +2956 -0
- package/dist/website_crm/module.js +44 -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 +200 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documents' demo data (RFC 0008 §5.8): the company's folders — Contracts and Suppliers open to everyone with
|
|
3
|
+
* Documents, HR kept to its members —, two tags, and a request to a supplier for their trade licence.
|
|
4
|
+
*/
|
|
5
|
+
import type { DemoContext } from '../modules-sdk/index.js';
|
|
6
|
+
export declare function documentsDemo(ctx: DemoContext): Promise<string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { idByName } from '../modules-sdk/index.js';
|
|
2
|
+
const DINA = { login: 'dina', name: 'Dina Rahman', groups: ['documents.manager'] };
|
|
3
|
+
export async function documentsDemo(ctx) {
|
|
4
|
+
await ctx.as(DINA, async (raw) => {
|
|
5
|
+
const env = raw;
|
|
6
|
+
const folders = await env
|
|
7
|
+
.model('documents.folder')
|
|
8
|
+
.create([{ name: 'Contracts' }, { name: 'Suppliers' }, { name: 'HR', restricted: true }]);
|
|
9
|
+
await env.model('documents.tag').create([{ name: 'Signed' }, { name: 'To review' }]);
|
|
10
|
+
const supplier = (await idByName(env, 'res.partner', 'Padma Cement'));
|
|
11
|
+
await env.model('documents.request').create([
|
|
12
|
+
{
|
|
13
|
+
name: 'Your trade licence (2026)',
|
|
14
|
+
folder: folders.ids[1],
|
|
15
|
+
partner: (supplier ?? null),
|
|
16
|
+
email: 'accounts@padmacement.example',
|
|
17
|
+
message: 'A scan or a photo is fine.',
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
return 'Documents: 3 folders (HR for its members), 2 tags, a request to a supplier.';
|
|
22
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type Mailer } from '../mail/index.js';
|
|
2
|
+
import { type Storage } from '../storage/index.js';
|
|
3
|
+
import type { Env } from './.kosh/bindings.js';
|
|
4
|
+
/** A new secret for a link: given once; only its digest is kept. */
|
|
5
|
+
export declare const newToken: () => string;
|
|
6
|
+
/**
|
|
7
|
+
* Stores `data` as the document's new version (the document read as the user first, so their rules apply); the
|
|
8
|
+
* document's file, type, size and count of versions follow.
|
|
9
|
+
*/
|
|
10
|
+
export declare function addVersion(env: Env, storage: Storage, id: number, file: {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly mime?: string | undefined;
|
|
13
|
+
readonly data: Uint8Array;
|
|
14
|
+
}): Promise<{
|
|
15
|
+
id: number;
|
|
16
|
+
versions: number;
|
|
17
|
+
}>;
|
|
18
|
+
/** The versions of a document the user may read, newest first. */
|
|
19
|
+
export declare function versionsOf(env: Env, id: number): Promise<{
|
|
20
|
+
id: number;
|
|
21
|
+
name: string;
|
|
22
|
+
mime: string;
|
|
23
|
+
size: number;
|
|
24
|
+
at: string;
|
|
25
|
+
by: number | null;
|
|
26
|
+
}[]>;
|
|
27
|
+
/**
|
|
28
|
+
* One search: the documents whose name matches, and the attachments of any record whose name matches — each kept
|
|
29
|
+
* only when the user may read its record.
|
|
30
|
+
*/
|
|
31
|
+
export declare function searchAll(env: Env, q: string, canRead: (model: string, id: number) => Promise<boolean>): Promise<{
|
|
32
|
+
documents: {
|
|
33
|
+
id: number;
|
|
34
|
+
name: string;
|
|
35
|
+
folder: string;
|
|
36
|
+
mime: string | null;
|
|
37
|
+
}[];
|
|
38
|
+
attachments: {
|
|
39
|
+
id: number;
|
|
40
|
+
name: string;
|
|
41
|
+
model: string;
|
|
42
|
+
record: number;
|
|
43
|
+
mime: string;
|
|
44
|
+
}[];
|
|
45
|
+
}>;
|
|
46
|
+
/** A share link of a document or a folder the user may read, for `days` (1 to 90), with an optional password. */
|
|
47
|
+
export declare function makeShare(env: Env, input: {
|
|
48
|
+
document?: number;
|
|
49
|
+
folder?: number;
|
|
50
|
+
days?: number;
|
|
51
|
+
password?: string;
|
|
52
|
+
}): Promise<{
|
|
53
|
+
token: string;
|
|
54
|
+
expiresAt: string;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* What a share link opens (as the system): its document, or its folder's documents, while it has not expired or
|
|
58
|
+
* been revoked, and with its password when it has one. @throws 404 for an unknown, expired or revoked link, 401
|
|
59
|
+
* for a missing or wrong password
|
|
60
|
+
*/
|
|
61
|
+
export declare function openShare(env: Env, token: string, password: string): Promise<{
|
|
62
|
+
share: number;
|
|
63
|
+
documents: {
|
|
64
|
+
id: number;
|
|
65
|
+
name: string;
|
|
66
|
+
mime: string | null;
|
|
67
|
+
size: number | null;
|
|
68
|
+
attachment: number | null;
|
|
69
|
+
}[];
|
|
70
|
+
}>;
|
|
71
|
+
/** The storage key of an attachment (as the system). */
|
|
72
|
+
export declare function keyOf(env: Env, attachment: number): Promise<string | null>;
|
|
73
|
+
export declare function configureRequests(next: {
|
|
74
|
+
mailer: Mailer | undefined;
|
|
75
|
+
apiUrl: string;
|
|
76
|
+
}): void;
|
|
77
|
+
/** As requests are sent: a new link each (only its digest kept), by email after the commit. */
|
|
78
|
+
export declare function announceRequests(env: Env, ids: readonly number[]): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Reminds the sent requests that are late (past their due date, or a week after they were sent), once each: a new
|
|
81
|
+
* link (the old one stops).
|
|
82
|
+
*/
|
|
83
|
+
export declare function remindRequests(env: Env, now?: Date): Promise<number>;
|
|
84
|
+
/** The open request of a link (as the system), or null. */
|
|
85
|
+
export declare function requestOf(env: Env, token: string): Promise<{
|
|
86
|
+
id: number;
|
|
87
|
+
name: string;
|
|
88
|
+
company: string;
|
|
89
|
+
message: string | null;
|
|
90
|
+
} | null>;
|
|
91
|
+
/** Takes a request's file (as the system): a document in its folder with the file, the request received, once. */
|
|
92
|
+
export declare function fulfil(env: Env, storage: Storage, token: string, file: {
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly mime?: string | undefined;
|
|
95
|
+
readonly data: Uint8Array;
|
|
96
|
+
}): Promise<{
|
|
97
|
+
document: number;
|
|
98
|
+
}>;
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documents' logic (RFC 0024 §2.8): versions — each upload a stored file of the document, the latest its current
|
|
3
|
+
* one —; one search over the documents and every record's attachments a user may read; share links that serve a
|
|
4
|
+
* document or a folder's documents until they expire (and with the password, when set); and requests whose link
|
|
5
|
+
* takes the file into the request's folder, once.
|
|
6
|
+
*/
|
|
7
|
+
import { randomBytes } from 'node:crypto';
|
|
8
|
+
import { layout } from '../mail/index.js';
|
|
9
|
+
import { digest, HttpProblem, hashPassword, verifyPassword } from '../server/index.js';
|
|
10
|
+
import { orm } from '../server/orm.js';
|
|
11
|
+
import { saveAttachment } from '../storage/index.js';
|
|
12
|
+
const DOCS = new Set(['documents.document']);
|
|
13
|
+
const DAY = 86_400_000;
|
|
14
|
+
/** A date as `YYYY-MM-DD` (date-only values from PostgreSQL may read as local midnights). */
|
|
15
|
+
const dayOf = (v) => {
|
|
16
|
+
if (!(v instanceof Date))
|
|
17
|
+
return String(v ?? '').slice(0, 10);
|
|
18
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
19
|
+
return `${v.getFullYear()}-${pad(v.getMonth() + 1)}-${pad(v.getDate())}`;
|
|
20
|
+
};
|
|
21
|
+
const notFound = (what) => new HttpProblem(404, 'not-found', 'Not found', `There is no ${what}.`);
|
|
22
|
+
/** A new secret for a link: given once; only its digest is kept. */
|
|
23
|
+
export const newToken = () => randomBytes(24).toString('base64url');
|
|
24
|
+
/**
|
|
25
|
+
* Stores `data` as the document's new version (the document read as the user first, so their rules apply); the
|
|
26
|
+
* document's file, type, size and count of versions follow.
|
|
27
|
+
*/
|
|
28
|
+
export async function addVersion(env, storage, id, file) {
|
|
29
|
+
const [doc] = await (await env.model('documents.document').search({
|
|
30
|
+
where: { id: orm.asId(id, 'documents.document') },
|
|
31
|
+
limit: 1,
|
|
32
|
+
})).load({});
|
|
33
|
+
if (doc === undefined)
|
|
34
|
+
throw notFound(`document ${id}`);
|
|
35
|
+
return env.asSuperuser({ reason: 'document version' }, async (su) => {
|
|
36
|
+
const saved = await saveAttachment(su, storage, DOCS, {
|
|
37
|
+
model: 'documents.document',
|
|
38
|
+
id: doc.id,
|
|
39
|
+
name: file.name,
|
|
40
|
+
mime: file.mime,
|
|
41
|
+
data: file.data,
|
|
42
|
+
});
|
|
43
|
+
// The count of its files (thumbnails aside): every upload is one.
|
|
44
|
+
const att = su.model('storage.attachment');
|
|
45
|
+
const versions = (await att.search({
|
|
46
|
+
where: { resModel: 'documents.document', resId: doc.id, variantOf: null },
|
|
47
|
+
})).length;
|
|
48
|
+
await su
|
|
49
|
+
.model('documents.document')
|
|
50
|
+
.browse([doc.id])
|
|
51
|
+
.write({ attachment: saved.id, mime: saved.mime, size: saved.size, versions });
|
|
52
|
+
await su.flush();
|
|
53
|
+
return { id: saved.id, versions };
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/** The versions of a document the user may read, newest first. */
|
|
57
|
+
export async function versionsOf(env, id) {
|
|
58
|
+
const [doc] = await (await env.model('documents.document').search({
|
|
59
|
+
where: { id: orm.asId(id, 'documents.document') },
|
|
60
|
+
limit: 1,
|
|
61
|
+
})).load({});
|
|
62
|
+
if (doc === undefined)
|
|
63
|
+
throw notFound(`document ${id}`);
|
|
64
|
+
return env.asSuperuser({ reason: 'document versions' }, async (su) => {
|
|
65
|
+
const att = su.model('storage.attachment');
|
|
66
|
+
const rows = await (await att.search({
|
|
67
|
+
where: { resModel: 'documents.document', resId: doc.id, variantOf: null },
|
|
68
|
+
order: ['id desc'],
|
|
69
|
+
})).load({});
|
|
70
|
+
return [...rows].map((r) => ({
|
|
71
|
+
id: r.id,
|
|
72
|
+
name: r.name,
|
|
73
|
+
mime: r.mime,
|
|
74
|
+
size: r.size,
|
|
75
|
+
at: r.createdAt instanceof Date ? r.createdAt.toISOString() : String(r.createdAt),
|
|
76
|
+
by: r.createdBy?.id ?? null,
|
|
77
|
+
}));
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* One search: the documents whose name matches, and the attachments of any record whose name matches — each kept
|
|
82
|
+
* only when the user may read its record.
|
|
83
|
+
*/
|
|
84
|
+
export async function searchAll(env, q, canRead) {
|
|
85
|
+
const text = q.trim().slice(0, 100);
|
|
86
|
+
if (text === '')
|
|
87
|
+
return { documents: [], attachments: [] };
|
|
88
|
+
const docs = await (await env.model('documents.document').search({
|
|
89
|
+
where: { name: { ilike: `%${text}%` } },
|
|
90
|
+
limit: 50,
|
|
91
|
+
})).load({ folder: true });
|
|
92
|
+
const found = await env.asSuperuser({ reason: 'document search' }, async (su) => {
|
|
93
|
+
const att = su.model('storage.attachment');
|
|
94
|
+
return [
|
|
95
|
+
...(await (await att.search({
|
|
96
|
+
where: {
|
|
97
|
+
name: { ilike: `%${text}%` },
|
|
98
|
+
variantOf: null,
|
|
99
|
+
resModel: { ne: 'documents.document' },
|
|
100
|
+
},
|
|
101
|
+
order: ['id desc'],
|
|
102
|
+
limit: 100,
|
|
103
|
+
})).load({})),
|
|
104
|
+
];
|
|
105
|
+
});
|
|
106
|
+
const attachments = [];
|
|
107
|
+
for (const a of found) {
|
|
108
|
+
if (attachments.length >= 50)
|
|
109
|
+
break;
|
|
110
|
+
if (await canRead(a.resModel, a.resId))
|
|
111
|
+
attachments.push({
|
|
112
|
+
id: a.id,
|
|
113
|
+
name: a.name,
|
|
114
|
+
model: a.resModel,
|
|
115
|
+
record: a.resId,
|
|
116
|
+
mime: a.mime,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
documents: [...docs].map((d) => ({
|
|
121
|
+
id: d.id,
|
|
122
|
+
name: d.name,
|
|
123
|
+
folder: d.folder.fullName ?? d.folder.name,
|
|
124
|
+
mime: d.mime,
|
|
125
|
+
})),
|
|
126
|
+
attachments,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** A share link of a document or a folder the user may read, for `days` (1 to 90), with an optional password. */
|
|
130
|
+
export async function makeShare(env, input) {
|
|
131
|
+
const days = input.days ?? 7;
|
|
132
|
+
if (!Number.isSafeInteger(days) || days < 1 || days > 90)
|
|
133
|
+
throw new HttpProblem(400, 'invalid-input', 'Invalid expiry', 'From 1 to 90 days.');
|
|
134
|
+
if (input.document !== undefined) {
|
|
135
|
+
const found = await env
|
|
136
|
+
.model('documents.document')
|
|
137
|
+
.search({ where: { id: orm.asId(input.document, 'documents.document') }, limit: 1 });
|
|
138
|
+
if (found.length === 0)
|
|
139
|
+
throw notFound(`document ${input.document}`);
|
|
140
|
+
}
|
|
141
|
+
else if (input.folder !== undefined) {
|
|
142
|
+
const found = await env
|
|
143
|
+
.model('documents.folder')
|
|
144
|
+
.search({ where: { id: orm.asId(input.folder, 'documents.folder') }, limit: 1 });
|
|
145
|
+
if (found.length === 0)
|
|
146
|
+
throw notFound(`folder ${input.folder}`);
|
|
147
|
+
}
|
|
148
|
+
else
|
|
149
|
+
throw new HttpProblem(400, 'invalid-input', 'Nothing to share', 'A document or a folder.');
|
|
150
|
+
const password = input.password ?? '';
|
|
151
|
+
if (password !== '' && password.length < 6)
|
|
152
|
+
throw new HttpProblem(400, 'invalid-input', 'Short password', 'At least 6 characters.');
|
|
153
|
+
const token = newToken();
|
|
154
|
+
const expiresAt = new Date(Date.now() + days * DAY);
|
|
155
|
+
await env.model('documents.share').create([
|
|
156
|
+
{
|
|
157
|
+
...(input.document === undefined ? {} : { document: input.document }),
|
|
158
|
+
...(input.folder === undefined ? {} : { folder: input.folder }),
|
|
159
|
+
tokenHash: digest(token),
|
|
160
|
+
passwordHash: password === '' ? null : await hashPassword(password),
|
|
161
|
+
expiresAt,
|
|
162
|
+
},
|
|
163
|
+
]);
|
|
164
|
+
await env.flush();
|
|
165
|
+
return { token, expiresAt: expiresAt.toISOString() };
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* What a share link opens (as the system): its document, or its folder's documents, while it has not expired or
|
|
169
|
+
* been revoked, and with its password when it has one. @throws 404 for an unknown, expired or revoked link, 401
|
|
170
|
+
* for a missing or wrong password
|
|
171
|
+
*/
|
|
172
|
+
export async function openShare(env, token, password) {
|
|
173
|
+
if (token === '' || token.length > 100)
|
|
174
|
+
throw notFound('such link');
|
|
175
|
+
const [share] = await (await env.model('documents.share').search({ where: { tokenHash: digest(token) }, limit: 1 })).load({ document: true, folder: true });
|
|
176
|
+
if (share === undefined || share.revoked || share.expiresAt.getTime() < Date.now())
|
|
177
|
+
throw notFound('such link (it may have expired)');
|
|
178
|
+
if (share.passwordHash !== null && !(await verifyPassword(password, share.passwordHash)))
|
|
179
|
+
throw new HttpProblem(401, 'password', 'Password', 'This link needs its password.');
|
|
180
|
+
const docs = share.document !== null
|
|
181
|
+
? await env.model('documents.document').browse([share.document.id]).load({})
|
|
182
|
+
: await (await env.model('documents.document').search({
|
|
183
|
+
where: { folder: share.folder?.id },
|
|
184
|
+
order: ['name asc'],
|
|
185
|
+
})).load({});
|
|
186
|
+
return {
|
|
187
|
+
share: share.id,
|
|
188
|
+
documents: [...docs].map((d) => ({
|
|
189
|
+
id: d.id,
|
|
190
|
+
name: d.name,
|
|
191
|
+
mime: d.mime,
|
|
192
|
+
size: d.size,
|
|
193
|
+
attachment: d.attachment?.id ?? null,
|
|
194
|
+
})),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/** The storage key of an attachment (as the system). */
|
|
198
|
+
export async function keyOf(env, attachment) {
|
|
199
|
+
const att = env.model('storage.attachment');
|
|
200
|
+
const [a] = [...(await att.browse([attachment]).load(['key']))];
|
|
201
|
+
return a?.key ?? null;
|
|
202
|
+
}
|
|
203
|
+
/** Who sends the requests and where their links point: set by the module. */
|
|
204
|
+
let config = {
|
|
205
|
+
mailer: undefined,
|
|
206
|
+
apiUrl: 'http://localhost:3000',
|
|
207
|
+
};
|
|
208
|
+
export function configureRequests(next) {
|
|
209
|
+
config = next;
|
|
210
|
+
}
|
|
211
|
+
/** As requests are sent: a new link each (only its digest kept), by email after the commit. */
|
|
212
|
+
export async function announceRequests(env, ids) {
|
|
213
|
+
for (const r of await env
|
|
214
|
+
.model('documents.request')
|
|
215
|
+
.browse(ids)
|
|
216
|
+
.load({ company: true })) {
|
|
217
|
+
const token = newToken();
|
|
218
|
+
await env
|
|
219
|
+
.model('documents.request')
|
|
220
|
+
.browse([r.id])
|
|
221
|
+
.write({ tokenHash: digest(token), sentAt: new Date() });
|
|
222
|
+
const due = r.dueDate === null ? null : dayOf(r.dueDate);
|
|
223
|
+
mail(env, config.mailer, r.email, {
|
|
224
|
+
title: `${r.company.name} asks you for a document`,
|
|
225
|
+
paragraphs: [
|
|
226
|
+
`${r.company.name} asks you for: ${r.name}.`,
|
|
227
|
+
...(r.message === null || r.message === '' ? [] : [r.message]),
|
|
228
|
+
...(due === null ? [] : [`Please send it by ${due}.`]),
|
|
229
|
+
],
|
|
230
|
+
action: {
|
|
231
|
+
label: 'Upload it',
|
|
232
|
+
url: `${config.apiUrl}/api/v1/public/documents/requests/${token}`,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function mail(env, mailer, to, content) {
|
|
238
|
+
if (mailer === undefined)
|
|
239
|
+
return;
|
|
240
|
+
const body = layout(content);
|
|
241
|
+
env.afterCommit(async () => {
|
|
242
|
+
await mailer
|
|
243
|
+
.send({ to, subject: content.title, html: body.html, text: body.text })
|
|
244
|
+
.catch(() => undefined);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Reminds the sent requests that are late (past their due date, or a week after they were sent), once each: a new
|
|
249
|
+
* link (the old one stops).
|
|
250
|
+
*/
|
|
251
|
+
export async function remindRequests(env, now = new Date()) {
|
|
252
|
+
const { mailer, apiUrl } = config;
|
|
253
|
+
const found = await (await env.model('documents.request').search({
|
|
254
|
+
where: { state: 'sent', remindedAt: { isNull: true } },
|
|
255
|
+
})).load({ company: true });
|
|
256
|
+
let reminded = 0;
|
|
257
|
+
for (const r of found) {
|
|
258
|
+
const due = r.dueDate !== null
|
|
259
|
+
? new Date(`${dayOf(r.dueDate)}T23:59:59Z`)
|
|
260
|
+
: new Date((r.sentAt?.getTime() ?? now.getTime()) + 7 * DAY);
|
|
261
|
+
if (due.getTime() > now.getTime())
|
|
262
|
+
continue;
|
|
263
|
+
const token = newToken();
|
|
264
|
+
await env
|
|
265
|
+
.model('documents.request')
|
|
266
|
+
.browse([r.id])
|
|
267
|
+
.write({ tokenHash: digest(token), remindedAt: now });
|
|
268
|
+
mail(env, mailer, r.email, {
|
|
269
|
+
title: `Reminder: ${r.company.name} is waiting for ${r.name}`,
|
|
270
|
+
paragraphs: [`${r.company.name} is still waiting for: ${r.name}.`],
|
|
271
|
+
action: { label: 'Upload it', url: `${apiUrl}/api/v1/public/documents/requests/${token}` },
|
|
272
|
+
});
|
|
273
|
+
reminded += 1;
|
|
274
|
+
}
|
|
275
|
+
await env.flush();
|
|
276
|
+
return reminded;
|
|
277
|
+
}
|
|
278
|
+
/** The open request of a link (as the system), or null. */
|
|
279
|
+
export async function requestOf(env, token) {
|
|
280
|
+
if (token === '' || token.length > 100)
|
|
281
|
+
return null;
|
|
282
|
+
const [r] = await (await env
|
|
283
|
+
.model('documents.request')
|
|
284
|
+
.search({ where: { tokenHash: digest(token), state: 'sent' }, limit: 1 })).load({ company: true });
|
|
285
|
+
return r === undefined
|
|
286
|
+
? null
|
|
287
|
+
: { id: r.id, name: r.name, company: r.company.name, message: r.message };
|
|
288
|
+
}
|
|
289
|
+
/** Takes a request's file (as the system): a document in its folder with the file, the request received, once. */
|
|
290
|
+
export async function fulfil(env, storage, token, file) {
|
|
291
|
+
const open = await requestOf(env, token);
|
|
292
|
+
if (open === null)
|
|
293
|
+
throw notFound('open request for this link (it may be answered already)');
|
|
294
|
+
const [r] = await env
|
|
295
|
+
.model('documents.request')
|
|
296
|
+
.browse([open.id])
|
|
297
|
+
.load({ folder: true, partner: true, company: true });
|
|
298
|
+
if (r === undefined)
|
|
299
|
+
throw notFound('request');
|
|
300
|
+
const made = await env.model('documents.document').create([
|
|
301
|
+
{
|
|
302
|
+
name: `${r.name} — ${r.partner?.name ?? r.email}`,
|
|
303
|
+
folder: r.folder.id,
|
|
304
|
+
company: r.company.id,
|
|
305
|
+
owner: r.createdBy?.id ?? null,
|
|
306
|
+
request: r.id,
|
|
307
|
+
},
|
|
308
|
+
]);
|
|
309
|
+
const id = made.ids[0];
|
|
310
|
+
await env.flush();
|
|
311
|
+
await addVersion(env, storage, id, file);
|
|
312
|
+
const one = env.model('documents.request').browse([r.id]);
|
|
313
|
+
await one.write({ document: id, tokenHash: null });
|
|
314
|
+
await one.receive();
|
|
315
|
+
await env.emit('documents.request.received', { id: r.id });
|
|
316
|
+
await env.flush();
|
|
317
|
+
return { document: id };
|
|
318
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* `shutro-erp/documents` (RFC 0024 §2.8): the **Documents** app. Folders (open, or kept to their members), documents with
|
|
4
|
+
* tags and versions, one search over documents and every record's attachments, share links with an expiry and an
|
|
5
|
+
* optional password, and requests that ask a person for a file by email and take it into the right folder.
|
|
6
|
+
*
|
|
7
|
+
* - `POST /api/v1/documents/upload?folder=&name=` the raw body is the file (`X-Filename`): a new document
|
|
8
|
+
* - `POST /api/v1/documents/:id/versions` a new version (the raw body)
|
|
9
|
+
* - `GET /api/v1/documents/:id/versions` its versions, newest first
|
|
10
|
+
* - `GET /api/v1/documents/search?q=` documents and record attachments the user may read
|
|
11
|
+
* - `POST /api/v1/documents/shares` `{ document | folder, days?, password? }` → `{ url }`
|
|
12
|
+
* - `POST /api/v1/documents/requests/remind` the late requests reminded now (managers; hourly too)
|
|
13
|
+
* - `GET /api/v1/public/documents/shares/:token` what a link shares (`x-share-password` when it has one)
|
|
14
|
+
* - `GET /api/v1/public/documents/shares/:token/documents/:id` a shared document's file
|
|
15
|
+
* - `GET|POST /api/v1/public/documents/requests/:token` the upload page of a request; its file (the raw body)
|
|
16
|
+
*/
|
|
17
|
+
import { type Mailer } from '../mail/index.js';
|
|
18
|
+
import { defineModule } from '../modules-sdk/index.js';
|
|
19
|
+
export { addVersion, fulfil, makeShare, openShare, remindRequests, searchAll, versionsOf, } from './documents.js';
|
|
20
|
+
export { DocumentsDocument, DocumentsFolder, DocumentsRequest, DocumentsShare, DocumentsTag, documentsShutro, } from './module.js';
|
|
21
|
+
export interface DocumentsOptions {
|
|
22
|
+
/** Who sends the requests; default: SMTP from the environment (`SMTP_URL`), none without it. */
|
|
23
|
+
readonly mailer?: Mailer | undefined;
|
|
24
|
+
/** The API's public address, which request and share links point to (`KOSH_API_URL`). */
|
|
25
|
+
readonly apiUrl?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Documents with explicit options (tests: a memory mailer). */
|
|
28
|
+
export declare function documentsModule(options?: DocumentsOptions): ReturnType<typeof defineModule>;
|
|
29
|
+
/** Documents (mail from the environment). */
|
|
30
|
+
export declare const documents: ReturnType<typeof defineModule>;
|