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.
Files changed (381) hide show
  1. package/dist/account_portal/.kosh/bindings.js +1 -1
  2. package/dist/account_portal/.kosh/schema.d.ts +54 -3
  3. package/dist/account_portal/module.d.ts +359 -6
  4. package/dist/accounting/.kosh/bindings.js +1 -1
  5. package/dist/accounting/.kosh/schema.d.ts +54 -3
  6. package/dist/accounting/index.js +214 -2
  7. package/dist/accounting/module.d.ts +217 -5
  8. package/dist/accounting/module.js +23 -2
  9. package/dist/calendar/.kosh/bindings.d.ts +22 -0
  10. package/dist/calendar/.kosh/bindings.js +15 -0
  11. package/dist/calendar/.kosh/schema.d.ts +795 -0
  12. package/dist/calendar/demo.d.ts +6 -0
  13. package/dist/calendar/demo.js +24 -0
  14. package/dist/calendar/index.d.ts +3 -0
  15. package/dist/calendar/index.js +291 -0
  16. package/dist/calendar/module.d.ts +1705 -0
  17. package/dist/calendar/module.js +180 -0
  18. package/dist/cli/init.js +48 -0
  19. package/dist/cli/templates.d.ts +1 -1
  20. package/dist/cli/templates.js +137 -0
  21. package/dist/contacts/.kosh/bindings.js +1 -1
  22. package/dist/contacts/.kosh/schema.d.ts +78 -3
  23. package/dist/contacts/demo.js +30 -1
  24. package/dist/contacts/index.d.ts +1 -1
  25. package/dist/contacts/index.js +155 -9
  26. package/dist/contacts/module.d.ts +338 -2
  27. package/dist/contacts/module.js +82 -5
  28. package/dist/crm/.kosh/bindings.d.ts +22 -0
  29. package/dist/crm/.kosh/bindings.js +15 -0
  30. package/dist/crm/.kosh/schema.d.ts +799 -0
  31. package/dist/crm/demo.d.ts +6 -0
  32. package/dist/crm/demo.js +45 -0
  33. package/dist/crm/index.d.ts +3 -0
  34. package/dist/crm/index.js +361 -0
  35. package/dist/crm/module.d.ts +1843 -0
  36. package/dist/crm/module.js +207 -0
  37. package/dist/event/.kosh/bindings.d.ts +22 -0
  38. package/dist/event/.kosh/bindings.js +15 -0
  39. package/dist/event/.kosh/schema.d.ts +843 -0
  40. package/dist/event/demo.d.ts +6 -0
  41. package/dist/event/demo.js +65 -0
  42. package/dist/event/index.d.ts +14 -0
  43. package/dist/event/index.js +333 -0
  44. package/dist/event/mails.d.ts +15 -0
  45. package/dist/event/mails.js +112 -0
  46. package/dist/event/module.d.ts +2800 -0
  47. package/dist/event/module.js +323 -0
  48. package/dist/event/web/CheckInBox.d.ts +9 -0
  49. package/dist/event/web/CheckInBox.js +87 -0
  50. package/dist/event/web/index.d.ts +11 -0
  51. package/dist/event/web/index.js +16 -0
  52. package/dist/event/web/messages.d.ts +2 -0
  53. package/dist/event/web/messages.js +23 -0
  54. package/dist/event_account/.kosh/bindings.d.ts +22 -0
  55. package/dist/event_account/.kosh/bindings.js +15 -0
  56. package/dist/event_account/.kosh/schema.d.ts +1639 -0
  57. package/dist/event_account/index.d.ts +3 -0
  58. package/dist/event_account/index.js +28 -0
  59. package/dist/event_account/module.d.ts +6968 -0
  60. package/dist/event_account/module.js +90 -0
  61. package/dist/hr/.kosh/bindings.d.ts +22 -0
  62. package/dist/hr/.kosh/bindings.js +15 -0
  63. package/dist/hr/.kosh/schema.d.ts +878 -0
  64. package/dist/hr/demo.d.ts +6 -0
  65. package/dist/hr/demo.js +60 -0
  66. package/dist/hr/index.d.ts +3 -0
  67. package/dist/hr/index.js +483 -0
  68. package/dist/hr/module.d.ts +2611 -0
  69. package/dist/hr/module.js +350 -0
  70. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  71. package/dist/l10n_bd/.kosh/schema.d.ts +54 -3
  72. package/dist/l10n_bd/module.d.ts +359 -6
  73. package/dist/l10n_in/.kosh/bindings.js +1 -1
  74. package/dist/l10n_in/.kosh/schema.d.ts +54 -3
  75. package/dist/l10n_in/module.d.ts +380 -7
  76. package/dist/maintenance/.kosh/bindings.d.ts +22 -0
  77. package/dist/maintenance/.kosh/bindings.js +15 -0
  78. package/dist/maintenance/.kosh/schema.d.ts +911 -0
  79. package/dist/maintenance/demo.d.ts +6 -0
  80. package/dist/maintenance/demo.js +60 -0
  81. package/dist/maintenance/index.d.ts +3 -0
  82. package/dist/maintenance/index.js +422 -0
  83. package/dist/maintenance/module.d.ts +3545 -0
  84. package/dist/maintenance/module.js +446 -0
  85. package/dist/maintenance_stock/.kosh/bindings.d.ts +22 -0
  86. package/dist/maintenance_stock/.kosh/bindings.js +15 -0
  87. package/dist/maintenance_stock/.kosh/schema.d.ts +1371 -0
  88. package/dist/maintenance_stock/index.d.ts +9 -0
  89. package/dist/maintenance_stock/index.js +52 -0
  90. package/dist/maintenance_stock/module.d.ts +6953 -0
  91. package/dist/maintenance_stock/module.js +192 -0
  92. package/dist/modules-sdk/index.d.ts +1 -1
  93. package/dist/modules-sdk/manifest.d.ts +70 -0
  94. package/dist/modules-sdk/manifest.js +35 -1
  95. package/dist/mrp/.kosh/bindings.d.ts +22 -0
  96. package/dist/mrp/.kosh/bindings.js +15 -0
  97. package/dist/mrp/.kosh/schema.d.ts +1378 -0
  98. package/dist/mrp/demo.d.ts +7 -0
  99. package/dist/mrp/demo.js +42 -0
  100. package/dist/mrp/index.d.ts +3 -0
  101. package/dist/mrp/index.js +392 -0
  102. package/dist/mrp/module.d.ts +8608 -0
  103. package/dist/mrp/module.js +695 -0
  104. package/dist/mrp_account/.kosh/bindings.d.ts +22 -0
  105. package/dist/mrp_account/.kosh/bindings.js +15 -0
  106. package/dist/mrp_account/.kosh/schema.d.ts +2106 -0
  107. package/dist/mrp_account/index.d.ts +3 -0
  108. package/dist/mrp_account/index.js +22 -0
  109. package/dist/mrp_account/module.d.ts +20840 -0
  110. package/dist/mrp_account/module.js +123 -0
  111. package/dist/payment/.kosh/bindings.js +1 -1
  112. package/dist/payment/.kosh/schema.d.ts +54 -3
  113. package/dist/payment/module.d.ts +359 -6
  114. package/dist/portal/.kosh/bindings.js +1 -1
  115. package/dist/portal/.kosh/schema.d.ts +78 -3
  116. package/dist/portal/module.d.ts +166 -2
  117. package/dist/pos/.kosh/bindings.d.ts +22 -0
  118. package/dist/pos/.kosh/bindings.js +15 -0
  119. package/dist/pos/.kosh/schema.d.ts +1690 -0
  120. package/dist/pos/accounting.d.ts +10 -0
  121. package/dist/pos/accounting.js +149 -0
  122. package/dist/pos/demo.d.ts +6 -0
  123. package/dist/pos/demo.js +90 -0
  124. package/dist/pos/index.d.ts +9 -0
  125. package/dist/pos/index.js +349 -0
  126. package/dist/pos/module.d.ts +9636 -0
  127. package/dist/pos/module.js +423 -0
  128. package/dist/pos/routes.d.ts +39 -0
  129. package/dist/pos/routes.js +368 -0
  130. package/dist/pos/web/Register.d.ts +9 -0
  131. package/dist/pos/web/Register.js +252 -0
  132. package/dist/pos/web/index.d.ts +11 -0
  133. package/dist/pos/web/index.js +16 -0
  134. package/dist/pos/web/messages.d.ts +2 -0
  135. package/dist/pos/web/messages.js +87 -0
  136. package/dist/pos_stock/.kosh/bindings.d.ts +22 -0
  137. package/dist/pos_stock/.kosh/bindings.js +15 -0
  138. package/dist/pos_stock/.kosh/schema.d.ts +2015 -0
  139. package/dist/pos_stock/index.d.ts +9 -0
  140. package/dist/pos_stock/index.js +35 -0
  141. package/dist/pos_stock/module.d.ts +11935 -0
  142. package/dist/pos_stock/module.js +115 -0
  143. package/dist/product/.kosh/bindings.js +1 -1
  144. package/dist/product/.kosh/schema.d.ts +51 -1
  145. package/dist/product/index.js +81 -4
  146. package/dist/product/module.d.ts +43 -1
  147. package/dist/product/module.js +9 -2
  148. package/dist/project/.kosh/bindings.js +1 -1
  149. package/dist/project/.kosh/schema.d.ts +54 -3
  150. package/dist/project/index.js +147 -7
  151. package/dist/project/module.d.ts +210 -2
  152. package/dist/project/module.js +52 -5
  153. package/dist/project_portal/.kosh/bindings.js +1 -1
  154. package/dist/project_portal/.kosh/schema.d.ts +54 -3
  155. package/dist/project_portal/module.d.ts +353 -4
  156. package/dist/purchase/.kosh/bindings.js +1 -1
  157. package/dist/purchase/.kosh/schema.d.ts +54 -3
  158. package/dist/purchase/index.js +163 -3
  159. package/dist/purchase/module.d.ts +215 -3
  160. package/dist/purchase/module.js +21 -3
  161. package/dist/purchase_account/.kosh/bindings.js +1 -1
  162. package/dist/purchase_account/.kosh/schema.d.ts +55 -3
  163. package/dist/purchase_account/index.js +26 -1
  164. package/dist/purchase_account/module.d.ts +393 -7
  165. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  166. package/dist/purchase_portal/.kosh/schema.d.ts +54 -3
  167. package/dist/purchase_portal/module.d.ts +366 -5
  168. package/dist/purchase_stock/.kosh/bindings.d.ts +22 -0
  169. package/dist/purchase_stock/.kosh/bindings.js +15 -0
  170. package/dist/purchase_stock/.kosh/schema.d.ts +1310 -0
  171. package/dist/purchase_stock/index.d.ts +7 -0
  172. package/dist/purchase_stock/index.js +91 -0
  173. package/dist/purchase_stock/module.d.ts +6763 -0
  174. package/dist/purchase_stock/module.js +144 -0
  175. package/dist/purchase_stock_account/.kosh/bindings.d.ts +22 -0
  176. package/dist/purchase_stock_account/.kosh/bindings.js +15 -0
  177. package/dist/purchase_stock_account/.kosh/schema.d.ts +1959 -0
  178. package/dist/purchase_stock_account/index.d.ts +3 -0
  179. package/dist/purchase_stock_account/index.js +24 -0
  180. package/dist/purchase_stock_account/module.d.ts +35366 -0
  181. package/dist/purchase_stock_account/module.js +162 -0
  182. package/dist/recruitment/.kosh/bindings.d.ts +22 -0
  183. package/dist/recruitment/.kosh/bindings.js +15 -0
  184. package/dist/recruitment/.kosh/schema.d.ts +990 -0
  185. package/dist/recruitment/demo.d.ts +6 -0
  186. package/dist/recruitment/demo.js +45 -0
  187. package/dist/recruitment/index.d.ts +3 -0
  188. package/dist/recruitment/index.js +385 -0
  189. package/dist/recruitment/module.d.ts +3247 -0
  190. package/dist/recruitment/module.js +193 -0
  191. package/dist/recruitment/web/HireButton.d.ts +9 -0
  192. package/dist/recruitment/web/HireButton.js +32 -0
  193. package/dist/recruitment/web/index.d.ts +11 -0
  194. package/dist/recruitment/web/index.js +16 -0
  195. package/dist/recruitment/web/messages.d.ts +2 -0
  196. package/dist/recruitment/web/messages.js +19 -0
  197. package/dist/reporting/documents.d.ts +5 -0
  198. package/dist/reporting/documents.js +28 -1
  199. package/dist/reporting/index.d.ts +1 -1
  200. package/dist/reporting/index.js +4 -2
  201. package/dist/reporting/models.js +9 -0
  202. package/dist/reporting/overviews.d.ts +16 -0
  203. package/dist/reporting/overviews.js +56 -0
  204. package/dist/reporting/routes-documents.js +1 -1
  205. package/dist/reporting/routes.js +138 -80
  206. package/dist/reporting/web/DashboardView.d.ts +11 -0
  207. package/dist/reporting/web/DashboardView.js +2 -2
  208. package/dist/reporting/web/DesignerView.js +5 -0
  209. package/dist/reporting/web/Overview.d.ts +9 -0
  210. package/dist/reporting/web/Overview.js +53 -0
  211. package/dist/reporting/web/index.d.ts +1 -0
  212. package/dist/reporting/web/index.js +4 -1
  213. package/dist/reporting/web/messages.js +9 -0
  214. package/dist/sale_account/.kosh/bindings.js +1 -1
  215. package/dist/sale_account/.kosh/schema.d.ts +59 -3
  216. package/dist/sale_account/index.js +22 -1
  217. package/dist/sale_account/module.d.ts +461 -7
  218. package/dist/sale_portal/.kosh/bindings.js +1 -1
  219. package/dist/sale_portal/.kosh/schema.d.ts +58 -3
  220. package/dist/sale_portal/module.d.ts +434 -5
  221. package/dist/sale_project/.kosh/bindings.js +1 -1
  222. package/dist/sale_project/.kosh/schema.d.ts +60 -3
  223. package/dist/sale_project/module.d.ts +476 -6
  224. package/dist/sale_stock/.kosh/bindings.d.ts +22 -0
  225. package/dist/sale_stock/.kosh/bindings.js +15 -0
  226. package/dist/sale_stock/.kosh/schema.d.ts +1228 -0
  227. package/dist/sale_stock/index.d.ts +7 -0
  228. package/dist/sale_stock/index.js +84 -0
  229. package/dist/sale_stock/module.d.ts +6791 -0
  230. package/dist/sale_stock/module.js +146 -0
  231. package/dist/sales/.kosh/bindings.js +1 -1
  232. package/dist/sales/.kosh/schema.d.ts +58 -3
  233. package/dist/sales/index.js +191 -4
  234. package/dist/sales/module.d.ts +355 -3
  235. package/dist/sales/module.js +78 -3
  236. package/dist/server/api/metadata.d.ts +5 -0
  237. package/dist/server/api/metadata.js +5 -0
  238. package/dist/server/api/rest.js +64 -1
  239. package/dist/server/api/views.js +1 -0
  240. package/dist/server/app-settings.d.ts +7 -0
  241. package/dist/server/app-settings.js +10 -0
  242. package/dist/server/auth/base.js +9 -0
  243. package/dist/server/index.d.ts +1 -0
  244. package/dist/server/index.js +1 -0
  245. package/dist/settings/app-settings.d.ts +2 -0
  246. package/dist/settings/app-settings.js +518 -0
  247. package/dist/settings/index.d.ts +1 -0
  248. package/dist/settings/index.js +15 -0
  249. package/dist/settings/people.js +29 -5
  250. package/dist/settings/web/AppSettingsPage.d.ts +11 -0
  251. package/dist/settings/web/AppSettingsPage.js +210 -0
  252. package/dist/settings/web/OverviewPage.js +16 -3
  253. package/dist/settings/web/PeoplePage.js +20 -6
  254. package/dist/settings/web/index.d.ts +1 -0
  255. package/dist/settings/web/index.js +3 -0
  256. package/dist/settings/web/messages.js +118 -2
  257. package/dist/stock/.kosh/bindings.d.ts +22 -0
  258. package/dist/stock/.kosh/bindings.js +15 -0
  259. package/dist/stock/.kosh/schema.d.ts +1147 -0
  260. package/dist/stock/demo.d.ts +7 -0
  261. package/dist/stock/demo.js +55 -0
  262. package/dist/stock/index.d.ts +3 -0
  263. package/dist/stock/index.js +674 -0
  264. package/dist/stock/module.d.ts +6330 -0
  265. package/dist/stock/module.js +1325 -0
  266. package/dist/stock/web/ScanBox.d.ts +8 -0
  267. package/dist/stock/web/ScanBox.js +90 -0
  268. package/dist/stock/web/index.d.ts +11 -0
  269. package/dist/stock/web/index.js +16 -0
  270. package/dist/stock/web/messages.d.ts +2 -0
  271. package/dist/stock/web/messages.js +25 -0
  272. package/dist/stock_account/.kosh/bindings.d.ts +22 -0
  273. package/dist/stock_account/.kosh/bindings.js +15 -0
  274. package/dist/stock_account/.kosh/schema.d.ts +1875 -0
  275. package/dist/stock_account/index.d.ts +3 -0
  276. package/dist/stock_account/index.js +130 -0
  277. package/dist/stock_account/module.d.ts +10655 -0
  278. package/dist/stock_account/module.js +339 -0
  279. package/dist/storage/attachments.d.ts +5 -0
  280. package/dist/storage/attachments.js +12 -1
  281. package/dist/storage/models.js +3 -0
  282. package/dist/storage/routes.js +13 -2
  283. package/dist/todo/.kosh/bindings.d.ts +22 -0
  284. package/dist/todo/.kosh/bindings.js +15 -0
  285. package/dist/todo/.kosh/schema.d.ts +732 -0
  286. package/dist/todo/demo.d.ts +6 -0
  287. package/dist/todo/demo.js +35 -0
  288. package/dist/todo/index.d.ts +3 -0
  289. package/dist/todo/index.js +187 -0
  290. package/dist/todo/module.d.ts +1180 -0
  291. package/dist/todo/module.js +130 -0
  292. package/dist/trade_finance/.kosh/bindings.d.ts +22 -0
  293. package/dist/trade_finance/.kosh/bindings.js +15 -0
  294. package/dist/trade_finance/.kosh/schema.d.ts +884 -0
  295. package/dist/trade_finance/demo.d.ts +6 -0
  296. package/dist/trade_finance/demo.js +63 -0
  297. package/dist/trade_finance/index.d.ts +3 -0
  298. package/dist/trade_finance/index.js +413 -0
  299. package/dist/trade_finance/module.d.ts +3779 -0
  300. package/dist/trade_finance/module.js +505 -0
  301. package/dist/trade_finance_account/.kosh/bindings.d.ts +22 -0
  302. package/dist/trade_finance_account/.kosh/bindings.js +15 -0
  303. package/dist/trade_finance_account/.kosh/schema.d.ts +1711 -0
  304. package/dist/trade_finance_account/index.d.ts +3 -0
  305. package/dist/trade_finance_account/index.js +92 -0
  306. package/dist/trade_finance_account/module.d.ts +7928 -0
  307. package/dist/trade_finance_account/module.js +244 -0
  308. package/dist/trade_finance_purchase/.kosh/bindings.d.ts +22 -0
  309. package/dist/trade_finance_purchase/.kosh/bindings.js +15 -0
  310. package/dist/trade_finance_purchase/.kosh/schema.d.ts +1153 -0
  311. package/dist/trade_finance_purchase/index.d.ts +8 -0
  312. package/dist/trade_finance_purchase/index.js +50 -0
  313. package/dist/trade_finance_purchase/module.d.ts +4252 -0
  314. package/dist/trade_finance_purchase/module.js +44 -0
  315. package/dist/trade_finance_sale/.kosh/bindings.d.ts +22 -0
  316. package/dist/trade_finance_sale/.kosh/bindings.js +15 -0
  317. package/dist/trade_finance_sale/.kosh/schema.d.ts +1071 -0
  318. package/dist/trade_finance_sale/index.d.ts +8 -0
  319. package/dist/trade_finance_sale/index.js +50 -0
  320. package/dist/trade_finance_sale/module.d.ts +4280 -0
  321. package/dist/trade_finance_sale/module.js +44 -0
  322. package/dist/ui/api.d.ts +2 -1
  323. package/dist/ui/api.js +2 -1
  324. package/dist/ui/app.js +2 -1
  325. package/dist/ui/components/AppIcon.js +23 -1
  326. package/dist/ui/components/primitives.d.ts +2 -0
  327. package/dist/ui/components/primitives.js +7 -1
  328. package/dist/ui/i18n/messages.d.ts +23 -0
  329. package/dist/ui/i18n/messages.js +38 -0
  330. package/dist/ui/index.d.ts +1 -0
  331. package/dist/ui/index.js +1 -0
  332. package/dist/ui/offline/queue.d.ts +5 -1
  333. package/dist/ui/offline/queue.js +2 -0
  334. package/dist/ui/registry.d.ts +5 -0
  335. package/dist/ui/shell/Home.js +55 -4
  336. package/dist/ui/views/FormView.js +98 -17
  337. package/dist/ui/views/KanbanView.d.ts +2 -0
  338. package/dist/ui/views/KanbanView.js +32 -3
  339. package/dist/ui/views/ListView.js +108 -11
  340. package/dist/ui/views/StatsRow.d.ts +14 -0
  341. package/dist/ui/views/StatsRow.js +88 -0
  342. package/dist/ui/views/widgets.d.ts +2 -1
  343. package/dist/ui/views/widgets.js +194 -1
  344. package/dist/views/builders.d.ts +19 -2
  345. package/dist/views/builders.js +21 -1
  346. package/dist/views/condition.d.ts +6 -0
  347. package/dist/views/condition.js +20 -0
  348. package/dist/views/documents.d.ts +8 -0
  349. package/dist/views/extend.d.ts +2 -2
  350. package/dist/views/extend.js +11 -1
  351. package/dist/views/index.d.ts +2 -2
  352. package/dist/views/index.js +2 -2
  353. package/dist/views/types.d.ts +52 -5
  354. package/dist/views/validate.js +39 -1
  355. package/dist/website/.kosh/bindings.d.ts +22 -0
  356. package/dist/website/.kosh/bindings.js +15 -0
  357. package/dist/website/.kosh/schema.d.ts +881 -0
  358. package/dist/website/demo.d.ts +6 -0
  359. package/dist/website/demo.js +115 -0
  360. package/dist/website/index.d.ts +9 -0
  361. package/dist/website/index.js +250 -0
  362. package/dist/website/module.d.ts +2987 -0
  363. package/dist/website/module.js +281 -0
  364. package/dist/website/render.d.ts +45 -0
  365. package/dist/website/render.js +102 -0
  366. package/dist/website/routes.d.ts +12 -0
  367. package/dist/website/routes.js +246 -0
  368. package/dist/website/web/PagePreview.d.ts +7 -0
  369. package/dist/website/web/PagePreview.js +33 -0
  370. package/dist/website/web/index.d.ts +11 -0
  371. package/dist/website/web/index.js +16 -0
  372. package/dist/website/web/messages.d.ts +2 -0
  373. package/dist/website/web/messages.js +15 -0
  374. package/dist/website_crm/.kosh/bindings.d.ts +22 -0
  375. package/dist/website_crm/.kosh/bindings.js +15 -0
  376. package/dist/website_crm/.kosh/schema.d.ts +966 -0
  377. package/dist/website_crm/index.d.ts +3 -0
  378. package/dist/website_crm/index.js +39 -0
  379. package/dist/website_crm/module.d.ts +2955 -0
  380. package/dist/website_crm/module.js +44 -0
  381. package/package.json +118 -1
