shutro-erp 0.3.4 → 0.3.5
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_portal/.kosh/bindings.js +1 -1
- package/dist/account_portal/.kosh/schema.d.ts +54 -3
- package/dist/account_portal/module.d.ts +359 -6
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +54 -3
- package/dist/accounting/index.js +214 -2
- package/dist/accounting/module.d.ts +217 -5
- package/dist/accounting/module.js +23 -2
- 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 +48 -0
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +137 -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 +82 -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 +799 -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 +1843 -0
- package/dist/crm/module.js +207 -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 +1639 -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 +6968 -0
- package/dist/event_account/module.js +90 -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 +54 -3
- package/dist/l10n_bd/module.d.ts +359 -6
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +54 -3
- package/dist/l10n_in/module.d.ts +380 -7
- 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 +1371 -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 +6953 -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 +70 -0
- 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 +1378 -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 +392 -0
- package/dist/mrp/module.d.ts +8608 -0
- package/dist/mrp/module.js +695 -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 +2106 -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 +20840 -0
- package/dist/mrp_account/module.js +123 -0
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +54 -3
- package/dist/payment/module.d.ts +359 -6
- package/dist/portal/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +78 -3
- 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 +1690 -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 +349 -0
- package/dist/pos/module.d.ts +9636 -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 +2015 -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 +11935 -0
- package/dist/pos_stock/module.js +115 -0
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +51 -1
- package/dist/product/index.js +81 -4
- package/dist/product/module.d.ts +43 -1
- package/dist/product/module.js +9 -2
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +54 -3
- package/dist/project/index.js +147 -7
- package/dist/project/module.d.ts +210 -2
- package/dist/project/module.js +52 -5
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +54 -3
- package/dist/project_portal/module.d.ts +353 -4
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +54 -3
- package/dist/purchase/index.js +163 -3
- package/dist/purchase/module.d.ts +215 -3
- package/dist/purchase/module.js +21 -3
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +55 -3
- package/dist/purchase_account/index.js +26 -1
- package/dist/purchase_account/module.d.ts +393 -7
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +54 -3
- package/dist/purchase_portal/module.d.ts +366 -5
- 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 +1310 -0
- package/dist/purchase_stock/index.d.ts +7 -0
- package/dist/purchase_stock/index.js +91 -0
- package/dist/purchase_stock/module.d.ts +6763 -0
- package/dist/purchase_stock/module.js +144 -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 +1959 -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 +35366 -0
- package/dist/purchase_stock_account/module.js +162 -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 +990 -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 +3247 -0
- package/dist/recruitment/module.js +193 -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 +59 -3
- package/dist/sale_account/index.js +22 -1
- package/dist/sale_account/module.d.ts +461 -7
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +58 -3
- package/dist/sale_portal/module.d.ts +434 -5
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +60 -3
- package/dist/sale_project/module.d.ts +476 -6
- 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 +1228 -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 +6791 -0
- package/dist/sale_stock/module.js +146 -0
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +58 -3
- package/dist/sales/index.js +191 -4
- package/dist/sales/module.d.ts +355 -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/stock/.kosh/bindings.d.ts +22 -0
- package/dist/stock/.kosh/bindings.js +15 -0
- package/dist/stock/.kosh/schema.d.ts +1147 -0
- package/dist/stock/demo.d.ts +7 -0
- package/dist/stock/demo.js +55 -0
- package/dist/stock/index.d.ts +3 -0
- package/dist/stock/index.js +674 -0
- package/dist/stock/module.d.ts +6330 -0
- package/dist/stock/module.js +1325 -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 +11 -0
- package/dist/stock/web/index.js +16 -0
- package/dist/stock/web/messages.d.ts +2 -0
- package/dist/stock/web/messages.js +25 -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 +1875 -0
- package/dist/stock_account/index.d.ts +3 -0
- package/dist/stock_account/index.js +130 -0
- package/dist/stock_account/module.d.ts +10655 -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 +413 -0
- package/dist/trade_finance/module.d.ts +3779 -0
- package/dist/trade_finance/module.js +505 -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 +1711 -0
- package/dist/trade_finance_account/index.d.ts +3 -0
- package/dist/trade_finance_account/index.js +92 -0
- package/dist/trade_finance_account/module.d.ts +7928 -0
- package/dist/trade_finance_account/module.js +244 -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 +1153 -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 +4252 -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 +1071 -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 +4280 -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 +2 -1
- package/dist/ui/components/AppIcon.js +23 -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 +23 -0
- package/dist/ui/i18n/messages.js +38 -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 +98 -17
- package/dist/ui/views/KanbanView.d.ts +2 -0
- package/dist/ui/views/KanbanView.js +32 -3
- package/dist/ui/views/ListView.js +108 -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 +194 -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 +250 -0
- package/dist/website/module.d.ts +2987 -0
- package/dist/website/module.js +281 -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 +966 -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 +2955 -0
- package/dist/website_crm/module.js +44 -0
- package/package.json +118 -1
package/dist/project/index.js
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import { contacts } from '../contacts/index.js';
|
|
8
8
|
import { messaging } from '../messaging/index.js';
|
|
9
9
|
import { defineModule } from '../modules-sdk/index.js';
|
|
10
|
-
import {
|
|
10
|
+
import { reporting } from '../reporting/index.js';
|
|
11
|
+
import { action, calendar, form, gantt, kanban, list, pivot, search } from '../views/index.js';
|
|
11
12
|
import { projectDemo, SUPPORT_PROJECT } from './demo.js';
|
|
12
13
|
import { ProjectProject, ProjectTask, ProjectTaskStage, ProjectTimesheet, projectShutro, } from './module.js';
|
|
13
14
|
export { SUPPORT_PROJECT } from './demo.js';
|
|
@@ -16,6 +17,30 @@ export const project = defineModule({
|
|
|
16
17
|
shutro: projectShutro,
|
|
17
18
|
kosh: '^0.1.0',
|
|
18
19
|
hooks: { demo: projectDemo },
|
|
20
|
+
// Defaults for tasks and timesheets (RFC 0020), per company.
|
|
21
|
+
settings: {
|
|
22
|
+
sections: [
|
|
23
|
+
{
|
|
24
|
+
key: 'work',
|
|
25
|
+
label: 'Tasks and timesheets',
|
|
26
|
+
description: 'What new tasks start with, and the steps timesheets are entered in.',
|
|
27
|
+
keywords: 'planned hours timesheet rounding step quarter half',
|
|
28
|
+
scope: 'company',
|
|
29
|
+
editors: ['project.manager'],
|
|
30
|
+
fields: [
|
|
31
|
+
{
|
|
32
|
+
key: 'projectPlannedHoursDefault',
|
|
33
|
+
min: 0,
|
|
34
|
+
help: 'Filled in on a new task when its project is chosen; each task can still be changed.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'projectTimesheetStep',
|
|
38
|
+
help: 'Hours that are not a multiple of the step are refused.',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
19
44
|
// support@<inbound domain>: a task in the support project (RFC 0006 §7.1), or the first project there is.
|
|
20
45
|
inboundAliases: [
|
|
21
46
|
{
|
|
@@ -34,7 +59,7 @@ export const project = defineModule({
|
|
|
34
59
|
},
|
|
35
60
|
},
|
|
36
61
|
],
|
|
37
|
-
depends: [contacts, messaging],
|
|
62
|
+
depends: [contacts, messaging, reporting],
|
|
38
63
|
app: {
|
|
39
64
|
code: 'projects',
|
|
40
65
|
label: 'Projects',
|
|
@@ -51,10 +76,89 @@ export const project = defineModule({
|
|
|
51
76
|
implies: ['user'],
|
|
52
77
|
},
|
|
53
78
|
},
|
|
79
|
+
// The Overview (RFC 0022 step 2): what is open, where the hours go, who carries the load.
|
|
80
|
+
overview: {
|
|
81
|
+
cards: [
|
|
82
|
+
{
|
|
83
|
+
id: 'projects_all',
|
|
84
|
+
title: 'Projects',
|
|
85
|
+
kind: 'kpi',
|
|
86
|
+
model: 'project.project',
|
|
87
|
+
measure: 'count',
|
|
88
|
+
w: 3,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: 'open_tasks',
|
|
92
|
+
title: 'Open tasks',
|
|
93
|
+
kind: 'kpi',
|
|
94
|
+
model: 'project.task',
|
|
95
|
+
measure: 'count',
|
|
96
|
+
filter: { 'stage.done': false },
|
|
97
|
+
w: 3,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'hours_month',
|
|
101
|
+
title: 'Hours this month',
|
|
102
|
+
kind: 'kpi',
|
|
103
|
+
model: 'project.timesheet',
|
|
104
|
+
measure: 'sum:hours',
|
|
105
|
+
comparison: { field: 'date', mode: 'previous' },
|
|
106
|
+
w: 3,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'planned_open',
|
|
110
|
+
title: 'Planned hours open',
|
|
111
|
+
kind: 'kpi',
|
|
112
|
+
model: 'project.task',
|
|
113
|
+
measure: 'sum:plannedHours',
|
|
114
|
+
filter: { 'stage.done': false },
|
|
115
|
+
w: 3,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'tasks_by_stage',
|
|
119
|
+
title: 'Tasks by stage',
|
|
120
|
+
kind: 'chart',
|
|
121
|
+
model: 'project.task',
|
|
122
|
+
measure: 'count',
|
|
123
|
+
groupBy: 'stage',
|
|
124
|
+
chart: 'bar',
|
|
125
|
+
w: 6,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'hours_by_project',
|
|
129
|
+
title: 'Hours by project',
|
|
130
|
+
kind: 'chart',
|
|
131
|
+
model: 'project.timesheet',
|
|
132
|
+
measure: 'sum:hours',
|
|
133
|
+
groupBy: 'project',
|
|
134
|
+
chart: 'pie',
|
|
135
|
+
w: 6,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: 'load_by_person',
|
|
139
|
+
title: 'Open tasks by person',
|
|
140
|
+
kind: 'chart',
|
|
141
|
+
model: 'project.task',
|
|
142
|
+
measure: 'count',
|
|
143
|
+
groupBy: 'assignee',
|
|
144
|
+
filter: { 'stage.done': false },
|
|
145
|
+
chart: 'bar',
|
|
146
|
+
w: 6,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: 'busiest',
|
|
150
|
+
title: 'Projects with most hours',
|
|
151
|
+
kind: 'list',
|
|
152
|
+
model: 'project.project',
|
|
153
|
+
measure: 'sum:hours',
|
|
154
|
+
w: 6,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
54
158
|
actions: {
|
|
55
159
|
'projects.action_projects': action(ProjectProject, {
|
|
56
160
|
label: 'Projects',
|
|
57
|
-
views: ['list', 'form'],
|
|
161
|
+
views: ['list', 'gantt', 'form'],
|
|
58
162
|
}),
|
|
59
163
|
'projects.action_tasks': action(ProjectTask, {
|
|
60
164
|
label: 'Tasks',
|
|
@@ -116,6 +220,31 @@ export const project = defineModule({
|
|
|
116
220
|
'project.project.form': form(ProjectProject, (k) => ({
|
|
117
221
|
header: { buttons: [] },
|
|
118
222
|
sheet: [
|
|
223
|
+
k.stats('related', [
|
|
224
|
+
{
|
|
225
|
+
id: 'project_tasks',
|
|
226
|
+
label: 'Tasks',
|
|
227
|
+
model: ProjectTask,
|
|
228
|
+
where: { project: { $record: 'id' } },
|
|
229
|
+
action: 'projects.action_tasks',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: 'project_open_tasks',
|
|
233
|
+
label: 'Open',
|
|
234
|
+
model: ProjectTask,
|
|
235
|
+
where: { project: { $record: 'id' }, 'stage.done': false },
|
|
236
|
+
action: 'projects.action_tasks',
|
|
237
|
+
tone: 'warning',
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: 'project_hours',
|
|
241
|
+
label: 'Hours',
|
|
242
|
+
model: ProjectTimesheet,
|
|
243
|
+
where: { project: { $record: 'id' } },
|
|
244
|
+
measure: { sum: 'hours' },
|
|
245
|
+
action: 'projects.action_timesheets',
|
|
246
|
+
},
|
|
247
|
+
]),
|
|
119
248
|
k.group('main', ['name', 'partner', 'manager', 'sequence']),
|
|
120
249
|
k.group('dates', ['dateStart', 'dateEnd', 'taskCount', 'hours']),
|
|
121
250
|
k.group('about', ['description'], { columns: 1 }),
|
|
@@ -135,18 +264,29 @@ export const project = defineModule({
|
|
|
135
264
|
card: {
|
|
136
265
|
title: 'name',
|
|
137
266
|
subtitle: 'project',
|
|
138
|
-
|
|
139
|
-
|
|
267
|
+
avatar: 'assignee',
|
|
268
|
+
color: 'project',
|
|
269
|
+
footer: [
|
|
270
|
+
{ field: 'deadline', widget: 'daysLeft' },
|
|
271
|
+
{ field: 'priority', widget: 'priority' },
|
|
272
|
+
],
|
|
140
273
|
},
|
|
141
274
|
}),
|
|
275
|
+
// Projects on a timeline, from their start to their deadline.
|
|
276
|
+
'project.project.gantt': gantt(ProjectProject, {
|
|
277
|
+
dateStart: 'dateStart',
|
|
278
|
+
dateStop: 'dateEnd',
|
|
279
|
+
title: 'name',
|
|
280
|
+
scale: 'week',
|
|
281
|
+
}),
|
|
142
282
|
'project.task.list': list(ProjectTask, {
|
|
143
283
|
columns: [
|
|
144
284
|
'name',
|
|
145
285
|
'project',
|
|
146
286
|
'stage',
|
|
147
287
|
'assignee',
|
|
148
|
-
'deadline',
|
|
149
|
-
{ field: 'priority', widget: '
|
|
288
|
+
{ field: 'deadline', widget: 'daysLeft' },
|
|
289
|
+
{ field: 'priority', widget: 'priority' },
|
|
150
290
|
{ field: 'plannedHours', sum: true },
|
|
151
291
|
{ field: 'effectiveHours', sum: true },
|
|
152
292
|
],
|
package/dist/project/module.d.ts
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
/** A column of the task kanban, shared by every project (per company later, if asked for). */
|
|
2
|
+
/** The company's project settings (RFC 0020): new tasks' planned hours, the step timesheets are entered in. */
|
|
3
|
+
export declare const CompanyProject: import("../server/orm.js").Extension<"res.company", {
|
|
4
|
+
readonly projectPlannedHoursDefault: import("../server/orm.js").DecimalField<{
|
|
5
|
+
readonly required: false;
|
|
6
|
+
readonly computed: false;
|
|
7
|
+
readonly inverse: false;
|
|
8
|
+
readonly sequence: false;
|
|
9
|
+
readonly computeName: undefined;
|
|
10
|
+
readonly store: true;
|
|
11
|
+
readonly hasDefault: false;
|
|
12
|
+
readonly readonly: false;
|
|
13
|
+
}>;
|
|
14
|
+
readonly projectTimesheetStep: import("../server/orm.js").SelectionField<"half" | "none" | "quarter" | "whole", {
|
|
15
|
+
readonly required: false;
|
|
16
|
+
readonly computed: false;
|
|
17
|
+
readonly inverse: false;
|
|
18
|
+
readonly sequence: false;
|
|
19
|
+
readonly computeName: undefined;
|
|
20
|
+
readonly store: true;
|
|
21
|
+
readonly hasDefault: true;
|
|
22
|
+
readonly readonly: false;
|
|
23
|
+
}>;
|
|
24
|
+
}, Record<never, never>>;
|
|
2
25
|
export declare const ProjectTaskStage: import("../server/orm.js").Model<"project.task.stage", {
|
|
3
26
|
readonly id: import("../server/orm.js").IdField<"project.task.stage">;
|
|
4
27
|
readonly createdAt: import("../server/orm.js").ScalarField<'datetime', Date, Date, {
|
|
@@ -1681,7 +1704,70 @@ export declare const projectShutro: import("../server/orm.js").Module<readonly [
|
|
|
1681
1704
|
readonly hasDefault: false;
|
|
1682
1705
|
readonly readonly: false;
|
|
1683
1706
|
}, string>;
|
|
1684
|
-
}>>], readonly [import("../server/orm.js").Module<readonly [import("../server/orm.js").Model<"res.partner", {
|
|
1707
|
+
}>>], readonly [import("../server/orm.js").Module<readonly [import("../server/orm.js").Model<"res.partner.tag", {
|
|
1708
|
+
readonly id: import("../server/orm.js").IdField<"res.partner.tag">;
|
|
1709
|
+
readonly createdAt: import("../server/orm.js").ScalarField<'datetime', Date, Date, {
|
|
1710
|
+
required: true;
|
|
1711
|
+
readonly: true;
|
|
1712
|
+
computed: false;
|
|
1713
|
+
inverse: false;
|
|
1714
|
+
hasDefault: false;
|
|
1715
|
+
sequence: false;
|
|
1716
|
+
}>;
|
|
1717
|
+
readonly updatedAt: import("../server/orm.js").ScalarField<'datetime', Date, Date, {
|
|
1718
|
+
required: true;
|
|
1719
|
+
readonly: true;
|
|
1720
|
+
computed: false;
|
|
1721
|
+
inverse: false;
|
|
1722
|
+
hasDefault: false;
|
|
1723
|
+
sequence: false;
|
|
1724
|
+
}>;
|
|
1725
|
+
readonly createdBy: import("../server/orm.js").Many2oneField<'res.users', {
|
|
1726
|
+
required: false;
|
|
1727
|
+
readonly: true;
|
|
1728
|
+
computed: false;
|
|
1729
|
+
inverse: false;
|
|
1730
|
+
hasDefault: false;
|
|
1731
|
+
sequence: false;
|
|
1732
|
+
}>;
|
|
1733
|
+
readonly updatedBy: import("../server/orm.js").Many2oneField<'res.users', {
|
|
1734
|
+
required: false;
|
|
1735
|
+
readonly: true;
|
|
1736
|
+
computed: false;
|
|
1737
|
+
inverse: false;
|
|
1738
|
+
hasDefault: false;
|
|
1739
|
+
sequence: false;
|
|
1740
|
+
}>;
|
|
1741
|
+
readonly displayName: import("../server/orm.js").CharField<{
|
|
1742
|
+
required: true;
|
|
1743
|
+
readonly: true;
|
|
1744
|
+
computed: true;
|
|
1745
|
+
inverse: false;
|
|
1746
|
+
hasDefault: false;
|
|
1747
|
+
sequence: false;
|
|
1748
|
+
}>;
|
|
1749
|
+
readonly name: import("../server/orm.js").CharField<{
|
|
1750
|
+
readonly required: true;
|
|
1751
|
+
readonly computed: false;
|
|
1752
|
+
readonly inverse: false;
|
|
1753
|
+
readonly sequence: false;
|
|
1754
|
+
readonly computeName: undefined;
|
|
1755
|
+
readonly store: true;
|
|
1756
|
+
readonly hasDefault: false;
|
|
1757
|
+
readonly readonly: false;
|
|
1758
|
+
}, string>;
|
|
1759
|
+
}, {} & import("../server/orm.js").TransitionMethods<{
|
|
1760
|
+
readonly name: import("../server/orm.js").CharField<{
|
|
1761
|
+
readonly required: true;
|
|
1762
|
+
readonly computed: false;
|
|
1763
|
+
readonly inverse: false;
|
|
1764
|
+
readonly sequence: false;
|
|
1765
|
+
readonly computeName: undefined;
|
|
1766
|
+
readonly store: true;
|
|
1767
|
+
readonly hasDefault: false;
|
|
1768
|
+
readonly readonly: false;
|
|
1769
|
+
}, string>;
|
|
1770
|
+
}>>, import("../server/orm.js").Model<"res.partner", {
|
|
1685
1771
|
readonly id: import("../server/orm.js").IdField<"res.partner">;
|
|
1686
1772
|
readonly createdAt: import("../server/orm.js").ScalarField<'datetime', Date, Date, {
|
|
1687
1773
|
required: true;
|
|
@@ -1735,6 +1821,46 @@ export declare const projectShutro: import("../server/orm.js").Module<readonly [
|
|
|
1735
1821
|
readonly hasDefault: false;
|
|
1736
1822
|
readonly readonly: false;
|
|
1737
1823
|
}, string>;
|
|
1824
|
+
readonly image: import("../server/orm.js").Many2oneField<"storage.attachment", {
|
|
1825
|
+
readonly required: false;
|
|
1826
|
+
readonly computed: false;
|
|
1827
|
+
readonly inverse: false;
|
|
1828
|
+
readonly sequence: false;
|
|
1829
|
+
readonly computeName: undefined;
|
|
1830
|
+
readonly store: true;
|
|
1831
|
+
readonly hasDefault: false;
|
|
1832
|
+
readonly readonly: false;
|
|
1833
|
+
}>;
|
|
1834
|
+
readonly tags: import("../server/orm.js").Many2manyField<"res.partner.tag", {
|
|
1835
|
+
readonly required: true;
|
|
1836
|
+
readonly computed: false;
|
|
1837
|
+
readonly inverse: false;
|
|
1838
|
+
readonly sequence: false;
|
|
1839
|
+
readonly computeName: undefined;
|
|
1840
|
+
readonly store: true;
|
|
1841
|
+
readonly hasDefault: true;
|
|
1842
|
+
readonly readonly: false;
|
|
1843
|
+
}>;
|
|
1844
|
+
readonly latitude: import("../server/orm.js").DecimalField<{
|
|
1845
|
+
readonly required: false;
|
|
1846
|
+
readonly computed: false;
|
|
1847
|
+
readonly inverse: false;
|
|
1848
|
+
readonly sequence: false;
|
|
1849
|
+
readonly computeName: undefined;
|
|
1850
|
+
readonly store: true;
|
|
1851
|
+
readonly hasDefault: false;
|
|
1852
|
+
readonly readonly: false;
|
|
1853
|
+
}>;
|
|
1854
|
+
readonly longitude: import("../server/orm.js").DecimalField<{
|
|
1855
|
+
readonly required: false;
|
|
1856
|
+
readonly computed: false;
|
|
1857
|
+
readonly inverse: false;
|
|
1858
|
+
readonly sequence: false;
|
|
1859
|
+
readonly computeName: undefined;
|
|
1860
|
+
readonly store: true;
|
|
1861
|
+
readonly hasDefault: false;
|
|
1862
|
+
readonly readonly: false;
|
|
1863
|
+
}>;
|
|
1738
1864
|
readonly isCompany: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
|
|
1739
1865
|
readonly required: true;
|
|
1740
1866
|
readonly computed: false;
|
|
@@ -1916,6 +2042,46 @@ export declare const projectShutro: import("../server/orm.js").Module<readonly [
|
|
|
1916
2042
|
readonly hasDefault: false;
|
|
1917
2043
|
readonly readonly: false;
|
|
1918
2044
|
}, string>;
|
|
2045
|
+
readonly image: import("../server/orm.js").Many2oneField<"storage.attachment", {
|
|
2046
|
+
readonly required: false;
|
|
2047
|
+
readonly computed: false;
|
|
2048
|
+
readonly inverse: false;
|
|
2049
|
+
readonly sequence: false;
|
|
2050
|
+
readonly computeName: undefined;
|
|
2051
|
+
readonly store: true;
|
|
2052
|
+
readonly hasDefault: false;
|
|
2053
|
+
readonly readonly: false;
|
|
2054
|
+
}>;
|
|
2055
|
+
readonly tags: import("../server/orm.js").Many2manyField<"res.partner.tag", {
|
|
2056
|
+
readonly required: true;
|
|
2057
|
+
readonly computed: false;
|
|
2058
|
+
readonly inverse: false;
|
|
2059
|
+
readonly sequence: false;
|
|
2060
|
+
readonly computeName: undefined;
|
|
2061
|
+
readonly store: true;
|
|
2062
|
+
readonly hasDefault: true;
|
|
2063
|
+
readonly readonly: false;
|
|
2064
|
+
}>;
|
|
2065
|
+
readonly latitude: import("../server/orm.js").DecimalField<{
|
|
2066
|
+
readonly required: false;
|
|
2067
|
+
readonly computed: false;
|
|
2068
|
+
readonly inverse: false;
|
|
2069
|
+
readonly sequence: false;
|
|
2070
|
+
readonly computeName: undefined;
|
|
2071
|
+
readonly store: true;
|
|
2072
|
+
readonly hasDefault: false;
|
|
2073
|
+
readonly readonly: false;
|
|
2074
|
+
}>;
|
|
2075
|
+
readonly longitude: import("../server/orm.js").DecimalField<{
|
|
2076
|
+
readonly required: false;
|
|
2077
|
+
readonly computed: false;
|
|
2078
|
+
readonly inverse: false;
|
|
2079
|
+
readonly sequence: false;
|
|
2080
|
+
readonly computeName: undefined;
|
|
2081
|
+
readonly store: true;
|
|
2082
|
+
readonly hasDefault: false;
|
|
2083
|
+
readonly readonly: false;
|
|
2084
|
+
}>;
|
|
1919
2085
|
readonly isCompany: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
|
|
1920
2086
|
readonly required: true;
|
|
1921
2087
|
readonly computed: false;
|
|
@@ -2086,4 +2252,46 @@ export declare const projectShutro: import("../server/orm.js").Module<readonly [
|
|
|
2086
2252
|
readonly hasDefault: false;
|
|
2087
2253
|
readonly readonly: false;
|
|
2088
2254
|
}>;
|
|
2089
|
-
}>>], readonly [import("../server/orm.js").Module<readonly import("../server/orm.js").AnyModel[], readonly import("../server/orm.js").ModuleBase[], readonly import("../server/orm.js").AnyExtension[]
|
|
2255
|
+
}>>], readonly [import("../server/orm.js").Module<readonly import("../server/orm.js").AnyModel[], readonly import("../server/orm.js").ModuleBase[], readonly import("../server/orm.js").AnyExtension[]>, import("../server/orm.js").Module<readonly import("../server/orm.js").AnyModel[], readonly import("../server/orm.js").ModuleBase[], readonly import("../server/orm.js").AnyExtension[]>], readonly [import("../server/orm.js").Extension<"res.company", {
|
|
2256
|
+
readonly contactTaxIdRequired: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
|
|
2257
|
+
readonly required: true;
|
|
2258
|
+
readonly computed: false;
|
|
2259
|
+
readonly inverse: false;
|
|
2260
|
+
readonly sequence: false;
|
|
2261
|
+
readonly computeName: undefined;
|
|
2262
|
+
readonly store: true;
|
|
2263
|
+
readonly hasDefault: true;
|
|
2264
|
+
readonly readonly: false;
|
|
2265
|
+
}>;
|
|
2266
|
+
readonly contactUniqueEmail: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
|
|
2267
|
+
readonly required: true;
|
|
2268
|
+
readonly computed: false;
|
|
2269
|
+
readonly inverse: false;
|
|
2270
|
+
readonly sequence: false;
|
|
2271
|
+
readonly computeName: undefined;
|
|
2272
|
+
readonly store: true;
|
|
2273
|
+
readonly hasDefault: true;
|
|
2274
|
+
readonly readonly: false;
|
|
2275
|
+
}>;
|
|
2276
|
+
}, Record<never, never>>]>, import("../server/orm.js").Module<readonly import("../server/orm.js").AnyModel[], readonly import("../server/orm.js").ModuleBase[], readonly import("../server/orm.js").AnyExtension[]>], readonly [import("../server/orm.js").Extension<"res.company", {
|
|
2277
|
+
readonly projectPlannedHoursDefault: import("../server/orm.js").DecimalField<{
|
|
2278
|
+
readonly required: false;
|
|
2279
|
+
readonly computed: false;
|
|
2280
|
+
readonly inverse: false;
|
|
2281
|
+
readonly sequence: false;
|
|
2282
|
+
readonly computeName: undefined;
|
|
2283
|
+
readonly store: true;
|
|
2284
|
+
readonly hasDefault: false;
|
|
2285
|
+
readonly readonly: false;
|
|
2286
|
+
}>;
|
|
2287
|
+
readonly projectTimesheetStep: import("../server/orm.js").SelectionField<"half" | "none" | "quarter" | "whole", {
|
|
2288
|
+
readonly required: false;
|
|
2289
|
+
readonly computed: false;
|
|
2290
|
+
readonly inverse: false;
|
|
2291
|
+
readonly sequence: false;
|
|
2292
|
+
readonly computeName: undefined;
|
|
2293
|
+
readonly store: true;
|
|
2294
|
+
readonly hasDefault: true;
|
|
2295
|
+
readonly readonly: false;
|
|
2296
|
+
}>;
|
|
2297
|
+
}, Record<never, never>>]>;
|
package/dist/project/module.js
CHANGED
|
@@ -7,11 +7,38 @@
|
|
|
7
7
|
import { contactsShutro } from '../contacts/index.js';
|
|
8
8
|
import { messagingShutro } from '../messaging/index.js';
|
|
9
9
|
import { orm } from '../server/orm.js';
|
|
10
|
-
import { compute, defineModel, defineModule, f, record } from './.kosh/bindings.js';
|
|
10
|
+
import { check, compute, defineModel, defineModule, extendModel, f, record, } from './.kosh/bindings.js';
|
|
11
11
|
const READ = ['read'];
|
|
12
12
|
const WRITE = ['read', 'write', 'create', 'unlink'];
|
|
13
13
|
const ALL = ['read', 'write', 'create', 'unlink', 'export', 'import'];
|
|
14
14
|
/** A column of the task kanban, shared by every project (per company later, if asked for). */
|
|
15
|
+
/** The company's project settings (RFC 0020): new tasks' planned hours, the step timesheets are entered in. */
|
|
16
|
+
export const CompanyProject = extendModel('res.company', {
|
|
17
|
+
fields: {
|
|
18
|
+
projectPlannedHoursDefault: f.decimal({ scale: 2, label: 'Planned hours of a new task' }),
|
|
19
|
+
projectTimesheetStep: f.selection({ none: 'Any', quarter: 'Quarter hours', half: 'Half hours', whole: 'Whole hours' }, { default: 'none', label: 'Timesheets in steps of' }),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
/** The timesheet steps as hours. */
|
|
23
|
+
const STEPS = {
|
|
24
|
+
quarter: orm.toDecimal('0.25'),
|
|
25
|
+
half: orm.toDecimal('0.5'),
|
|
26
|
+
whole: orm.toDecimal('1'),
|
|
27
|
+
};
|
|
28
|
+
/** The current company's project settings. */
|
|
29
|
+
async function projectSettings(env) {
|
|
30
|
+
const [company] = (await env
|
|
31
|
+
.model('res.company')
|
|
32
|
+
.browse([env.companyId])
|
|
33
|
+
.load(['projectPlannedHoursDefault', 'projectTimesheetStep'])).read(['projectPlannedHoursDefault', 'projectTimesheetStep']);
|
|
34
|
+
const planned = company?.['projectPlannedHoursDefault'];
|
|
35
|
+
return {
|
|
36
|
+
plannedHours: planned === null || planned === undefined ? null : String(planned),
|
|
37
|
+
step: typeof company?.['projectTimesheetStep'] === 'string'
|
|
38
|
+
? company['projectTimesheetStep']
|
|
39
|
+
: 'none',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
15
42
|
export const ProjectTaskStage = defineModel('project.task.stage', {
|
|
16
43
|
label: 'Task stage',
|
|
17
44
|
order: ['sequence asc', 'id asc'],
|
|
@@ -127,11 +154,17 @@ export const ProjectTask = defineModel('project.task', {
|
|
|
127
154
|
timesheets: f.one2many('project.timesheet', 'task'),
|
|
128
155
|
},
|
|
129
156
|
onchange: {
|
|
130
|
-
// A task of a project takes the project's customer.
|
|
131
|
-
project: async (d) => {
|
|
157
|
+
// A task of a project takes the project's customer, and the company's planned hours when it has none.
|
|
158
|
+
project: async (d, env) => {
|
|
132
159
|
const p = await d.record('project');
|
|
160
|
+
const draft = d;
|
|
133
161
|
if (p?.partner)
|
|
134
|
-
|
|
162
|
+
draft.set('partner', p.partner.id);
|
|
163
|
+
if ((draft.get('plannedHours') ?? null) === null) {
|
|
164
|
+
const { plannedHours } = await projectSettings(env);
|
|
165
|
+
if (plannedHours !== null)
|
|
166
|
+
draft.set('plannedHours', plannedHours);
|
|
167
|
+
}
|
|
135
168
|
},
|
|
136
169
|
},
|
|
137
170
|
});
|
|
@@ -166,10 +199,23 @@ export const ProjectTimesheet = defineModel('project.timesheet', {
|
|
|
166
199
|
sqlConstraints: {
|
|
167
200
|
hoursPositive: { check: orm.sql `hours > 0`, message: 'Hours are positive.' },
|
|
168
201
|
},
|
|
202
|
+
constraints: {
|
|
203
|
+
// The company's step (App settings › Projects): quarter, half or whole hours.
|
|
204
|
+
hoursOnTheStep: {
|
|
205
|
+
...check('project.timesheet', ['hours'], async (lines) => {
|
|
206
|
+
const { step } = await projectSettings(lines.env);
|
|
207
|
+
const unit = STEPS[step];
|
|
208
|
+
if (unit === undefined)
|
|
209
|
+
return [];
|
|
210
|
+
return lines.filter((l) => !l.hours.mod(unit).isZero());
|
|
211
|
+
}),
|
|
212
|
+
message: 'Timesheet hours are entered in the company’s steps (App settings › Projects).',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
169
215
|
});
|
|
170
216
|
export const projectShutro = defineModule({
|
|
171
217
|
name: 'project',
|
|
172
|
-
version: '0.
|
|
218
|
+
version: '0.2.0',
|
|
173
219
|
depends: [contactsShutro, messagingShutro],
|
|
174
220
|
groups: [
|
|
175
221
|
orm.defineGroup({
|
|
@@ -184,6 +230,7 @@ export const projectShutro = defineModule({
|
|
|
184
230
|
}),
|
|
185
231
|
],
|
|
186
232
|
models: [ProjectTaskStage, ProjectProject, ProjectTask, ProjectTimesheet],
|
|
233
|
+
extensions: [CompanyProject],
|
|
187
234
|
// The kanban every installation starts with (theirs to change afterwards).
|
|
188
235
|
data: [
|
|
189
236
|
record('project.task.stage', 'stage_new', { name: 'New', sequence: 1 }, { noupdate: true }),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: d9d9d74bc29efc35
|
|
2
2
|
// Bindings of module `project_portal`: import the definition API from here to get types scoped to what it can see.
|
|
3
3
|
export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
|
|
4
4
|
import { definitions } from '../../server/orm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: d9d9d74bc29efc35
|
|
2
2
|
// Schema view of module `project_portal` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
|
|
3
3
|
import type { F } from '../../server/orm.js';
|
|
4
4
|
|
|
@@ -13,6 +13,7 @@ export interface SchemaView {
|
|
|
13
13
|
readonly 'auth.user_group': AuthUserGroup;
|
|
14
14
|
readonly 'kosh.image': KoshImage;
|
|
15
15
|
readonly 'kosh.saved_view': KoshSavedView;
|
|
16
|
+
readonly 'kosh.setting': KoshSetting;
|
|
16
17
|
readonly 'mail.activity': MailActivity;
|
|
17
18
|
readonly 'mail.activity.type': MailActivityType;
|
|
18
19
|
readonly 'mail.channel': MailChannel;
|
|
@@ -34,6 +35,7 @@ export interface SchemaView {
|
|
|
34
35
|
readonly 'res.company': ResCompany;
|
|
35
36
|
readonly 'res.currency': ResCurrency;
|
|
36
37
|
readonly 'res.partner': ResPartner;
|
|
38
|
+
readonly 'res.partner.tag': ResPartnerTag;
|
|
37
39
|
readonly 'res.users': ResUsers;
|
|
38
40
|
readonly 'storage.attachment': StorageAttachment;
|
|
39
41
|
}
|
|
@@ -254,6 +256,26 @@ export interface KoshSavedView {
|
|
|
254
256
|
export interface KoshSavedViewMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.saved_view'> {
|
|
255
257
|
}
|
|
256
258
|
|
|
259
|
+
/** `kosh.setting` (owner: base). */
|
|
260
|
+
export interface KoshSetting {
|
|
261
|
+
readonly name: 'kosh.setting';
|
|
262
|
+
readonly fields: {
|
|
263
|
+
readonly id: F.Id<'kosh.setting'>;
|
|
264
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
265
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
266
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
267
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
268
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
269
|
+
readonly key: F.Char<{ readonly required: true }>;
|
|
270
|
+
readonly value: F.Json;
|
|
271
|
+
};
|
|
272
|
+
readonly methods: KoshSettingMethods;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** Methods of `kosh.setting`: declared ones and transitions. */
|
|
276
|
+
export interface KoshSettingMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.setting'> {
|
|
277
|
+
}
|
|
278
|
+
|
|
257
279
|
/** `mail.activity` (owner: messaging). */
|
|
258
280
|
export interface MailActivity {
|
|
259
281
|
readonly name: 'mail.activity';
|
|
@@ -713,7 +735,7 @@ export interface ProjectTimesheet {
|
|
|
713
735
|
export interface ProjectTimesheetMethods extends F.Methods<typeof import('../../project/index.js').projectShutro, 'project.timesheet'> {
|
|
714
736
|
}
|
|
715
737
|
|
|
716
|
-
/** `res.company` (owner: base). */
|
|
738
|
+
/** `res.company` (owner: base; extended by: contacts, project). */
|
|
717
739
|
export interface ResCompany {
|
|
718
740
|
readonly name: 'res.company';
|
|
719
741
|
readonly fields: {
|
|
@@ -733,12 +755,16 @@ export interface ResCompany {
|
|
|
733
755
|
readonly email: F.Char;
|
|
734
756
|
readonly phone: F.Char;
|
|
735
757
|
readonly website: F.Char;
|
|
758
|
+
readonly contactTaxIdRequired: F.Bool<{ readonly required: true; readonly default: true }>; // contacts
|
|
759
|
+
readonly contactUniqueEmail: F.Bool<{ readonly required: true; readonly default: true }>; // contacts
|
|
760
|
+
readonly projectPlannedHoursDefault: F.Decimal; // project
|
|
761
|
+
readonly projectTimesheetStep: F.Selection<'none' | 'quarter' | 'half' | 'whole', { readonly default: true }>; // project
|
|
736
762
|
};
|
|
737
763
|
readonly methods: ResCompanyMethods;
|
|
738
764
|
}
|
|
739
765
|
|
|
740
766
|
/** Methods of `res.company`: declared ones and transitions. */
|
|
741
|
-
export interface ResCompanyMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'res.company'> {
|
|
767
|
+
export interface ResCompanyMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'res.company'>, F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.company'>, F.Methods<typeof import('../../project/index.js').projectShutro, 'res.company'> {
|
|
742
768
|
}
|
|
743
769
|
|
|
744
770
|
/** `res.currency` (owner: base). */
|
|
@@ -775,6 +801,10 @@ export interface ResPartner {
|
|
|
775
801
|
readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
776
802
|
readonly company: F.Many2one<'res.company', { readonly default: true }>;
|
|
777
803
|
readonly name: F.Char<{ readonly required: true }>;
|
|
804
|
+
readonly image: F.Many2one<'storage.attachment'>;
|
|
805
|
+
readonly tags: F.Many2many<'res.partner.tag', { readonly required: true }>;
|
|
806
|
+
readonly latitude: F.Decimal;
|
|
807
|
+
readonly longitude: F.Decimal;
|
|
778
808
|
readonly isCompany: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
779
809
|
readonly parent: F.Many2one<'res.partner'>;
|
|
780
810
|
readonly contacts: F.One2many<'res.partner', { readonly required: true }>;
|
|
@@ -801,6 +831,25 @@ export interface ResPartner {
|
|
|
801
831
|
export interface ResPartnerMethods extends F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.partner'>, F.Methods<typeof import('../../portal/index.js').portalShutro, 'res.partner'> {
|
|
802
832
|
}
|
|
803
833
|
|
|
834
|
+
/** `res.partner.tag` (owner: contacts). */
|
|
835
|
+
export interface ResPartnerTag {
|
|
836
|
+
readonly name: 'res.partner.tag';
|
|
837
|
+
readonly fields: {
|
|
838
|
+
readonly id: F.Id<'res.partner.tag'>;
|
|
839
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
840
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
841
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
842
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
843
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
844
|
+
readonly name: F.Char<{ readonly required: true }>;
|
|
845
|
+
};
|
|
846
|
+
readonly methods: ResPartnerTagMethods;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** Methods of `res.partner.tag`: declared ones and transitions. */
|
|
850
|
+
export interface ResPartnerTagMethods extends F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.partner.tag'> {
|
|
851
|
+
}
|
|
852
|
+
|
|
804
853
|
/** `res.users` (owner: base; extended by: portal). */
|
|
805
854
|
export interface ResUsers {
|
|
806
855
|
readonly name: 'res.users';
|
|
@@ -847,6 +896,8 @@ export interface StorageAttachment {
|
|
|
847
896
|
readonly key: F.Char<{ readonly required: true }>;
|
|
848
897
|
readonly resModel: F.Char<{ readonly required: true }>;
|
|
849
898
|
readonly resId: F.Integer<{ readonly required: true }>;
|
|
899
|
+
readonly variantOf: F.Many2one<'storage.attachment'>;
|
|
900
|
+
readonly width: F.Integer;
|
|
850
901
|
};
|
|
851
902
|
readonly methods: StorageAttachmentMethods;
|
|
852
903
|
}
|