shutro-erp 0.2.1 → 0.3.1

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.
Files changed (273) hide show
  1. package/README.md +74 -67
  2. package/dist/account_portal/.kosh/bindings.d.ts +22 -0
  3. package/dist/account_portal/.kosh/bindings.js +15 -0
  4. package/dist/account_portal/.kosh/schema.d.ts +1380 -0
  5. package/dist/account_portal/index.d.ts +3 -0
  6. package/dist/account_portal/index.js +73 -0
  7. package/dist/account_portal/module.d.ts +5983 -0
  8. package/dist/account_portal/module.js +18 -0
  9. package/dist/accounting/.kosh/bindings.js +1 -1
  10. package/dist/accounting/.kosh/schema.d.ts +172 -9
  11. package/dist/accounting/chart.d.ts +40 -8
  12. package/dist/accounting/chart.js +124 -30
  13. package/dist/accounting/closing.d.ts +6 -1
  14. package/dist/accounting/closing.js +5 -1
  15. package/dist/accounting/demo.js +6 -5
  16. package/dist/accounting/index.d.ts +3 -3
  17. package/dist/accounting/index.js +200 -23
  18. package/dist/accounting/module.d.ts +3326 -1086
  19. package/dist/accounting/module.js +408 -66
  20. package/dist/accounting/payments.d.ts +25 -0
  21. package/dist/accounting/payments.js +96 -4
  22. package/dist/accounting/web/RegisterPayment.d.ts +3 -2
  23. package/dist/accounting/web/RegisterPayment.js +39 -6
  24. package/dist/accounting/web/SettingsPage.js +5 -1
  25. package/dist/accounting/web/messages.js +10 -0
  26. package/dist/assistant/routes.js +1 -1
  27. package/dist/automation/engine.js +1 -1
  28. package/dist/automation/web/messages.js +2 -2
  29. package/dist/cli/apps.d.ts +1 -1
  30. package/dist/cli/apps.js +14 -14
  31. package/dist/cli/bin.js +3 -0
  32. package/dist/cli/index.js +11 -11
  33. package/dist/cli/init.d.ts +1 -1
  34. package/dist/cli/init.js +224 -78
  35. package/dist/cli/launch.d.ts +16 -0
  36. package/dist/cli/launch.js +138 -0
  37. package/dist/cli/project.d.ts +7 -7
  38. package/dist/cli/project.js +25 -25
  39. package/dist/cli/prompt.d.ts +35 -0
  40. package/dist/cli/prompt.js +48 -2
  41. package/dist/cli/templates.d.ts +14 -6
  42. package/dist/cli/templates.js +61 -34
  43. package/dist/cli/tui.d.ts +7 -0
  44. package/dist/cli/tui.js +254 -0
  45. package/dist/cli/ui.d.ts +21 -8
  46. package/dist/cli/ui.js +65 -19
  47. package/dist/contacts/.kosh/bindings.js +1 -1
  48. package/dist/contacts/.kosh/schema.d.ts +33 -1
  49. package/dist/contacts/index.js +24 -1
  50. package/dist/contacts/module.d.ts +42 -0
  51. package/dist/contacts/module.js +3 -1
  52. package/dist/import/convert.d.ts +55 -0
  53. package/dist/import/convert.js +224 -0
  54. package/dist/import/csv.d.ts +28 -0
  55. package/dist/import/csv.js +115 -0
  56. package/dist/import/index.d.ts +33 -0
  57. package/dist/import/index.js +60 -0
  58. package/dist/import/mapping.d.ts +15 -0
  59. package/dist/import/mapping.js +33 -0
  60. package/dist/import/match.d.ts +24 -0
  61. package/dist/import/match.js +60 -0
  62. package/dist/import/models.d.ts +2 -0
  63. package/dist/import/models.js +102 -0
  64. package/dist/import/routes.d.ts +13 -0
  65. package/dist/import/routes.js +392 -0
  66. package/dist/import/run.d.ts +131 -0
  67. package/dist/import/run.js +568 -0
  68. package/dist/import/service.d.ts +153 -0
  69. package/dist/import/service.js +367 -0
  70. package/dist/import/web/ImportButton.d.ts +7 -0
  71. package/dist/import/web/ImportButton.js +31 -0
  72. package/dist/import/web/ImportWizard.d.ts +75 -0
  73. package/dist/import/web/ImportWizard.js +217 -0
  74. package/dist/import/web/index.d.ts +13 -0
  75. package/dist/import/web/index.js +18 -0
  76. package/dist/import/web/messages.d.ts +2 -0
  77. package/dist/import/web/messages.js +139 -0
  78. package/dist/import/worker.d.ts +3 -0
  79. package/dist/import/worker.js +52 -0
  80. package/dist/import/xlsx.d.ts +20 -0
  81. package/dist/import/xlsx.js +192 -0
  82. package/dist/l10n_bd/.kosh/bindings.d.ts +22 -0
  83. package/dist/l10n_bd/.kosh/bindings.js +15 -0
  84. package/dist/l10n_bd/.kosh/schema.d.ts +1311 -0
  85. package/dist/l10n_bd/documents.d.ts +8 -0
  86. package/dist/l10n_bd/documents.js +183 -0
  87. package/dist/l10n_bd/index.d.ts +8 -0
  88. package/dist/l10n_bd/index.js +156 -0
  89. package/dist/l10n_bd/module.d.ts +5705 -0
  90. package/dist/l10n_bd/module.js +163 -0
  91. package/dist/l10n_bd/mushak.d.ts +67 -0
  92. package/dist/l10n_bd/mushak.js +139 -0
  93. package/dist/l10n_bd/routes.d.ts +3 -0
  94. package/dist/l10n_bd/routes.js +205 -0
  95. package/dist/l10n_bd/web/MushakPage.d.ts +7 -0
  96. package/dist/l10n_bd/web/MushakPage.js +53 -0
  97. package/dist/l10n_bd/web/index.d.ts +13 -0
  98. package/dist/l10n_bd/web/index.js +18 -0
  99. package/dist/l10n_bd/web/messages.d.ts +2 -0
  100. package/dist/l10n_bd/web/messages.js +101 -0
  101. package/dist/l10n_in/.kosh/bindings.d.ts +22 -0
  102. package/dist/l10n_in/.kosh/bindings.js +15 -0
  103. package/dist/l10n_in/.kosh/schema.d.ts +1373 -0
  104. package/dist/l10n_in/documents.d.ts +8 -0
  105. package/dist/l10n_in/documents.js +114 -0
  106. package/dist/l10n_in/einvoice.d.ts +253 -0
  107. package/dist/l10n_in/einvoice.js +485 -0
  108. package/dist/l10n_in/gstr.d.ts +109 -0
  109. package/dist/l10n_in/gstr.js +430 -0
  110. package/dist/l10n_in/index.d.ts +20 -0
  111. package/dist/l10n_in/index.js +232 -0
  112. package/dist/l10n_in/module.d.ts +7823 -0
  113. package/dist/l10n_in/module.js +427 -0
  114. package/dist/l10n_in/routes-einvoice.d.ts +15 -0
  115. package/dist/l10n_in/routes-einvoice.js +124 -0
  116. package/dist/l10n_in/routes.d.ts +17 -0
  117. package/dist/l10n_in/routes.js +282 -0
  118. package/dist/l10n_in/web/EInvoicePanel.d.ts +8 -0
  119. package/dist/l10n_in/web/EInvoicePanel.js +63 -0
  120. package/dist/l10n_in/web/GstPage.d.ts +7 -0
  121. package/dist/l10n_in/web/GstPage.js +57 -0
  122. package/dist/l10n_in/web/GstSettings.d.ts +10 -0
  123. package/dist/l10n_in/web/GstSettings.js +36 -0
  124. package/dist/l10n_in/web/index.d.ts +15 -0
  125. package/dist/l10n_in/web/index.js +22 -0
  126. package/dist/l10n_in/web/messages.d.ts +2 -0
  127. package/dist/l10n_in/web/messages.js +166 -0
  128. package/dist/mail/index.js +2 -2
  129. package/dist/modules-sdk/demo.d.ts +2 -0
  130. package/dist/modules-sdk/demo.js +7 -3
  131. package/dist/modules-sdk/index.d.ts +2 -2
  132. package/dist/modules-sdk/index.js +1 -1
  133. package/dist/modules-sdk/loader.js +2 -2
  134. package/dist/modules-sdk/manifest.d.ts +132 -0
  135. package/dist/modules-sdk/manifest.js +22 -0
  136. package/dist/notify/inbox.js +21 -0
  137. package/dist/notify/messages.js +7 -3
  138. package/dist/notify/models.d.ts +1 -1
  139. package/dist/notify/models.js +2 -0
  140. package/dist/notify/routes.js +1 -1
  141. package/dist/notify/web/messages.js +5 -1
  142. package/dist/portal/.kosh/bindings.d.ts +22 -0
  143. package/dist/portal/.kosh/bindings.js +15 -0
  144. package/dist/portal/.kosh/schema.d.ts +376 -0
  145. package/dist/portal/announce.d.ts +16 -0
  146. package/dist/portal/announce.js +117 -0
  147. package/dist/portal/documents.d.ts +17 -0
  148. package/dist/portal/documents.js +61 -0
  149. package/dist/portal/index.d.ts +20 -0
  150. package/dist/portal/index.js +65 -0
  151. package/dist/portal/module.d.ts +1405 -0
  152. package/dist/portal/module.js +84 -0
  153. package/dist/portal/routes-documents.d.ts +2 -0
  154. package/dist/portal/routes-documents.js +391 -0
  155. package/dist/portal/routes.d.ts +13 -0
  156. package/dist/portal/routes.js +313 -0
  157. package/dist/portal/rules.d.ts +11 -0
  158. package/dist/portal/rules.js +25 -0
  159. package/dist/portal/web/PortalAccess.d.ts +8 -0
  160. package/dist/portal/web/PortalAccess.js +66 -0
  161. package/dist/portal/web/index.d.ts +12 -0
  162. package/dist/portal/web/index.js +17 -0
  163. package/dist/portal/web/messages.d.ts +2 -0
  164. package/dist/portal/web/messages.js +33 -0
  165. package/dist/product/.kosh/bindings.js +1 -1
  166. package/dist/product/.kosh/schema.d.ts +42 -3
  167. package/dist/product/demo.js +6 -5
  168. package/dist/product/index.d.ts +1 -0
  169. package/dist/product/index.js +17 -4
  170. package/dist/product/module.d.ts +346 -14
  171. package/dist/product/module.js +48 -18
  172. package/dist/product/taxes.d.ts +59 -0
  173. package/dist/product/taxes.js +61 -0
  174. package/dist/project/.kosh/bindings.js +1 -1
  175. package/dist/project/.kosh/schema.d.ts +33 -1
  176. package/dist/project/module.d.ts +20 -0
  177. package/dist/project_portal/.kosh/bindings.d.ts +22 -0
  178. package/dist/project_portal/.kosh/bindings.js +15 -0
  179. package/dist/project_portal/.kosh/schema.d.ts +701 -0
  180. package/dist/project_portal/index.d.ts +9 -0
  181. package/dist/project_portal/index.js +42 -0
  182. package/dist/project_portal/module.d.ts +2142 -0
  183. package/dist/project_portal/module.js +22 -0
  184. package/dist/purchase/.kosh/bindings.js +1 -1
  185. package/dist/purchase/.kosh/schema.d.ts +45 -4
  186. package/dist/purchase/demo.js +3 -3
  187. package/dist/purchase/index.js +1 -1
  188. package/dist/purchase/module.d.ts +232 -8
  189. package/dist/purchase/module.js +51 -9
  190. package/dist/purchase_account/.kosh/bindings.js +1 -1
  191. package/dist/purchase_account/.kosh/schema.d.ts +174 -10
  192. package/dist/purchase_account/module.d.ts +2008 -641
  193. package/dist/purchase_account/module.js +2 -2
  194. package/dist/purchase_portal/.kosh/bindings.d.ts +22 -0
  195. package/dist/purchase_portal/.kosh/bindings.js +15 -0
  196. package/dist/purchase_portal/.kosh/schema.d.ts +852 -0
  197. package/dist/purchase_portal/index.d.ts +9 -0
  198. package/dist/purchase_portal/index.js +53 -0
  199. package/dist/purchase_portal/module.d.ts +2758 -0
  200. package/dist/purchase_portal/module.js +18 -0
  201. package/dist/reporting/documents.js +20 -3
  202. package/dist/reporting/index.d.ts +1 -0
  203. package/dist/reporting/index.js +1 -0
  204. package/dist/reporting/routes-documents.js +9 -2
  205. package/dist/reporting/words.d.ts +11 -0
  206. package/dist/reporting/words.js +229 -0
  207. package/dist/sale_account/.kosh/bindings.js +1 -1
  208. package/dist/sale_account/.kosh/schema.d.ts +174 -10
  209. package/dist/sale_account/module.d.ts +2008 -641
  210. package/dist/sale_account/module.js +3 -3
  211. package/dist/sale_portal/.kosh/bindings.d.ts +22 -0
  212. package/dist/sale_portal/.kosh/bindings.js +15 -0
  213. package/dist/sale_portal/.kosh/schema.d.ts +766 -0
  214. package/dist/sale_portal/index.d.ts +9 -0
  215. package/dist/sale_portal/index.js +71 -0
  216. package/dist/sale_portal/module.d.ts +2718 -0
  217. package/dist/sale_portal/module.js +19 -0
  218. package/dist/sale_project/.kosh/bindings.js +1 -1
  219. package/dist/sale_project/.kosh/schema.d.ts +45 -4
  220. package/dist/sale_project/module.d.ts +390 -10
  221. package/dist/sales/.kosh/bindings.js +1 -1
  222. package/dist/sales/.kosh/schema.d.ts +45 -4
  223. package/dist/sales/demo.js +3 -3
  224. package/dist/sales/index.js +67 -1
  225. package/dist/sales/module.d.ts +232 -8
  226. package/dist/sales/module.js +51 -12
  227. package/dist/server/api/client.js +1 -1
  228. package/dist/server/api/openapi.js +17 -1
  229. package/dist/server/apps.js +5 -5
  230. package/dist/server/auth/api-keys.d.ts +13 -0
  231. package/dist/server/auth/api-keys.js +65 -0
  232. package/dist/server/auth/base.js +26 -0
  233. package/dist/server/auth/crypto.js +1 -1
  234. package/dist/server/auth/scopes.d.ts +12 -0
  235. package/dist/server/auth/scopes.js +51 -0
  236. package/dist/server/auth/service.d.ts +59 -1
  237. package/dist/server/auth/service.js +236 -6
  238. package/dist/server/demo.d.ts +1 -1
  239. package/dist/server/demo.js +1 -1
  240. package/dist/server/env-names.d.ts +2 -0
  241. package/dist/server/env-names.js +16 -0
  242. package/dist/server/host.js +5 -1
  243. package/dist/server/identity.d.ts +7 -0
  244. package/dist/server/index.d.ts +2 -1
  245. package/dist/server/index.js +2 -1
  246. package/dist/server/registry.js +1 -1
  247. package/dist/server/server.d.ts +5 -0
  248. package/dist/server/server.js +71 -6
  249. package/dist/settings/routes.js +1 -1
  250. package/dist/settings/web/ApiKeysPage.d.ts +8 -0
  251. package/dist/settings/web/ApiKeysPage.js +70 -0
  252. package/dist/settings/web/index.d.ts +1 -0
  253. package/dist/settings/web/index.js +4 -0
  254. package/dist/settings/web/messages.js +62 -0
  255. package/dist/storage/routes.js +1 -1
  256. package/dist/studio/build.js +1 -1
  257. package/dist/studio/generate.js +4 -4
  258. package/dist/studio/module.js +5 -5
  259. package/dist/studio/web/messages.js +2 -2
  260. package/dist/ui/api.d.ts +2 -0
  261. package/dist/ui/app.js +27 -4
  262. package/dist/ui/context.d.ts +3 -1
  263. package/dist/ui/context.js +2 -2
  264. package/dist/ui/i18n/messages.js +2 -2
  265. package/dist/ui/index.d.ts +1 -1
  266. package/dist/ui/index.js +1 -1
  267. package/dist/ui/lib/format.d.ts +2 -0
  268. package/dist/ui/lib/format.js +3 -1
  269. package/dist/ui/pwa/worker.js +2 -2
  270. package/dist/ui/registry.d.ts +15 -0
  271. package/dist/ui/registry.js +20 -0
  272. package/dist/ui/views/FormView.js +19 -6
  273. package/package.json +52 -4
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 2d429d925bd4e737
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: b513566045fc25a0
2
2
  // Schema view of module `sales` (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
 