@@ -0,0 +1,350 @@
1
+ /**
2
+ * The data layer of Workforce (RFC 0021): departments as a tree, positions, employees (separate from users: an
3
+ * employee may never sign in) with their manager, contracts, and leave. Personal details and wages are visible to
4
+ * HR managers only (field security). A leave's working days follow the company's week (the weekend setting) and are
5
+ * checked by the server; a request may not overlap another of the same person, nor go beyond the year's days of its
6
+ * type. Approving and refusing need the decision permission (HR managers) or go through the line manager's route.
7
+ */
8
+ import { contactsShutro } from '../contacts/index.js';
9
+ import { messagingShutro } from '../messaging/index.js';
10
+ import { installationSetting } from '../server/index.js';
11
+ import { orm } from '../server/orm.js';
12
+ import { check, defineModel, defineModule, f, onchange, record, records, } from './.kosh/bindings.js';
13
+ const READ = ['read'];
14
+ const ALL = ['read', 'write', 'create', 'unlink'];
15
+ const HR = ['hr.manager'];
16
+ const me = { $env: 'uid' };
17
+ /** The weekend of each choice, as JavaScript day numbers (0: Sunday). */
18
+ export const WEEKENDS = {
19
+ fri_sat: [5, 6],
20
+ sat_sun: [6, 0],
21
+ fri: [5],
22
+ };
23
+ /** Working days from `from` to `to` (inclusive, ISO dates) outside the weekend. */
24
+ export function workingDays(from, to, weekend) {
25
+ const start = Date.parse(`${from}T00:00:00Z`);
26
+ const end = Date.parse(`${to}T00:00:00Z`);
27
+ if (Number.isNaN(start) || Number.isNaN(end) || end < start)
28
+ return 0;
29
+ let days = 0;
30
+ for (let t = start; t <= end; t += 86_400_000)
31
+ if (!weekend.includes(new Date(t).getUTCDay()))
32
+ days += 1;
33
+ return days;
34
+ }
35
+ /** The installation's weekend (App settings › Workforce). */
36
+ export async function weekendOf(env) {
37
+ const choice = await installationSetting(env, 'hr.weekend', 'fri_sat');
38
+ return WEEKENDS[String(choice)] ?? WEEKENDS['fri_sat'];
39
+ }
40
+ /**
41
+ * A date as `YYYY-MM-DD`. Date-only values read from PostgreSQL are local midnights: their local parts are the date
42
+ * (`toISOString()` would move them a day back east of UTC).
43
+ */
44
+ const iso = (v) => {
45
+ if (!(v instanceof Date))
46
+ return String(v ?? '');
47
+ const pad = (n) => String(n).padStart(2, '0');
48
+ return `${v.getFullYear()}-${pad(v.getMonth() + 1)}-${pad(v.getDate())}`;
49
+ };
50
+ export const HrDepartment = defineModel('hr.department', {
51
+ label: 'Department',
52
+ recName: 'name',
53
+ order: ['name asc'],
54
+ archivable: true,
55
+ companyScoped: { required: true },
56
+ access: { 'hr.user': READ, 'hr.manager': ALL },
57
+ fields: {
58
+ name: f.char({ required: true }),
59
+ parent: f.many2one('hr.department', { ondelete: 'restrict', label: 'Part of' }),
60
+ head: f.many2one('hr.employee', { ondelete: 'set null', label: 'Head' }),
61
+ },
62
+ });
63
+ export const HrJob = defineModel('hr.job', {
64
+ label: 'Position',
65
+ recName: 'name',
66
+ order: ['name asc'],
67
+ archivable: true,
68
+ companyScoped: { required: true },
69
+ access: { 'hr.user': READ, 'hr.manager': ALL },
70
+ fields: {
71
+ name: f.char({ required: true, translate: true }),
72
+ department: f.many2one('hr.department', { ondelete: 'set null' }),
73
+ },
74
+ });
75
+ export const HrEmployee = defineModel('hr.employee', {
76
+ label: 'Employee',
77
+ recName: 'name',
78
+ order: ['name asc'],
79
+ archivable: true,
80
+ companyScoped: { required: true },
81
+ tracking: ['department', 'job', 'manager'],
82
+ access: { 'hr.user': READ, 'hr.manager': [...ALL, 'export', 'import'] },
83
+ fields: {
84
+ name: f.char({ required: true }),
85
+ /** The person's sign-in, when they have one. */
86
+ user: f.many2one('res.users', { ondelete: 'set null', label: 'User' }),
87
+ department: f.many2one('hr.department', { ondelete: 'set null' }),
88
+ job: f.many2one('hr.job', { ondelete: 'set null', label: 'Position' }),
89
+ manager: f.many2one('hr.employee', { ondelete: 'set null' }),
90
+ team: f.one2many('hr.employee', 'manager', { label: 'Team' }),
91
+ workEmail: f.char({ label: 'Work email' }),
92
+ workPhone: f.char({ label: 'Work phone' }),
93
+ hireDate: f.date({ label: 'Joined' }),
94
+ // Personal: HR managers only.
95
+ birthday: f.date({ groups: HR }),
96
+ nationalId: f.char({ label: 'National ID', groups: HR }),
97
+ privateAddress: f.text({ label: 'Home address', groups: HR }),
98
+ emergencyContact: f.char({ label: 'Emergency contact', groups: HR }),
99
+ },
100
+ constraints: {
101
+ oneEmployeePerUser: {
102
+ ...check('hr.employee', ['user'], async (employees) => employees.env.asSuperuser({ reason: 'one employee per user' }, async (su) => {
103
+ const failing = [];
104
+ for (const e of employees) {
105
+ if (e.user === null)
106
+ continue;
107
+ const twins = await su
108
+ .withFlags({ activeTest: false })
109
+ .model('hr.employee')
110
+ .search({ where: { user: e.user.id, id: { ne: e.id } }, limit: 1 });
111
+ if (twins.length > 0)
112
+ failing.push(e.id);
113
+ }
114
+ return failing;
115
+ })),
116
+ message: 'This user is already another employee.',
117
+ },
118
+ },
119
+ });
120
+ export const HrContract = defineModel('hr.contract', {
121
+ label: 'Contract',
122
+ recName: 'name',
123
+ order: ['dateStart desc', 'id desc'],
124
+ companyScoped: { required: true },
125
+ tracking: ['state', 'dateEnd', 'wage'],
126
+ access: { 'hr.user': READ, 'hr.manager': ALL },
127
+ rules: {
128
+ own: { groups: ['hr.user'], perms: ['read'], domain: { 'employee.user': me } },
129
+ all: { groups: ['hr.manager'], perms: [...ALL], domain: {} },
130
+ },
131
+ fields: {
132
+ name: f.char({ required: true, label: 'Reference' }),
133
+ employee: f.many2one('hr.employee', { required: true, ondelete: 'cascade' }),
134
+ kind: f.selection({ permanent: 'Permanent', fixed: 'Fixed term', probation: 'Probation', intern: 'Internship' }, { required: true, default: 'permanent', label: 'Type' }),
135
+ dateStart: f.date({ required: true, label: 'Starts' }),
136
+ dateEnd: f.date({ label: 'Ends' }),
137
+ wage: f.decimal({ scale: 2, label: 'Monthly wage', groups: HR }),
138
+ state: f.state({
139
+ states: { draft: 'Draft', running: 'Running', ended: 'Ended', cancelled: 'Cancelled' },
140
+ initial: 'draft',
141
+ transitions: {
142
+ start: { from: ['draft'], to: 'running' },
143
+ end: { from: ['running'], to: 'ended' },
144
+ cancel: { from: ['draft', 'running'], to: 'cancelled' },
145
+ },
146
+ }),
147
+ },
148
+ sqlConstraints: {
149
+ endsAfterStart: {
150
+ check: orm.sql `date_end IS NULL OR date_end >= date_start`,
151
+ message: 'A contract ends after it starts.',
152
+ },
153
+ },
154
+ });
155
+ export const HrLeaveType = defineModel('hr.leave.type', {
156
+ label: 'Leave type',
157
+ recName: 'name',
158
+ order: ['name asc'],
159
+ archivable: true,
160
+ access: { 'hr.user': READ, 'hr.manager': ALL },
161
+ fields: {
162
+ name: f.char({ required: true, translate: true }),
163
+ /** Days per calendar year for each person; empty: no balance (unpaid leave). */
164
+ daysPerYear: f.integer({ label: 'Days per year' }),
165
+ },
166
+ });
167
+ export const HrLeave = defineModel('hr.leave', {
168
+ label: 'Leave',
169
+ order: ['dateFrom desc', 'id desc'],
170
+ companyScoped: { required: true },
171
+ tracking: ['state', 'dateFrom', 'dateTo'],
172
+ access: { 'hr.user': ALL, 'hr.manager': ALL },
173
+ rules: {
174
+ // One's own requests in full; changed while still a draft.
175
+ seeOwn: { groups: ['hr.user'], perms: ['read'], domain: { 'employee.user': me } },
176
+ draftOwn: {
177
+ groups: ['hr.user'],
178
+ perms: ['write', 'create', 'unlink'],
179
+ domain: { 'employee.user': me, state: 'draft' },
180
+ },
181
+ // Line managers see their team's.
182
+ team: { groups: ['hr.user'], perms: ['read'], domain: { 'employee.manager.user': me } },
183
+ all: { groups: ['hr.manager'], perms: [...ALL], domain: {} },
184
+ },
185
+ fields: {
186
+ employee: f.many2one('hr.employee', { required: true, ondelete: 'cascade' }),
187
+ type: f.many2one('hr.leave.type', { required: true, ondelete: 'restrict', label: 'Type' }),
188
+ dateFrom: f.date({ required: true, label: 'From' }),
189
+ dateTo: f.date({ required: true, label: 'To' }),
190
+ /** Working days, by the company's week; checked by the server. */
191
+ days: f.integer({ required: true, default: 0, label: 'Working days' }),
192
+ reason: f.text(),
193
+ state: f.state({
194
+ states: { draft: 'Draft', submitted: 'Waiting', approved: 'Approved', refused: 'Refused' },
195
+ initial: 'draft',
196
+ transitions: {
197
+ submit: { from: ['draft'], to: 'submitted' },
198
+ // Never by the person asking, HR managers included.
199
+ approve: {
200
+ from: ['submitted'],
201
+ to: 'approved',
202
+ requires: 'hr.leave_decide',
203
+ guard: records('hr.leave', (leaves) => notOwn(leaves)),
204
+ message: 'Someone else decides your leave.',
205
+ },
206
+ refuse: {
207
+ from: ['submitted'],
208
+ to: 'refused',
209
+ requires: 'hr.leave_decide',
210
+ guard: records('hr.leave', (leaves) => notOwn(leaves)),
211
+ message: 'Someone else decides your leave.',
212
+ },
213
+ redraft: { from: ['submitted', 'refused'], to: 'draft' },
214
+ },
215
+ }),
216
+ },
217
+ sqlConstraints: {
218
+ ordered: {
219
+ check: orm.sql `date_to >= date_from`,
220
+ message: 'A leave ends on or after it starts.',
221
+ },
222
+ },
223
+ constraints: {
224
+ // The days the form says are the working days the server counts.
225
+ workingDays: {
226
+ ...check('hr.leave', ['dateFrom', 'dateTo', 'days'], async (leaves) => {
227
+ const weekend = await weekendOf(leaves.env);
228
+ return [...leaves]
229
+ .filter((l) => {
230
+ const days = workingDays(iso(l.dateFrom), iso(l.dateTo), weekend);
231
+ return days === 0 || l.days !== days;
232
+ })
233
+ .map((l) => l.id);
234
+ }),
235
+ message: 'The working days do not match the dates (or none falls on a working day).',
236
+ },
237
+ noOverlap: {
238
+ ...check('hr.leave', ['employee', 'dateFrom', 'dateTo', 'state'], async (leaves) => leaves.env.asSuperuser({ reason: 'overlapping leave' }, async (su) => {
239
+ const failing = [];
240
+ for (const l of leaves) {
241
+ if (l.state === 'refused')
242
+ continue;
243
+ const clash = await su.model('hr.leave').search({
244
+ where: {
245
+ employee: l.employee.id,
246
+ id: { ne: l.id },
247
+ state: { in: ['draft', 'submitted', 'approved'] },
248
+ dateFrom: { lte: l.dateTo },
249
+ dateTo: { gte: l.dateFrom },
250
+ },
251
+ limit: 1,
252
+ });
253
+ if (clash.length > 0)
254
+ failing.push(l.id);
255
+ }
256
+ return failing;
257
+ })),
258
+ message: 'This person already has leave on some of these days.',
259
+ },
260
+ // The year's days of its type: what is waiting and approved, this one included.
261
+ balance: {
262
+ ...check('hr.leave', ['employee', 'type', 'days', 'dateFrom', 'state'], async (leaves) => leaves.env.asSuperuser({ reason: 'leave balance' }, async (su) => {
263
+ const failing = [];
264
+ for (const l of leaves) {
265
+ if (l.state !== 'submitted' && l.state !== 'approved')
266
+ continue;
267
+ const [type] = (await su.model('hr.leave.type').browse([l.type.id]).load(['daysPerYear'])).read(['daysPerYear']);
268
+ const allowed = type?.['daysPerYear'];
269
+ if (allowed === null || allowed === undefined)
270
+ continue;
271
+ const year = iso(l.dateFrom).slice(0, 4);
272
+ const taken = (await (await su.model('hr.leave').search({
273
+ where: {
274
+ employee: l.employee.id,
275
+ type: l.type.id,
276
+ state: { in: ['submitted', 'approved'] },
277
+ dateFrom: { gte: `${year}-01-01`, lte: `${year}-12-31` },
278
+ },
279
+ })).load(['days']))
280
+ .read(['days'])
281
+ .reduce((sum, r) => sum + Number(r['days'] ?? 0), 0);
282
+ if (taken > Number(allowed))
283
+ failing.push(l.id);
284
+ }
285
+ return failing;
286
+ })),
287
+ message: 'Not enough days left of this leave type this year.',
288
+ },
289
+ },
290
+ onchange: {
291
+ dateFrom: onchange('hr.leave', async (d, env) => fillDays(d, env)),
292
+ dateTo: onchange('hr.leave', async (d, env) => fillDays(d, env)),
293
+ },
294
+ });
295
+ /** The leaves among `records` that the acting user asked for themself. */
296
+ async function notOwn(records) {
297
+ const { env, ids } = records;
298
+ return env.asSuperuser({ reason: 'own leave' }, async (su) => {
299
+ const leaves = (await su
300
+ .model('hr.leave')
301
+ .browse([...ids])
302
+ .load(['employee'])).read(['id', 'employee']);
303
+ const people = new Map((await su
304
+ .model('hr.employee')
305
+ .browse(leaves.map((l) => l['employee']))
306
+ .load(['user']))
307
+ .read(['id', 'user'])
308
+ .map((e) => [e['id'], e['user']]));
309
+ return leaves
310
+ .filter((l) => people.get(l['employee']) === env.uid)
311
+ .map((l) => l['id']);
312
+ });
313
+ }
314
+ /** The form's working days, from the dates and the company's week. */
315
+ async function fillDays(d, env) {
316
+ const from = d.get('dateFrom');
317
+ const to = d.get('dateTo');
318
+ if (from === null || from === undefined)
319
+ return;
320
+ if (to === null || to === undefined || iso(to) < iso(from))
321
+ d.set('dateTo', iso(from));
322
+ d.set('days', workingDays(iso(from), iso(d.get('dateTo') ?? from), await weekendOf(env)));
323
+ }
324
+ export const hrShutro = defineModule({
325
+ name: 'hr',
326
+ version: '0.1.0',
327
+ depends: [contactsShutro, messagingShutro],
328
+ groups: [
329
+ orm.defineGroup({ code: 'hr.user', label: 'Employee', implies: ['messaging.user'] }),
330
+ orm.defineGroup({
331
+ code: 'hr.manager',
332
+ label: 'HR manager',
333
+ implies: ['hr.user', 'contacts.user'],
334
+ }),
335
+ ],
336
+ permissions: [
337
+ orm.definePermission({
338
+ code: 'hr.leave_decide',
339
+ label: 'Approve and refuse leave',
340
+ groups: ['hr.manager'],
341
+ }),
342
+ ],
343
+ models: [HrDepartment, HrJob, HrEmployee, HrContract, HrLeaveType, HrLeave],
344
+ data: [
345
+ record('hr.leave.type', 'leave_casual', { name: 'Casual leave', daysPerYear: 10 }, { noupdate: true }),
346
+ record('hr.leave.type', 'leave_sick', { name: 'Sick leave', daysPerYear: 14 }, { noupdate: true }),
347
+ record('hr.leave.type', 'leave_annual', { name: 'Earned leave', daysPerYear: 20 }, { noupdate: true }),
348
+ record('hr.leave.type', 'leave_unpaid', { name: 'Unpaid leave' }, { noupdate: true }),
349
+ ],
350
+ });
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: d28665dceee41886
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: f724be50cf2472e1
2
2
  // Bindings of module `l10n_bd`: 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: d28665dceee41886
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: f724be50cf2472e1
2
2
  // Schema view of module `l10n_bd` (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
 
