shutro-erp 0.3.6 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (623) hide show
  1. package/dist/account_asset/.kosh/bindings.js +1 -1
  2. package/dist/account_asset/.kosh/schema.d.ts +530 -8
  3. package/dist/account_asset/i18n/bn.d.ts +2 -0
  4. package/dist/account_asset/i18n/bn.js +97 -0
  5. package/dist/account_asset/index.js +2 -0
  6. package/dist/account_asset/module.d.ts +4899 -1445
  7. package/dist/account_budget/.kosh/bindings.js +1 -1
  8. package/dist/account_budget/.kosh/schema.d.ts +1130 -56
  9. package/dist/account_budget/i18n/bn.d.ts +2 -0
  10. package/dist/account_budget/i18n/bn.js +63 -0
  11. package/dist/account_budget/index.js +14 -0
  12. package/dist/account_budget/module.d.ts +17958 -4532
  13. package/dist/account_budget/module.js +15 -0
  14. package/dist/account_portal/.kosh/bindings.js +1 -1
  15. package/dist/account_portal/.kosh/schema.d.ts +530 -8
  16. package/dist/account_portal/i18n/bn.d.ts +2 -0
  17. package/dist/account_portal/i18n/bn.js +6 -0
  18. package/dist/account_portal/index.js +2 -0
  19. package/dist/account_portal/module.d.ts +5167 -1693
  20. package/dist/accounting/.kosh/bindings.js +1 -1
  21. package/dist/accounting/.kosh/schema.d.ts +530 -8
  22. package/dist/accounting/closing.js +1 -0
  23. package/dist/accounting/fiscal.d.ts +578 -0
  24. package/dist/accounting/fiscal.js +401 -0
  25. package/dist/accounting/followups.d.ts +618 -0
  26. package/dist/accounting/followups.js +420 -0
  27. package/dist/accounting/i18n/bn.d.ts +2 -0
  28. package/dist/accounting/i18n/bn.js +425 -0
  29. package/dist/accounting/index.d.ts +2 -0
  30. package/dist/accounting/index.js +649 -2
  31. package/dist/accounting/module.d.ts +4998 -1451
  32. package/dist/accounting/module.js +124 -18
  33. package/dist/accounting/statements.d.ts +878 -0
  34. package/dist/accounting/statements.js +728 -0
  35. package/dist/accounting/web/BankReconcilePage.d.ts +9 -0
  36. package/dist/accounting/web/BankReconcilePage.js +138 -0
  37. package/dist/accounting/web/FollowupsPage.d.ts +8 -0
  38. package/dist/accounting/web/FollowupsPage.js +54 -0
  39. package/dist/accounting/web/PostingPreview.d.ts +8 -0
  40. package/dist/accounting/web/PostingPreview.js +26 -0
  41. package/dist/accounting/web/index.d.ts +3 -0
  42. package/dist/accounting/web/index.js +9 -0
  43. package/dist/accounting/web/messages.js +140 -0
  44. package/dist/approvals/.kosh/bindings.js +1 -1
  45. package/dist/approvals/.kosh/schema.d.ts +272 -4
  46. package/dist/approvals/demo.d.ts +7 -0
  47. package/dist/approvals/demo.js +41 -0
  48. package/dist/approvals/i18n/bn.d.ts +2 -0
  49. package/dist/approvals/i18n/bn.js +133 -0
  50. package/dist/approvals/index.d.ts +19 -1
  51. package/dist/approvals/index.js +477 -7
  52. package/dist/approvals/mails.d.ts +7 -2
  53. package/dist/approvals/mails.js +8 -3
  54. package/dist/approvals/module.d.ts +2930 -1
  55. package/dist/approvals/module.js +468 -7
  56. package/dist/approvals/web/Config.d.ts +12 -0
  57. package/dist/approvals/web/Config.js +60 -0
  58. package/dist/approvals/web/Matrix.d.ts +9 -0
  59. package/dist/approvals/web/Matrix.js +26 -0
  60. package/dist/approvals/web/index.d.ts +3 -1
  61. package/dist/approvals/web/index.js +8 -1
  62. package/dist/approvals/web/messages.js +92 -0
  63. package/dist/approvals_purchase/.kosh/bindings.js +15 -0
  64. package/dist/approvals_purchase/.kosh/schema.d.ts +1997 -0
  65. package/dist/approvals_purchase/i18n/bn.d.ts +2 -0
  66. package/dist/approvals_purchase/i18n/bn.js +5 -0
  67. package/dist/approvals_purchase/index.d.ts +3 -0
  68. package/dist/approvals_purchase/index.js +47 -0
  69. package/dist/approvals_purchase/module.d.ts +12670 -0
  70. package/dist/approvals_purchase/module.js +84 -0
  71. package/dist/attendance/.kosh/bindings.js +1 -1
  72. package/dist/attendance/.kosh/schema.d.ts +59 -1
  73. package/dist/attendance/i18n/bn.d.ts +2 -0
  74. package/dist/attendance/i18n/bn.js +147 -0
  75. package/dist/attendance/index.js +3 -1
  76. package/dist/attendance/module.d.ts +452 -8
  77. package/dist/automation/engine.js +1 -1
  78. package/dist/calendar/.kosh/bindings.js +1 -1
  79. package/dist/calendar/.kosh/schema.d.ts +2 -1
  80. package/dist/calendar/i18n/bn.d.ts +2 -0
  81. package/dist/calendar/i18n/bn.js +80 -0
  82. package/dist/calendar/index.js +77 -0
  83. package/dist/calendar/module.d.ts +26 -0
  84. package/dist/calendar/module.js +14 -4
  85. package/dist/cli/apps.js +25 -5
  86. package/dist/cli/init.js +14 -4
  87. package/dist/cli/templates.d.ts +1 -1
  88. package/dist/cli/templates.js +34 -5
  89. package/dist/contacts/.kosh/bindings.js +1 -1
  90. package/dist/contacts/.kosh/schema.d.ts +2 -1
  91. package/dist/contacts/i18n/bn.d.ts +2 -0
  92. package/dist/contacts/i18n/bn.js +67 -0
  93. package/dist/contacts/index.js +3 -0
  94. package/dist/contacts/module.d.ts +42 -0
  95. package/dist/contacts/module.js +6 -1
  96. package/dist/crm/.kosh/bindings.js +1 -1
  97. package/dist/crm/.kosh/schema.d.ts +2 -1
  98. package/dist/crm/i18n/bn.d.ts +2 -0
  99. package/dist/crm/i18n/bn.js +80 -0
  100. package/dist/crm/index.js +22 -0
  101. package/dist/crm/module.d.ts +20 -0
  102. package/dist/crm/module.js +4 -2
  103. package/dist/documents/.kosh/bindings.js +1 -1
  104. package/dist/documents/.kosh/schema.d.ts +2 -1
  105. package/dist/documents/i18n/bn.d.ts +2 -0
  106. package/dist/documents/i18n/bn.js +83 -0
  107. package/dist/documents/index.js +128 -1
  108. package/dist/documents/module.d.ts +20 -0
  109. package/dist/documents/module.js +1 -0
  110. package/dist/event/.kosh/bindings.js +1 -1
  111. package/dist/event/.kosh/schema.d.ts +2 -1
  112. package/dist/event/i18n/bn.d.ts +2 -0
  113. package/dist/event/i18n/bn.js +101 -0
  114. package/dist/event/index.js +66 -0
  115. package/dist/event/module.d.ts +20 -0
  116. package/dist/event/module.js +8 -1
  117. package/dist/event_account/.kosh/bindings.js +1 -1
  118. package/dist/event_account/.kosh/schema.d.ts +530 -8
  119. package/dist/event_account/i18n/bn.d.ts +2 -0
  120. package/dist/event_account/i18n/bn.js +5 -0
  121. package/dist/event_account/index.js +2 -0
  122. package/dist/event_account/module.d.ts +4905 -1431
  123. package/dist/expense/.kosh/bindings.js +1 -1
  124. package/dist/expense/.kosh/schema.d.ts +323 -2
  125. package/dist/expense/i18n/bn.d.ts +2 -0
  126. package/dist/expense/i18n/bn.js +155 -0
  127. package/dist/expense/index.js +8 -1
  128. package/dist/expense/module.d.ts +2715 -694
  129. package/dist/expense/module.js +3 -1
  130. package/dist/expense_account/.kosh/bindings.js +1 -1
  131. package/dist/expense_account/.kosh/schema.d.ts +587 -8
  132. package/dist/expense_account/i18n/bn.d.ts +2 -0
  133. package/dist/expense_account/i18n/bn.js +15 -0
  134. package/dist/expense_account/index.js +2 -0
  135. package/dist/expense_account/module.d.ts +8094 -2619
  136. package/dist/helpdesk/.kosh/bindings.js +1 -1
  137. package/dist/helpdesk/.kosh/schema.d.ts +2 -1
  138. package/dist/helpdesk/i18n/bn.d.ts +2 -0
  139. package/dist/helpdesk/i18n/bn.js +127 -0
  140. package/dist/helpdesk/index.js +2 -0
  141. package/dist/helpdesk/module.d.ts +20 -0
  142. package/dist/hr/.kosh/bindings.js +1 -1
  143. package/dist/hr/.kosh/schema.d.ts +59 -1
  144. package/dist/hr/demo.js +11 -1
  145. package/dist/hr/i18n/bn.d.ts +2 -0
  146. package/dist/hr/i18n/bn.js +126 -0
  147. package/dist/hr/index.d.ts +1 -1
  148. package/dist/hr/index.js +158 -12
  149. package/dist/hr/module.d.ts +932 -59
  150. package/dist/hr/module.js +114 -17
  151. package/dist/{mrp → indent}/.kosh/bindings.js +2 -2
  152. package/dist/indent/.kosh/schema.d.ts +2084 -0
  153. package/dist/indent/demo.d.ts +7 -0
  154. package/dist/indent/demo.js +48 -0
  155. package/dist/indent/i18n/bn.d.ts +2 -0
  156. package/dist/indent/i18n/bn.js +143 -0
  157. package/dist/indent/index.d.ts +3 -0
  158. package/dist/indent/index.js +450 -0
  159. package/dist/{mrp → indent}/module.d.ts +7164 -3075
  160. package/dist/indent/module.js +792 -0
  161. package/dist/indent_purchase/.kosh/bindings.d.ts +22 -0
  162. package/dist/indent_purchase/.kosh/bindings.js +15 -0
  163. package/dist/indent_purchase/.kosh/schema.d.ts +2710 -0
  164. package/dist/indent_purchase/i18n/bn.d.ts +2 -0
  165. package/dist/indent_purchase/i18n/bn.js +13 -0
  166. package/dist/indent_purchase/index.d.ts +3 -0
  167. package/dist/indent_purchase/index.js +61 -0
  168. package/dist/indent_purchase/module.d.ts +27950 -0
  169. package/dist/indent_purchase/module.js +163 -0
  170. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  171. package/dist/l10n_bd/.kosh/schema.d.ts +530 -8
  172. package/dist/l10n_bd/i18n/bn.d.ts +2 -0
  173. package/dist/l10n_bd/i18n/bn.js +69 -0
  174. package/dist/l10n_bd/index.js +2 -0
  175. package/dist/l10n_bd/module.d.ts +5167 -1693
  176. package/dist/l10n_bd_payroll/.kosh/bindings.js +1 -1
  177. package/dist/l10n_bd_payroll/.kosh/schema.d.ts +587 -8
  178. package/dist/l10n_bd_payroll/i18n/bn.d.ts +2 -0
  179. package/dist/l10n_bd_payroll/i18n/bn.js +4 -0
  180. package/dist/l10n_bd_payroll/index.js +2 -0
  181. package/dist/l10n_bd_payroll/module.d.ts +5910 -1548
  182. package/dist/l10n_bd_pos/.kosh/bindings.d.ts +22 -0
  183. package/dist/{mrp_account → l10n_bd_pos}/.kosh/bindings.js +2 -2
  184. package/dist/{mrp_account → l10n_bd_pos}/.kosh/schema.d.ts +693 -651
  185. package/dist/l10n_bd_pos/i18n/bn.d.ts +2 -0
  186. package/dist/l10n_bd_pos/i18n/bn.js +32 -0
  187. package/dist/l10n_bd_pos/index.d.ts +3 -0
  188. package/dist/l10n_bd_pos/index.js +111 -0
  189. package/dist/{mrp_account → l10n_bd_pos}/module.d.ts +7402 -7647
  190. package/dist/l10n_bd_pos/module.js +43 -0
  191. package/dist/l10n_in/.kosh/bindings.js +1 -1
  192. package/dist/l10n_in/.kosh/schema.d.ts +530 -8
  193. package/dist/l10n_in/i18n/bn.d.ts +2 -0
  194. package/dist/l10n_in/i18n/bn.js +95 -0
  195. package/dist/l10n_in/index.js +2 -0
  196. package/dist/l10n_in/module.d.ts +6703 -1652
  197. package/dist/l10n_in/module.js +25 -5
  198. package/dist/l10n_in/web/GstSettings.js +2 -2
  199. package/dist/mail/inbound/handle.js +2 -4
  200. package/dist/mail/inbound/models.js +5 -3
  201. package/dist/mail/index.d.ts +12 -1
  202. package/dist/mail/index.js +139 -2
  203. package/dist/mail/send.d.ts +56 -0
  204. package/dist/mail/send.js +394 -0
  205. package/dist/mail/web/SendButton.d.ts +9 -0
  206. package/dist/mail/web/SendButton.js +71 -0
  207. package/dist/mail/web/SendSelected.d.ts +8 -0
  208. package/dist/mail/web/SendSelected.js +33 -0
  209. package/dist/mail/web/index.d.ts +2 -0
  210. package/dist/mail/web/index.js +6 -0
  211. package/dist/mail/web/messages.js +36 -0
  212. package/dist/maintenance/.kosh/bindings.js +1 -1
  213. package/dist/maintenance/.kosh/schema.d.ts +2 -1
  214. package/dist/maintenance/i18n/bn.d.ts +2 -0
  215. package/dist/maintenance/i18n/bn.js +132 -0
  216. package/dist/maintenance/index.js +85 -0
  217. package/dist/maintenance/module.d.ts +25 -0
  218. package/dist/maintenance/module.js +27 -9
  219. package/dist/maintenance_stock/.kosh/bindings.js +1 -1
  220. package/dist/maintenance_stock/.kosh/schema.d.ts +298 -2
  221. package/dist/maintenance_stock/i18n/bn.d.ts +2 -0
  222. package/dist/maintenance_stock/i18n/bn.js +21 -0
  223. package/dist/maintenance_stock/index.js +2 -0
  224. package/dist/maintenance_stock/module.d.ts +5302 -1256
  225. package/dist/maintenance_stock/module.js +1 -0
  226. package/dist/modules-sdk/apps.d.ts +10 -0
  227. package/dist/modules-sdk/apps.js +32 -0
  228. package/dist/modules-sdk/index.d.ts +1 -1
  229. package/dist/modules-sdk/manifest.d.ts +68 -2
  230. package/dist/payment/.kosh/bindings.js +1 -1
  231. package/dist/payment/.kosh/schema.d.ts +530 -8
  232. package/dist/payment/i18n/bn.d.ts +2 -0
  233. package/dist/payment/i18n/bn.js +59 -0
  234. package/dist/payment/index.js +85 -0
  235. package/dist/payment/module.d.ts +5134 -1660
  236. package/dist/payment/module.js +17 -3
  237. package/dist/payment/settle.js +1 -0
  238. package/dist/payroll/.kosh/bindings.js +1 -1
  239. package/dist/payroll/.kosh/schema.d.ts +59 -1
  240. package/dist/payroll/i18n/bn.d.ts +2 -0
  241. package/dist/payroll/i18n/bn.js +206 -0
  242. package/dist/payroll/index.js +2 -0
  243. package/dist/payroll/module.d.ts +936 -48
  244. package/dist/payroll_account/.kosh/bindings.js +1 -1
  245. package/dist/payroll_account/.kosh/schema.d.ts +587 -8
  246. package/dist/payroll_account/i18n/bn.d.ts +2 -0
  247. package/dist/payroll_account/i18n/bn.js +10 -0
  248. package/dist/payroll_account/index.js +2 -0
  249. package/dist/payroll_account/module.d.ts +7534 -3192
  250. package/dist/permissions/approvals.d.ts +97 -4
  251. package/dist/permissions/approvals.js +780 -31
  252. package/dist/permissions/index.d.ts +1 -1
  253. package/dist/permissions/index.js +2 -2
  254. package/dist/permissions/models.js +177 -5
  255. package/dist/permissions/routes.d.ts +3 -0
  256. package/dist/permissions/routes.js +36 -2
  257. package/dist/permissions/web/ApprovalPanel.js +43 -5
  258. package/dist/permissions/web/messages.js +52 -0
  259. package/dist/portal/.kosh/bindings.js +1 -1
  260. package/dist/portal/.kosh/schema.d.ts +2 -1
  261. package/dist/portal/documents.d.ts +3 -0
  262. package/dist/portal/documents.js +21 -1
  263. package/dist/portal/i18n/bn.d.ts +2 -0
  264. package/dist/portal/i18n/bn.js +33 -0
  265. package/dist/portal/index.js +2 -0
  266. package/dist/portal/module.d.ts +20 -0
  267. package/dist/portal/routes-documents.js +76 -0
  268. package/dist/pos/.kosh/bindings.js +1 -1
  269. package/dist/pos/.kosh/schema.d.ts +531 -8
  270. package/dist/pos/i18n/bn.d.ts +2 -0
  271. package/dist/pos/i18n/bn.js +133 -0
  272. package/dist/pos/index.js +83 -1
  273. package/dist/pos/module.d.ts +6888 -1777
  274. package/dist/pos/module.js +49 -5
  275. package/dist/pos/routes.js +80 -7
  276. package/dist/pos/web/Register.js +2 -5
  277. package/dist/pos_stock/.kosh/bindings.js +1 -1
  278. package/dist/pos_stock/.kosh/schema.d.ts +626 -9
  279. package/dist/pos_stock/i18n/bn.d.ts +2 -0
  280. package/dist/pos_stock/i18n/bn.js +6 -0
  281. package/dist/pos_stock/index.js +2 -0
  282. package/dist/pos_stock/module.d.ts +10798 -3276
  283. package/dist/product/.kosh/bindings.js +1 -1
  284. package/dist/product/.kosh/schema.d.ts +202 -1
  285. package/dist/product/i18n/bn.d.ts +2 -0
  286. package/dist/product/i18n/bn.js +175 -0
  287. package/dist/product/index.d.ts +1 -0
  288. package/dist/product/index.js +288 -1
  289. package/dist/product/module.d.ts +1725 -0
  290. package/dist/product/module.js +66 -6
  291. package/dist/product/pricelist.d.ts +575 -0
  292. package/dist/product/pricelist.js +257 -0
  293. package/dist/product/variants.d.ts +908 -0
  294. package/dist/product/variants.js +251 -0
  295. package/dist/production/.kosh/bindings.d.ts +22 -0
  296. package/dist/production/.kosh/bindings.js +15 -0
  297. package/dist/production/.kosh/schema.d.ts +2345 -0
  298. package/dist/{mrp → production}/demo.d.ts +1 -1
  299. package/dist/{mrp → production}/demo.js +5 -5
  300. package/dist/production/depth.d.ts +790 -0
  301. package/dist/production/depth.js +262 -0
  302. package/dist/production/i18n/bn.d.ts +2 -0
  303. package/dist/production/i18n/bn.js +350 -0
  304. package/dist/production/index.d.ts +6 -0
  305. package/dist/production/index.js +1256 -0
  306. package/dist/production/module.d.ts +17327 -0
  307. package/dist/production/module.js +1333 -0
  308. package/dist/production/plan.d.ts +921 -0
  309. package/dist/production/plan.js +511 -0
  310. package/dist/production/schedule.d.ts +656 -0
  311. package/dist/production/schedule.js +309 -0
  312. package/dist/production_account/.kosh/bindings.d.ts +22 -0
  313. package/dist/production_account/.kosh/bindings.js +15 -0
  314. package/dist/production_account/.kosh/schema.d.ts +3496 -0
  315. package/dist/production_account/i18n/bn.d.ts +2 -0
  316. package/dist/production_account/i18n/bn.js +93 -0
  317. package/dist/production_account/index.d.ts +4 -0
  318. package/dist/production_account/index.js +246 -0
  319. package/dist/production_account/module.d.ts +1192 -0
  320. package/dist/{mrp_account → production_account}/module.js +72 -18
  321. package/dist/production_account/overhead.d.ts +1195 -0
  322. package/dist/production_account/overhead.js +554 -0
  323. package/dist/project/.kosh/bindings.js +1 -1
  324. package/dist/project/.kosh/schema.d.ts +65 -2
  325. package/dist/project/i18n/bn.d.ts +2 -0
  326. package/dist/project/i18n/bn.js +383 -0
  327. package/dist/project/index.js +123 -0
  328. package/dist/project/module.d.ts +20 -0
  329. package/dist/project/module.js +73 -14
  330. package/dist/project_account/.kosh/bindings.js +1 -1
  331. package/dist/project_account/.kosh/schema.d.ts +530 -8
  332. package/dist/project_account/i18n/bn.d.ts +2 -0
  333. package/dist/project_account/i18n/bn.js +6 -0
  334. package/dist/project_account/index.js +2 -0
  335. package/dist/project_account/module.d.ts +4926 -1452
  336. package/dist/project_portal/.kosh/bindings.js +1 -1
  337. package/dist/project_portal/.kosh/schema.d.ts +65 -2
  338. package/dist/project_portal/i18n/bn.d.ts +2 -0
  339. package/dist/project_portal/i18n/bn.js +6 -0
  340. package/dist/project_portal/index.js +2 -0
  341. package/dist/project_portal/module.d.ts +40 -0
  342. package/dist/project_purchase/.kosh/bindings.js +1 -1
  343. package/dist/project_purchase/.kosh/schema.d.ts +1126 -53
  344. package/dist/project_purchase/i18n/bn.d.ts +2 -0
  345. package/dist/project_purchase/i18n/bn.js +4 -0
  346. package/dist/project_purchase/index.js +2 -0
  347. package/dist/project_purchase/module.d.ts +17912 -4446
  348. package/dist/purchase/.kosh/bindings.js +1 -1
  349. package/dist/purchase/.kosh/schema.d.ts +813 -3
  350. package/dist/purchase/comparison.d.ts +993 -0
  351. package/dist/purchase/comparison.js +415 -0
  352. package/dist/purchase/extras.d.ts +1509 -0
  353. package/dist/purchase/extras.js +445 -0
  354. package/dist/purchase/i18n/bn.d.ts +2 -0
  355. package/dist/purchase/i18n/bn.js +413 -0
  356. package/dist/purchase/index.d.ts +5 -0
  357. package/dist/purchase/index.js +1280 -4
  358. package/dist/purchase/module.d.ts +7139 -398
  359. package/dist/purchase/module.js +295 -11
  360. package/dist/purchase/request.d.ts +696 -0
  361. package/dist/purchase/request.js +446 -0
  362. package/dist/purchase/tender.d.ts +1208 -0
  363. package/dist/purchase/tender.js +507 -0
  364. package/dist/purchase/vendorprice.d.ts +340 -0
  365. package/dist/purchase/vendorprice.js +153 -0
  366. package/dist/purchase_account/.kosh/bindings.js +1 -1
  367. package/dist/purchase_account/.kosh/schema.d.ts +1130 -57
  368. package/dist/purchase_account/i18n/bn.d.ts +2 -0
  369. package/dist/purchase_account/i18n/bn.js +22 -0
  370. package/dist/purchase_account/index.js +19 -0
  371. package/dist/purchase_account/module.d.ts +12276 -2247
  372. package/dist/purchase_account/module.js +241 -9
  373. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  374. package/dist/purchase_portal/.kosh/schema.d.ts +813 -3
  375. package/dist/purchase_portal/i18n/bn.d.ts +2 -0
  376. package/dist/purchase_portal/i18n/bn.js +5 -0
  377. package/dist/purchase_portal/index.js +2 -0
  378. package/dist/purchase_portal/module.d.ts +6849 -353
  379. package/dist/purchase_stock/.kosh/bindings.js +1 -1
  380. package/dist/purchase_stock/.kosh/schema.d.ts +910 -4
  381. package/dist/purchase_stock/i18n/bn.d.ts +2 -0
  382. package/dist/purchase_stock/i18n/bn.js +19 -0
  383. package/dist/purchase_stock/index.d.ts +1 -1
  384. package/dist/purchase_stock/index.js +29 -0
  385. package/dist/purchase_stock/module.d.ts +12410 -1864
  386. package/dist/purchase_stock/module.js +81 -9
  387. package/dist/purchase_stock/scorecard.d.ts +22 -0
  388. package/dist/purchase_stock/scorecard.js +77 -0
  389. package/dist/purchase_stock/web/Scorecard.d.ts +7 -0
  390. package/dist/purchase_stock/web/Scorecard.js +22 -0
  391. package/dist/purchase_stock/web/index.d.ts +11 -0
  392. package/dist/purchase_stock/web/index.js +16 -0
  393. package/dist/purchase_stock/web/messages.d.ts +2 -0
  394. package/dist/purchase_stock/web/messages.js +27 -0
  395. package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
  396. package/dist/purchase_stock_account/.kosh/schema.d.ts +1286 -58
  397. package/dist/purchase_stock_account/i18n/bn.d.ts +2 -0
  398. package/dist/purchase_stock_account/i18n/bn.js +8 -0
  399. package/dist/purchase_stock_account/index.js +18 -0
  400. package/dist/purchase_stock_account/module.d.ts +7 -37995
  401. package/dist/purchase_stock_account/module.js +24 -3
  402. package/dist/recruitment/.kosh/bindings.js +1 -1
  403. package/dist/recruitment/.kosh/schema.d.ts +59 -1
  404. package/dist/recruitment/i18n/bn.d.ts +2 -0
  405. package/dist/recruitment/i18n/bn.js +93 -0
  406. package/dist/recruitment/index.js +64 -0
  407. package/dist/recruitment/module.d.ts +458 -8
  408. package/dist/recruitment/module.js +11 -3
  409. package/dist/reporting/documents.d.ts +5 -0
  410. package/dist/reporting/documents.js +11 -1
  411. package/dist/reporting/index.d.ts +1 -1
  412. package/dist/reporting/index.js +1 -1
  413. package/dist/reporting/web/CalendarView.d.ts +18 -5
  414. package/dist/reporting/web/CalendarView.js +163 -29
  415. package/dist/reporting/web/messages.js +18 -0
  416. package/dist/sale_account/.kosh/bindings.js +1 -1
  417. package/dist/sale_account/.kosh/schema.d.ts +642 -16
  418. package/dist/sale_account/i18n/bn.d.ts +2 -0
  419. package/dist/sale_account/i18n/bn.js +48 -0
  420. package/dist/sale_account/index.d.ts +1 -1
  421. package/dist/sale_account/index.js +102 -4
  422. package/dist/sale_account/module.d.ts +8254 -2212
  423. package/dist/sale_account/module.js +535 -46
  424. package/dist/sale_crm/.kosh/bindings.d.ts +22 -0
  425. package/dist/sale_crm/.kosh/bindings.js +15 -0
  426. package/dist/{mrp → sale_crm}/.kosh/schema.d.ts +389 -567
  427. package/dist/sale_crm/i18n/bn.d.ts +2 -0
  428. package/dist/sale_crm/i18n/bn.js +9 -0
  429. package/dist/sale_crm/index.d.ts +7 -0
  430. package/dist/sale_crm/index.js +104 -0
  431. package/dist/sale_crm/module.d.ts +5609 -0
  432. package/dist/sale_crm/module.js +73 -0
  433. package/dist/sale_portal/.kosh/bindings.js +1 -1
  434. package/dist/sale_portal/.kosh/schema.d.ts +291 -4
  435. package/dist/sale_portal/i18n/bn.d.ts +2 -0
  436. package/dist/sale_portal/i18n/bn.js +7 -0
  437. package/dist/sale_portal/index.js +10 -0
  438. package/dist/sale_portal/module.d.ts +2564 -294
  439. package/dist/sale_project/.kosh/bindings.js +1 -1
  440. package/dist/sale_project/.kosh/schema.d.ts +354 -5
  441. package/dist/sale_project/i18n/bn.d.ts +2 -0
  442. package/dist/sale_project/i18n/bn.js +12 -0
  443. package/dist/sale_project/index.js +2 -0
  444. package/dist/sale_project/module.d.ts +6249 -2402
  445. package/dist/sale_stock/.kosh/bindings.js +1 -1
  446. package/dist/sale_stock/.kosh/schema.d.ts +387 -5
  447. package/dist/sale_stock/i18n/bn.d.ts +2 -0
  448. package/dist/sale_stock/i18n/bn.js +15 -0
  449. package/dist/sale_stock/index.js +2 -0
  450. package/dist/sale_stock/module.d.ts +8057 -1759
  451. package/dist/sale_stock/module.js +20 -3
  452. package/dist/sales/.kosh/bindings.js +1 -1
  453. package/dist/sales/.kosh/schema.d.ts +291 -4
  454. package/dist/sales/i18n/bn.d.ts +2 -0
  455. package/dist/sales/i18n/bn.js +128 -0
  456. package/dist/sales/index.js +120 -5
  457. package/dist/sales/module.d.ts +3567 -633
  458. package/dist/sales/module.js +306 -11
  459. package/dist/server/api/duplicate.d.ts +14 -0
  460. package/dist/server/api/duplicate.js +75 -0
  461. package/dist/server/api/explain.d.ts +70 -0
  462. package/dist/server/api/explain.js +111 -0
  463. package/dist/server/api/metadata.d.ts +2 -0
  464. package/dist/server/api/metadata.js +9 -0
  465. package/dist/server/api/openapi.js +15 -0
  466. package/dist/server/api/rest.d.ts +1 -0
  467. package/dist/server/api/rest.js +76 -12
  468. package/dist/server/api/views.js +1 -1
  469. package/dist/server/apps.d.ts +16 -1
  470. package/dist/server/apps.js +164 -2
  471. package/dist/server/auth/base.js +2 -0
  472. package/dist/server/auth/service.d.ts +8 -0
  473. package/dist/server/auth/service.js +19 -0
  474. package/dist/server/events.d.ts +13 -0
  475. package/dist/server/events.js +22 -0
  476. package/dist/server/i18n.d.ts +27 -0
  477. package/dist/server/i18n.js +143 -0
  478. package/dist/server/index.d.ts +2 -0
  479. package/dist/server/index.js +2 -0
  480. package/dist/server/server.js +6 -0
  481. package/dist/settings/company.d.ts +3 -1
  482. package/dist/settings/company.js +26 -5
  483. package/dist/settings/routes.d.ts +10 -0
  484. package/dist/settings/routes.js +19 -3
  485. package/dist/settings/web/AppsPage.d.ts +3 -2
  486. package/dist/settings/web/AppsPage.js +26 -8
  487. package/dist/settings/web/CompaniesPage.js +91 -6
  488. package/dist/settings/web/messages.js +64 -0
  489. package/dist/sign/.kosh/bindings.js +1 -1
  490. package/dist/sign/.kosh/schema.d.ts +2 -1
  491. package/dist/sign/i18n/bn.d.ts +2 -0
  492. package/dist/sign/i18n/bn.js +97 -0
  493. package/dist/sign/index.d.ts +15 -0
  494. package/dist/sign/index.js +129 -1
  495. package/dist/sign/module.d.ts +40 -0
  496. package/dist/sign/module.js +11 -2
  497. package/dist/stock/.kosh/bindings.js +1 -1
  498. package/dist/stock/.kosh/schema.d.ts +298 -2
  499. package/dist/stock/i18n/bn.d.ts +2 -0
  500. package/dist/stock/i18n/bn.js +311 -0
  501. package/dist/stock/index.d.ts +3 -1
  502. package/dist/stock/index.js +442 -3
  503. package/dist/stock/ledger.d.ts +78 -0
  504. package/dist/stock/ledger.js +582 -0
  505. package/dist/stock/module.d.ts +5280 -2044
  506. package/dist/stock/module.js +222 -23
  507. package/dist/stock/replenish.js +16 -1
  508. package/dist/stock/returns.d.ts +157 -0
  509. package/dist/stock/returns.js +163 -0
  510. package/dist/stock/web/Ledger.d.ts +9 -0
  511. package/dist/stock/web/Ledger.js +108 -0
  512. package/dist/stock/web/Operations.d.ts +8 -0
  513. package/dist/stock/web/Operations.js +33 -0
  514. package/dist/stock/web/ReturnButton.d.ts +7 -0
  515. package/dist/stock/web/ReturnButton.js +62 -0
  516. package/dist/stock/web/index.d.ts +3 -0
  517. package/dist/stock/web/index.js +9 -0
  518. package/dist/stock/web/messages.js +154 -0
  519. package/dist/stock_account/.kosh/bindings.js +1 -1
  520. package/dist/stock_account/.kosh/schema.d.ts +682 -9
  521. package/dist/stock_account/i18n/bn.d.ts +2 -0
  522. package/dist/stock_account/i18n/bn.js +73 -0
  523. package/dist/stock_account/index.d.ts +1 -0
  524. package/dist/stock_account/index.js +131 -3
  525. package/dist/stock_account/landed.d.ts +429 -0
  526. package/dist/stock_account/landed.js +335 -0
  527. package/dist/stock_account/module.d.ts +11247 -3363
  528. package/dist/stock_account/module.js +135 -6
  529. package/dist/stock_account/web/LandedPreview.d.ts +7 -0
  530. package/dist/stock_account/web/LandedPreview.js +23 -0
  531. package/dist/stock_account/web/index.d.ts +11 -0
  532. package/dist/stock_account/web/index.js +16 -0
  533. package/dist/stock_account/web/messages.d.ts +2 -0
  534. package/dist/stock_account/web/messages.js +27 -0
  535. package/dist/todo/i18n/bn.d.ts +2 -0
  536. package/dist/todo/i18n/bn.js +66 -0
  537. package/dist/todo/index.js +59 -0
  538. package/dist/todo/module.d.ts +5 -0
  539. package/dist/todo/module.js +5 -3
  540. package/dist/trade_finance/.kosh/bindings.js +1 -1
  541. package/dist/trade_finance/.kosh/schema.d.ts +2 -1
  542. package/dist/trade_finance/i18n/bn.d.ts +2 -0
  543. package/dist/trade_finance/i18n/bn.js +162 -0
  544. package/dist/trade_finance/index.js +93 -0
  545. package/dist/trade_finance/module.d.ts +26 -0
  546. package/dist/trade_finance/module.js +27 -8
  547. package/dist/trade_finance_account/.kosh/bindings.js +1 -1
  548. package/dist/trade_finance_account/.kosh/schema.d.ts +530 -8
  549. package/dist/trade_finance_account/i18n/bn.d.ts +2 -0
  550. package/dist/trade_finance_account/i18n/bn.js +27 -0
  551. package/dist/trade_finance_account/index.js +2 -0
  552. package/dist/trade_finance_account/module.d.ts +4906 -1432
  553. package/dist/trade_finance_account/module.js +1 -0
  554. package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
  555. package/dist/trade_finance_purchase/.kosh/schema.d.ts +813 -3
  556. package/dist/trade_finance_purchase/i18n/bn.d.ts +2 -0
  557. package/dist/trade_finance_purchase/i18n/bn.js +6 -0
  558. package/dist/trade_finance_purchase/index.js +2 -0
  559. package/dist/trade_finance_purchase/module.d.ts +6909 -413
  560. package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
  561. package/dist/trade_finance_sale/.kosh/schema.d.ts +291 -4
  562. package/dist/trade_finance_sale/i18n/bn.d.ts +2 -0
  563. package/dist/trade_finance_sale/i18n/bn.js +6 -0
  564. package/dist/trade_finance_sale/index.js +2 -0
  565. package/dist/trade_finance_sale/module.d.ts +2601 -331
  566. package/dist/ui/api.d.ts +2 -0
  567. package/dist/ui/app.d.ts +9 -0
  568. package/dist/ui/app.js +24 -4
  569. package/dist/ui/components/AppIcon.js +2 -2
  570. package/dist/ui/components/Explain.d.ts +69 -0
  571. package/dist/ui/components/Explain.js +62 -0
  572. package/dist/ui/context.d.ts +8 -1
  573. package/dist/ui/context.js +34 -1
  574. package/dist/ui/i18n/messages.d.ts +36 -0
  575. package/dist/ui/i18n/messages.js +72 -0
  576. package/dist/ui/index.d.ts +2 -1
  577. package/dist/ui/index.js +1 -0
  578. package/dist/ui/registry.d.ts +14 -0
  579. package/dist/ui/registry.js +10 -0
  580. package/dist/ui/views/FormView.d.ts +6 -0
  581. package/dist/ui/views/FormView.js +47 -10
  582. package/dist/ui/views/ListView.d.ts +8 -0
  583. package/dist/ui/views/ListView.js +10 -3
  584. package/dist/ui/views/StatsRow.js +2 -1
  585. package/dist/views/extend.js +12 -0
  586. package/dist/views/types.d.ts +13 -2
  587. package/dist/views/validate.js +8 -1
  588. package/dist/website/.kosh/bindings.js +1 -1
  589. package/dist/website/.kosh/schema.d.ts +2 -1
  590. package/dist/website/i18n/bn.d.ts +2 -0
  591. package/dist/website/i18n/bn.js +113 -0
  592. package/dist/website/index.js +36 -0
  593. package/dist/website/module.d.ts +20 -0
  594. package/dist/website/module.js +29 -5
  595. package/dist/website_crm/.kosh/bindings.js +1 -1
  596. package/dist/website_crm/.kosh/schema.d.ts +2 -1
  597. package/dist/website_crm/i18n/bn.d.ts +2 -0
  598. package/dist/website_crm/i18n/bn.js +5 -0
  599. package/dist/website_crm/index.js +2 -0
  600. package/dist/website_crm/module.d.ts +40 -0
  601. package/dist/website_sale/.kosh/bindings.js +1 -1
  602. package/dist/website_sale/.kosh/schema.d.ts +642 -17
  603. package/dist/website_sale/i18n/bn.d.ts +2 -0
  604. package/dist/website_sale/i18n/bn.js +132 -0
  605. package/dist/website_sale/index.js +83 -1
  606. package/dist/website_sale/module.d.ts +18705 -5550
  607. package/dist/website_sale/module.js +32 -10
  608. package/dist/website_sale/shop.js +22 -9
  609. package/dist/website_sale_stock/.kosh/bindings.js +1 -1
  610. package/dist/website_sale_stock/.kosh/schema.d.ts +737 -18
  611. package/dist/website_sale_stock/i18n/bn.d.ts +2 -0
  612. package/dist/website_sale_stock/i18n/bn.js +4 -0
  613. package/dist/website_sale_stock/index.js +2 -0
  614. package/dist/website_sale_stock/module.d.ts +10 -24997
  615. package/dist/website_sale_stock/module.js +7 -3
  616. package/package.json +36 -8
  617. package/dist/mrp/index.d.ts +0 -3
  618. package/dist/mrp/index.js +0 -393
  619. package/dist/mrp/module.js +0 -757
  620. package/dist/mrp_account/index.d.ts +0 -3
  621. package/dist/mrp_account/index.js +0 -22
  622. /package/dist/{mrp → approvals_purchase}/.kosh/bindings.d.ts +0 -0
  623. /package/dist/{mrp_account → indent}/.kosh/bindings.d.ts +0 -0
