shutro-erp 0.3.5 → 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 (768) hide show
  1. package/dist/account_asset/.kosh/bindings.js +15 -0
  2. package/dist/{mrp_account → account_asset}/.kosh/schema.d.ts +785 -614
  3. package/dist/account_asset/board.d.ts +61 -0
  4. package/dist/account_asset/board.js +86 -0
  5. package/dist/account_asset/books.d.ts +42 -0
  6. package/dist/account_asset/books.js +398 -0
  7. package/dist/account_asset/demo.d.ts +7 -0
  8. package/dist/account_asset/demo.js +72 -0
  9. package/dist/account_asset/i18n/bn.d.ts +2 -0
  10. package/dist/account_asset/i18n/bn.js +97 -0
  11. package/dist/account_asset/index.d.ts +9 -0
  12. package/dist/account_asset/index.js +337 -0
  13. package/dist/account_asset/module.d.ts +11076 -0
  14. package/dist/account_asset/module.js +230 -0
  15. package/dist/account_budget/.kosh/bindings.js +15 -0
  16. package/dist/account_budget/.kosh/schema.d.ts +2841 -0
  17. package/dist/account_budget/budget.d.ts +5 -0
  18. package/dist/account_budget/budget.js +142 -0
  19. package/dist/account_budget/demo.d.ts +6 -0
  20. package/dist/account_budget/demo.js +30 -0
  21. package/dist/account_budget/i18n/bn.d.ts +2 -0
  22. package/dist/account_budget/i18n/bn.js +63 -0
  23. package/dist/account_budget/index.d.ts +4 -0
  24. package/dist/account_budget/index.js +237 -0
  25. package/dist/account_budget/module.d.ts +27289 -0
  26. package/dist/account_budget/module.js +182 -0
  27. package/dist/account_portal/.kosh/bindings.js +1 -1
  28. package/dist/account_portal/.kosh/schema.d.ts +651 -10
  29. package/dist/account_portal/i18n/bn.d.ts +2 -0
  30. package/dist/account_portal/i18n/bn.js +6 -0
  31. package/dist/account_portal/index.js +2 -0
  32. package/dist/account_portal/module.d.ts +5212 -1592
  33. package/dist/accounting/.kosh/bindings.js +1 -1
  34. package/dist/accounting/.kosh/schema.d.ts +651 -10
  35. package/dist/accounting/closing.js +1 -0
  36. package/dist/accounting/fiscal.d.ts +578 -0
  37. package/dist/accounting/fiscal.js +401 -0
  38. package/dist/accounting/followups.d.ts +618 -0
  39. package/dist/accounting/followups.js +420 -0
  40. package/dist/accounting/i18n/bn.d.ts +2 -0
  41. package/dist/accounting/i18n/bn.js +425 -0
  42. package/dist/accounting/index.d.ts +3 -1
  43. package/dist/accounting/index.js +780 -5
  44. package/dist/accounting/module.d.ts +5386 -1543
  45. package/dist/accounting/module.js +155 -18
  46. package/dist/accounting/statements.d.ts +878 -0
  47. package/dist/accounting/statements.js +728 -0
  48. package/dist/accounting/web/BankReconcilePage.d.ts +9 -0
  49. package/dist/accounting/web/BankReconcilePage.js +138 -0
  50. package/dist/accounting/web/FollowupsPage.d.ts +8 -0
  51. package/dist/accounting/web/FollowupsPage.js +54 -0
  52. package/dist/accounting/web/PostingPreview.d.ts +8 -0
  53. package/dist/accounting/web/PostingPreview.js +26 -0
  54. package/dist/accounting/web/index.d.ts +3 -0
  55. package/dist/accounting/web/index.js +9 -0
  56. package/dist/accounting/web/messages.js +140 -0
  57. package/dist/approvals/.kosh/bindings.d.ts +22 -0
  58. package/dist/approvals/.kosh/bindings.js +15 -0
  59. package/dist/approvals/.kosh/schema.d.ts +879 -0
  60. package/dist/approvals/demo.d.ts +7 -0
  61. package/dist/approvals/demo.js +41 -0
  62. package/dist/approvals/i18n/bn.d.ts +2 -0
  63. package/dist/approvals/i18n/bn.js +133 -0
  64. package/dist/approvals/index.d.ts +36 -0
  65. package/dist/approvals/index.js +772 -0
  66. package/dist/approvals/mails.d.ts +30 -0
  67. package/dist/approvals/mails.js +87 -0
  68. package/dist/approvals/module.d.ts +2930 -0
  69. package/dist/approvals/module.js +473 -0
  70. package/dist/approvals/web/Config.d.ts +12 -0
  71. package/dist/approvals/web/Config.js +60 -0
  72. package/dist/approvals/web/History.d.ts +4 -0
  73. package/dist/approvals/web/History.js +13 -0
  74. package/dist/approvals/web/Inbox.d.ts +9 -0
  75. package/dist/approvals/web/Inbox.js +114 -0
  76. package/dist/approvals/web/Matrix.d.ts +9 -0
  77. package/dist/approvals/web/Matrix.js +26 -0
  78. package/dist/approvals/web/Mine.d.ts +7 -0
  79. package/dist/approvals/web/Mine.js +27 -0
  80. package/dist/approvals/web/index.d.ts +15 -0
  81. package/dist/approvals/web/index.js +29 -0
  82. package/dist/approvals/web/messages.d.ts +2 -0
  83. package/dist/approvals/web/messages.js +211 -0
  84. package/dist/approvals/web/shared.d.ts +59 -0
  85. package/dist/approvals/web/shared.js +46 -0
  86. package/dist/approvals_purchase/.kosh/bindings.d.ts +22 -0
  87. package/dist/approvals_purchase/.kosh/bindings.js +15 -0
  88. package/dist/approvals_purchase/.kosh/schema.d.ts +1997 -0
  89. package/dist/approvals_purchase/i18n/bn.d.ts +2 -0
  90. package/dist/approvals_purchase/i18n/bn.js +5 -0
  91. package/dist/approvals_purchase/index.d.ts +3 -0
  92. package/dist/approvals_purchase/index.js +47 -0
  93. package/dist/approvals_purchase/module.d.ts +12670 -0
  94. package/dist/approvals_purchase/module.js +84 -0
  95. package/dist/attendance/.kosh/bindings.d.ts +22 -0
  96. package/dist/attendance/.kosh/bindings.js +15 -0
  97. package/dist/attendance/.kosh/schema.d.ts +1106 -0
  98. package/dist/attendance/days.d.ts +96 -0
  99. package/dist/attendance/days.js +430 -0
  100. package/dist/attendance/demo.d.ts +7 -0
  101. package/dist/attendance/demo.js +58 -0
  102. package/dist/attendance/i18n/bn.d.ts +2 -0
  103. package/dist/attendance/i18n/bn.js +147 -0
  104. package/dist/attendance/index.d.ts +4 -0
  105. package/dist/attendance/index.js +515 -0
  106. package/dist/attendance/module.d.ts +4413 -0
  107. package/dist/attendance/module.js +412 -0
  108. package/dist/attendance/routes.d.ts +16 -0
  109. package/dist/attendance/routes.js +266 -0
  110. package/dist/attendance/web/Check.d.ts +8 -0
  111. package/dist/attendance/web/Check.js +40 -0
  112. package/dist/attendance/web/Kiosk.d.ts +8 -0
  113. package/dist/attendance/web/Kiosk.js +62 -0
  114. package/dist/attendance/web/PinButton.d.ts +7 -0
  115. package/dist/attendance/web/PinButton.js +29 -0
  116. package/dist/attendance/web/index.d.ts +13 -0
  117. package/dist/attendance/web/index.js +22 -0
  118. package/dist/attendance/web/messages.d.ts +2 -0
  119. package/dist/attendance/web/messages.js +61 -0
  120. package/dist/automation/engine.js +1 -1
  121. package/dist/calendar/.kosh/bindings.js +1 -1
  122. package/dist/calendar/.kosh/schema.d.ts +2 -1
  123. package/dist/calendar/i18n/bn.d.ts +2 -0
  124. package/dist/calendar/i18n/bn.js +80 -0
  125. package/dist/calendar/index.js +77 -0
  126. package/dist/calendar/module.d.ts +26 -0
  127. package/dist/calendar/module.js +14 -4
  128. package/dist/cli/apps.js +25 -5
  129. package/dist/cli/init.js +46 -4
  130. package/dist/cli/templates.d.ts +1 -1
  131. package/dist/cli/templates.js +123 -5
  132. package/dist/contacts/.kosh/bindings.js +1 -1
  133. package/dist/contacts/.kosh/schema.d.ts +2 -1
  134. package/dist/contacts/i18n/bn.d.ts +2 -0
  135. package/dist/contacts/i18n/bn.js +67 -0
  136. package/dist/contacts/index.js +3 -0
  137. package/dist/contacts/module.d.ts +42 -0
  138. package/dist/contacts/module.js +19 -3
  139. package/dist/crm/.kosh/bindings.js +1 -1
  140. package/dist/crm/.kosh/schema.d.ts +3 -1
  141. package/dist/crm/i18n/bn.d.ts +2 -0
  142. package/dist/crm/i18n/bn.js +80 -0
  143. package/dist/crm/index.js +22 -0
  144. package/dist/crm/module.d.ts +22 -0
  145. package/dist/crm/module.js +6 -3
  146. package/dist/documents/.kosh/bindings.d.ts +22 -0
  147. package/dist/documents/.kosh/bindings.js +15 -0
  148. package/dist/documents/.kosh/schema.d.ts +863 -0
  149. package/dist/documents/demo.d.ts +6 -0
  150. package/dist/documents/demo.js +22 -0
  151. package/dist/documents/documents.d.ts +98 -0
  152. package/dist/documents/documents.js +318 -0
  153. package/dist/documents/i18n/bn.d.ts +2 -0
  154. package/dist/documents/i18n/bn.js +83 -0
  155. package/dist/documents/index.d.ts +30 -0
  156. package/dist/documents/index.js +569 -0
  157. package/dist/documents/module.d.ts +2801 -0
  158. package/dist/documents/module.js +215 -0
  159. package/dist/documents/web/Versions.d.ts +7 -0
  160. package/dist/documents/web/Versions.js +45 -0
  161. package/dist/documents/web/index.d.ts +11 -0
  162. package/dist/documents/web/index.js +16 -0
  163. package/dist/documents/web/messages.d.ts +2 -0
  164. package/dist/documents/web/messages.js +21 -0
  165. package/dist/event/.kosh/bindings.js +1 -1
  166. package/dist/event/.kosh/schema.d.ts +2 -1
  167. package/dist/event/i18n/bn.d.ts +2 -0
  168. package/dist/event/i18n/bn.js +101 -0
  169. package/dist/event/index.js +66 -0
  170. package/dist/event/module.d.ts +20 -0
  171. package/dist/event/module.js +8 -1
  172. package/dist/event_account/.kosh/bindings.js +1 -1
  173. package/dist/event_account/.kosh/schema.d.ts +651 -10
  174. package/dist/event_account/i18n/bn.d.ts +2 -0
  175. package/dist/event_account/i18n/bn.js +5 -0
  176. package/dist/event_account/index.js +2 -0
  177. package/dist/event_account/module.d.ts +5133 -1513
  178. package/dist/expense/.kosh/bindings.d.ts +22 -0
  179. package/dist/expense/.kosh/bindings.js +15 -0
  180. package/dist/expense/.kosh/schema.d.ts +1620 -0
  181. package/dist/expense/demo.d.ts +7 -0
  182. package/dist/expense/demo.js +69 -0
  183. package/dist/expense/i18n/bn.d.ts +2 -0
  184. package/dist/expense/i18n/bn.js +155 -0
  185. package/dist/expense/index.d.ts +3 -0
  186. package/dist/expense/index.js +502 -0
  187. package/dist/expense/module.d.ts +6768 -0
  188. package/dist/expense/module.js +649 -0
  189. package/dist/expense_account/.kosh/bindings.d.ts +22 -0
  190. package/dist/expense_account/.kosh/bindings.js +15 -0
  191. package/dist/expense_account/.kosh/schema.d.ts +2515 -0
  192. package/dist/expense_account/i18n/bn.d.ts +2 -0
  193. package/dist/expense_account/i18n/bn.js +15 -0
  194. package/dist/expense_account/index.d.ts +3 -0
  195. package/dist/expense_account/index.js +76 -0
  196. package/dist/expense_account/module.d.ts +14628 -0
  197. package/dist/expense_account/module.js +318 -0
  198. package/dist/helpdesk/.kosh/bindings.d.ts +22 -0
  199. package/dist/helpdesk/.kosh/bindings.js +15 -0
  200. package/dist/helpdesk/.kosh/schema.d.ts +886 -0
  201. package/dist/helpdesk/demo.d.ts +7 -0
  202. package/dist/helpdesk/demo.js +65 -0
  203. package/dist/helpdesk/hours.d.ts +17 -0
  204. package/dist/helpdesk/hours.js +94 -0
  205. package/dist/helpdesk/i18n/bn.d.ts +2 -0
  206. package/dist/helpdesk/i18n/bn.js +127 -0
  207. package/dist/helpdesk/index.d.ts +10 -0
  208. package/dist/helpdesk/index.js +463 -0
  209. package/dist/helpdesk/module.d.ts +2960 -0
  210. package/dist/helpdesk/module.js +326 -0
  211. package/dist/helpdesk/routes.d.ts +12 -0
  212. package/dist/helpdesk/routes.js +132 -0
  213. package/dist/helpdesk/sla.d.ts +37 -0
  214. package/dist/helpdesk/sla.js +226 -0
  215. package/dist/hr/.kosh/bindings.js +1 -1
  216. package/dist/hr/.kosh/schema.d.ts +59 -1
  217. package/dist/hr/demo.js +11 -1
  218. package/dist/hr/i18n/bn.d.ts +2 -0
  219. package/dist/hr/i18n/bn.js +126 -0
  220. package/dist/hr/index.d.ts +1 -1
  221. package/dist/hr/index.js +158 -12
  222. package/dist/hr/module.d.ts +932 -59
  223. package/dist/hr/module.js +114 -17
  224. package/dist/indent/.kosh/bindings.d.ts +22 -0
  225. package/dist/indent/.kosh/bindings.js +15 -0
  226. package/dist/indent/.kosh/schema.d.ts +2084 -0
  227. package/dist/indent/demo.d.ts +7 -0
  228. package/dist/indent/demo.js +48 -0
  229. package/dist/indent/i18n/bn.d.ts +2 -0
  230. package/dist/indent/i18n/bn.js +143 -0
  231. package/dist/indent/index.d.ts +3 -0
  232. package/dist/indent/index.js +450 -0
  233. package/dist/indent/module.d.ts +13424 -0
  234. package/dist/indent/module.js +792 -0
  235. package/dist/indent_purchase/.kosh/bindings.d.ts +22 -0
  236. package/dist/indent_purchase/.kosh/bindings.js +15 -0
  237. package/dist/indent_purchase/.kosh/schema.d.ts +2710 -0
  238. package/dist/indent_purchase/i18n/bn.d.ts +2 -0
  239. package/dist/indent_purchase/i18n/bn.js +13 -0
  240. package/dist/indent_purchase/index.d.ts +3 -0
  241. package/dist/indent_purchase/index.js +61 -0
  242. package/dist/indent_purchase/module.d.ts +27950 -0
  243. package/dist/indent_purchase/module.js +163 -0
  244. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  245. package/dist/l10n_bd/.kosh/schema.d.ts +651 -10
  246. package/dist/l10n_bd/i18n/bn.d.ts +2 -0
  247. package/dist/l10n_bd/i18n/bn.js +69 -0
  248. package/dist/l10n_bd/index.js +2 -0
  249. package/dist/l10n_bd/module.d.ts +5212 -1592
  250. package/dist/l10n_bd_payroll/.kosh/bindings.d.ts +22 -0
  251. package/dist/l10n_bd_payroll/.kosh/bindings.js +15 -0
  252. package/dist/l10n_bd_payroll/.kosh/schema.d.ts +2891 -0
  253. package/dist/l10n_bd_payroll/data.d.ts +47 -0
  254. package/dist/l10n_bd_payroll/data.js +347 -0
  255. package/dist/l10n_bd_payroll/i18n/bn.d.ts +2 -0
  256. package/dist/l10n_bd_payroll/i18n/bn.js +4 -0
  257. package/dist/l10n_bd_payroll/index.d.ts +4 -0
  258. package/dist/l10n_bd_payroll/index.js +26 -0
  259. package/dist/l10n_bd_payroll/module.d.ts +17294 -0
  260. package/dist/l10n_bd_payroll/module.js +86 -0
  261. package/dist/l10n_bd_pos/.kosh/bindings.d.ts +22 -0
  262. package/dist/{mrp_account → l10n_bd_pos}/.kosh/bindings.js +2 -2
  263. package/dist/l10n_bd_pos/.kosh/schema.d.ts +2341 -0
  264. package/dist/l10n_bd_pos/i18n/bn.d.ts +2 -0
  265. package/dist/l10n_bd_pos/i18n/bn.js +32 -0
  266. package/dist/l10n_bd_pos/index.d.ts +3 -0
  267. package/dist/l10n_bd_pos/index.js +111 -0
  268. package/dist/{mrp_account → l10n_bd_pos}/module.d.ts +9047 -6981
  269. package/dist/l10n_bd_pos/module.js +43 -0
  270. package/dist/l10n_in/.kosh/bindings.js +1 -1
  271. package/dist/l10n_in/.kosh/schema.d.ts +651 -10
  272. package/dist/l10n_in/i18n/bn.d.ts +2 -0
  273. package/dist/l10n_in/i18n/bn.js +95 -0
  274. package/dist/l10n_in/index.js +2 -0
  275. package/dist/l10n_in/module.d.ts +6778 -1580
  276. package/dist/l10n_in/module.js +25 -5
  277. package/dist/l10n_in/web/GstSettings.js +2 -2
  278. package/dist/mail/inbound/handle.js +8 -5
  279. package/dist/mail/inbound/models.js +5 -3
  280. package/dist/mail/index.d.ts +12 -1
  281. package/dist/mail/index.js +139 -2
  282. package/dist/mail/send.d.ts +56 -0
  283. package/dist/mail/send.js +394 -0
  284. package/dist/mail/web/SendButton.d.ts +9 -0
  285. package/dist/mail/web/SendButton.js +71 -0
  286. package/dist/mail/web/SendSelected.d.ts +8 -0
  287. package/dist/mail/web/SendSelected.js +33 -0
  288. package/dist/mail/web/index.d.ts +2 -0
  289. package/dist/mail/web/index.js +6 -0
  290. package/dist/mail/web/messages.js +36 -0
  291. package/dist/maintenance/.kosh/bindings.js +1 -1
  292. package/dist/maintenance/.kosh/schema.d.ts +2 -1
  293. package/dist/maintenance/i18n/bn.d.ts +2 -0
  294. package/dist/maintenance/i18n/bn.js +132 -0
  295. package/dist/maintenance/index.js +85 -0
  296. package/dist/maintenance/module.d.ts +25 -0
  297. package/dist/maintenance/module.js +27 -9
  298. package/dist/maintenance_stock/.kosh/bindings.js +1 -1
  299. package/dist/maintenance_stock/.kosh/schema.d.ts +374 -3
  300. package/dist/maintenance_stock/i18n/bn.d.ts +2 -0
  301. package/dist/maintenance_stock/i18n/bn.js +21 -0
  302. package/dist/maintenance_stock/index.js +2 -0
  303. package/dist/maintenance_stock/module.d.ts +6095 -1327
  304. package/dist/maintenance_stock/module.js +1 -0
  305. package/dist/modules-sdk/apps.d.ts +10 -0
  306. package/dist/modules-sdk/apps.js +32 -0
  307. package/dist/modules-sdk/index.d.ts +1 -1
  308. package/dist/modules-sdk/manifest.d.ts +105 -2
  309. package/dist/payment/.kosh/bindings.js +1 -1
  310. package/dist/payment/.kosh/schema.d.ts +653 -11
  311. package/dist/payment/i18n/bn.d.ts +2 -0
  312. package/dist/payment/i18n/bn.js +59 -0
  313. package/dist/payment/index.d.ts +41 -0
  314. package/dist/payment/index.js +216 -74
  315. package/dist/payment/module.d.ts +5353 -1675
  316. package/dist/payment/module.js +36 -6
  317. package/dist/payment/settle.js +11 -1
  318. package/dist/payroll/.kosh/bindings.d.ts +22 -0
  319. package/dist/payroll/.kosh/bindings.js +15 -0
  320. package/dist/payroll/.kosh/schema.d.ts +1448 -0
  321. package/dist/payroll/compute.d.ts +35 -0
  322. package/dist/payroll/compute.js +398 -0
  323. package/dist/payroll/demo.d.ts +55 -0
  324. package/dist/payroll/demo.js +121 -0
  325. package/dist/payroll/formula.d.ts +62 -0
  326. package/dist/payroll/formula.js +320 -0
  327. package/dist/payroll/i18n/bn.d.ts +2 -0
  328. package/dist/payroll/i18n/bn.js +206 -0
  329. package/dist/payroll/index.d.ts +230 -0
  330. package/dist/payroll/index.js +715 -0
  331. package/dist/{mrp → payroll}/module.d.ts +4294 -2624
  332. package/dist/payroll/module.js +606 -0
  333. package/dist/payroll/routes.d.ts +10 -0
  334. package/dist/payroll/routes.js +112 -0
  335. package/dist/payroll_account/.kosh/bindings.d.ts +22 -0
  336. package/dist/payroll_account/.kosh/bindings.js +15 -0
  337. package/dist/payroll_account/.kosh/schema.d.ts +2887 -0
  338. package/dist/payroll_account/i18n/bn.d.ts +2 -0
  339. package/dist/payroll_account/i18n/bn.js +10 -0
  340. package/dist/payroll_account/index.d.ts +3 -0
  341. package/dist/payroll_account/index.js +42 -0
  342. package/dist/payroll_account/module.d.ts +16738 -0
  343. package/dist/payroll_account/module.js +256 -0
  344. package/dist/permissions/approvals.d.ts +227 -12
  345. package/dist/permissions/approvals.js +1421 -67
  346. package/dist/permissions/index.d.ts +1 -1
  347. package/dist/permissions/index.js +2 -2
  348. package/dist/permissions/models.js +364 -13
  349. package/dist/permissions/routes.d.ts +9 -1
  350. package/dist/permissions/routes.js +72 -5
  351. package/dist/permissions/web/ApprovalPanel.d.ts +5 -4
  352. package/dist/permissions/web/ApprovalPanel.js +75 -11
  353. package/dist/permissions/web/index.d.ts +6 -4
  354. package/dist/permissions/web/index.js +13 -4
  355. package/dist/permissions/web/messages.d.ts +2 -0
  356. package/dist/permissions/web/messages.js +95 -0
  357. package/dist/portal/.kosh/bindings.js +1 -1
  358. package/dist/portal/.kosh/schema.d.ts +2 -1
  359. package/dist/portal/documents.d.ts +3 -0
  360. package/dist/portal/documents.js +21 -1
  361. package/dist/portal/i18n/bn.d.ts +2 -0
  362. package/dist/portal/i18n/bn.js +33 -0
  363. package/dist/portal/index.js +3 -1
  364. package/dist/portal/module.d.ts +20 -0
  365. package/dist/portal/routes-documents.js +76 -0
  366. package/dist/pos/.kosh/bindings.js +1 -1
  367. package/dist/pos/.kosh/schema.d.ts +652 -10
  368. package/dist/pos/i18n/bn.d.ts +2 -0
  369. package/dist/pos/i18n/bn.js +133 -0
  370. package/dist/pos/index.js +87 -1
  371. package/dist/pos/module.d.ts +6967 -1709
  372. package/dist/pos/module.js +49 -5
  373. package/dist/pos/routes.js +80 -7
  374. package/dist/pos/web/Register.js +2 -5
  375. package/dist/pos_stock/.kosh/bindings.js +1 -1
  376. package/dist/pos_stock/.kosh/schema.d.ts +822 -12
  377. package/dist/pos_stock/i18n/bn.d.ts +2 -0
  378. package/dist/pos_stock/i18n/bn.js +6 -0
  379. package/dist/pos_stock/index.js +2 -0
  380. package/dist/pos_stock/module.d.ts +11241 -2851
  381. package/dist/product/.kosh/bindings.js +1 -1
  382. package/dist/product/.kosh/schema.d.ts +203 -1
  383. package/dist/product/i18n/bn.d.ts +2 -0
  384. package/dist/product/i18n/bn.js +175 -0
  385. package/dist/product/index.d.ts +1 -0
  386. package/dist/product/index.js +301 -1
  387. package/dist/product/module.d.ts +1727 -0
  388. package/dist/product/module.js +67 -6
  389. package/dist/product/pricelist.d.ts +575 -0
  390. package/dist/product/pricelist.js +257 -0
  391. package/dist/product/variants.d.ts +908 -0
  392. package/dist/product/variants.js +251 -0
  393. package/dist/production/.kosh/bindings.d.ts +22 -0
  394. package/dist/production/.kosh/bindings.js +15 -0
  395. package/dist/production/.kosh/schema.d.ts +2345 -0
  396. package/dist/{mrp → production}/demo.d.ts +1 -1
  397. package/dist/{mrp → production}/demo.js +5 -5
  398. package/dist/production/depth.d.ts +790 -0
  399. package/dist/production/depth.js +262 -0
  400. package/dist/production/i18n/bn.d.ts +2 -0
  401. package/dist/production/i18n/bn.js +350 -0
  402. package/dist/production/index.d.ts +6 -0
  403. package/dist/production/index.js +1256 -0
  404. package/dist/production/module.d.ts +17327 -0
  405. package/dist/production/module.js +1333 -0
  406. package/dist/production/plan.d.ts +921 -0
  407. package/dist/production/plan.js +511 -0
  408. package/dist/production/schedule.d.ts +656 -0
  409. package/dist/production/schedule.js +309 -0
  410. package/dist/production_account/.kosh/bindings.d.ts +22 -0
  411. package/dist/production_account/.kosh/bindings.js +15 -0
  412. package/dist/production_account/.kosh/schema.d.ts +3496 -0
  413. package/dist/production_account/i18n/bn.d.ts +2 -0
  414. package/dist/production_account/i18n/bn.js +93 -0
  415. package/dist/production_account/index.d.ts +4 -0
  416. package/dist/production_account/index.js +246 -0
  417. package/dist/production_account/module.d.ts +1192 -0
  418. package/dist/{mrp_account → production_account}/module.js +72 -18
  419. package/dist/production_account/overhead.d.ts +1195 -0
  420. package/dist/production_account/overhead.js +554 -0
  421. package/dist/project/.kosh/bindings.js +1 -1
  422. package/dist/project/.kosh/schema.d.ts +735 -1
  423. package/dist/project/i18n/bn.d.ts +2 -0
  424. package/dist/project/i18n/bn.js +383 -0
  425. package/dist/project/index.d.ts +3 -1
  426. package/dist/project/index.js +1024 -14
  427. package/dist/project/module.d.ts +9912 -390
  428. package/dist/project/module.js +1590 -14
  429. package/dist/project/routes.d.ts +44 -0
  430. package/dist/project/routes.js +314 -0
  431. package/dist/project/schedule.d.ts +72 -0
  432. package/dist/project/schedule.js +192 -0
  433. package/dist/project/web/Refresh.d.ts +8 -0
  434. package/dist/project/web/Refresh.js +29 -0
  435. package/dist/project/web/Schedule.d.ts +9 -0
  436. package/dist/project/web/Schedule.js +93 -0
  437. package/dist/project/web/Structure.d.ts +8 -0
  438. package/dist/project/web/Structure.js +86 -0
  439. package/dist/project/web/Workload.d.ts +8 -0
  440. package/dist/project/web/Workload.js +43 -0
  441. package/dist/project/web/index.d.ts +14 -0
  442. package/dist/project/web/index.js +25 -0
  443. package/dist/project/web/messages.d.ts +2 -0
  444. package/dist/project/web/messages.js +85 -0
  445. package/dist/project_account/.kosh/bindings.d.ts +22 -0
  446. package/dist/project_account/.kosh/bindings.js +15 -0
  447. package/dist/project_account/.kosh/schema.d.ts +2763 -0
  448. package/dist/project_account/i18n/bn.d.ts +2 -0
  449. package/dist/project_account/i18n/bn.js +6 -0
  450. package/dist/project_account/index.d.ts +3 -0
  451. package/dist/project_account/index.js +29 -0
  452. package/dist/project_account/module.d.ts +15013 -0
  453. package/dist/project_account/module.js +76 -0
  454. package/dist/project_portal/.kosh/bindings.js +1 -1
  455. package/dist/project_portal/.kosh/schema.d.ts +735 -1
  456. package/dist/project_portal/i18n/bn.d.ts +2 -0
  457. package/dist/project_portal/i18n/bn.js +6 -0
  458. package/dist/project_portal/index.js +2 -0
  459. package/dist/project_portal/module.d.ts +4796 -87
  460. package/dist/project_purchase/.kosh/bindings.d.ts +22 -0
  461. package/dist/project_purchase/.kosh/bindings.js +15 -0
  462. package/dist/project_purchase/.kosh/schema.d.ts +3393 -0
  463. package/dist/project_purchase/i18n/bn.d.ts +2 -0
  464. package/dist/project_purchase/i18n/bn.js +4 -0
  465. package/dist/project_purchase/index.d.ts +9 -0
  466. package/dist/project_purchase/index.js +24 -0
  467. package/dist/project_purchase/module.d.ts +38613 -0
  468. package/dist/project_purchase/module.js +56 -0
  469. package/dist/purchase/.kosh/bindings.js +1 -1
  470. package/dist/purchase/.kosh/schema.d.ts +908 -5
  471. package/dist/purchase/comparison.d.ts +993 -0
  472. package/dist/purchase/comparison.js +415 -0
  473. package/dist/purchase/extras.d.ts +1509 -0
  474. package/dist/purchase/extras.js +445 -0
  475. package/dist/purchase/i18n/bn.d.ts +2 -0
  476. package/dist/purchase/i18n/bn.js +413 -0
  477. package/dist/purchase/index.d.ts +5 -0
  478. package/dist/purchase/index.js +1280 -4
  479. package/dist/purchase/module.d.ts +7147 -395
  480. package/dist/purchase/module.js +303 -10
  481. package/dist/purchase/request.d.ts +696 -0
  482. package/dist/purchase/request.js +446 -0
  483. package/dist/purchase/tender.d.ts +1208 -0
  484. package/dist/purchase/tender.js +507 -0
  485. package/dist/purchase/vendorprice.d.ts +340 -0
  486. package/dist/purchase/vendorprice.js +153 -0
  487. package/dist/purchase_account/.kosh/bindings.js +1 -1
  488. package/dist/purchase_account/.kosh/schema.d.ts +1209 -16
  489. package/dist/purchase_account/i18n/bn.d.ts +2 -0
  490. package/dist/purchase_account/i18n/bn.js +22 -0
  491. package/dist/purchase_account/index.js +20 -0
  492. package/dist/purchase_account/module.d.ts +12232 -2028
  493. package/dist/purchase_account/module.js +252 -9
  494. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  495. package/dist/purchase_portal/.kosh/schema.d.ts +908 -5
  496. package/dist/purchase_portal/i18n/bn.d.ts +2 -0
  497. package/dist/purchase_portal/i18n/bn.js +5 -0
  498. package/dist/purchase_portal/index.js +2 -0
  499. package/dist/purchase_portal/module.d.ts +6853 -352
  500. package/dist/purchase_stock/.kosh/bindings.js +1 -1
  501. package/dist/purchase_stock/.kosh/schema.d.ts +1096 -21
  502. package/dist/purchase_stock/i18n/bn.d.ts +2 -0
  503. package/dist/purchase_stock/i18n/bn.js +19 -0
  504. package/dist/purchase_stock/index.d.ts +2 -2
  505. package/dist/purchase_stock/index.js +38 -2
  506. package/dist/purchase_stock/module.d.ts +12930 -1612
  507. package/dist/purchase_stock/module.js +317 -9
  508. package/dist/purchase_stock/scorecard.d.ts +22 -0
  509. package/dist/purchase_stock/scorecard.js +77 -0
  510. package/dist/purchase_stock/web/Scorecard.d.ts +7 -0
  511. package/dist/purchase_stock/web/Scorecard.js +22 -0
  512. package/dist/purchase_stock/web/index.d.ts +11 -0
  513. package/dist/purchase_stock/web/index.js +16 -0
  514. package/dist/purchase_stock/web/messages.d.ts +2 -0
  515. package/dist/purchase_stock/web/messages.js +27 -0
  516. package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
  517. package/dist/purchase_stock_account/.kosh/schema.d.ts +1444 -20
  518. package/dist/purchase_stock_account/i18n/bn.d.ts +2 -0
  519. package/dist/purchase_stock_account/i18n/bn.js +8 -0
  520. package/dist/purchase_stock_account/index.js +18 -0
  521. package/dist/purchase_stock_account/module.d.ts +7 -35346
  522. package/dist/purchase_stock_account/module.js +35 -8
  523. package/dist/recruitment/.kosh/bindings.js +1 -1
  524. package/dist/recruitment/.kosh/schema.d.ts +60 -1
  525. package/dist/recruitment/i18n/bn.d.ts +2 -0
  526. package/dist/recruitment/i18n/bn.js +93 -0
  527. package/dist/recruitment/index.js +64 -0
  528. package/dist/recruitment/module.d.ts +460 -8
  529. package/dist/recruitment/module.js +13 -4
  530. package/dist/reporting/documents.d.ts +5 -0
  531. package/dist/reporting/documents.js +11 -1
  532. package/dist/reporting/index.d.ts +1 -1
  533. package/dist/reporting/index.js +1 -1
  534. package/dist/reporting/web/CalendarView.d.ts +18 -5
  535. package/dist/reporting/web/CalendarView.js +163 -29
  536. package/dist/reporting/web/messages.js +18 -0
  537. package/dist/sale_account/.kosh/bindings.js +1 -1
  538. package/dist/sale_account/.kosh/schema.d.ts +763 -18
  539. package/dist/sale_account/i18n/bn.d.ts +2 -0
  540. package/dist/sale_account/i18n/bn.js +48 -0
  541. package/dist/sale_account/index.d.ts +1 -1
  542. package/dist/sale_account/index.js +102 -4
  543. package/dist/sale_account/module.d.ts +8241 -2052
  544. package/dist/sale_account/module.js +535 -46
  545. package/dist/sale_crm/.kosh/bindings.d.ts +22 -0
  546. package/dist/sale_crm/.kosh/bindings.js +15 -0
  547. package/dist/{mrp → sale_crm}/.kosh/schema.d.ts +391 -494
  548. package/dist/sale_crm/i18n/bn.d.ts +2 -0
  549. package/dist/sale_crm/i18n/bn.js +9 -0
  550. package/dist/sale_crm/index.d.ts +7 -0
  551. package/dist/sale_crm/index.js +104 -0
  552. package/dist/sale_crm/module.d.ts +5609 -0
  553. package/dist/sale_crm/module.js +73 -0
  554. package/dist/sale_portal/.kosh/bindings.js +1 -1
  555. package/dist/sale_portal/.kosh/schema.d.ts +292 -4
  556. package/dist/sale_portal/i18n/bn.d.ts +2 -0
  557. package/dist/sale_portal/i18n/bn.js +7 -0
  558. package/dist/sale_portal/index.js +10 -0
  559. package/dist/sale_portal/module.d.ts +2563 -292
  560. package/dist/sale_project/.kosh/bindings.js +1 -1
  561. package/dist/sale_project/.kosh/schema.d.ts +1025 -4
  562. package/dist/sale_project/i18n/bn.d.ts +2 -0
  563. package/dist/sale_project/i18n/bn.js +12 -0
  564. package/dist/sale_project/index.js +2 -0
  565. package/dist/sale_project/module.d.ts +9280 -762
  566. package/dist/sale_project/module.js +17 -1
  567. package/dist/sale_stock/.kosh/bindings.js +1 -1
  568. package/dist/sale_stock/.kosh/schema.d.ts +463 -6
  569. package/dist/sale_stock/i18n/bn.d.ts +2 -0
  570. package/dist/sale_stock/i18n/bn.js +15 -0
  571. package/dist/sale_stock/index.js +2 -0
  572. package/dist/sale_stock/module.d.ts +8355 -1334
  573. package/dist/sale_stock/module.js +20 -3
  574. package/dist/sales/.kosh/bindings.js +1 -1
  575. package/dist/sales/.kosh/schema.d.ts +292 -4
  576. package/dist/sales/i18n/bn.d.ts +2 -0
  577. package/dist/sales/i18n/bn.js +128 -0
  578. package/dist/sales/index.js +124 -5
  579. package/dist/sales/module.d.ts +3568 -633
  580. package/dist/sales/module.js +306 -11
  581. package/dist/server/api/duplicate.d.ts +14 -0
  582. package/dist/server/api/duplicate.js +75 -0
  583. package/dist/server/api/explain.d.ts +70 -0
  584. package/dist/server/api/explain.js +111 -0
  585. package/dist/server/api/metadata.d.ts +2 -0
  586. package/dist/server/api/metadata.js +9 -0
  587. package/dist/server/api/openapi.js +15 -0
  588. package/dist/server/api/rest.d.ts +1 -0
  589. package/dist/server/api/rest.js +76 -12
  590. package/dist/server/api/views.js +1 -1
  591. package/dist/server/apps.d.ts +16 -1
  592. package/dist/server/apps.js +164 -2
  593. package/dist/server/auth/base.js +2 -0
  594. package/dist/server/auth/service.d.ts +8 -0
  595. package/dist/server/auth/service.js +19 -0
  596. package/dist/server/events.d.ts +13 -0
  597. package/dist/server/events.js +22 -0
  598. package/dist/server/i18n.d.ts +27 -0
  599. package/dist/server/i18n.js +143 -0
  600. package/dist/server/index.d.ts +2 -0
  601. package/dist/server/index.js +2 -0
  602. package/dist/server/server.js +6 -0
  603. package/dist/settings/company.d.ts +3 -1
  604. package/dist/settings/company.js +26 -5
  605. package/dist/settings/routes.d.ts +10 -0
  606. package/dist/settings/routes.js +19 -3
  607. package/dist/settings/web/AppsPage.d.ts +3 -2
  608. package/dist/settings/web/AppsPage.js +26 -8
  609. package/dist/settings/web/CompaniesPage.js +91 -6
  610. package/dist/settings/web/messages.js +64 -0
  611. package/dist/sign/.kosh/bindings.d.ts +22 -0
  612. package/dist/{mrp → sign}/.kosh/bindings.js +2 -2
  613. package/dist/sign/.kosh/schema.d.ts +991 -0
  614. package/dist/sign/i18n/bn.d.ts +2 -0
  615. package/dist/sign/i18n/bn.js +97 -0
  616. package/dist/sign/index.d.ts +29 -0
  617. package/dist/sign/index.js +478 -0
  618. package/dist/sign/module.d.ts +4518 -0
  619. package/dist/sign/module.js +167 -0
  620. package/dist/sign/sign.d.ts +82 -0
  621. package/dist/sign/sign.js +474 -0
  622. package/dist/stock/.kosh/bindings.js +1 -1
  623. package/dist/stock/.kosh/schema.d.ts +374 -3
  624. package/dist/stock/demo.d.ts +2 -1
  625. package/dist/stock/demo.js +28 -1
  626. package/dist/stock/i18n/bn.d.ts +2 -0
  627. package/dist/stock/i18n/bn.js +311 -0
  628. package/dist/stock/index.d.ts +4 -1
  629. package/dist/stock/index.js +674 -6
  630. package/dist/stock/ledger.d.ts +78 -0
  631. package/dist/stock/ledger.js +582 -0
  632. package/dist/stock/module.d.ts +6142 -1380
  633. package/dist/stock/module.js +780 -26
  634. package/dist/stock/replenish.d.ts +38 -0
  635. package/dist/stock/replenish.js +191 -0
  636. package/dist/stock/returns.d.ts +157 -0
  637. package/dist/stock/returns.js +163 -0
  638. package/dist/stock/web/Ledger.d.ts +9 -0
  639. package/dist/stock/web/Ledger.js +108 -0
  640. package/dist/stock/web/Operations.d.ts +8 -0
  641. package/dist/stock/web/Operations.js +33 -0
  642. package/dist/stock/web/Replenishment.d.ts +8 -0
  643. package/dist/stock/web/Replenishment.js +84 -0
  644. package/dist/stock/web/ReturnButton.d.ts +7 -0
  645. package/dist/stock/web/ReturnButton.js +62 -0
  646. package/dist/stock/web/index.d.ts +7 -2
  647. package/dist/stock/web/index.js +15 -2
  648. package/dist/stock/web/messages.js +206 -0
  649. package/dist/stock_account/.kosh/bindings.js +1 -1
  650. package/dist/stock_account/.kosh/schema.d.ts +878 -12
  651. package/dist/stock_account/i18n/bn.d.ts +2 -0
  652. package/dist/stock_account/i18n/bn.js +73 -0
  653. package/dist/stock_account/index.d.ts +1 -0
  654. package/dist/stock_account/index.js +141 -3
  655. package/dist/stock_account/landed.d.ts +429 -0
  656. package/dist/stock_account/landed.js +335 -0
  657. package/dist/stock_account/module.d.ts +12143 -3391
  658. package/dist/stock_account/module.js +135 -6
  659. package/dist/stock_account/web/LandedPreview.d.ts +7 -0
  660. package/dist/stock_account/web/LandedPreview.js +23 -0
  661. package/dist/stock_account/web/index.d.ts +11 -0
  662. package/dist/stock_account/web/index.js +16 -0
  663. package/dist/stock_account/web/messages.d.ts +2 -0
  664. package/dist/stock_account/web/messages.js +27 -0
  665. package/dist/todo/i18n/bn.d.ts +2 -0
  666. package/dist/todo/i18n/bn.js +66 -0
  667. package/dist/todo/index.js +59 -0
  668. package/dist/todo/module.d.ts +5 -0
  669. package/dist/todo/module.js +5 -3
  670. package/dist/trade_finance/.kosh/bindings.js +1 -1
  671. package/dist/trade_finance/.kosh/schema.d.ts +2 -1
  672. package/dist/trade_finance/i18n/bn.d.ts +2 -0
  673. package/dist/trade_finance/i18n/bn.js +162 -0
  674. package/dist/trade_finance/index.js +95 -0
  675. package/dist/trade_finance/module.d.ts +26 -0
  676. package/dist/trade_finance/module.js +29 -8
  677. package/dist/trade_finance_account/.kosh/bindings.js +1 -1
  678. package/dist/trade_finance_account/.kosh/schema.d.ts +651 -10
  679. package/dist/trade_finance_account/i18n/bn.d.ts +2 -0
  680. package/dist/trade_finance_account/i18n/bn.js +27 -0
  681. package/dist/trade_finance_account/index.js +3 -0
  682. package/dist/trade_finance_account/module.d.ts +5129 -1509
  683. package/dist/trade_finance_account/module.js +2 -0
  684. package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
  685. package/dist/trade_finance_purchase/.kosh/schema.d.ts +908 -5
  686. package/dist/trade_finance_purchase/i18n/bn.d.ts +2 -0
  687. package/dist/trade_finance_purchase/i18n/bn.js +6 -0
  688. package/dist/trade_finance_purchase/index.js +2 -0
  689. package/dist/trade_finance_purchase/module.d.ts +6909 -408
  690. package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
  691. package/dist/trade_finance_sale/.kosh/schema.d.ts +292 -4
  692. package/dist/trade_finance_sale/i18n/bn.d.ts +2 -0
  693. package/dist/trade_finance_sale/i18n/bn.js +6 -0
  694. package/dist/trade_finance_sale/index.js +2 -0
  695. package/dist/trade_finance_sale/module.d.ts +2602 -331
  696. package/dist/ui/api.d.ts +2 -0
  697. package/dist/ui/app.d.ts +9 -0
  698. package/dist/ui/app.js +47 -15
  699. package/dist/ui/components/AppIcon.js +9 -2
  700. package/dist/ui/components/Explain.d.ts +69 -0
  701. package/dist/ui/components/Explain.js +62 -0
  702. package/dist/ui/context.d.ts +8 -1
  703. package/dist/ui/context.js +34 -1
  704. package/dist/ui/i18n/messages.d.ts +40 -0
  705. package/dist/ui/i18n/messages.js +80 -0
  706. package/dist/ui/index.d.ts +2 -1
  707. package/dist/ui/index.js +1 -0
  708. package/dist/ui/registry.d.ts +14 -0
  709. package/dist/ui/registry.js +10 -0
  710. package/dist/ui/views/FormView.d.ts +6 -0
  711. package/dist/ui/views/FormView.js +51 -12
  712. package/dist/ui/views/KanbanView.js +9 -1
  713. package/dist/ui/views/ListView.d.ts +8 -0
  714. package/dist/ui/views/ListView.js +14 -5
  715. package/dist/ui/views/StatsRow.js +2 -1
  716. package/dist/ui/views/widgets.js +7 -1
  717. package/dist/views/extend.js +12 -0
  718. package/dist/views/types.d.ts +13 -2
  719. package/dist/views/validate.js +8 -1
  720. package/dist/website/.kosh/bindings.js +1 -1
  721. package/dist/website/.kosh/schema.d.ts +2 -1
  722. package/dist/website/i18n/bn.d.ts +2 -0
  723. package/dist/website/i18n/bn.js +113 -0
  724. package/dist/website/index.js +37 -0
  725. package/dist/website/module.d.ts +20 -0
  726. package/dist/website/module.js +30 -5
  727. package/dist/website_crm/.kosh/bindings.js +1 -1
  728. package/dist/website_crm/.kosh/schema.d.ts +3 -1
  729. package/dist/website_crm/i18n/bn.d.ts +2 -0
  730. package/dist/website_crm/i18n/bn.js +5 -0
  731. package/dist/website_crm/index.js +2 -0
  732. package/dist/website_crm/module.d.ts +41 -0
  733. package/dist/website_sale/.kosh/bindings.d.ts +22 -0
  734. package/dist/website_sale/.kosh/bindings.js +15 -0
  735. package/dist/website_sale/.kosh/schema.d.ts +2909 -0
  736. package/dist/website_sale/couriers.d.ts +50 -0
  737. package/dist/website_sale/couriers.js +59 -0
  738. package/dist/website_sale/demo.d.ts +7 -0
  739. package/dist/website_sale/demo.js +90 -0
  740. package/dist/website_sale/growth.d.ts +31 -0
  741. package/dist/website_sale/growth.js +163 -0
  742. package/dist/website_sale/i18n/bn.d.ts +2 -0
  743. package/dist/website_sale/i18n/bn.js +132 -0
  744. package/dist/website_sale/index.d.ts +49 -0
  745. package/dist/website_sale/index.js +620 -0
  746. package/dist/website_sale/module.d.ts +35182 -0
  747. package/dist/website_sale/module.js +419 -0
  748. package/dist/website_sale/shipments.d.ts +16 -0
  749. package/dist/website_sale/shipments.js +113 -0
  750. package/dist/website_sale/shop.d.ts +81 -0
  751. package/dist/website_sale/shop.js +662 -0
  752. package/dist/website_sale_stock/.kosh/bindings.d.ts +22 -0
  753. package/dist/website_sale_stock/.kosh/bindings.js +15 -0
  754. package/dist/website_sale_stock/.kosh/schema.d.ts +3400 -0
  755. package/dist/website_sale_stock/i18n/bn.d.ts +2 -0
  756. package/dist/website_sale_stock/i18n/bn.js +4 -0
  757. package/dist/website_sale_stock/index.d.ts +9 -0
  758. package/dist/website_sale_stock/index.js +22 -0
  759. package/dist/website_sale_stock/module.d.ts +11 -0
  760. package/dist/website_sale_stock/module.js +32 -0
  761. package/package.json +117 -8
  762. package/dist/mrp/index.d.ts +0 -3
  763. package/dist/mrp/index.js +0 -392
  764. package/dist/mrp/module.js +0 -695
  765. package/dist/mrp_account/index.d.ts +0 -3
  766. package/dist/mrp_account/index.js +0 -22
  767. /package/dist/{mrp → account_asset}/.kosh/bindings.d.ts +0 -0
  768. /package/dist/{mrp_account → account_budget}/.kosh/bindings.d.ts +0 -0