@@ -30,6 +30,7 @@ export interface SchemaView {
30
30
  readonly 'auth.user_group': AuthUserGroup;
31
31
  readonly 'kosh.image': KoshImage;
32
32
  readonly 'kosh.saved_view': KoshSavedView;
33
+ readonly 'kosh.setting': KoshSetting;
33
34
  readonly 'mail.activity': MailActivity;
34
35
  readonly 'mail.activity.type': MailActivityType;
35
36
  readonly 'mail.channel': MailChannel;
@@ -53,6 +54,7 @@ export interface SchemaView {
53
54
  readonly 'res.currency': ResCurrency;
54
55
  readonly 'res.currency.rate': ResCurrencyRate;
55
56
  readonly 'res.partner': ResPartner;
57
+ readonly 'res.partner.tag': ResPartnerTag;
56
58
  readonly 'res.users': ResUsers;
57
59
  readonly 'storage.attachment': StorageAttachment;
58
60
  readonly 'uom.uom': UomUom;
@@ -780,6 +782,26 @@ export interface KoshSavedView {
780
782
  export interface KoshSavedViewMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.saved_view'> {
781
783
  }
782
784
 
785
+ /** `kosh.setting` (owner: base). */
786
+ export interface KoshSetting {
787
+ readonly name: 'kosh.setting';
788
+ readonly fields: {
789
+ readonly id: F.Id<'kosh.setting'>;
790
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
791
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
792
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
793
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
794
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
795
+ readonly key: F.Char<{ readonly required: true }>;
796
+ readonly value: F.Json;
797
+ };
798
+ readonly methods: KoshSettingMethods;
799
+ }
800
+
801
+ /** Methods of `kosh.setting`: declared ones and transitions. */
802
+ export interface KoshSettingMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.setting'> {
803
+ }
804
+
783
805
  /** `mail.activity` (owner: messaging). */
784
806
  export interface MailActivity {
785
807
  readonly name: 'mail.activity';
@@ -1094,6 +1116,7 @@ export interface ProductProduct {
1094
1116
  readonly category: F.Many2one<'product.category'>;
1095
1117
  readonly uom: F.Many2one<'uom.uom'>;
1096
1118
  readonly barcode: F.Char;
1119
+ readonly image: F.Many2one<'storage.attachment'>;
1097
1120
  readonly listPrice: F.Decimal<{ readonly required: true; readonly default: true }>;
1098
1121
  readonly standardPrice: F.Decimal<{ readonly required: true; readonly default: true }>;
1099
1122
  readonly saleOk: F.Bool<{ readonly required: true; readonly default: true }>;
@@ -1124,6 +1147,7 @@ export interface ReportDashboard {
1124
1147
  readonly name: F.Char<{ readonly required: true }>;
1125
1148
  readonly items: F.Json<unknown, { readonly required: true; readonly default: true }>;
1126
1149
  readonly shared: F.Bool<{ readonly required: true; readonly default: true }>;
1150
+ readonly key: F.Char;
1127
1151
  };
1128
1152
  readonly methods: ReportDashboardMethods;
1129
1153
  }
@@ -1264,7 +1288,7 @@ export interface ResBankAccount {
1264
1288
  export interface ResBankAccountMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'res.bank.account'> {
1265
1289
  }
1266
1290
 
1267
- /** `res.company` (owner: base; extended by: accounting, l10n_bd). */
1291
+ /** `res.company` (owner: base; extended by: contacts, accounting, l10n_bd). */
1268
1292
  export interface ResCompany {
1269
1293
  readonly name: 'res.company';
1270
1294
  readonly fields: {
@@ -1284,6 +1308,8 @@ export interface ResCompany {
1284
1308
  readonly email: F.Char;
1285
1309
  readonly phone: F.Char;
1286
1310
  readonly website: F.Char;
1311
+ readonly contactTaxIdRequired: F.Bool<{ readonly required: true; readonly default: true }>; // contacts
1312
+ readonly contactUniqueEmail: F.Bool<{ readonly required: true; readonly default: true }>; // contacts
1287
1313
  readonly fiscalYearStart: F.Integer<{ readonly required: true; readonly default: true }>; // accounting
1288
1314
  readonly chartTemplate: F.Char; // accounting
1289
1315
  readonly country: F.Char; // accounting
@@ -1302,7 +1328,7 @@ export interface ResCompany {
1302
1328
  }
1303
1329
 
1304
1330
  /** Methods of `res.company`: declared ones and transitions. */
1305
- export interface ResCompanyMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'res.company'>, F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'res.company'>, F.Methods<typeof import('../module.js').l10nBdShutro, 'res.company'> {
1331
+ 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('../../accounting/index.js').accountingShutro, 'res.company'>, F.Methods<typeof import('../module.js').l10nBdShutro, 'res.company'> {
1306
1332
  }
1307
1333
 
1308
1334
  /** `res.currency` (owner: base). */
@@ -1361,6 +1387,10 @@ export interface ResPartner {
1361
1387
  readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
1362
1388
  readonly company: F.Many2one<'res.company', { readonly default: true }>;
1363
1389
  readonly name: F.Char<{ readonly required: true }>;
1390
+ readonly image: F.Many2one<'storage.attachment'>;
1391
+ readonly tags: F.Many2many<'res.partner.tag', { readonly required: true }>;
1392
+ readonly latitude: F.Decimal;
1393
+ readonly longitude: F.Decimal;
1364
1394
  readonly isCompany: F.Bool<{ readonly required: true; readonly default: true }>;
1365
1395
  readonly parent: F.Many2one<'res.partner'>;
1366
1396
  readonly contacts: F.One2many<'res.partner', { readonly required: true }>;
@@ -1389,6 +1419,25 @@ export interface ResPartner {
1389
1419
  export interface ResPartnerMethods extends F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.partner'>, F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'res.partner'>, F.Methods<typeof import('../module.js').l10nBdShutro, 'res.partner'> {
1390
1420
  }
1391
1421
 
1422
+ /** `res.partner.tag` (owner: contacts). */
1423
+ export interface ResPartnerTag {
1424
+ readonly name: 'res.partner.tag';
1425
+ readonly fields: {
1426
+ readonly id: F.Id<'res.partner.tag'>;
1427
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1428
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1429
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
1430
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
1431
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
1432
+ readonly name: F.Char<{ readonly required: true }>;
1433
+ };
1434
+ readonly methods: ResPartnerTagMethods;
1435
+ }
1436
+
1437
+ /** Methods of `res.partner.tag`: declared ones and transitions. */
1438
+ export interface ResPartnerTagMethods extends F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.partner.tag'> {
1439
+ }
1440
+
1392
1441
  /** `res.users` (owner: base). */
1393
1442
  export interface ResUsers {
1394
1443
  readonly name: 'res.users';
@@ -1434,6 +1483,8 @@ export interface StorageAttachment {
1434
1483
  readonly key: F.Char<{ readonly required: true }>;
1435
1484
  readonly resModel: F.Char<{ readonly required: true }>;
1436
1485
  readonly resId: F.Integer<{ readonly required: true }>;
1486
+ readonly variantOf: F.Many2one<'storage.attachment'>;
1487
+ readonly width: F.Integer;
1437
1488
  };
1438
1489
  readonly methods: StorageAttachmentMethods;
1439
1490
  }