@@ -0,0 +1,511 @@
1
+ /**
2
+ * Production plans (RFC 0031 §3.3): what to make in a period, per product, bill, work centre and slot. **Generate
3
+ * forecast** explodes every line through every level of its bills — the packaging bill of a second stage included —
4
+ * into materials with what is required, on hand, on order and short; **Procure** orders the shortages through the
5
+ * warehouse's reorder rules (a request for quotation by the vendor prices with Purchase, a production order for
6
+ * made components); **capacity** refuses a slot beyond the work centre's batch limits or its hours, saying why; the
7
+ * plan is approved through the approval engine and **scheduled** into production orders, one per line, each linked
8
+ * back. A Gantt by work centre shows the slots.
9
+ */
10
+ import { approvalGuard, requestApprovals } from '../permissions/index.js';
11
+ import { orm } from '../server/orm.js';
12
+ import { defaultLocations, inProductUnit } from '../stock/index.js';
13
+ import { compute, defineModel, f, onchange, records } from './.kosh/bindings.js';
14
+ const READ = ['read'];
15
+ const ALL = ['read', 'write', 'create', 'unlink'];
16
+ const zero = orm.toDecimal(0);
17
+ /** A date-only value as `YYYY-MM-DD`. */
18
+ function isoDay(v) {
19
+ if (!(v instanceof Date))
20
+ return String(v ?? '').slice(0, 10);
21
+ const pad = (n) => String(n).padStart(2, '0');
22
+ return `${v.getFullYear()}-${pad(v.getMonth() + 1)}-${pad(v.getDate())}`;
23
+ }
24
+ const PLAN_STATES = {
25
+ draft: 'Draft',
26
+ forecast: 'Forecast',
27
+ to_approve: 'Waiting approval',
28
+ approved: 'Approved',
29
+ scheduled: 'Scheduled',
30
+ cancel: 'Cancelled',
31
+ };
32
+ export const ProductionPlan = defineModel('production.plan', {
33
+ label: 'Production plan',
34
+ recName: 'name',
35
+ order: ['dateFrom desc', 'id desc'],
36
+ companyScoped: { required: true },
37
+ tracking: ['state', 'dateFrom', 'dateTo', 'warehouse'],
38
+ access: { 'production.user': READ, 'production.manager': [...ALL, 'export', 'import'] },
39
+ fields: {
40
+ name: f.char({ required: true, sequence: 'production.plan', label: 'Reference' }),
41
+ title: f.char({ label: 'Plan' }),
42
+ dateFrom: f.date({ required: true, label: 'From' }),
43
+ dateTo: f.date({ required: true, label: 'To' }),
44
+ warehouse: f.many2one('stock.warehouse', {
45
+ ondelete: 'restrict',
46
+ help: 'Where the products are made and the materials taken; empty: the company’s first warehouse.',
47
+ }),
48
+ workcenters: f.many2many('production.workcenter', {
49
+ relation: 'production_plan_workcenter',
50
+ label: 'Work centres',
51
+ help: 'The centres the plan runs on; lines use one of them.',
52
+ }),
53
+ note: f.text(),
54
+ lines: f.one2many('production.plan.line', 'plan', { label: 'What to make' }),
55
+ materials: f.one2many('production.plan.material', 'plan', { label: 'Materials' }),
56
+ orders: f.one2many('production.order', 'plan', { label: 'Production orders' }),
57
+ shortageCount: f.integer({
58
+ store: true,
59
+ label: 'Materials short',
60
+ help: 'Materials the forecast finds short of what is on hand and on order.',
61
+ ...compute('production.plan', 'shortageCount', ['materials.shortage'], (plans) => {
62
+ for (const p of plans)
63
+ p.shortageCount = [...p.materials].filter((m) => (m.shortage ?? zero).gt(0)).length;
64
+ }),
65
+ }),
66
+ state: f.state({
67
+ states: PLAN_STATES,
68
+ initial: 'draft',
69
+ help: 'Drafted, forecast (its materials known), approved, scheduled into batches.',
70
+ transitions: {
71
+ /** The materials of every line through every level of its bills, with what is on hand and on order. */
72
+ forecast: {
73
+ from: ['draft', 'forecast'],
74
+ to: 'forecast',
75
+ guard: records('production.plan', async (plans) => [...(await plans.load({ lines: true }))]
76
+ .filter((p) => p.lines.length === 0)
77
+ .map((p) => p.id)),
78
+ message: 'Add the products to make first.',
79
+ after: records('production.plan', async (plans) => {
80
+ const env = plans.env;
81
+ await env.flush();
82
+ for (const id of plans.ids)
83
+ await generateForecast(env, id);
84
+ }),
85
+ },
86
+ /** The shortages ordered through the warehouse's reorder rules. */
87
+ procure: {
88
+ from: ['forecast'],
89
+ to: 'forecast',
90
+ guard: records('production.plan', async (plans) => [...(await plans.load({ materials: true }))]
91
+ .filter((p) => ![...p.materials].some((m) => (m.shortage ?? zero).gt(0)))
92
+ .map((p) => p.id)),
93
+ message: 'Nothing is short.',
94
+ after: records('production.plan', async (plans) => {
95
+ const env = plans.env;
96
+ await env.flush();
97
+ for (const id of plans.ids)
98
+ await procureShortages(env, id);
99
+ }),
100
+ },
101
+ submit: {
102
+ from: ['forecast'],
103
+ to: 'to_approve',
104
+ guard: records('production.plan', async (plans) => [...(await plans.load({ lines: true }))]
105
+ .filter((p) => [...p.lines].some((l) => (l.capacityNote ?? '') !== ''))
106
+ .map((p) => p.id)),
107
+ message: 'A line goes beyond its work centre’s capacity: see the lines’ capacity notes.',
108
+ after: records('production.plan', async (plans) => {
109
+ await requestApprovals(plans);
110
+ for (const p of await plans.load({}))
111
+ await plans.env.emit('production.plan.submitted', { id: p.id });
112
+ }),
113
+ },
114
+ approve: {
115
+ from: ['to_approve'],
116
+ to: 'approved',
117
+ guard: records('production.plan', (plans) => approvalGuard(plans)),
118
+ message: 'Waiting for approvals.',
119
+ after: records('production.plan', async (plans) => {
120
+ for (const p of await plans.load({}))
121
+ await plans.env.emit('production.plan.approved', { id: p.id });
122
+ }),
123
+ },
124
+ reject: { from: ['to_approve'], to: 'forecast' },
125
+ /** The lines' batches: schedules split by the work centres' maximum batch. */
126
+ schedule: {
127
+ from: ['approved'],
128
+ to: 'scheduled',
129
+ after: records('production.plan', async (plans) => {
130
+ const env = plans.env;
131
+ await env.flush();
132
+ for (const id of plans.ids)
133
+ await generateSchedules(env, id);
134
+ for (const p of await plans.load({}))
135
+ await env.emit('production.plan.scheduled', { id: p.id });
136
+ }),
137
+ },
138
+ cancel: { from: ['draft', 'forecast', 'to_approve', 'approved'], to: 'cancel' },
139
+ redraft: { from: ['cancel', 'forecast'], to: 'draft' },
140
+ },
141
+ extensible: true,
142
+ }),
143
+ },
144
+ sqlConstraints: {
145
+ period: {
146
+ check: orm.sql `date_to >= date_from`,
147
+ message: 'A plan ends on or after it starts.',
148
+ },
149
+ },
150
+ });
151
+ export const ProductionPlanLine = defineModel('production.plan.line', {
152
+ label: 'Plan line',
153
+ recName: 'label',
154
+ order: ['start asc', 'id asc'],
155
+ access: { 'production.user': READ, 'production.manager': ALL },
156
+ fields: {
157
+ plan: f.many2one('production.plan', { required: true, ondelete: 'cascade' }),
158
+ product: f.many2one('product.product', { required: true, ondelete: 'restrict' }),
159
+ bom: f.many2one('production.bom', { ondelete: 'restrict', label: 'Bill of materials' }),
160
+ packagingBom: f.many2one('production.bom', {
161
+ ondelete: 'restrict',
162
+ label: 'Packaging bill',
163
+ help: 'The packaging bill of a second stage (step 4): its materials are forecast too.',
164
+ }),
165
+ quantity: f.decimal({ scale: 4, required: true, default: '1' }),
166
+ workcenter: f.many2one('production.workcenter', { required: true, ondelete: 'restrict' }),
167
+ start: f.datetime({ required: true }),
168
+ end: f.datetime({ required: true }),
169
+ minutes: f.decimal({
170
+ scale: 2,
171
+ store: true,
172
+ label: 'Minutes needed',
173
+ help: 'The bill’s operations for the quantity.',
174
+ ...compute('production.plan.line', 'minutes', ['quantity', 'bom.quantity', 'bom.operations.minutes'], (lines) => {
175
+ for (const l of lines) {
176
+ if (l.bom === null || l.bom.quantity.lte(0)) {
177
+ l.minutes = zero;
178
+ continue;
179
+ }
180
+ const factor = l.quantity.div(l.bom.quantity);
181
+ l.minutes = [...l.bom.operations]
182
+ .reduce((s, op) => s.plus(op.minutes.times(factor)), zero)
183
+ .toDecimalPlaces(2);
184
+ }
185
+ }),
186
+ }),
187
+ capacityNote: f.char({
188
+ size: 300,
189
+ store: true,
190
+ label: 'Capacity',
191
+ help: 'Why the slot does not fit its work centre — the batch limits, the minutes against its hours over the slot (setup and cleanup included) —; empty when it fits.',
192
+ ...compute('production.plan.line', 'capacityNote', [
193
+ 'quantity',
194
+ 'start',
195
+ 'end',
196
+ 'bom.quantity',
197
+ 'bom.operations.minutes',
198
+ 'product.name',
199
+ 'workcenter.name',
200
+ 'workcenter.batchMin',
201
+ 'workcenter.batchMax',
202
+ 'workcenter.hoursPerDay',
203
+ 'workcenter.setupMinutes',
204
+ 'workcenter.cleanupMinutes',
205
+ ], (lines) => {
206
+ for (const l of lines) {
207
+ const w = l.workcenter;
208
+ const why = [];
209
+ if (w.batchMin !== null && l.quantity.lt(w.batchMin))
210
+ why.push(`below the minimum batch of ${w.batchMin.toString()}`);
211
+ if (w.batchMax !== null && l.quantity.gt(w.batchMax))
212
+ why.push(`above the maximum batch of ${w.batchMax.toString()}`);
213
+ const start = new Date(l.start);
214
+ const end = new Date(l.end);
215
+ const days = Math.max(1, Math.ceil((end.getTime() - start.getTime()) / 86_400_000));
216
+ const available = w.hoursPerDay.times(60).times(days);
217
+ const minutes = l.bom === null || l.bom.quantity.lte(0)
218
+ ? zero
219
+ : [...l.bom.operations].reduce((s, op) => s.plus(op.minutes.times(l.quantity.div(l.bom?.quantity ?? zero))), zero);
220
+ const needed = minutes.plus(w.setupMinutes ?? zero).plus(w.cleanupMinutes ?? zero);
221
+ if (needed.gt(available))
222
+ why.push(`${needed.toDecimalPlaces(0).toString()} minutes needed, ${available.toDecimalPlaces(0).toString()} available at ${w.name} in ${days} day(s)`);
223
+ l.capacityNote = why.length === 0 ? '' : `${l.product.name}: ${why.join('; ')}.`;
224
+ }
225
+ }),
226
+ }),
227
+ schedules: f.one2many('production.schedule', 'planLine', { label: 'Batches' }),
228
+ scheduleCount: f.integer({
229
+ store: true,
230
+ label: 'Batches',
231
+ help: 'The schedules made from the line, one per batch of its work centre.',
232
+ ...compute('production.plan.line', 'scheduleCount', ['schedules.quantity'], (lines) => {
233
+ for (const l of lines)
234
+ l.scheduleCount = l.schedules.length;
235
+ }),
236
+ }),
237
+ label: f.char({
238
+ store: true,
239
+ label: 'Line',
240
+ ...compute('production.plan.line', 'label', ['product.name', 'quantity'], (lines) => {
241
+ for (const l of lines)
242
+ l.label = `${l.product.name} × ${l.quantity.toString()}`;
243
+ }),
244
+ }),
245
+ },
246
+ sqlConstraints: {
247
+ positive: { check: orm.sql `quantity > 0`, message: 'A line makes a positive quantity.' },
248
+ slot: { check: orm.sql `"end" > start`, message: 'A slot ends after it starts.' },
249
+ },
250
+ onchange: {
251
+ product: onchange('production.plan.line', async (d, env) => {
252
+ const product = (await d.record('product'));
253
+ if (product === null)
254
+ return;
255
+ const { validBom } = await import('./module.js');
256
+ const bom = await validBom(env, product.id, isoDay(env.today()));
257
+ if (bom !== null)
258
+ d.set('bom', bom);
259
+ }),
260
+ },
261
+ });
262
+ export const ProductionPlanMaterial = defineModel('production.plan.material', {
263
+ label: 'Plan material',
264
+ order: ['plan asc', 'id asc'],
265
+ access: { 'production.user': READ, 'production.manager': READ },
266
+ fields: {
267
+ plan: f.many2one('production.plan', { required: true, ondelete: 'cascade' }),
268
+ product: f.many2one('product.product', { required: true, ondelete: 'restrict' }),
269
+ required: f.decimal({ scale: 4, required: true, default: '0' }),
270
+ onHand: f.decimal({ scale: 4, required: true, default: '0', label: 'On hand' }),
271
+ onOrder: f.decimal({ scale: 4, required: true, default: '0', label: 'On order' }),
272
+ shortage: f.decimal({
273
+ scale: 4,
274
+ store: true,
275
+ help: 'Required beyond what is on hand and on order.',
276
+ ...compute('production.plan.material', 'shortage', ['required', 'onHand', 'onOrder'], (rows) => {
277
+ for (const m of rows) {
278
+ const left = m.required.minus(m.onHand).minus(m.onOrder);
279
+ m.shortage = left.gt(0) ? left : zero;
280
+ }
281
+ }),
282
+ }),
283
+ procured: f.decimal({ scale: 4, required: true, default: '0', help: 'Ordered by Procure.' }),
284
+ document: f.char({
285
+ label: 'Ordered by',
286
+ help: 'The request for quotation or production order Procure made.',
287
+ }),
288
+ note: f.char({ size: 300 }),
289
+ },
290
+ });
291
+ /** The components of a bill for `quantity` of its product, gross of losses, in the components' units. */
292
+ async function componentsOf(env, bomId, quantity) {
293
+ const [bom] = await env
294
+ .model('production.bom')
295
+ .browse([bomId])
296
+ .load({ lines: { product: { uom: true }, uom: true } });
297
+ if (bom === undefined || bom.quantity.lte(0))
298
+ return [];
299
+ const factor = quantity.div(bom.quantity);
300
+ return [...bom.lines].map((l) => ({
301
+ product: l.product.id,
302
+ quantity: inProductUnit((l.grossQuantity ?? l.quantity).times(factor), (l.uom ?? null), (l.product.uom ?? null)),
303
+ }));
304
+ }
305
+ /**
306
+ * Explodes a bill through every level: a component with a usable bill of its own is made, its components counted
307
+ * instead (ten levels at most); the rest are materials.
308
+ */
309
+ async function explodeAll(env, bomId, quantity, date, into, depth = 0) {
310
+ const { validBom } = await import('./module.js');
311
+ for (const c of await componentsOf(env, bomId, quantity)) {
312
+ const sub = depth < 10 ? await validBom(env, c.product, date) : null;
313
+ if (sub !== null)
314
+ await explodeAll(env, sub, c.quantity, date, into, depth + 1);
315
+ else
316
+ into.set(c.product, (into.get(c.product) ?? zero).plus(c.quantity));
317
+ }
318
+ }
319
+ /** The plan's materials: every line's bill (and packaging bill) exploded, with on hand and on order. */
320
+ export async function generateForecast(env, id) {
321
+ await env.asSuperuser({ reason: 'production plan forecast' }, async (su) => {
322
+ const [p] = await su
323
+ .model('production.plan')
324
+ .browse([id])
325
+ .load({
326
+ lines: { bom: true, packagingBom: true },
327
+ materials: true,
328
+ warehouse: true,
329
+ company: true,
330
+ });
331
+ if (p === undefined)
332
+ return;
333
+ if (p.materials.length > 0)
334
+ await p.materials.unlink();
335
+ const date = isoDay(p.dateFrom);
336
+ const into = new Map();
337
+ for (const l of p.lines) {
338
+ if (l.bom !== null)
339
+ await explodeAll(su, l.bom.id, l.quantity, date, into);
340
+ if (l.packagingBom !== null) {
341
+ // Packs of the product: the packaging bill's materials for the packs the line fills.
342
+ const packSize = l.packagingBom.packSize ?? zero;
343
+ const packs = packSize.gt(0) ? l.quantity.div(packSize) : l.quantity;
344
+ for (const c of await componentsOf(su, l.packagingBom.id, packs))
345
+ if (c.product !== l.product.id)
346
+ into.set(c.product, (into.get(c.product) ?? zero).plus(c.quantity));
347
+ }
348
+ }
349
+ const places = await defaultLocations(su, 'internal', p.warehouse?.id ?? null, p.company.id);
350
+ const receiving = (await defaultLocations(su, 'receipt', p.warehouse?.id ?? null, p.company.id)).destination;
351
+ for (const [product, required] of into) {
352
+ let onHand = zero;
353
+ let onOrder = zero;
354
+ if (places.source !== null) {
355
+ const quants = await (await su.model('stock.quant').search({
356
+ where: { product: product, location: { childOf: places.source } },
357
+ })).load(['quantity']);
358
+ onHand = [...quants].reduce((s, q) => s.plus(q.quantity), zero);
359
+ // Coming in: confirmed receipts into the warehouse, what is not done yet.
360
+ const incoming = await (await su.model('stock.move').search({
361
+ where: {
362
+ product: product,
363
+ 'picking.state': 'confirmed',
364
+ 'picking.kind': 'receipt',
365
+ },
366
+ })).load({ picking: { destination: true } });
367
+ onOrder = [...incoming]
368
+ .filter((m) => receiving === null || (m.picking?.destination?.id ?? receiving) === receiving)
369
+ .reduce((s, m) => s.plus((m.productQty ?? m.quantity).minus(m.doneQty ?? zero)), zero);
370
+ }
371
+ await su.model('production.plan.material').create([
372
+ {
373
+ plan: p.id,
374
+ product: product,
375
+ required: required.toDecimalPlaces(4),
376
+ onHand: onHand.toDecimalPlaces(4),
377
+ onOrder: onOrder.gt(0) ? onOrder.toDecimalPlaces(4) : zero,
378
+ },
379
+ ]);
380
+ }
381
+ await su.flush();
382
+ });
383
+ }
384
+ /** Materials are the system's (read-only for everyone): what Procure did is noted as superuser. */
385
+ async function noteMaterial(env, id, values) {
386
+ await env.asSuperuser({ reason: 'production plan procurement' }, async (su) => {
387
+ await su
388
+ .model('production.plan.material')
389
+ .browse([id])
390
+ .write(values);
391
+ await su.flush();
392
+ });
393
+ }
394
+ /** The vendor of the product's preferred vendor price, else its first; `null` without Purchase or without prices. */
395
+ async function preferredVendor(env, product) {
396
+ let prices;
397
+ try {
398
+ prices = [
399
+ ...(await (await env.model('product.vendor.price').search({ where: { product } })).load({ vendor: true })),
400
+ ];
401
+ }
402
+ catch {
403
+ return null; // Purchase (the `product.vendor.price` model) is not installed.
404
+ }
405
+ const chosen = prices.find((v) => v.preferred) ?? prices[0];
406
+ return chosen?.vendor?.id ?? null;
407
+ }
408
+ /**
409
+ * Orders the shortages through the warehouse's reorder rules: the rule of the product and warehouse (made when
410
+ * there is none: a buy rule) is asked for the shortage; what it makes — a request for quotation with Purchase, a
411
+ * production order for a made component — is noted on the material, or why nothing was.
412
+ */
413
+ export async function procureShortages(env, id) {
414
+ const { orderRules } = await import('../stock/index.js');
415
+ const [p] = await env
416
+ .model('production.plan')
417
+ .browse([id])
418
+ .load({ materials: { product: true }, warehouse: true, company: true });
419
+ if (p === undefined)
420
+ return;
421
+ const warehouse = p.warehouse?.id ??
422
+ (await defaultLocations(env, 'internal', null, p.company.id)).warehouse;
423
+ if (warehouse === null)
424
+ return;
425
+ for (const m of p.materials) {
426
+ if ((m.shortage ?? zero).lte(0))
427
+ continue;
428
+ let rule = (await env.model('stock.reorder').search({
429
+ where: { product: m.product.id, warehouse, company: p.company.id },
430
+ limit: 1,
431
+ })).ids[0];
432
+ if (rule === undefined) {
433
+ // No rule yet: a make rule for a product with a usable bill, else a buy rule from the product's preferred
434
+ // vendor price (Purchase); without either, the material says so and nothing is ordered.
435
+ const { validBom } = await import('./module.js');
436
+ const made = await validBom(env, m.product.id, isoDay(env.today()));
437
+ const vendor = made === null ? await preferredVendor(env, m.product.id) : null;
438
+ if (made === null && vendor === null) {
439
+ await noteMaterial(env, m.id, {
440
+ note: 'No reorder rule for the product and no vendor price to buy from: add one in Stockroom › Replenishment or on the product.',
441
+ });
442
+ continue;
443
+ }
444
+ rule = (await env.model('stock.reorder').create([
445
+ {
446
+ product: m.product.id,
447
+ warehouse,
448
+ company: p.company.id,
449
+ method: made === null ? 'buy' : 'make',
450
+ vendor,
451
+ minimum: '0',
452
+ maximum: '0',
453
+ },
454
+ ])).ids[0];
455
+ }
456
+ if (rule === undefined)
457
+ continue;
458
+ const result = await orderRules(env, [rule], new Map([[rule, m.shortage ?? zero]]));
459
+ const ordered = result.ordered[0];
460
+ const skipped = result.skipped[0];
461
+ await noteMaterial(env, m.id, {
462
+ procured: ordered === undefined ? zero : orm.toDecimal(ordered.quantity),
463
+ document: ordered?.document ?? null,
464
+ note: ordered === undefined ? (skipped?.reason ?? 'Not ordered.') : null,
465
+ });
466
+ }
467
+ await env.flush();
468
+ }
469
+ /**
470
+ * The plan's batches: each line split evenly into as many schedules as its work centre's maximum batch needs, the
471
+ * slot divided among them, each linked to its line; lines that already have batches are left alone.
472
+ */
473
+ export async function generateSchedules(env, id) {
474
+ const [p] = await env
475
+ .model('production.plan')
476
+ .browse([id])
477
+ .load({ lines: { workcenter: true, schedules: true }, warehouse: true, company: true });
478
+ if (p === undefined)
479
+ return;
480
+ for (const l of p.lines) {
481
+ if (l.schedules.length > 0)
482
+ continue;
483
+ const max = l.workcenter.batchMax ?? null;
484
+ const n = max?.gt(0) ? Math.max(1, Math.ceil(Number(l.quantity.div(max).toString()))) : 1;
485
+ const start = new Date(l.start).getTime();
486
+ const end = new Date(l.end).getTime();
487
+ const slice = Math.max(1, Math.floor((end - start) / n));
488
+ const each = l.quantity.div(n).toDecimalPlaces(4);
489
+ let left = l.quantity;
490
+ for (let i = 0; i < n; i++) {
491
+ const quantity = i === n - 1 ? left : each;
492
+ left = left.minus(quantity);
493
+ await env.model('production.schedule').create([
494
+ {
495
+ plan: p.id,
496
+ planLine: l.id,
497
+ product: l.product.id,
498
+ bom: l.bom?.id ?? null,
499
+ packagingBom: l.packagingBom?.id ?? null,
500
+ quantity,
501
+ workcenter: l.workcenter.id,
502
+ start: new Date(start + i * slice),
503
+ end: new Date(i === n - 1 ? end : start + (i + 1) * slice),
504
+ warehouse: p.warehouse?.id ?? null,
505
+ company: p.company.id,
506
+ },
507
+ ]);
508
+ }
509
+ }
510
+ await env.flush();
511
+ }