@@ -0,0 +1,662 @@
1
+ /**
2
+ * The Shop's logic (RFC 0024 §2.7), run as the system in the site's company once the public routes know the site:
3
+ * the catalogue (published products in the visitor's language), carts (a quotation per secret token, its lines priced
4
+ * by the server from the product — never by the visitor), delivery methods with their fee for the cart, and checkout —
5
+ * the customer found by email or made, cash on delivery confirmed (or left for someone to confirm above the site's
6
+ * limit), or an online payment started whose confirmation confirms, invoices and pays the order.
7
+ */
8
+ import { startPayment } from '../payment/index.js';
9
+ import { HttpProblem } from '../server/index.js';
10
+ import { orm } from '../server/orm.js';
11
+ import { feeOf, hashToken, newCartToken } from './module.js';
12
+ const zero = orm.toDecimal(0);
13
+ const LANGS = { en: 'en_US', bn: 'bn_BD' };
14
+ const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15
+ /** At most this many of one product in a cart, and this many lines. */
16
+ const MAX_QUANTITY = orm.toDecimal(1000);
17
+ const MAX_LINES = 100;
18
+ const invalid = (field, detail) => new HttpProblem(422, 'invalid-input', `Invalid ${field}`, detail);
19
+ const money = (d) => (d ?? zero).toDecimalPlaces(2).toFixed(2);
20
+ /** The environment reading in the visitor's language. */
21
+ export const inLang = (env, lang) => env.withLang(LANGS[lang] ?? 'en_US');
22
+ /** Published products on sale, searched, filtered, sorted and paged. */
23
+ export async function catalogue(env, query, site) {
24
+ const size = Math.min(Math.max(query.size ?? 24, 1), 60);
25
+ const page = Math.max(query.page ?? 1, 1);
26
+ const where = { published: true, saleOk: true };
27
+ if (query.q !== undefined && query.q.trim() !== '') {
28
+ const q = query.q.trim().slice(0, 100);
29
+ where['or'] = [{ name: { ilike: `%${q}%` } }, { code: { ilike: `%${q}%` } }];
30
+ }
31
+ if (query.category !== undefined) {
32
+ // The category and those inside it.
33
+ const inside = new Set([query.category]);
34
+ let next = [query.category];
35
+ while (next.length > 0 && inside.size < 500) {
36
+ next = (await env.model('product.category').search({ where: { parent: { in: next } } })).ids.filter((c) => !inside.has(c));
37
+ for (const c of next)
38
+ inside.add(c);
39
+ }
40
+ where['category'] = { in: [...inside] };
41
+ }
42
+ if (query.min !== undefined || query.max !== undefined)
43
+ where['listPrice'] = {
44
+ ...(query.min === undefined ? {} : { gte: query.min.toString() }),
45
+ ...(query.max === undefined ? {} : { lte: query.max.toString() }),
46
+ };
47
+ const order = query.sort === 'price'
48
+ ? ['listPrice asc', 'id asc']
49
+ : query.sort === '-price'
50
+ ? ['listPrice desc', 'id asc']
51
+ : query.sort === 'name'
52
+ ? ['name asc', 'id asc']
53
+ : query.sort === 'new'
54
+ ? ['id desc']
55
+ : ['shopSequence asc', 'name asc', 'id asc'];
56
+ const all = await env.model('product.product').search({ where: where });
57
+ const found = await env.model('product.product').search({
58
+ where: where,
59
+ order: order,
60
+ limit: size,
61
+ offset: (page - 1) * size,
62
+ });
63
+ const products = await withAvailability(env, site, [...(await found.load({ category: true, uom: true }))].map(card));
64
+ return { products, total: all.length, page, pages: Math.max(Math.ceil(all.length / size), 1) };
65
+ }
66
+ // biome-ignore lint/suspicious/noExplicitAny: a loaded product of any load spec
67
+ function card(p) {
68
+ return {
69
+ id: p.id,
70
+ name: p.name,
71
+ code: p.code,
72
+ price: money(p.listPrice),
73
+ category: p.category === null ? null : { id: p.category.id, name: p.category.name },
74
+ unit: p.uom?.name ?? null,
75
+ hasImage: p.image !== null,
76
+ };
77
+ }
78
+ /** A published product's page: its card, description, weight and related products (published ones). */
79
+ /**
80
+ * The cards with what is available, when stock is followed (`website_sale_stock`): in stock, few left (with how
81
+ * many) or out of stock, by the site's "few left" threshold; null when it is not.
82
+ */
83
+ async function withAvailability(env, site, cards) {
84
+ if (cards.length === 0)
85
+ return cards;
86
+ const available = await env
87
+ .model('product.product')
88
+ .browse(cards.map((c) => c['id']))
89
+ .shopAvailable();
90
+ const [s] = site === undefined
91
+ ? []
92
+ : await env
93
+ .model('website.site')
94
+ .browse([site.id])
95
+ .load({});
96
+ const few = orm.toDecimal(s?.fewLeft ?? 5);
97
+ return cards.map((c) => {
98
+ const raw = available.get(c['id']) ?? null;
99
+ if (raw === null)
100
+ return { ...c, availability: null };
101
+ const left = orm.toDecimal(raw);
102
+ return left.lte(0)
103
+ ? { ...c, availability: 'out_of_stock' }
104
+ : left.lte(few)
105
+ ? { ...c, availability: 'few_left', left: left.toString() }
106
+ : { ...c, availability: 'in_stock' };
107
+ });
108
+ }
109
+ export async function productPage(env, id, site) {
110
+ const [p] = await (await env.model('product.product').search({
111
+ where: { id: orm.asId(id, 'product.product'), published: true, saleOk: true },
112
+ limit: 1,
113
+ })).load({ category: true, uom: true, related: true });
114
+ if (p === undefined)
115
+ return null;
116
+ const related = await (await env.model('product.product').search({
117
+ where: {
118
+ id: { in: [...p.related.ids] },
119
+ published: true,
120
+ saleOk: true,
121
+ },
122
+ })).load({ category: true, uom: true });
123
+ const [self] = await withAvailability(env, site, [card(p)]);
124
+ return {
125
+ ...self,
126
+ description: p.websiteDescription,
127
+ seo: {
128
+ title: p.seoTitle ?? p.name,
129
+ description: p.seoDescription ?? (p.websiteDescription ?? '').slice(0, 160),
130
+ },
131
+ weight: p.weight === null ? null : p.weight.toString(),
132
+ related: await withAvailability(env, site, [...related].map(card)),
133
+ };
134
+ }
135
+ /** The product categories that hold published products, with their parents. */
136
+ export async function categories(env) {
137
+ const products = await (await env.model('product.product').search({ where: { published: true, saleOk: true } })).load({ category: true });
138
+ const ids = new Set();
139
+ for (const p of products)
140
+ if (p.category !== null)
141
+ ids.add(p.category.id);
142
+ const out = new Map();
143
+ let next = [...ids];
144
+ while (next.length > 0) {
145
+ const found = await env
146
+ .model('product.category')
147
+ .browse(next)
148
+ .load({ parent: true });
149
+ next = [];
150
+ for (const c of found) {
151
+ out.set(c.id, { id: c.id, name: c.name, parent: c.parent?.id ?? null });
152
+ if (c.parent !== null && !out.has(c.parent.id))
153
+ next.push(c.parent.id);
154
+ }
155
+ }
156
+ return [...out.values()].sort((a, b) => a.name.localeCompare(b.name));
157
+ }
158
+ /** Who carts belong to before checkout: the site's visitor contact, made the first time. */
159
+ async function visitorOf(env, site) {
160
+ const [s] = await env
161
+ .model('website.site')
162
+ .browse([site.id])
163
+ .load({ visitor: true });
164
+ if (s?.visitor !== null && s?.visitor !== undefined)
165
+ return s.visitor.id;
166
+ const made = await env
167
+ .model('res.partner')
168
+ .create([{ name: `${s?.name ?? site.key} — shop visitor`, company: site.company }]);
169
+ const id = made.ids[0];
170
+ await env
171
+ .model('website.site')
172
+ .browse([site.id])
173
+ .write({ visitor: id });
174
+ return id;
175
+ }
176
+ /** Who the site's orders are assigned to: its salesperson, else whoever made the site. */
177
+ async function salespersonOf(env, site) {
178
+ const [s] = await env
179
+ .model('website.site')
180
+ .browse([site.id])
181
+ .load({ salesperson: true });
182
+ return s?.salesperson?.id ?? s?.createdBy ?? null;
183
+ }
184
+ /** A new cart: a quotation of the site's company for its visitor, with a new secret token. */
185
+ export async function newCart(env, site) {
186
+ const token = newCartToken();
187
+ const [company] = await env
188
+ .model('res.company')
189
+ .browse([site.company])
190
+ .load({ currency: true });
191
+ const visitor = await visitorOf(env, site);
192
+ const made = await env.model('sale.order').create([
193
+ {
194
+ partner: visitor,
195
+ // The customer's price list, when they have one (RFC 0028 §3.1).
196
+ pricelist: (await pricelistOf(env, visitor)),
197
+ currency: company?.currency.id,
198
+ company: site.company,
199
+ website: site.id,
200
+ cartToken: hashToken(token),
201
+ user: (await salespersonOf(env, site)),
202
+ },
203
+ ]);
204
+ await env.flush();
205
+ return { token, id: made.ids[0] };
206
+ }
207
+ /** The order of `token` on the site: a cart (not checked out) unless `placed`. */
208
+ export async function orderOf(env, site, token, placed = false) {
209
+ if (token === '' || token.length > 100)
210
+ return null;
211
+ const [id] = (await env.model('sale.order').search({
212
+ where: {
213
+ website: site.id,
214
+ cartToken: hashToken(token),
215
+ ...(placed
216
+ ? { placedAt: { isNull: false } }
217
+ : { placedAt: { isNull: true }, state: 'draft' }),
218
+ },
219
+ limit: 1,
220
+ })).ids;
221
+ return id ?? null;
222
+ }
223
+ /** What the visitor sees of a cart or an order. */
224
+ export async function cartView(env, id) {
225
+ const [o] = await env
226
+ .model('sale.order')
227
+ .browse([id])
228
+ .load({ lines: { product: true }, currency: true, carrier: true, coupon: true });
229
+ if (o === undefined)
230
+ throw new HttpProblem(404, 'not-found', 'Not found', 'There is no cart.');
231
+ const goods = [...o.lines].filter((l) => !l.isDelivery && !l.isDiscount);
232
+ const fee = [...o.lines]
233
+ .filter((l) => l.isDelivery)
234
+ .reduce((s, l) => s.plus((l.priceUnit ?? zero).times(l.quantity)), zero);
235
+ const payments = await (await env.model('payment.transaction').search({
236
+ where: { saleOrder: id },
237
+ order: ['id desc'],
238
+ limit: 1,
239
+ })).load({});
240
+ return {
241
+ name: o.name,
242
+ state: o.state,
243
+ placed: o.placedAt !== null,
244
+ currency: o.currency.name,
245
+ lines: goods.map((l) => ({
246
+ product: l.product.id,
247
+ name: l.name,
248
+ quantity: l.quantity.toString(),
249
+ price: money(l.priceUnit ?? zero),
250
+ subtotal: money((l.priceUnit ?? zero).times(l.quantity)),
251
+ })),
252
+ carrier: o.carrier === null ? null : { id: o.carrier.id, name: o.carrier.name },
253
+ delivery: money(fee),
254
+ untaxed: money(o.amountUntaxed?.amount),
255
+ tax: money(o.amountTax?.amount),
256
+ total: money(o.amountTotal?.amount),
257
+ coupon: o.coupon === null ? null : o.coupon.code,
258
+ discount: money([...o.lines].reduce((s, l) => l.isDiscount
259
+ ? s.minus((l.priceUnit ?? zero).times(l.quantity))
260
+ : s.plus((l.priceUnit ?? zero).times(l.quantity).times(l.discount).div(100)), zero)),
261
+ payment: o.shopPayment,
262
+ paymentState: [...payments][0]?.state ?? null,
263
+ };
264
+ }
265
+ /** A customer's price list (RFC 0028 §3.1), or null. */
266
+ async function pricelistOf(env, partner) {
267
+ if (typeof partner !== 'number')
268
+ return null;
269
+ const [p] = await env
270
+ .model('res.partner')
271
+ .browse([partner])
272
+ .load({ pricelist: true });
273
+ return p?.pricelist?.id ?? null;
274
+ }
275
+ const goodsOf = async (env, id) => {
276
+ const [o] = await env
277
+ .model('sale.order')
278
+ .browse([id])
279
+ .load({ lines: { product: true }, carrier: true, partner: true });
280
+ const goods = [...(o?.lines ?? [])].filter((l) => !l.isDelivery && !l.isDiscount);
281
+ return {
282
+ order: o,
283
+ amount: goods.reduce((s, l) => s.plus((l.priceUnit ?? zero).times(l.quantity)), zero),
284
+ weight: goods.reduce((s, l) => s.plus((l.product.weight ?? zero).times(l.quantity)), zero),
285
+ };
286
+ };
287
+ /** Sets how many of `product` the cart holds (0 removes it), at the product's price; the fee follows. */
288
+ export async function setLine(env, id, product, quantity) {
289
+ if (quantity.lt(0) || quantity.gt(MAX_QUANTITY))
290
+ throw invalid('quantity', `From 0 to ${MAX_QUANTITY.toString()}.`);
291
+ const [p] = await (await env.model('product.product').search({
292
+ where: { id: orm.asId(product, 'product.product'), published: true, saleOk: true },
293
+ limit: 1,
294
+ })).load({ taxes: true, uom: true });
295
+ if (p === undefined)
296
+ throw invalid('product', 'This product is not on the shop.');
297
+ // Beyond what is available, unless the site sells beyond stock.
298
+ const [cart] = await env.model('sale.order').browse([id]).load({ website: true });
299
+ if (cart?.website !== null && cart?.website !== undefined && !cart.website.allowBackorders) {
300
+ const raw = (await env.model('product.product').browse([p.id]).shopAvailable()).get(p.id);
301
+ if (raw !== null && raw !== undefined && quantity.gt(orm.toDecimal(raw)))
302
+ throw invalid('quantity', orm.toDecimal(raw).lte(0)
303
+ ? `${p.name} is out of stock.`
304
+ : `Only ${orm.toDecimal(raw).toString()} of ${p.name} left.`);
305
+ }
306
+ const lines = await (await env
307
+ .model('sale.order.line')
308
+ .search({ where: { order: id, isDelivery: false, isDiscount: false } })).load({ product: true });
309
+ const line = [...lines].find((l) => l.product.id === p.id);
310
+ if (line !== undefined) {
311
+ if (quantity.isZero())
312
+ await env.model('sale.order.line').browse([line.id]).unlink();
313
+ else
314
+ await env.model('sale.order.line').browse([line.id]).write({ quantity });
315
+ }
316
+ else if (!quantity.isZero()) {
317
+ if (lines.length >= MAX_LINES)
318
+ throw invalid('cart', `At most ${MAX_LINES} products.`);
319
+ await env.model('sale.order.line').create([
320
+ {
321
+ order: id,
322
+ product: p.id,
323
+ name: p.name,
324
+ quantity,
325
+ uom: p.uom?.id ?? null,
326
+ // Priced by the cart's price list (the customer's), else at the list price (RFC 0028 §3.1).
327
+ taxes: { set: [...p.taxes.ids] },
328
+ },
329
+ ]);
330
+ }
331
+ await env.flush();
332
+ await reprice(env, id);
333
+ }
334
+ /** The cart's fee and coupon again, after a change. */
335
+ async function reprice(env, id, city) {
336
+ const [o] = await env.model('sale.order').browse([id]).load({ carrier: true, partner: true });
337
+ if (o?.carrier !== null && o?.carrier !== undefined)
338
+ await setDelivery(env, id, o.carrier.id, city === undefined ? o.partner.city : city);
339
+ else
340
+ await refreshCoupon(env, id);
341
+ }
342
+ const day = (v) => v === null || v === undefined
343
+ ? null
344
+ : v instanceof Date
345
+ ? `${v.getFullYear()}-${String(v.getMonth() + 1).padStart(2, '0')}-${String(v.getDate()).padStart(2, '0')}`
346
+ : String(v).slice(0, 10);
347
+ /** Why `coupon` does not apply to goods worth `amount` today (null: it applies). */
348
+ function couponProblem(env, coupon, amount) {
349
+ const today = env.today();
350
+ const from = day(coupon.validFrom);
351
+ const to = day(coupon.validTo);
352
+ if (from !== null && today < from)
353
+ return `The coupon ${coupon.code} starts on ${from}.`;
354
+ if (to !== null && today > to)
355
+ return `The coupon ${coupon.code} ended on ${to}.`;
356
+ if (coupon.maxUses !== null && coupon.uses >= coupon.maxUses)
357
+ return `The coupon ${coupon.code} has been used up.`;
358
+ if (amount.lt(coupon.minimum))
359
+ return `The coupon ${coupon.code} is for orders of ${money(coupon.minimum)} or more.`;
360
+ return null;
361
+ }
362
+ /**
363
+ * Applies the cart's coupon: a percentage off each goods line, or an amount off as a line of its own (never more than
364
+ * the goods), or the delivery fee (`setDelivery`); a coupon that no longer applies (the cart fell below its minimum)
365
+ * is taken off.
366
+ */
367
+ async function refreshCoupon(env, id) {
368
+ const [o] = await env.model('sale.order').browse([id]).load({ coupon: true, lines: true });
369
+ if (o === undefined)
370
+ return;
371
+ const goods = [...o.lines].filter((l) => !l.isDelivery && !l.isDiscount);
372
+ const amount = goods.reduce((s, l) => s.plus((l.priceUnit ?? zero).times(l.quantity)), zero);
373
+ let coupon = o.coupon;
374
+ if (coupon !== null && couponProblem(env, coupon, amount) !== null) {
375
+ await env.model('sale.order').browse([id]).write({ coupon: null });
376
+ coupon = null;
377
+ }
378
+ const percent = coupon?.kind === 'percent' ? coupon.value : zero;
379
+ for (const l of goods)
380
+ if (!l.discount.eq(percent))
381
+ await env.model('sale.order.line').browse([l.id]).write({ discount: percent });
382
+ const old = await env.model('sale.order.line').search({ where: { order: id, isDiscount: true } });
383
+ if (old.length > 0)
384
+ await old.unlink();
385
+ if (coupon?.kind === 'amount' && coupon.value.gt(0) && amount.gt(0)) {
386
+ const off = coupon.value.lt(amount) ? coupon.value : amount;
387
+ await env.model('sale.order.line').create([
388
+ {
389
+ order: id,
390
+ product: await discountProduct(env, coupon.id),
391
+ name: `Coupon ${coupon.code}`,
392
+ quantity: '1',
393
+ priceUnit: off.negated(),
394
+ isDiscount: true,
395
+ },
396
+ ]);
397
+ }
398
+ await env.flush();
399
+ }
400
+ /** The service product an amount off is charged as, made the first time. */
401
+ async function discountProduct(env, coupon) {
402
+ const [c] = await env
403
+ .model('shop.coupon')
404
+ .browse([coupon])
405
+ .load({ product: true });
406
+ if (c?.product !== null && c?.product !== undefined)
407
+ return c.product.id;
408
+ const made = await env
409
+ .model('product.product')
410
+ .create([
411
+ { name: `Coupon ${c?.code ?? ''}`, kind: 'service', saleOk: false, purchaseOk: false },
412
+ ]);
413
+ const product = made.ids[0];
414
+ await env
415
+ .model('shop.coupon')
416
+ .browse([coupon])
417
+ .write({ product: product });
418
+ return product;
419
+ }
420
+ /** Puts a coupon on the cart (an empty code takes it off). @throws 422 with why it does not apply */
421
+ export async function setCoupon(env, site, id, code) {
422
+ const clean = code.trim().toUpperCase();
423
+ if (clean === '') {
424
+ await env.model('sale.order').browse([id]).write({ coupon: null });
425
+ await reprice(env, id);
426
+ return;
427
+ }
428
+ const [coupon] = await (await env.model('shop.coupon').search({
429
+ where: { code: clean.slice(0, 40), company: site.company },
430
+ limit: 1,
431
+ })).load({});
432
+ if (coupon === undefined)
433
+ throw invalid('coupon', `There is no coupon ${clean}.`);
434
+ const { amount } = await goodsOf(env, id);
435
+ const problem = couponProblem(env, coupon, amount);
436
+ if (problem !== null)
437
+ throw invalid('coupon', problem);
438
+ await env.model('sale.order').browse([id]).write({ coupon: coupon.id });
439
+ await reprice(env, id);
440
+ }
441
+ /** At checkout: the coupon still applies, and once per customer means once for this email. */
442
+ async function checkCouponAtCheckout(env, site, id, email) {
443
+ const [o] = await env.model('sale.order').browse([id]).load({ coupon: true });
444
+ const coupon = o?.coupon;
445
+ if (coupon === null || coupon === undefined)
446
+ return null;
447
+ const { amount } = await goodsOf(env, id);
448
+ const problem = couponProblem(env, coupon, amount);
449
+ if (problem !== null)
450
+ throw invalid('coupon', problem);
451
+ if (coupon.oncePerCustomer) {
452
+ const before = await env.model('sale.order').search({
453
+ where: {
454
+ coupon: coupon.id,
455
+ website: site.id,
456
+ placedAt: { isNull: false },
457
+ state: { ne: 'cancel' },
458
+ 'partner.email': email,
459
+ },
460
+ limit: 1,
461
+ });
462
+ if (before.length > 0)
463
+ throw invalid('coupon', `The coupon ${coupon.code} is once per customer: it was used already.`);
464
+ }
465
+ return coupon.id;
466
+ }
467
+ /** The company's delivery methods with their fee for the cart, delivered to `city`. */
468
+ export async function carriersFor(env, id, city) {
469
+ const { amount, weight, order } = await goodsOf(env, id);
470
+ const found = await (await env.model('delivery.carrier').search({
471
+ where: { company: order?.company.id },
472
+ })).load({});
473
+ return [...found].map((c) => ({
474
+ id: c.id,
475
+ name: c.name,
476
+ fee: money(feeOf(c, amount, weight, city)),
477
+ cod: c.cod,
478
+ description: c.description,
479
+ }));
480
+ }
481
+ /** The fee's service product of a method, made the first time. */
482
+ async function feeProduct(env, carrier) {
483
+ const [c] = await env
484
+ .model('delivery.carrier')
485
+ .browse([carrier])
486
+ .load({ product: true });
487
+ if (c?.product !== null && c?.product !== undefined)
488
+ return c.product.id;
489
+ const made = await env
490
+ .model('product.product')
491
+ .create([
492
+ { name: `Delivery: ${c?.name ?? ''}`, kind: 'service', saleOk: false, purchaseOk: false },
493
+ ]);
494
+ const product = made.ids[0];
495
+ await env
496
+ .model('delivery.carrier')
497
+ .browse([carrier])
498
+ .write({ product: product });
499
+ return product;
500
+ }
501
+ /** Chooses the delivery method: its fee, for the cart and `city`, replaces the cart's fee line. */
502
+ export async function setDelivery(env, id, carrier, city) {
503
+ const { amount, weight, order } = await goodsOf(env, id);
504
+ const [c] = await (await env.model('delivery.carrier').search({
505
+ where: { id: carrier, company: order?.company.id },
506
+ limit: 1,
507
+ })).load({});
508
+ if (c === undefined)
509
+ throw invalid('delivery method', 'Choose one of the methods offered.');
510
+ const [withCoupon] = await env.model('sale.order').browse([id]).load({ coupon: true });
511
+ const free = withCoupon?.coupon?.kind === 'free_delivery' &&
512
+ couponProblem(env, withCoupon.coupon, amount) === null;
513
+ const fee = free ? zero : feeOf(c, amount, weight, city);
514
+ const old = await env.model('sale.order.line').search({ where: { order: id, isDelivery: true } });
515
+ if (old.length > 0)
516
+ await old.unlink();
517
+ await env.model('sale.order.line').create([
518
+ {
519
+ order: id,
520
+ product: await feeProduct(env, c.id),
521
+ name: c.name,
522
+ quantity: '1',
523
+ priceUnit: fee,
524
+ isDelivery: true,
525
+ },
526
+ ]);
527
+ await env.model('sale.order').browse([id]).write({ carrier: c.id });
528
+ await env.flush();
529
+ await refreshCoupon(env, id);
530
+ }
531
+ const text = (v, field, max, required = true) => {
532
+ const s = typeof v === 'string' ? v.trim() : '';
533
+ if (required && s === '')
534
+ throw invalid(field, 'is required.');
535
+ if (s.length > max)
536
+ throw invalid(field, `is at most ${max} characters.`);
537
+ return s;
538
+ };
539
+ /** Reads and checks a checkout's input. */
540
+ export function checkoutInput(body) {
541
+ const b = (body ?? {});
542
+ const email = text(b['email'], 'email', 200);
543
+ if (!EMAIL.test(email))
544
+ throw invalid('email', 'is an email address.');
545
+ const returnUrl = text(b['returnUrl'], 'return address', 500, false);
546
+ if (returnUrl !== '' && !/^https?:\/\/[^\s]+$/i.test(returnUrl))
547
+ throw invalid('return address', 'is an http(s) address.');
548
+ const carrier = Number(b['carrier']);
549
+ if (!Number.isSafeInteger(carrier) || carrier <= 0)
550
+ throw invalid('delivery method', 'Choose one of the methods offered.');
551
+ return {
552
+ name: text(b['name'], 'name', 120),
553
+ email,
554
+ phone: text(b['phone'], 'phone', 30),
555
+ street: text(b['street'], 'address', 200),
556
+ city: text(b['city'], 'city', 80),
557
+ carrier,
558
+ payment: text(b['payment'], 'payment', 20),
559
+ note: text(b['note'], 'note', 1000, false),
560
+ ...(returnUrl === '' ? {} : { returnUrl }),
561
+ };
562
+ }
563
+ /**
564
+ * Places the cart: the customer (found by email in the company, else made), the delivery to their city, the note.
565
+ * Cash on delivery confirms it when the method takes cash and the total is within the site's limit (above it, it
566
+ * stays a quotation for the team to confirm); paying online starts a payment and returns where to send the visitor.
567
+ */
568
+ export async function checkout(env, site, id, input) {
569
+ const lines = await env
570
+ .model('sale.order.line')
571
+ .search({ where: { order: id, isDelivery: false } });
572
+ if (lines.length === 0)
573
+ throw invalid('cart', 'The cart is empty.');
574
+ const [existing] = (await env.model('res.partner').search({
575
+ where: { email: input.email, company: site.company },
576
+ limit: 1,
577
+ })).ids;
578
+ const values = {
579
+ name: input.name,
580
+ email: input.email,
581
+ phone: input.phone,
582
+ street: input.street,
583
+ city: input.city,
584
+ };
585
+ let partner;
586
+ if (existing !== undefined) {
587
+ partner = existing;
588
+ // A known customer's address is not changed by a visitor: the order keeps it in its note.
589
+ }
590
+ else
591
+ partner = (await env.model('res.partner').create([{ ...values, company: site.company }])).ids[0];
592
+ await env
593
+ .model('sale.order')
594
+ .browse([id])
595
+ .write({ partner: partner });
596
+ await setDelivery(env, id, input.carrier, input.city);
597
+ const [c] = await env
598
+ .model('delivery.carrier')
599
+ .browse([input.carrier])
600
+ .load({});
601
+ const deliverTo = `Deliver to: ${input.name}, ${input.phone}, ${input.street}, ${input.city}`;
602
+ const note = [deliverTo, input.note ?? ''].filter((s) => s !== '').join('\n');
603
+ const [s] = await env
604
+ .model('website.site')
605
+ .browse([site.id])
606
+ .load({});
607
+ const order = env.model('sale.order').browse([id]);
608
+ const coupon = await checkCouponAtCheckout(env, site, id, input.email);
609
+ if (coupon !== null) {
610
+ const [c] = await env
611
+ .model('shop.coupon')
612
+ .browse([coupon])
613
+ .load({});
614
+ await env
615
+ .model('shop.coupon')
616
+ .browse([coupon])
617
+ .write({ uses: (c?.uses ?? 0) + 1 });
618
+ }
619
+ if (input.payment === 'cod') {
620
+ if (c?.cod !== true)
621
+ throw invalid('payment', 'This delivery method does not take cash on delivery.');
622
+ await order.write({ shopPayment: 'cod', shopNote: note, placedAt: new Date() });
623
+ await env.flush();
624
+ const [o] = await order.load({});
625
+ if (s?.codLimit === null ||
626
+ s?.codLimit === undefined ||
627
+ (o?.amountTotal?.amount ?? zero).lte(s.codLimit))
628
+ await order.confirm();
629
+ const [placed] = await order.load({});
630
+ return {
631
+ order: placed?.name ?? '',
632
+ state: placed?.state ?? 'draft',
633
+ total: money(placed?.amountTotal?.amount),
634
+ };
635
+ }
636
+ const provider = Number(input.payment);
637
+ if (!Number.isSafeInteger(provider) || provider <= 0)
638
+ throw invalid('payment', 'Cash on delivery, or one of the providers offered.');
639
+ await order.write({ shopPayment: 'online', shopNote: note, placedAt: new Date() });
640
+ await env.flush();
641
+ const [o] = await order.load({ partner: true, currency: true });
642
+ if (o === undefined)
643
+ throw new HttpProblem(404, 'not-found', 'Not found', 'There is no cart.');
644
+ const started = await startPayment(env, {
645
+ provider,
646
+ move: null,
647
+ partner: o.partner,
648
+ currency: o.currency,
649
+ amount: o.amountTotal?.amount ?? zero,
650
+ company: site.company,
651
+ description: `Order ${o.name}`,
652
+ ...(input.returnUrl === undefined ? {} : { returnUrl: input.returnUrl }),
653
+ values: { saleOrder: o.id },
654
+ });
655
+ return {
656
+ order: o.name,
657
+ state: o.state,
658
+ total: money(o.amountTotal?.amount),
659
+ redirectUrl: started.redirectUrl,
660
+ reference: started.reference,
661
+ };
662
+ }
@@ -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'];