@@ -6,6 +6,7 @@ import type { F } from '../../server/orm.js';
6
6
  export interface SchemaView {
7
7
  readonly 'account.tax': AccountTax;
8
8
  readonly 'audit.event': AuditEvent;
9
+ readonly 'auth.api_key': AuthApiKey;
9
10
  readonly 'auth.credential': AuthCredential;
10
11
  readonly 'auth.session': AuthSession;
11
12
  readonly 'auth.user_grant': AuthUserGrant;
@@ -43,7 +44,13 @@ export interface AccountTax {
43
44
  readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
44
45
  readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
45
46
  readonly use: F.Selection<'sale' | 'purchase', { readonly required: true; readonly default: true }>;
47
+ readonly sequence: F.Integer<{ readonly required: true; readonly default: true }>;
48
+ readonly amountType: F.Selection<'percent' | 'fixed', { readonly required: true; readonly default: true }>;
46
49
  readonly rate: F.Decimal<{ readonly required: true; readonly default: true }>;
50
+ readonly fixedAmount: F.Decimal<{ readonly required: true; readonly default: true }>;
51
+ readonly affectsBase: F.Bool<{ readonly required: true; readonly default: true }>;
52
+ readonly priceIncluded: F.Bool<{ readonly required: true; readonly default: true }>;
53
+ readonly reverseCharge: F.Bool<{ readonly required: true; readonly default: true }>;
47
54
  };
48
55
  readonly methods: AccountTaxMethods;
49
56
  }
