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
@@ -3,85 +3,550 @@
3
3
  * invoiced with one transition (`invoice`), which creates a draft customer invoice from the order's lines
4
4
  * (product, description, quantity, price, discount, taxes) in the company's sales journal; the order shows its
5
5
  * invoicing state and its invoices, the invoice its order.
6
+ *
7
+ * Credit control (RFC 0028 §3.2): a customer's credit limit (else the company's default) against what they owe —
8
+ * unpaid posted invoices, confirmed orders not invoiced yet and the order being confirmed —, by the company's mode:
9
+ * off, warn (shown on the order), block (refused), or approval (the order asks for a credit approval, decided by
10
+ * Accounting managers through the Approvals engine, and is confirmed when approved). Payment terms on the order (else
11
+ * the customer's) and its invoice address go to the invoice.
6
12
  */
7
- import { accountingShutro } from '../accounting/index.js';
13
+ import { accountingShutro, salesStopped } from '../accounting/index.js';
14
+ import { approvalGuard, permissionsShutro, requestApprovals } from '../permissions/index.js';
8
15
  import { salesShutro } from '../sales/index.js';
9
16
  import { orm } from '../server/orm.js';
10
17
  import { compute, defineModule, extendModel, f, records } from './.kosh/bindings.js';
18
+ /** The company's credit settings (RFC 0028 §3.2). */
19
+ export const CompanyCredit = extendModel('res.company', {
20
+ fields: {
21
+ creditControl: f.selection({
22
+ off: 'Off',
23
+ warn: 'Warn on the order',
24
+ block: 'Refuse the confirmation',
25
+ approval: 'Ask for an approval',
26
+ }, {
27
+ default: 'off',
28
+ label: 'Credit control',
29
+ help: 'What happens when confirming an order takes a customer over their credit limit.',
30
+ }),
31
+ creditLimitDefault: f.decimal({
32
+ scale: 2,
33
+ label: 'Default credit limit',
34
+ help: 'For customers without a limit of their own; empty: no limit.',
35
+ }),
36
+ },
37
+ });
38
+ /** A customer's credit limit and payment terms (RFC 0028 §3.2). */
39
+ export const PartnerCredit = extendModel('res.partner', {
40
+ fields: {
41
+ creditLimit: f.decimal({
42
+ scale: 2,
43
+ label: 'Credit limit',
44
+ help: 'What this customer may owe at most (unpaid invoices and orders not invoiced); empty: the company’s default.',
45
+ }),
46
+ customerPaymentTerm: f.many2one('account.payment.term', {
47
+ ondelete: 'set null',
48
+ label: 'Customer payment terms',
49
+ help: 'The payment terms of this customer’s orders and invoices, unless an order says otherwise.',
50
+ }),
51
+ },
52
+ });
53
+ const zero = orm.toDecimal('0');
54
+ const amountOf = (v) => v === null || v === undefined
55
+ ? zero
56
+ : typeof v === 'object' && v !== null && 'amount' in v
57
+ ? orm.toDecimal(String(v.amount))
58
+ : orm.toDecimal(String(v));
59
+ /**
60
+ * What a customer owes in a company — unpaid posted invoices (less credit notes) and confirmed orders not invoiced
61
+ * yet, `order` left out — and their limit (null: none), read as the system.
62
+ */
63
+ export async function creditOf(env, partner, company, order) {
64
+ return env.asSuperuser({ reason: 'credit control' }, async (su) => {
65
+ let owed = zero;
66
+ for (const m of await (await su.model('account.move').search({
67
+ where: {
68
+ partner: partner,
69
+ company: company,
70
+ state: 'posted',
71
+ kind: { in: ['out_invoice', 'out_debit', 'out_refund'] },
72
+ },
73
+ })).load([]))
74
+ owed =
75
+ m.kind === 'out_refund'
76
+ ? owed.minus(amountOf(m.amountResidual))
77
+ : owed.plus(amountOf(m.amountResidual));
78
+ for (const o of await (await su.model('sale.order').search({
79
+ where: {
80
+ partner: partner,
81
+ company: company,
82
+ state: { in: ['sale', 'done'] },
83
+ invoiceState: 'to_invoice',
84
+ ...(order === null ? {} : { id: { ne: order } }),
85
+ },
86
+ })).load([]))
87
+ owed = owed.plus(amountOf(o.amountTotal));
88
+ const [p] = await su
89
+ .model('res.partner')
90
+ .browse([partner])
91
+ .load([]);
92
+ const [c] = await su
93
+ .model('res.company')
94
+ .browse([company])
95
+ .load([]);
96
+ const limit = p?.creditLimit ??
97
+ c?.creditLimitDefault ??
98
+ null;
99
+ return { owed, limit };
100
+ });
101
+ }
11
102
  export const MoveSaleOrder = extendModel('account.move', {
12
103
  fields: {
13
104
  saleOrder: f.many2one('sale.order', { label: 'Sales order' }),
14
105
  },
15
106
  });
107
+ /** An invoice line's order line, and down payments (RFC 0028 §3.3). */
108
+ export const MoveLineSale = extendModel('account.move.line', {
109
+ fields: {
110
+ saleLine: f.many2one('sale.order.line', { ondelete: 'set null', label: 'Order line' }),
111
+ /** A down payment of this order (positive), or its deduction (negative). */
112
+ downPaymentOf: f.many2one('sale.order', { ondelete: 'set null', label: 'Down payment of' }),
113
+ },
114
+ });
115
+ /** How much of each order line is invoiced: its invoice lines' quantities (credit notes take back). */
116
+ export const SaleLineInvoicing = extendModel('sale.order.line', {
117
+ fields: {
118
+ invoiceLines: f.one2many('account.move.line', 'saleLine'),
119
+ qtyInvoiced: f.decimal({
120
+ scale: 3,
121
+ store: true,
122
+ label: 'Invoiced',
123
+ help: 'The quantity on this line’s invoices, less credit notes; cancelled invoices do not count.',
124
+ ...compute('sale.order.line', 'qtyInvoiced', ['invoiceLines.quantity', 'invoiceLines.move.state', 'invoiceLines.move.kind'], (lines) => {
125
+ for (const l of lines)
126
+ l.qtyInvoiced = [...l.invoiceLines]
127
+ .filter((il) => il.move.state !== 'cancel')
128
+ .reduce((sum, il) => il.move.kind === 'out_refund'
129
+ ? sum.minus(il.quantity ?? zero)
130
+ : sum.plus(il.quantity ?? zero), zero);
131
+ }),
132
+ }),
133
+ },
134
+ });
135
+ /** The company's down payment product (made on first use): its income account books down payments. */
136
+ export const CompanyDownPayment = extendModel('res.company', {
137
+ fields: {
138
+ downPaymentProduct: f.many2one('product.product', {
139
+ ondelete: 'restrict',
140
+ label: 'Down payment product',
141
+ help: 'The service down payments are invoiced as; made on the first down payment.',
142
+ }),
143
+ },
144
+ });
145
+ /**
146
+ * What each line of `orders` has to invoice now (RFC 0028 §3.3): the ordered quantity, or the delivered one for
147
+ * products invoiced on delivery (Stockroom's, when installed; services count as delivered), less what is invoiced.
148
+ */
149
+ export async function toInvoice(env, orderIds) {
150
+ const out = new Map();
151
+ const lines = await (await env.model('sale.order.line').search({ where: { order: { in: [...orderIds] } } })).load({ product: true });
152
+ // Stockroom's delivered quantities, when it is installed.
153
+ const delivered = new Map();
154
+ try {
155
+ const raw = env.model('sale.order.line');
156
+ const ids = lines.map((l) => l.id);
157
+ if (ids.length > 0)
158
+ for (const row of (await raw.browse(ids).load(['qtyDelivered'])).read(['qtyDelivered']))
159
+ delivered.set(row['id'], orm.toDecimal(String(row['qtyDelivered'] ?? '0')));
160
+ }
161
+ catch {
162
+ // no Stockroom: what was ordered counts as delivered
163
+ }
164
+ for (const l of lines) {
165
+ const byDelivery = l.product?.invoicePolicy === 'delivered' &&
166
+ l.product?.kind !== 'service' &&
167
+ delivered.size > 0;
168
+ const basis = byDelivery ? (delivered.get(l.id) ?? zero) : l.quantity;
169
+ out.set(l.id, basis.minus(l.qtyInvoiced ?? zero));
170
+ }
171
+ return out;
172
+ }
173
+ /**
174
+ * What each line of `orders` has to credit for what came back (RFC 0030 §3.2): the returned quantity, as far as it is
175
+ * invoiced beyond what is still delivered — so a return is credited once, whatever the invoicing policy.
176
+ */
177
+ export async function toCredit(env, orderIds) {
178
+ const out = new Map();
179
+ const lines = await (await env.model('sale.order.line').search({ where: { order: { in: [...orderIds] } } })).load({});
180
+ const ids = lines.map((l) => l.id);
181
+ const returned = await optionalLineField(env, 'sale.order.line', ids, 'qtyReturned');
182
+ const delivered = await optionalLineField(env, 'sale.order.line', ids, 'qtyDelivered');
183
+ if (returned === null || delivered === null)
184
+ return out; // no Stockroom: nothing comes back
185
+ for (const l of lines) {
186
+ const back = returned.get(l.id) ?? zero;
187
+ if (back.lte(0))
188
+ continue;
189
+ const over = (l.qtyInvoiced ?? zero).minus(delivered.get(l.id) ?? zero);
190
+ const credit = back.lt(over) ? back : over;
191
+ if (credit.gt(0))
192
+ out.set(l.id, credit);
193
+ }
194
+ return out;
195
+ }
196
+ /** A numeric field of order lines a bridge may add (Stockroom's), by line; null when it is not there. */
197
+ async function optionalLineField(env, model, ids, field) {
198
+ if (ids.length === 0)
199
+ return new Map();
200
+ try {
201
+ const raw = env.model(model);
202
+ return new Map((await raw.browse([...ids]).load([field]))
203
+ .read([field])
204
+ .map((r) => [r['id'], orm.toDecimal(String(r[field] ?? '0'))]));
205
+ }
206
+ catch {
207
+ return null;
208
+ }
209
+ }
210
+ /** The down payments of an order not deducted yet (invoiced, less the deductions), as the system. */
211
+ async function downPaymentsLeft(env, order) {
212
+ return env.asSuperuser({ reason: 'down payments' }, async (su) => {
213
+ let left = zero;
214
+ for (const l of await (await su.model('account.move.line').search({ where: { downPaymentOf: order } })).load({ move: true }))
215
+ if (l.move.state !== 'cancel')
216
+ left = left.plus((l.priceUnit ?? zero).times(l.quantity ?? zero));
217
+ return left;
218
+ });
219
+ }
220
+ /** The company's down payment product, made once. */
221
+ async function downPaymentProduct(env, company) {
222
+ return env.asSuperuser({ reason: 'down payment product' }, async (su) => {
223
+ const [c] = await su
224
+ .model('res.company')
225
+ .browse([company])
226
+ .load({ downPaymentProduct: true });
227
+ const existing = c?.downPaymentProduct?.id;
228
+ if (existing !== undefined)
229
+ return existing;
230
+ const made = await su
231
+ .model('product.product')
232
+ .create([
233
+ { name: 'Down payment', kind: 'service', saleOk: false, purchaseOk: false },
234
+ ]);
235
+ const id = made.ids[0];
236
+ await su
237
+ .model('res.company')
238
+ .browse([company])
239
+ .write({ downPaymentProduct: id });
240
+ return id;
241
+ });
242
+ }
243
+ /**
244
+ * A draft customer invoice for an order (RFC 0028 §3.3): the given lines, to its invoice address with its payment
245
+ * terms, else the customer's. @throws when the company has no sales journal
246
+ */
247
+ async function invoiceFor(env, order, lines, kind = 'out_invoice') {
248
+ const [o] = await env
249
+ .model('sale.order')
250
+ .browse([order])
251
+ .load({
252
+ partner: true,
253
+ partnerInvoice: true,
254
+ paymentTerm: true,
255
+ currency: true,
256
+ company: true,
257
+ });
258
+ if (o === undefined)
259
+ throw new orm.ValidationError('sale.order', [], 'No such order.', '');
260
+ const journal = await env.model('account.journal').search({
261
+ where: { company: o.company.id, type: 'sale' },
262
+ limit: 1,
263
+ });
264
+ const journalId = journal.ids[0];
265
+ if (journalId === undefined)
266
+ throw new orm.ValidationError('sale.order', ['state'], 'The company has no sales journal.', 'Install a chart of accounts (Accounting › Configuration).');
267
+ const made = await env.model('account.move').create([
268
+ {
269
+ kind,
270
+ journal: journalId,
271
+ // The invoice address and payment terms of the order, else the customer's (RFC 0028 §3.2).
272
+ partner: o.partnerInvoice?.id ?? o.partner.id,
273
+ paymentTerm: o.paymentTerm?.id ?? o.partner.customerPaymentTerm?.id ?? null,
274
+ currency: o.currency.id,
275
+ company: o.company.id,
276
+ date: env.today(),
277
+ invoiceOrigin: o.name,
278
+ saleOrder: o.id,
279
+ lines: { create: lines },
280
+ },
281
+ ]);
282
+ return made.ids[0];
283
+ }
284
+ /**
285
+ * A down payment on a confirmed order (RFC 0028 §3.3): a percent of its total or an amount, invoiced on the
286
+ * company's down payment product; the next invoices deduct it. Returns the invoice.
287
+ */
288
+ export async function downPayment(env, order, input) {
289
+ const [o] = await env
290
+ .model('sale.order')
291
+ .browse([order])
292
+ .load({ company: true });
293
+ if (o === undefined)
294
+ throw new orm.ValidationError('sale.order', [], 'No such order.', '');
295
+ if (o.state !== 'sale')
296
+ throw new orm.ValidationError('sale.order', ['state'], 'Down payments are for confirmed orders.', 'Confirm the order first.');
297
+ const total = amountOf(o.amountTotal);
298
+ const amount = input.amount ?? (input.percent === undefined ? zero : total.times(input.percent).div(100));
299
+ const left = await downPaymentsLeft(env, order);
300
+ if (amount.lte(0) || amount.plus(left).gt(total))
301
+ throw new orm.ValidationError('sale.order', [], `A down payment is more than nothing and, with those not deducted yet (${left.toFixed(2)}), at most the order’s total (${total.toFixed(2)}).`, 'Give a smaller amount or percent.');
302
+ const product = await downPaymentProduct(env, o.company.id);
303
+ return invoiceFor(env, order, [
304
+ {
305
+ lineKind: 'product',
306
+ product,
307
+ name: `Down payment on ${String(o.name)}`,
308
+ quantity: '1',
309
+ priceUnit: amount.toDecimalPlaces(2).toString(),
310
+ downPaymentOf: order,
311
+ debit: '0',
312
+ credit: '0',
313
+ },
314
+ ]);
315
+ }
16
316
  export const SaleOrderInvoicing = extendModel('sale.order', {
17
317
  fields: {
318
+ /** The order's payment terms (RFC 0028 §3.2); empty: the customer's, on the invoice. */
319
+ paymentTerm: f.many2one('account.payment.term', {
320
+ ondelete: 'restrict',
321
+ label: 'Payment terms',
322
+ help: 'Passed to the invoice; empty: the customer’s payment terms.',
323
+ }),
324
+ /** What the last credit check found (RFC 0028 §3.2), shown on the order. */
325
+ creditNote: f.char({ label: 'Credit' }),
326
+ /** The next down payment (RFC 0028 §3.3): a percent of the total or an amount; cleared once invoiced. */
327
+ downPaymentPercent: f.decimal({
328
+ scale: 2,
329
+ label: 'Down payment %',
330
+ help: 'A percent of the order’s total, invoiced by “Invoice a down payment”.',
331
+ }),
332
+ downPaymentAmount: f.decimal({
333
+ scale: 2,
334
+ label: 'Down payment amount',
335
+ help: 'An amount, invoiced by “Invoice a down payment” (used instead of the percent).',
336
+ }),
337
+ /** Waiting for a credit approval (the approval policy's condition). */
338
+ creditHeld: f.boolean({ default: false, label: 'Held for credit' }),
18
339
  invoices: f.one2many('account.move', 'saleOrder'),
19
340
  invoiceState: f.selection({ no: 'Nothing to invoice', to_invoice: 'To invoice', invoiced: 'Invoiced' }, {
20
341
  store: true,
21
342
  label: 'Invoicing',
22
- ...compute('sale.order', 'invoiceState', ['state', 'invoices.state'], (orders) => {
343
+ help: 'To invoice while some ordered quantity is not invoiced yet; invoiced when all of it is.',
344
+ ...compute('sale.order', 'invoiceState', ['state', 'lines.quantity', 'lines.qtyInvoiced'], (orders) => {
23
345
  for (const o of orders)
24
346
  o.invoiceState =
25
347
  o.state === 'sale' || o.state === 'done'
26
- ? o.invoices.filter((i) => i.state !== 'cancel').length > 0
348
+ ? o.lines.length > 0 &&
349
+ [...o.lines].every((l) => (l.qtyInvoiced ?? zero).gte(l.quantity))
27
350
  ? 'invoiced'
28
351
  : 'to_invoice'
29
352
  : 'no';
30
353
  }),
31
354
  }),
32
355
  },
356
+ overrides: {
357
+ // The credit check before a confirmation (RFC 0028 §3.2).
358
+ confirming: async function (next) {
359
+ await next();
360
+ const orders = this;
361
+ const env = orders.env;
362
+ for (const o of await env
363
+ .model('sale.order')
364
+ .browse([...orders.ids])
365
+ .load({ company: true, partner: true })) {
366
+ // A customer at a follow-up level that stops sales (RFC 0029 §3.4) is not sold to until they pay.
367
+ const stopped = await salesStopped(env, o.partner.id);
368
+ if (stopped !== null)
369
+ throw new orm.ValidationError('sale.order', ['state'], `Sales to ${String(o.partner.name)} are on hold: their payment follow-up reached "${stopped.level}".`, 'Collect the overdue invoices first, or pause their follow-up in Accounting › Follow-ups.');
370
+ const mode = String(o.company.creditControl ?? 'off');
371
+ if (mode === 'off')
372
+ continue;
373
+ const { owed, limit } = await creditOf(env, o.partner.id, o.company.id, o.id);
374
+ if (limit === null)
375
+ continue;
376
+ const total = owed.plus(amountOf(o.amountTotal));
377
+ const note = `Owes ${owed.toFixed(2)}; with this order ${total.toFixed(2)}, limit ${limit.toFixed(2)}.`;
378
+ if (total.lte(limit)) {
379
+ if (o.creditNote !== null)
380
+ await env.model('sale.order').browse([o.id]).write({ creditNote: null });
381
+ continue;
382
+ }
383
+ if (mode === 'warn') {
384
+ await env
385
+ .model('sale.order')
386
+ .browse([o.id])
387
+ .write({ creditNote: `Over the credit limit. ${note}` });
388
+ continue;
389
+ }
390
+ throw new orm.ValidationError('sale.order', ['state'], `${String(o.name)} takes ${String(o.partner.name)} over their credit limit. ${note}`, mode === 'approval'
391
+ ? 'Ask for a credit approval instead (Accounting managers decide).'
392
+ : 'Collect a payment first, or raise the customer’s limit.');
393
+ }
394
+ },
395
+ },
33
396
  fieldOverrides: {
34
397
  state: {
398
+ statesAdd: { credit: 'Credit approval' },
35
399
  transitionsAdd: {
400
+ // Over the limit, in approval mode: the order waits for Accounting managers.
401
+ askCredit: {
402
+ from: ['draft', 'sent'],
403
+ to: 'credit',
404
+ guard: records('sale.order', async (orders) => {
405
+ const loaded = await orders.load({ lines: true, company: true });
406
+ return loaded.filter((o) => o.lines.length === 0 || o.company.creditControl !== 'approval');
407
+ }),
408
+ message: 'Credit approvals are for orders with lines, when the company asks for them.',
409
+ after: records('sale.order', async (orders) => {
410
+ const env = orders.env;
411
+ for (const o of await orders.load({ company: true, partner: true })) {
412
+ const { owed, limit } = await creditOf(env, o.partner.id, o.company.id, o.id);
413
+ const total = owed.plus(amountOf(o.amountTotal));
414
+ await env
415
+ .model('sale.order')
416
+ .browse([o.id])
417
+ .write({
418
+ creditHeld: true,
419
+ creditNote: `Waiting for a credit approval: with this order ${total.toFixed(2)}, limit ${limit === null ? 'none' : limit.toFixed(2)}.`,
420
+ });
421
+ }
422
+ await requestApprovals(orders);
423
+ }),
424
+ },
425
+ creditApprove: {
426
+ from: ['credit'],
427
+ to: 'sale',
428
+ guard: records('sale.order', (orders) => approvalGuard(orders)),
429
+ message: 'Waiting for the credit approval.',
430
+ after: records('sale.order', async (orders) => {
431
+ for (const o of await orders.load({})) {
432
+ await orders.env.emit('sale.order.confirmed', { id: o.id });
433
+ await orders.env
434
+ .model('sale.order')
435
+ .browse([o.id])
436
+ .write({ creditHeld: false, creditNote: null });
437
+ }
438
+ }),
439
+ },
440
+ creditReject: {
441
+ from: ['credit'],
442
+ to: 'draft',
443
+ after: records('sale.order', async (orders) => {
444
+ for (const o of await orders.load({}))
445
+ await orders.env
446
+ .model('sale.order')
447
+ .browse([o.id])
448
+ .write({ creditHeld: false, creditNote: 'The credit approval was refused.' });
449
+ }),
450
+ },
451
+ // A down payment: the amount typed in, else the percent; the next invoices deduct it.
452
+ invoiceDownPayment: {
453
+ from: ['sale'],
454
+ to: 'sale',
455
+ guard: records('sale.order', async (orders) => (await orders.load({})).filter((o) => o.downPaymentAmount === null && o.downPaymentPercent === null)),
456
+ message: 'Give a down payment percent or amount first.',
457
+ after: records('sale.order', async (orders) => {
458
+ const env = orders.env;
459
+ for (const o of await orders.load({})) {
460
+ await downPayment(env, o.id, {
461
+ ...(o.downPaymentAmount !== null
462
+ ? { amount: o.downPaymentAmount }
463
+ : { percent: o.downPaymentPercent ?? zero }),
464
+ });
465
+ await env
466
+ .model('sale.order')
467
+ .browse([o.id])
468
+ .write({ downPaymentAmount: null, downPaymentPercent: null });
469
+ }
470
+ }),
471
+ },
472
+ // A credit note for what the customer sent back (RFC 0030 §3.2), at the line's price.
473
+ refund: {
474
+ from: ['sale'],
475
+ to: 'sale',
476
+ guard: records('sale.order', async (orders) => {
477
+ const due = await toCredit(orders.env, [...orders.ids]);
478
+ const loaded = await orders.load({ lines: true });
479
+ return loaded.filter((o) => ![...o.lines].some((l) => due.has(l.id)));
480
+ }),
481
+ message: 'Nothing to credit: no return of this order is invoiced and not credited yet.',
482
+ after: records('sale.order', async (orders) => {
483
+ const env = orders.env;
484
+ const due = await toCredit(env, [...orders.ids]);
485
+ for (const o of await orders.load({ lines: { product: true, taxes: true } })) {
486
+ const lines = [...o.lines]
487
+ .filter((l) => due.has(l.id))
488
+ .map((l) => ({
489
+ lineKind: 'product',
490
+ product: l.product.id,
491
+ name: `${String(l.name)} (returned)`,
492
+ quantity: (due.get(l.id) ?? zero).toString(),
493
+ priceUnit: l.priceUnit,
494
+ discount: l.discount,
495
+ taxes: { set: [...l.taxes].map((t) => t.id) },
496
+ saleLine: l.id,
497
+ debit: '0',
498
+ credit: '0',
499
+ }));
500
+ if (lines.length > 0)
501
+ await invoiceFor(env, o.id, lines, 'out_refund');
502
+ }
503
+ }),
504
+ },
36
505
  invoice: {
37
506
  from: ['sale'],
38
507
  to: 'sale',
508
+ // Something to invoice now: ordered, or delivered for products invoiced on delivery, not invoiced yet.
39
509
  guard: records('sale.order', async (orders) => {
40
- const loaded = await orders.load({ invoices: true });
41
- return loaded.filter((o) => o.invoices.filter((i) => i.state !== 'cancel').length > 0);
510
+ const due = await toInvoice(orders.env, [...orders.ids]);
511
+ const loaded = await orders.load({ lines: true });
512
+ return loaded.filter((o) => ![...o.lines].some((l) => (due.get(l.id) ?? zero).gt(0)));
42
513
  }),
43
- message: 'This order is invoiced already.',
514
+ message: 'Nothing to invoice now: this order is invoiced already, as far as it is ordered or delivered.',
44
515
  after: records('sale.order', async (orders) => {
45
516
  const env = orders.env;
46
- const loaded = await orders.load({
517
+ const due = await toInvoice(env, [...orders.ids]);
518
+ for (const o of await orders.load({
47
519
  lines: { product: true, taxes: true },
48
- partner: true,
49
- currency: true,
50
520
  company: true,
51
- });
52
- for (const o of loaded) {
53
- const journal = await env.model('account.journal').search({
54
- where: { company: o.company.id, type: 'sale' },
55
- limit: 1,
56
- });
57
- const journalId = journal.ids[0];
58
- if (journalId === undefined)
59
- throw new orm.ValidationError('sale.order', ['state'], 'The company has no sales journal.', 'Install a chart of accounts (Accounting › Configuration).');
60
- await env.model('account.move').create([
61
- {
62
- kind: 'out_invoice',
63
- journal: journalId,
64
- partner: o.partner.id,
65
- currency: o.currency.id,
66
- company: o.company.id,
67
- date: env.today(),
68
- invoiceOrigin: o.name,
69
- saleOrder: o.id,
70
- lines: {
71
- create: o.lines.map((l) => ({
72
- lineKind: 'product',
73
- product: l.product.id,
74
- name: l.name,
75
- quantity: l.quantity,
76
- priceUnit: l.priceUnit,
77
- discount: l.discount,
78
- taxes: { set: [...l.taxes].map((t) => t.id) },
79
- debit: '0',
80
- credit: '0',
81
- })),
82
- },
83
- },
84
- ]);
521
+ })) {
522
+ const lines = [...o.lines]
523
+ .filter((l) => (due.get(l.id) ?? zero).gt(0))
524
+ .map((l) => ({
525
+ lineKind: 'product',
526
+ product: l.product.id,
527
+ name: l.name,
528
+ quantity: (due.get(l.id) ?? zero).toString(),
529
+ priceUnit: l.priceUnit,
530
+ discount: l.discount,
531
+ taxes: { set: [...l.taxes].map((t) => t.id) },
532
+ saleLine: l.id,
533
+ debit: '0',
534
+ credit: '0',
535
+ }));
536
+ // Down payments not deducted yet come off this invoice.
537
+ const left = await downPaymentsLeft(env, o.id);
538
+ if (left.gt(0))
539
+ lines.push({
540
+ lineKind: 'product',
541
+ product: await downPaymentProduct(env, o.company.id),
542
+ name: `Down payment deducted (${String(o.name)})`,
543
+ quantity: '1',
544
+ priceUnit: left.negated().toString(),
545
+ downPaymentOf: o.id,
546
+ debit: '0',
547
+ credit: '0',
548
+ });
549
+ await invoiceFor(env, o.id, lines);
85
550
  }
86
551
  }),
87
552
  },
@@ -91,8 +556,24 @@ export const SaleOrderInvoicing = extendModel('sale.order', {
91
556
  });
92
557
  export const saleAccountShutro = defineModule({
93
558
  name: 'sale_account',
94
- version: '0.1.0',
95
- depends: [salesShutro, accountingShutro],
559
+ version: '0.3.0',
560
+ migrations: [
561
+ {
562
+ version: '0.3.0',
563
+ description: 'Invoicing by line: existing invoice lines linked to their order lines (same order, product and description), so invoiced orders are not invoiced again',
564
+ up: async (ctx) => {
565
+ await ctx.sql `UPDATE account_move_line ml SET sale_line_id = sol.id
566
+ FROM account_move m, sale_order_line sol
567
+ WHERE ml.move_id = m.id AND m.sale_order_id = sol.order_id AND ml.product_id = sol.product_id
568
+ AND ml.name = sol.name AND ml.line_kind = 'product' AND ml.sale_line_id IS NULL`;
569
+ await ctx.sql `UPDATE sale_order_line sol SET qty_invoiced = coalesce((
570
+ SELECT sum(CASE WHEN m.kind = 'out_refund' THEN -ml.quantity ELSE ml.quantity END)
571
+ FROM account_move_line ml JOIN account_move m ON m.id = ml.move_id
572
+ WHERE ml.sale_line_id = sol.id AND m.state <> 'cancel'), 0)`;
573
+ },
574
+ },
575
+ ],
576
+ depends: [salesShutro, accountingShutro, permissionsShutro],
96
577
  groups: [
97
578
  orm.defineGroup({
98
579
  code: 'sale_account.user',
@@ -101,5 +582,13 @@ export const saleAccountShutro = defineModule({
101
582
  }),
102
583
  ],
103
584
  models: [],
104
- extensions: [MoveSaleOrder, SaleOrderInvoicing],
585
+ extensions: [
586
+ MoveSaleOrder,
587
+ MoveLineSale,
588
+ SaleLineInvoicing,
589
+ SaleOrderInvoicing,
590
+ CompanyCredit,
591
+ PartnerCredit,
592
+ CompanyDownPayment,
593
+ ],
105
594
  });
@@ -0,0 +1,22 @@
1
+ export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
2
+ import { type DefinitionHelpers } from '../../server/orm.js';
3
+ import type { DefaultLoaded, Env as CoreEnv, RecordSet as CoreRecordSet, Shutro as CoreShutro } from '../../server/orm.js';
4
+ import type { SchemaView } from './schema.js';
5
+ export type { SchemaView };
6
+ /** Every model visible in this view. */
7
+ export type ModelName = keyof SchemaView & string;
8
+ /** `Env` typed to this view. */
9
+ export type Env = CoreEnv<SchemaView>;
10
+ /** `Shutro` typed to this view. */
11
+ export type Shutro = CoreShutro<SchemaView>;
12
+ /** A recordset of `M`, with the default loaded shape unless `L` is given. */
13
+ export type Records<M extends ModelName, L = DefaultLoaded<SchemaView, M>> = CoreRecordSet<SchemaView, M, L>;
14
+ export declare const compute: DefinitionHelpers<SchemaView>['compute'];
15
+ export declare const check: DefinitionHelpers<SchemaView>['check'];
16
+ export declare const onchange: DefinitionHelpers<SchemaView>['onchange'];
17
+ export declare const records: DefinitionHelpers<SchemaView>['records'];
18
+ export declare const method: DefinitionHelpers<SchemaView>['method'];
19
+ /** Module data (RFC 0017): records, overrides of dependencies' records, and references, typed like creates. */
20
+ export declare const record: DefinitionHelpers<SchemaView>['record'];
21
+ export declare const override: DefinitionHelpers<SchemaView>['override'];
22
+ export declare const ref: DefinitionHelpers<SchemaView>['ref'];