@@ -78,6 +85,34 @@ export interface AuditEvent {
78
85
  export interface AuditEventMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'audit.event'> {
79
86
  }
80
87
 
88
+ /** `auth.api_key` (owner: base). */
89
+ export interface AuthApiKey {
90
+ readonly name: 'auth.api_key';
91
+ readonly fields: {
92
+ readonly id: F.Id<'auth.api_key'>;
93
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
94
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
95
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
96
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
97
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
98
+ readonly name: F.Char<{ readonly required: true }>;
99
+ readonly user: F.Many2one<'res.users', { readonly required: true }>;
100
+ readonly tokenHash: F.Char<{ readonly required: true }>;
101
+ readonly prefix: F.Char<{ readonly required: true }>;
102
+ readonly scopes: F.Text<{ readonly required: true }>;
103
+ readonly expiresAt: F.Datetime<{ readonly required: true }>;
104
+ readonly lastUsedAt: F.Datetime;
105
+ readonly lastUsedIp: F.Char;
106
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
107
+ readonly issuedBy: F.Many2one<'res.users'>;
108
+ };
109
+ readonly methods: AuthApiKeyMethods;
110
+ }
111
+
112
+ /** Methods of `auth.api_key`: declared ones and transitions. */
113
+ export interface AuthApiKeyMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'auth.api_key'> {
114
+ }
115
+
81
116
  /** `auth.credential` (owner: base). */
82
117
  export interface AuthCredential {
83
118
  readonly name: 'auth.credential';
@@ -416,8 +451,10 @@ export interface ProductProduct {
416
451
  readonly standardPrice: F.Decimal<{ readonly required: true; readonly default: true }>;
417
452
  readonly saleOk: F.Bool<{ readonly required: true; readonly default: true }>;
418
453
  readonly purchaseOk: F.Bool<{ readonly required: true; readonly default: true }>;
419
- readonly tax: F.Many2one<'account.tax'>;
420
- readonly purchaseTax: F.Many2one<'account.tax'>;
454
+ readonly taxes: F.Many2many<'account.tax', { readonly required: true }>;
455
+ readonly purchaseTaxes: F.Many2many<'account.tax', { readonly required: true }>;
456
+ readonly tax: F.Many2one<'account.tax', { readonly readonly: true }>;
457
+ readonly purchaseTax: F.Many2one<'account.tax', { readonly readonly: true }>;
421
458
  readonly description: F.Text<{ readonly translate: true }>;
422
459
  };
423
460
  readonly methods: ProductProductMethods;
@@ -439,6 +476,7 @@ export interface ResCompany {
439
476
  readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
440
477
  readonly name: F.Char<{ readonly required: true }>;
441
478
  readonly currency: F.Many2one<'res.currency', { readonly required: true }>;
479
+ readonly numberGrouping: F.Selection<'international' | 'lakh', { readonly required: true; readonly default: true }>;
442
480
  };
443
481
  readonly methods: ResCompanyMethods;
444
482
  }
@@ -492,6 +530,7 @@ export interface ResPartner {
492
530
  readonly city: F.Char;
493
531
  readonly zip: F.Char;
494
532
  readonly country: F.Char;
533
+ readonly state: F.Char;
495
534
  readonly taxId: F.Char;
496
535
  readonly isCustomer: F.Bool<{ readonly required: true; readonly default: true }>;
497
536
  readonly isVendor: F.Bool<{ readonly required: true; readonly default: true }>;
@@ -524,6 +563,7 @@ export interface ResUsers {
524
563
  readonly companies: F.Many2many<'res.company', { readonly required: true }>;
525
564
  readonly lang: F.Char<{ readonly default: true }>;
526
565
  readonly tz: F.Char<{ readonly default: true }>;
566
+ readonly isService: F.Bool<{ readonly required: true; readonly default: true }>;
527
567
  };
528
568
  readonly methods: ResUsersMethods;
529
569
  }
@@ -587,7 +627,8 @@ export interface SaleOrderLine {
587
627
  readonly uom: F.Many2one<'uom.uom'>;
588
628
  readonly priceUnit: F.Decimal<{ readonly required: true; readonly default: true }>;
589
629
  readonly discount: F.Decimal<{ readonly required: true; readonly default: true }>;
590
- readonly tax: F.Many2one<'account.tax'>;
630
+ readonly taxes: F.Many2many<'account.tax', { readonly required: true }>;
631
+ readonly tax: F.Many2one<'account.tax', { readonly readonly: true }>;
591
632
  readonly currency: F.Many2one<'res.currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
592
633
  readonly subtotal: F.Monetary<'currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
593
634
  readonly taxAmount: F.Monetary<'currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
@@ -1,5 +1,5 @@
1
1
  /** Demo data of Sales (RFC 0008 §5.8): quotations and confirmed orders of a salesperson, with VAT. */
2
- import { idByName } from '../modules-sdk/index.js';
2
+ import { idByName, maybeIdByName } from '../modules-sdk/index.js';
3
3
  import { orm } from '../server/orm.js';
4
4
  /** The demo salesperson. */
5
5
  export const RAHIM = { login: 'rahim', name: 'Rahim Uddin', groups: ['sales.user'] };
@@ -54,7 +54,7 @@ export async function salesDemo(context) {
54
54
  .load({ currency: true });
55
55
  if (company === undefined)
56
56
  throw new Error('Demo data: no company.');
57
- const vat = await idByName(env, 'account.tax', 'VAT 15%');
57
+ const vat = await maybeIdByName(env, 'account.tax', 'VAT 15%');
58
58
  let confirmed = 0;
59
59
  for (const o of ORDERS) {
60
60
  const lines = [];
@@ -65,7 +65,7 @@ export async function salesDemo(context) {
65
65
  name: l.product,
66
66
  quantity: l.quantity,
67
67
  priceUnit: l.price,
68
- tax: orm.asId(vat, 'account.tax'),
68
+ taxes: { set: vat === null ? [] : [orm.asId(vat, 'account.tax')] },
69
69
  });
70
70
  }
71
71
  const created = await env.model('sale.order').create([
@@ -29,6 +29,72 @@ export const sales = defineModule({
29
29
  user: { label: 'Salesperson (own orders)', groups: ['sales.user'] },
30
30
  manager: { label: 'Manager (all orders)', groups: ['sales.manager'], implies: ['user'] },
31
31
  },
32
+ // The printed quotation (RFC 0005), installed as a template designers can change; the portal prints it too.
33
+ documents: [
34
+ {
35
+ key: 'quotation',
36
+ name: 'Quotation',
37
+ model: 'sale.order',
38
+ layout: {
39
+ paper: 'A4',
40
+ header: '{{company.name}}',
41
+ footer: 'Page {{page}} of {{pages}}',
42
+ blocks: [
43
+ { kind: 'heading', id: 'title', text: '{{state}} {{name}}', level: 1 },
44
+ {
45
+ kind: 'columns',
46
+ id: 'parties',
47
+ left: [
48
+ {
49
+ kind: 'fields',
50
+ id: 'customer',
51
+ items: [
52
+ { label: 'Customer', bind: 'partner.name' },
53
+ { label: 'Customer reference', bind: 'clientReference' },
54
+ ],
55
+ },
56
+ ],
57
+ right: [
58
+ {
59
+ kind: 'fields',
60
+ id: 'dates',
61
+ items: [
62
+ { label: 'Order date', bind: 'dateOrder' },
63
+ { label: 'Valid until', bind: 'validityDate' },
64
+ { label: 'Salesperson', bind: 'user.name' },
65
+ ],
66
+ },
67
+ ],
68
+ },
69
+ {
70
+ kind: 'table',
71
+ id: 'lines',
72
+ bind: 'lines',
73
+ columns: [
74
+ { label: 'Description', bind: 'name' },
75
+ { label: 'Quantity', bind: 'quantity', align: 'end' },
76
+ { label: 'Unit price', bind: 'priceUnit', align: 'end' },
77
+ { label: 'Discount %', bind: 'discount', align: 'end' },
78
+ { label: 'Tax', bind: 'taxAmount', align: 'end' },
79
+ { label: 'Subtotal', bind: 'subtotal', align: 'end', sum: true },
80
+ ],
81
+ },
82
+ {
83
+ kind: 'fields',
84
+ id: 'totals',
85
+ columns: 3,
86
+ items: [
87
+ { label: 'Untaxed', bind: 'amountUntaxed' },
88
+ { label: 'Taxes', bind: 'amountTax' },
89
+ { label: 'Total', bind: 'amountTotal' },
90
+ ],
91
+ },
92
+ { kind: 'text', id: 'in_words', text: '{{amountTotal|words}}' },
93
+ { kind: 'text', id: 'terms', text: '{{note}}' },
94
+ ],
95
+ },
96
+ },
97
+ ],
32
98
  actions: {
33
99
  'sales.action_quotations': action(SaleOrder, {
34
100
  label: 'Quotations',
@@ -109,7 +175,7 @@ export const sales = defineModule({
109
175
  'uom',
110
176
  'priceUnit',
111
177
  'discount',
112
- 'tax',
178
+ 'taxes',
113
179
  'subtotal',
114
180
  ], { readonlyWhen: { state: { in: ['done', 'cancel'] } } }),
115
181
  k.group('totals', ['amountUntaxed', 'amountTax', 'amountTotal'], { label: 'Totals' }),
@@ -467,6 +467,16 @@ export declare const SaleOrderLine: import("../server/orm.js").Model<"sale.order
467
467
  readonly hasDefault: true;
468
468
  readonly readonly: false;
469
469
  }>;
470
+ readonly taxes: import("../server/orm.js").Many2manyField<"account.tax", {
471
+ readonly required: true;
472
+ readonly computed: false;
473
+ readonly inverse: false;
474
+ readonly sequence: false;
475
+ readonly computeName: undefined;
476
+ readonly store: true;
477
+ readonly hasDefault: true;
478
+ readonly readonly: false;
479
+ }>;
470
480
  readonly tax: import("../server/orm.js").Many2oneField<"account.tax", {
471
481
  readonly required: false;
472
482
  readonly computed: false;
@@ -475,7 +485,7 @@ export declare const SaleOrderLine: import("../server/orm.js").Model<"sale.order
475
485
  readonly computeName: undefined;
476
486
  readonly store: true;
477
487
  readonly hasDefault: false;
478
- readonly readonly: false;
488
+ readonly readonly: true;
479
489
  }>;
480
490
  readonly currency: import("../server/orm.js").Many2oneField<"res.currency", {
481
491
  readonly required: false;
@@ -579,6 +589,18 @@ export declare const SaleOrderLine: import("../server/orm.js").Model<"sale.order
579
589
  readonly hasDefault: true;
580
590
  readonly readonly: false;
581
591
  }>;
592
+ /** The line's taxes, applied in order (RFC 0016). */
593
+ readonly taxes: import("../server/orm.js").Many2manyField<"account.tax", {
594
+ readonly required: true;
595
+ readonly computed: false;
596
+ readonly inverse: false;
597
+ readonly sequence: false;
598
+ readonly computeName: undefined;
599
+ readonly store: true;
600
+ readonly hasDefault: true;
601
+ readonly readonly: false;
602
+ }>;
603
+ /** Before 0.2.0, one tax per line: copied into `taxes` by the migration; dropped later. */
582
604
  readonly tax: import("../server/orm.js").Many2oneField<"account.tax", {
583
605
  readonly required: false;
584
606
  readonly computed: false;
@@ -587,7 +609,7 @@ export declare const SaleOrderLine: import("../server/orm.js").Model<"sale.order
587
609
  readonly computeName: undefined;
588
610
  readonly store: true;
589
611
  readonly hasDefault: false;
590
- readonly readonly: false;
612
+ readonly readonly: true;
591
613
  }>;
592
614
  /** The order's currency, so line amounts are Money in it. */
593
615
  readonly currency: import("../server/orm.js").Many2oneField<"res.currency", {
@@ -1089,6 +1111,16 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1089
1111
  readonly hasDefault: true;
1090
1112
  readonly readonly: false;
1091
1113
  }>;
1114
+ readonly taxes: import("../server/orm.js").Many2manyField<"account.tax", {
1115
+ readonly required: true;
1116
+ readonly computed: false;
1117
+ readonly inverse: false;
1118
+ readonly sequence: false;
1119
+ readonly computeName: undefined;
1120
+ readonly store: true;
1121
+ readonly hasDefault: true;
1122
+ readonly readonly: false;
1123
+ }>;
1092
1124
  readonly tax: import("../server/orm.js").Many2oneField<"account.tax", {
1093
1125
  readonly required: false;
1094
1126
  readonly computed: false;
@@ -1097,7 +1129,7 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1097
1129
  readonly computeName: undefined;
1098
1130
  readonly store: true;
1099
1131
  readonly hasDefault: false;
1100
- readonly readonly: false;
1132
+ readonly readonly: true;
1101
1133
  }>;
1102
1134
  readonly currency: import("../server/orm.js").Many2oneField<"res.currency", {
1103
1135
  readonly required: false;
@@ -1201,6 +1233,18 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1201
1233
  readonly hasDefault: true;
1202
1234
  readonly readonly: false;
1203
1235
  }>;
1236
+ /** The line's taxes, applied in order (RFC 0016). */
1237
+ readonly taxes: import("../server/orm.js").Many2manyField<"account.tax", {
1238
+ readonly required: true;
1239
+ readonly computed: false;
1240
+ readonly inverse: false;
1241
+ readonly sequence: false;
1242
+ readonly computeName: undefined;
1243
+ readonly store: true;
1244
+ readonly hasDefault: true;
1245
+ readonly readonly: false;
1246
+ }>;
1247
+ /** Before 0.2.0, one tax per line: copied into `taxes` by the migration; dropped later. */
1204
1248
  readonly tax: import("../server/orm.js").Many2oneField<"account.tax", {
1205
1249
  readonly required: false;
1206
1250
  readonly computed: false;
@@ -1209,7 +1253,7 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1209
1253
  readonly computeName: undefined;
1210
1254
  readonly store: true;
1211
1255
  readonly hasDefault: false;
1212
- readonly readonly: false;
1256
+ readonly readonly: true;
1213
1257
  }>;
1214
1258
  /** The order's currency, so line amounts are Money in it. */
1215
1259
  readonly currency: import("../server/orm.js").Many2oneField<"res.currency", {
@@ -1406,6 +1450,16 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1406
1450
  readonly hasDefault: false;
1407
1451
  readonly readonly: false;
1408
1452
  }, string>;
1453
+ readonly state: import("../server/orm.js").CharField<{
1454
+ readonly required: false;
1455
+ readonly computed: false;
1456
+ readonly inverse: false;
1457
+ readonly sequence: false;
1458
+ readonly computeName: undefined;
1459
+ readonly store: true;
1460
+ readonly hasDefault: false;
1461
+ readonly readonly: false;
1462
+ }, string>;
1409
1463
  readonly taxId: import("../server/orm.js").CharField<{
1410
1464
  readonly required: false;
1411
1465
  readonly computed: false;
@@ -1577,6 +1631,16 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1577
1631
  readonly hasDefault: false;
1578
1632
  readonly readonly: false;
1579
1633
  }, string>;
1634
+ readonly state: import("../server/orm.js").CharField<{
1635
+ readonly required: false;
1636
+ readonly computed: false;
1637
+ readonly inverse: false;
1638
+ readonly sequence: false;
1639
+ readonly computeName: undefined;
1640
+ readonly store: true;
1641
+ readonly hasDefault: false;
1642
+ readonly readonly: false;
1643
+ }, string>;
1580
1644
  readonly taxId: import("../server/orm.js").CharField<{
1581
1645
  readonly required: false;
1582
1646
  readonly computed: false;
@@ -1897,6 +1961,26 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1897
1961
  readonly hasDefault: true;
1898
1962
  readonly readonly: false;
1899
1963
  }>;
1964
+ readonly sequence: import("../server/orm.js").ScalarField<"integer", number, number, {
1965
+ readonly required: true;
1966
+ readonly computed: false;
1967
+ readonly inverse: false;
1968
+ readonly sequence: false;
1969
+ readonly computeName: undefined;
1970
+ readonly store: true;
1971
+ readonly hasDefault: true;
1972
+ readonly readonly: false;
1973
+ }>;
1974
+ readonly amountType: import("../server/orm.js").SelectionField<"fixed" | "percent", {
1975
+ readonly required: true;
1976
+ readonly computed: false;
1977
+ readonly inverse: false;
1978
+ readonly sequence: false;
1979
+ readonly computeName: undefined;
1980
+ readonly store: true;
1981
+ readonly hasDefault: true;
1982
+ readonly readonly: false;
1983
+ }>;
1900
1984
  readonly rate: import("../server/orm.js").DecimalField<{
1901
1985
  readonly required: true;
1902
1986
  readonly computed: false;
@@ -1907,6 +1991,46 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1907
1991
  readonly hasDefault: true;
1908
1992
  readonly readonly: false;
1909
1993
  }>;
1994
+ readonly fixedAmount: import("../server/orm.js").DecimalField<{
1995
+ readonly required: true;
1996
+ readonly computed: false;
1997
+ readonly inverse: false;
1998
+ readonly sequence: false;
1999
+ readonly computeName: undefined;
2000
+ readonly store: true;
2001
+ readonly hasDefault: true;
2002
+ readonly readonly: false;
2003
+ }>;
2004
+ readonly affectsBase: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
2005
+ readonly required: true;
2006
+ readonly computed: false;
2007
+ readonly inverse: false;
2008
+ readonly sequence: false;
2009
+ readonly computeName: undefined;
2010
+ readonly store: true;
2011
+ readonly hasDefault: true;
2012
+ readonly readonly: false;
2013
+ }>;
2014
+ readonly priceIncluded: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
2015
+ readonly required: true;
2016
+ readonly computed: false;
2017
+ readonly inverse: false;
2018
+ readonly sequence: false;
2019
+ readonly computeName: undefined;
2020
+ readonly store: true;
2021
+ readonly hasDefault: true;
2022
+ readonly readonly: false;
2023
+ }>;
2024
+ readonly reverseCharge: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
2025
+ readonly required: true;
2026
+ readonly computed: false;
2027
+ readonly inverse: false;
2028
+ readonly sequence: false;
2029
+ readonly computeName: undefined;
2030
+ readonly store: true;
2031
+ readonly hasDefault: true;
2032
+ readonly readonly: false;
2033
+ }>;
1910
2034
  }, {} & import("../server/orm.js").TransitionMethods<{
1911
2035
  readonly name: import("../server/orm.js").CharField<{
1912
2036
  readonly required: true;
@@ -1928,6 +2052,26 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1928
2052
  readonly hasDefault: true;
1929
2053
  readonly readonly: false;
1930
2054
  }>;
2055
+ readonly sequence: import("../server/orm.js").ScalarField<"integer", number, number, {
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 amountType: import("../server/orm.js").SelectionField<"fixed" | "percent", {
2066
+ readonly required: true;
2067
+ readonly computed: false;
2068
+ readonly inverse: false;
2069
+ readonly sequence: false;
2070
+ readonly computeName: undefined;
2071
+ readonly store: true;
2072
+ readonly hasDefault: true;
2073
+ readonly readonly: false;
2074
+ }>;
1931
2075
  readonly rate: import("../server/orm.js").DecimalField<{
1932
2076
  readonly required: true;
1933
2077
  readonly computed: false;
@@ -1938,6 +2082,46 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
1938
2082
  readonly hasDefault: true;
1939
2083
  readonly readonly: false;
1940
2084
  }>;
2085
+ readonly fixedAmount: import("../server/orm.js").DecimalField<{
2086
+ readonly required: true;
2087
+ readonly computed: false;
2088
+ readonly inverse: false;
2089
+ readonly sequence: false;
2090
+ readonly computeName: undefined;
2091
+ readonly store: true;
2092
+ readonly hasDefault: true;
2093
+ readonly readonly: false;
2094
+ }>;
2095
+ readonly affectsBase: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
2096
+ readonly required: true;
2097
+ readonly computed: false;
2098
+ readonly inverse: false;
2099
+ readonly sequence: false;
2100
+ readonly computeName: undefined;
2101
+ readonly store: true;
2102
+ readonly hasDefault: true;
2103
+ readonly readonly: false;
2104
+ }>;
2105
+ readonly priceIncluded: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
2106
+ readonly required: true;
2107
+ readonly computed: false;
2108
+ readonly inverse: false;
2109
+ readonly sequence: false;
2110
+ readonly computeName: undefined;
2111
+ readonly store: true;
2112
+ readonly hasDefault: true;
2113
+ readonly readonly: false;
2114
+ }>;
2115
+ readonly reverseCharge: import("../server/orm.js").ScalarField<"boolean", boolean, boolean, {
2116
+ readonly required: true;
2117
+ readonly computed: false;
2118
+ readonly inverse: false;
2119
+ readonly sequence: false;
2120
+ readonly computeName: undefined;
2121
+ readonly store: true;
2122
+ readonly hasDefault: true;
2123
+ readonly readonly: false;
2124
+ }>;
1941
2125
  }>>, import("../server/orm.js").Model<"product.product", {
1942
2126
  readonly id: import("../server/orm.js").IdField<"product.product">;
1943
2127
  readonly createdAt: import("../server/orm.js").ScalarField<'datetime', Date, Date, {
@@ -2081,6 +2265,26 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
2081
2265
  readonly hasDefault: true;
2082
2266
  readonly readonly: false;
2083
2267
  }>;
2268
+ readonly taxes: import("../server/orm.js").Many2manyField<"account.tax", {
2269
+ readonly required: true;
2270
+ readonly computed: false;
2271
+ readonly inverse: false;
2272
+ readonly sequence: false;
2273
+ readonly computeName: undefined;
2274
+ readonly store: true;
2275
+ readonly hasDefault: true;
2276
+ readonly readonly: false;
2277
+ }>;
2278
+ readonly purchaseTaxes: import("../server/orm.js").Many2manyField<"account.tax", {
2279
+ readonly required: true;
2280
+ readonly computed: false;
2281
+ readonly inverse: false;
2282
+ readonly sequence: false;
2283
+ readonly computeName: undefined;
2284
+ readonly store: true;
2285
+ readonly hasDefault: true;
2286
+ readonly readonly: false;
2287
+ }>;
2084
2288
  readonly tax: import("../server/orm.js").Many2oneField<"account.tax", {
2085
2289
  readonly required: false;
2086
2290
  readonly computed: false;
@@ -2089,7 +2293,7 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
2089
2293
  readonly computeName: undefined;
2090
2294
  readonly store: true;
2091
2295
  readonly hasDefault: false;
2092
- readonly readonly: false;
2296
+ readonly readonly: true;
2093
2297
  }>;
2094
2298
  readonly purchaseTax: import("../server/orm.js").Many2oneField<"account.tax", {
2095
2299
  readonly required: false;
@@ -2099,7 +2303,7 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
2099
2303
  readonly computeName: undefined;
2100
2304
  readonly store: true;
2101
2305
  readonly hasDefault: false;
2102
- readonly readonly: false;
2306
+ readonly readonly: true;
2103
2307
  }>;
2104
2308
  readonly description: import("../server/orm.js").ScalarField<"text", string, string | Readonly<Record<string, string>>, {
2105
2309
  readonly required: false;
@@ -2212,6 +2416,26 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
2212
2416
  readonly hasDefault: true;
2213
2417
  readonly readonly: false;
2214
2418
  }>;
2419
+ readonly taxes: import("../server/orm.js").Many2manyField<"account.tax", {
2420
+ readonly required: true;
2421
+ readonly computed: false;
2422
+ readonly inverse: false;
2423
+ readonly sequence: false;
2424
+ readonly computeName: undefined;
2425
+ readonly store: true;
2426
+ readonly hasDefault: true;
2427
+ readonly readonly: false;
2428
+ }>;
2429
+ readonly purchaseTaxes: import("../server/orm.js").Many2manyField<"account.tax", {
2430
+ readonly required: true;
2431
+ readonly computed: false;
2432
+ readonly inverse: false;
2433
+ readonly sequence: false;
2434
+ readonly computeName: undefined;
2435
+ readonly store: true;
2436
+ readonly hasDefault: true;
2437
+ readonly readonly: false;
2438
+ }>;
2215
2439
  readonly tax: import("../server/orm.js").Many2oneField<"account.tax", {
2216
2440
  readonly required: false;
2217
2441
  readonly computed: false;
@@ -2220,7 +2444,7 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
2220
2444
  readonly computeName: undefined;
2221
2445
  readonly store: true;
2222
2446
  readonly hasDefault: false;
2223
- readonly readonly: false;
2447
+ readonly readonly: true;
2224
2448
  }>;
2225
2449
  readonly purchaseTax: import("../server/orm.js").Many2oneField<"account.tax", {
2226
2450
  readonly required: false;
@@ -2230,7 +2454,7 @@ export declare const salesShutro: import("../server/orm.js").Module<readonly [im
2230
2454
  readonly computeName: undefined;
2231
2455
  readonly store: true;
2232
2456
  readonly hasDefault: false;
2233
- readonly readonly: false;
2457
+ readonly readonly: true;
2234
2458
  }>;
2235
2459
  readonly description: import("../server/orm.js").ScalarField<"text", string, string | Readonly<Record<string, string>>, {
2236
2460
  readonly required: false;