@ketvietlab/ketsuite 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2615) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +15 -1
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +59 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/deployment.d.ts +5 -0
  8. package/dist/deployment.d.ts.map +1 -0
  9. package/dist/deployment.js +155 -0
  10. package/dist/deployment.js.map +1 -0
  11. package/dist/development.d.ts +8 -0
  12. package/dist/development.d.ts.map +1 -0
  13. package/dist/development.js +40 -0
  14. package/dist/development.js.map +1 -0
  15. package/dist/index.d.ts +84 -6
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +72 -6
  18. package/dist/index.js.map +1 -1
  19. package/dist/modules/account/analytics.d.ts +32 -0
  20. package/dist/modules/account/analytics.d.ts.map +1 -0
  21. package/dist/modules/account/analytics.js +457 -0
  22. package/dist/modules/account/analytics.js.map +1 -0
  23. package/dist/modules/account/assets-costing.d.ts +4 -0
  24. package/dist/modules/account/assets-costing.d.ts.map +1 -0
  25. package/dist/modules/account/assets-costing.js +1134 -0
  26. package/dist/modules/account/assets-costing.js.map +1 -0
  27. package/dist/modules/account/audit.d.ts +3 -0
  28. package/dist/modules/account/audit.d.ts.map +1 -0
  29. package/dist/modules/account/audit.js +14 -0
  30. package/dist/modules/account/audit.js.map +1 -0
  31. package/dist/modules/account/books.d.ts +4 -0
  32. package/dist/modules/account/books.d.ts.map +1 -0
  33. package/dist/modules/account/books.js +150 -0
  34. package/dist/modules/account/books.js.map +1 -0
  35. package/dist/modules/account/cash-receivables.d.ts +3 -0
  36. package/dist/modules/account/cash-receivables.d.ts.map +1 -0
  37. package/dist/modules/account/cash-receivables.js +1087 -0
  38. package/dist/modules/account/cash-receivables.js.map +1 -0
  39. package/dist/modules/account/close.d.ts +4 -0
  40. package/dist/modules/account/close.d.ts.map +1 -0
  41. package/dist/modules/account/close.js +343 -0
  42. package/dist/modules/account/close.js.map +1 -0
  43. package/dist/modules/account/date.d.ts +21 -0
  44. package/dist/modules/account/date.d.ts.map +1 -0
  45. package/dist/modules/account/date.js +70 -0
  46. package/dist/modules/account/date.js.map +1 -0
  47. package/dist/modules/account/functions.d.ts +131 -3
  48. package/dist/modules/account/functions.d.ts.map +1 -1
  49. package/dist/modules/account/functions.js +2570 -389
  50. package/dist/modules/account/functions.js.map +1 -1
  51. package/dist/modules/account/index.d.ts +1 -2
  52. package/dist/modules/account/index.d.ts.map +1 -1
  53. package/dist/modules/account/index.js +403 -8
  54. package/dist/modules/account/index.js.map +1 -1
  55. package/dist/modules/account/models.d.ts.map +1 -1
  56. package/dist/modules/account/models.js +748 -0
  57. package/dist/modules/account/models.js.map +1 -1
  58. package/dist/modules/account/money.d.ts +60 -0
  59. package/dist/modules/account/money.d.ts.map +1 -0
  60. package/dist/modules/account/money.js +237 -0
  61. package/dist/modules/account/money.js.map +1 -0
  62. package/dist/modules/account/open-items.d.ts +3 -0
  63. package/dist/modules/account/open-items.d.ts.map +1 -0
  64. package/dist/modules/account/open-items.js +390 -0
  65. package/dist/modules/account/open-items.js.map +1 -0
  66. package/dist/modules/account/opening.d.ts +3 -0
  67. package/dist/modules/account/opening.d.ts.map +1 -0
  68. package/dist/modules/account/opening.js +323 -0
  69. package/dist/modules/account/opening.js.map +1 -0
  70. package/dist/modules/account/period.d.ts +21 -0
  71. package/dist/modules/account/period.d.ts.map +1 -0
  72. package/dist/modules/account/period.js +155 -0
  73. package/dist/modules/account/period.js.map +1 -0
  74. package/dist/modules/account/relations.d.ts.map +1 -1
  75. package/dist/modules/account/relations.js +46 -0
  76. package/dist/modules/account/relations.js.map +1 -1
  77. package/dist/modules/account/reports.d.ts +4 -0
  78. package/dist/modules/account/reports.d.ts.map +1 -0
  79. package/dist/modules/account/reports.js +125 -0
  80. package/dist/modules/account/reports.js.map +1 -0
  81. package/dist/modules/account/setup.d.ts +3 -1
  82. package/dist/modules/account/setup.d.ts.map +1 -1
  83. package/dist/modules/account/setup.js +45 -160
  84. package/dist/modules/account/setup.js.map +1 -1
  85. package/dist/modules/account_activity_backend/index.d.ts.map +1 -1
  86. package/dist/modules/account_activity_backend/index.js +0 -1
  87. package/dist/modules/account_activity_backend/index.js.map +1 -1
  88. package/dist/modules/account_backend/index.js +3339 -494
  89. package/dist/modules/account_backend/index.js.map +1 -1
  90. package/dist/modules/account_backend/overview.d.ts +92 -0
  91. package/dist/modules/account_backend/overview.d.ts.map +1 -0
  92. package/dist/modules/account_backend/overview.js +257 -0
  93. package/dist/modules/account_backend/overview.js.map +1 -0
  94. package/dist/modules/account_backend/relation-control.d.ts +48 -0
  95. package/dist/modules/account_backend/relation-control.d.ts.map +1 -0
  96. package/dist/modules/account_backend/relation-control.js +67 -0
  97. package/dist/modules/account_backend/relation-control.js.map +1 -0
  98. package/dist/modules/account_backend/screens/account-defaults.d.ts +28 -0
  99. package/dist/modules/account_backend/screens/account-defaults.d.ts.map +1 -0
  100. package/dist/modules/account_backend/screens/account-defaults.js +60 -0
  101. package/dist/modules/account_backend/screens/account-defaults.js.map +1 -0
  102. package/dist/modules/account_backend/screens/account-form.d.ts +16 -0
  103. package/dist/modules/account_backend/screens/account-form.d.ts.map +1 -0
  104. package/dist/modules/account_backend/screens/account-form.js +53 -0
  105. package/dist/modules/account_backend/screens/account-form.js.map +1 -0
  106. package/dist/modules/account_backend/screens/accounting-books.d.ts +15 -0
  107. package/dist/modules/account_backend/screens/accounting-books.d.ts.map +1 -0
  108. package/dist/modules/account_backend/screens/accounting-books.js +86 -0
  109. package/dist/modules/account_backend/screens/accounting-books.js.map +1 -0
  110. package/dist/modules/account_backend/screens/accounts-list.d.ts +50 -0
  111. package/dist/modules/account_backend/screens/accounts-list.d.ts.map +1 -0
  112. package/dist/modules/account_backend/screens/accounts-list.js +66 -0
  113. package/dist/modules/account_backend/screens/accounts-list.js.map +1 -0
  114. package/dist/modules/account_backend/screens/customer-invoice-form.d.ts +13 -0
  115. package/dist/modules/account_backend/screens/customer-invoice-form.d.ts.map +1 -0
  116. package/dist/modules/account_backend/screens/customer-invoice-form.js +20 -0
  117. package/dist/modules/account_backend/screens/customer-invoice-form.js.map +1 -0
  118. package/dist/modules/account_backend/screens/customer-invoices-list.d.ts +62 -0
  119. package/dist/modules/account_backend/screens/customer-invoices-list.d.ts.map +1 -0
  120. package/dist/modules/account_backend/screens/customer-invoices-list.js +82 -0
  121. package/dist/modules/account_backend/screens/customer-invoices-list.js.map +1 -0
  122. package/dist/modules/account_backend/screens/general-ledger.d.ts +24 -0
  123. package/dist/modules/account_backend/screens/general-ledger.d.ts.map +1 -0
  124. package/dist/modules/account_backend/screens/general-ledger.js +73 -0
  125. package/dist/modules/account_backend/screens/general-ledger.js.map +1 -0
  126. package/dist/modules/account_backend/screens/index.d.ts +27 -0
  127. package/dist/modules/account_backend/screens/index.d.ts.map +1 -0
  128. package/dist/modules/account_backend/screens/index.js +27 -0
  129. package/dist/modules/account_backend/screens/index.js.map +1 -0
  130. package/dist/modules/account_backend/screens/journal-entries-list.d.ts +48 -0
  131. package/dist/modules/account_backend/screens/journal-entries-list.d.ts.map +1 -0
  132. package/dist/modules/account_backend/screens/journal-entries-list.js +58 -0
  133. package/dist/modules/account_backend/screens/journal-entries-list.js.map +1 -0
  134. package/dist/modules/account_backend/screens/journal-entry-create.d.ts +14 -0
  135. package/dist/modules/account_backend/screens/journal-entry-create.d.ts.map +1 -0
  136. package/dist/modules/account_backend/screens/journal-entry-create.js +41 -0
  137. package/dist/modules/account_backend/screens/journal-entry-create.js.map +1 -0
  138. package/dist/modules/account_backend/screens/journal-form.d.ts +15 -0
  139. package/dist/modules/account_backend/screens/journal-form.d.ts.map +1 -0
  140. package/dist/modules/account_backend/screens/journal-form.js +53 -0
  141. package/dist/modules/account_backend/screens/journal-form.js.map +1 -0
  142. package/dist/modules/account_backend/screens/journals-list.d.ts +51 -0
  143. package/dist/modules/account_backend/screens/journals-list.d.ts.map +1 -0
  144. package/dist/modules/account_backend/screens/journals-list.js +70 -0
  145. package/dist/modules/account_backend/screens/journals-list.js.map +1 -0
  146. package/dist/modules/account_backend/screens/move-detail.d.ts +26 -0
  147. package/dist/modules/account_backend/screens/move-detail.d.ts.map +1 -0
  148. package/dist/modules/account_backend/screens/move-detail.js +130 -0
  149. package/dist/modules/account_backend/screens/move-detail.js.map +1 -0
  150. package/dist/modules/account_backend/screens/opening-balances.d.ts +28 -0
  151. package/dist/modules/account_backend/screens/opening-balances.d.ts.map +1 -0
  152. package/dist/modules/account_backend/screens/opening-balances.js +96 -0
  153. package/dist/modules/account_backend/screens/opening-balances.js.map +1 -0
  154. package/dist/modules/account_backend/screens/overview.d.ts +62 -0
  155. package/dist/modules/account_backend/screens/overview.d.ts.map +1 -0
  156. package/dist/modules/account_backend/screens/overview.js +215 -0
  157. package/dist/modules/account_backend/screens/overview.js.map +1 -0
  158. package/dist/modules/account_backend/screens/partner-statement.d.ts +26 -0
  159. package/dist/modules/account_backend/screens/partner-statement.d.ts.map +1 -0
  160. package/dist/modules/account_backend/screens/partner-statement.js +82 -0
  161. package/dist/modules/account_backend/screens/partner-statement.js.map +1 -0
  162. package/dist/modules/account_backend/screens/payment-form.d.ts +14 -0
  163. package/dist/modules/account_backend/screens/payment-form.d.ts.map +1 -0
  164. package/dist/modules/account_backend/screens/payment-form.js +21 -0
  165. package/dist/modules/account_backend/screens/payment-form.js.map +1 -0
  166. package/dist/modules/account_backend/screens/payment-term-form.d.ts +25 -0
  167. package/dist/modules/account_backend/screens/payment-term-form.d.ts.map +1 -0
  168. package/dist/modules/account_backend/screens/payment-term-form.js +96 -0
  169. package/dist/modules/account_backend/screens/payment-term-form.js.map +1 -0
  170. package/dist/modules/account_backend/screens/payment-terms-list.d.ts +23 -0
  171. package/dist/modules/account_backend/screens/payment-terms-list.d.ts.map +1 -0
  172. package/dist/modules/account_backend/screens/payment-terms-list.js +104 -0
  173. package/dist/modules/account_backend/screens/payment-terms-list.js.map +1 -0
  174. package/dist/modules/account_backend/screens/payments-list.d.ts +62 -0
  175. package/dist/modules/account_backend/screens/payments-list.d.ts.map +1 -0
  176. package/dist/modules/account_backend/screens/payments-list.js +71 -0
  177. package/dist/modules/account_backend/screens/payments-list.js.map +1 -0
  178. package/dist/modules/account_backend/screens/period-closes.d.ts +21 -0
  179. package/dist/modules/account_backend/screens/period-closes.d.ts.map +1 -0
  180. package/dist/modules/account_backend/screens/period-closes.js +123 -0
  181. package/dist/modules/account_backend/screens/period-closes.js.map +1 -0
  182. package/dist/modules/account_backend/screens/shared.d.ts +16 -0
  183. package/dist/modules/account_backend/screens/shared.d.ts.map +1 -0
  184. package/dist/modules/account_backend/screens/shared.js +15 -0
  185. package/dist/modules/account_backend/screens/shared.js.map +1 -0
  186. package/dist/modules/account_backend/screens/tax-form.d.ts +14 -0
  187. package/dist/modules/account_backend/screens/tax-form.d.ts.map +1 -0
  188. package/dist/modules/account_backend/screens/tax-form.js +25 -0
  189. package/dist/modules/account_backend/screens/tax-form.js.map +1 -0
  190. package/dist/modules/account_backend/screens/taxes-list.d.ts +55 -0
  191. package/dist/modules/account_backend/screens/taxes-list.d.ts.map +1 -0
  192. package/dist/modules/account_backend/screens/taxes-list.js +83 -0
  193. package/dist/modules/account_backend/screens/taxes-list.js.map +1 -0
  194. package/dist/modules/account_backend/screens/trial-balance.d.ts +19 -0
  195. package/dist/modules/account_backend/screens/trial-balance.d.ts.map +1 -0
  196. package/dist/modules/account_backend/screens/trial-balance.js +75 -0
  197. package/dist/modules/account_backend/screens/trial-balance.js.map +1 -0
  198. package/dist/modules/account_backend/screens/vendor-bill-form.d.ts +13 -0
  199. package/dist/modules/account_backend/screens/vendor-bill-form.d.ts.map +1 -0
  200. package/dist/modules/account_backend/screens/vendor-bill-form.js +20 -0
  201. package/dist/modules/account_backend/screens/vendor-bill-form.js.map +1 -0
  202. package/dist/modules/account_backend/screens/vendor-bills-list.d.ts +62 -0
  203. package/dist/modules/account_backend/screens/vendor-bills-list.d.ts.map +1 -0
  204. package/dist/modules/account_backend/screens/vendor-bills-list.js +84 -0
  205. package/dist/modules/account_backend/screens/vendor-bills-list.js.map +1 -0
  206. package/dist/modules/account_mail_backend/index.d.ts.map +1 -1
  207. package/dist/modules/account_mail_backend/index.js +0 -1
  208. package/dist/modules/account_mail_backend/index.js.map +1 -1
  209. package/dist/modules/account_partner/index.js +0 -2
  210. package/dist/modules/account_partner/index.js.map +1 -1
  211. package/dist/modules/account_partner_backend/index.d.ts +1 -1
  212. package/dist/modules/account_partner_backend/index.d.ts.map +1 -1
  213. package/dist/modules/account_partner_backend/index.js +2 -3
  214. package/dist/modules/account_partner_backend/index.js.map +1 -1
  215. package/dist/modules/account_partner_backend/routes.d.ts.map +1 -1
  216. package/dist/modules/account_partner_backend/routes.js +19 -25
  217. package/dist/modules/account_partner_backend/routes.js.map +1 -1
  218. package/dist/modules/account_partner_backend/screens/accounting-terms.d.ts +20 -0
  219. package/dist/modules/account_partner_backend/screens/accounting-terms.d.ts.map +1 -0
  220. package/dist/modules/account_partner_backend/screens/accounting-terms.js +63 -0
  221. package/dist/modules/account_partner_backend/screens/accounting-terms.js.map +1 -0
  222. package/dist/modules/account_partner_backend/screens/index.d.ts +2 -0
  223. package/dist/modules/account_partner_backend/screens/index.d.ts.map +1 -0
  224. package/dist/modules/account_partner_backend/screens/index.js +2 -0
  225. package/dist/modules/account_partner_backend/screens/index.js.map +1 -0
  226. package/dist/modules/account_staff_channel/channel-routes.d.ts +2 -0
  227. package/dist/modules/account_staff_channel/channel-routes.d.ts.map +1 -0
  228. package/dist/modules/account_staff_channel/channel-routes.js +776 -0
  229. package/dist/modules/account_staff_channel/channel-routes.js.map +1 -0
  230. package/dist/modules/account_staff_channel/functions.d.ts.map +1 -0
  231. package/dist/modules/account_staff_channel/functions.js +143 -0
  232. package/dist/modules/account_staff_channel/functions.js.map +1 -0
  233. package/dist/modules/account_staff_channel/index.d.ts +5 -0
  234. package/dist/modules/account_staff_channel/index.d.ts.map +1 -0
  235. package/dist/modules/account_staff_channel/index.js +42 -0
  236. package/dist/modules/account_staff_channel/index.js.map +1 -0
  237. package/dist/modules/account_staff_channel/models.d.ts.map +1 -0
  238. package/dist/modules/account_staff_channel/models.js +30 -0
  239. package/dist/modules/account_staff_channel/models.js.map +1 -0
  240. package/dist/modules/activity/index.d.ts.map +1 -1
  241. package/dist/modules/activity/index.js +0 -1
  242. package/dist/modules/activity/index.js.map +1 -1
  243. package/dist/modules/activity_backend/index.d.ts +1 -1
  244. package/dist/modules/activity_backend/index.d.ts.map +1 -1
  245. package/dist/modules/activity_backend/index.js +3 -12
  246. package/dist/modules/activity_backend/index.js.map +1 -1
  247. package/dist/modules/activity_backend/routes.d.ts.map +1 -1
  248. package/dist/modules/activity_backend/routes.js +36 -22
  249. package/dist/modules/activity_backend/routes.js.map +1 -1
  250. package/dist/modules/activity_backend/screens/activities-list.d.ts +15 -0
  251. package/dist/modules/activity_backend/screens/activities-list.d.ts.map +1 -0
  252. package/dist/modules/activity_backend/screens/activities-list.js +40 -0
  253. package/dist/modules/activity_backend/screens/activities-list.js.map +1 -0
  254. package/dist/modules/activity_backend/screens/index.d.ts +2 -0
  255. package/dist/modules/activity_backend/screens/index.d.ts.map +1 -0
  256. package/dist/modules/activity_backend/screens/index.js +2 -0
  257. package/dist/modules/activity_backend/screens/index.js.map +1 -0
  258. package/dist/modules/address/data/VN/NOTICE.md +1 -1
  259. package/dist/modules/address/index.d.ts.map +1 -1
  260. package/dist/modules/address/index.js +0 -1
  261. package/dist/modules/address/index.js.map +1 -1
  262. package/dist/modules/address_backend/index.d.ts +1 -1
  263. package/dist/modules/address_backend/index.d.ts.map +1 -1
  264. package/dist/modules/address_backend/index.js +1 -3
  265. package/dist/modules/address_backend/index.js.map +1 -1
  266. package/dist/modules/address_backend/routes.d.ts.map +1 -1
  267. package/dist/modules/address_backend/routes.js +20 -27
  268. package/dist/modules/address_backend/routes.js.map +1 -1
  269. package/dist/modules/address_backend/screens/catalogs-list.d.ts +14 -0
  270. package/dist/modules/address_backend/screens/catalogs-list.d.ts.map +1 -0
  271. package/dist/modules/address_backend/screens/catalogs-list.js +38 -0
  272. package/dist/modules/address_backend/screens/catalogs-list.js.map +1 -0
  273. package/dist/modules/address_backend/screens/country-browser.d.ts +12 -0
  274. package/dist/modules/address_backend/screens/country-browser.d.ts.map +1 -0
  275. package/dist/modules/address_backend/screens/country-browser.js +74 -0
  276. package/dist/modules/address_backend/screens/country-browser.js.map +1 -0
  277. package/dist/modules/address_backend/screens/index.d.ts +4 -0
  278. package/dist/modules/address_backend/screens/index.d.ts.map +1 -0
  279. package/dist/modules/address_backend/screens/index.js +3 -0
  280. package/dist/modules/address_backend/screens/index.js.map +1 -0
  281. package/dist/modules/address_backend/screens/types.d.ts +20 -0
  282. package/dist/modules/address_backend/screens/types.d.ts.map +1 -0
  283. package/dist/modules/address_backend/screens/types.js.map +1 -0
  284. package/dist/modules/attendance/channel-routes.d.ts +2 -0
  285. package/dist/modules/attendance/channel-routes.d.ts.map +1 -0
  286. package/dist/modules/attendance/channel-routes.js +223 -0
  287. package/dist/modules/attendance/channel-routes.js.map +1 -0
  288. package/dist/modules/attendance/functions.d.ts.map +1 -1
  289. package/dist/modules/attendance/functions.js +171 -22
  290. package/dist/modules/attendance/functions.js.map +1 -1
  291. package/dist/modules/attendance/index.d.ts.map +1 -1
  292. package/dist/modules/attendance/index.js +4 -2
  293. package/dist/modules/attendance/index.js.map +1 -1
  294. package/dist/modules/attendance/messages.d.ts +6 -0
  295. package/dist/modules/attendance/messages.d.ts.map +1 -1
  296. package/dist/modules/attendance/messages.js +6 -0
  297. package/dist/modules/attendance/messages.js.map +1 -1
  298. package/dist/modules/attendance/models.d.ts.map +1 -1
  299. package/dist/modules/attendance/models.js +1 -0
  300. package/dist/modules/attendance/models.js.map +1 -1
  301. package/dist/modules/attendance_backend/index.d.ts +3 -1
  302. package/dist/modules/attendance_backend/index.d.ts.map +1 -1
  303. package/dist/modules/attendance_backend/index.js +65 -4
  304. package/dist/modules/attendance_backend/index.js.map +1 -1
  305. package/dist/modules/attendance_backend/routes.d.ts.map +1 -1
  306. package/dist/modules/attendance_backend/routes.js +240 -53
  307. package/dist/modules/attendance_backend/routes.js.map +1 -1
  308. package/dist/modules/attendance_backend/screens/credentials.d.ts +32 -0
  309. package/dist/modules/attendance_backend/screens/credentials.d.ts.map +1 -0
  310. package/dist/modules/attendance_backend/screens/credentials.js +84 -0
  311. package/dist/modules/attendance_backend/screens/credentials.js.map +1 -0
  312. package/dist/modules/attendance_backend/screens/index.d.ts +4 -0
  313. package/dist/modules/attendance_backend/screens/index.d.ts.map +1 -0
  314. package/dist/modules/attendance_backend/screens/index.js +4 -0
  315. package/dist/modules/attendance_backend/screens/index.js.map +1 -0
  316. package/dist/modules/attendance_backend/screens/my-work.d.ts +35 -0
  317. package/dist/modules/attendance_backend/screens/my-work.d.ts.map +1 -0
  318. package/dist/modules/attendance_backend/screens/my-work.js +189 -0
  319. package/dist/modules/attendance_backend/screens/my-work.js.map +1 -0
  320. package/dist/modules/attendance_backend/screens/period.d.ts +22 -0
  321. package/dist/modules/attendance_backend/screens/period.d.ts.map +1 -0
  322. package/dist/modules/attendance_backend/screens/period.js +85 -0
  323. package/dist/modules/attendance_backend/screens/period.js.map +1 -0
  324. package/dist/modules/attendance_backend/screens.d.ts +0 -4
  325. package/dist/modules/attendance_backend/screens.d.ts.map +1 -1
  326. package/dist/modules/attendance_backend/screens.js +1 -209
  327. package/dist/modules/attendance_backend/screens.js.map +1 -1
  328. package/dist/modules/backend/catalogue.d.ts.map +1 -1
  329. package/dist/modules/backend/catalogue.js +53 -115
  330. package/dist/modules/backend/catalogue.js.map +1 -1
  331. package/dist/modules/backend/chart.d.ts +42 -0
  332. package/dist/modules/backend/chart.d.ts.map +1 -0
  333. package/dist/modules/backend/chart.js +39 -0
  334. package/dist/modules/backend/chart.js.map +1 -0
  335. package/dist/modules/backend/design/HANDOFF.md +118 -38
  336. package/dist/modules/backend/design/auth.css +463 -0
  337. package/dist/modules/backend/design/brand/logo-dark.png +0 -0
  338. package/dist/modules/backend/design/brand/logo-light.png +0 -0
  339. package/dist/modules/backend/design/charts.css +229 -0
  340. package/dist/modules/backend/design/client/chart.d.mts +31 -0
  341. package/dist/modules/backend/design/client/chart.d.mts.map +1 -0
  342. package/dist/modules/backend/design/client/chart.mjs +23 -0
  343. package/dist/modules/backend/design/client/chart.mjs.map +7 -0
  344. package/dist/modules/backend/design/client/relation-select.d.mts +6 -1
  345. package/dist/modules/backend/design/client/relation-select.d.mts.map +1 -1
  346. package/dist/modules/backend/design/client/relation-select.mjs +2 -7
  347. package/dist/modules/backend/design/client/relation-select.mjs.map +7 -1
  348. package/dist/modules/backend/design/client/table-selection.d.mts +7 -0
  349. package/dist/modules/backend/design/client/table-selection.d.mts.map +1 -0
  350. package/dist/modules/backend/design/client/table-selection.mjs +2 -0
  351. package/dist/modules/backend/design/client/table-selection.mjs.map +7 -0
  352. package/dist/modules/backend/design/content.css +809 -0
  353. package/dist/modules/backend/design/controls.css +451 -0
  354. package/dist/modules/backend/design/design-system.css +2 -0
  355. package/dist/modules/backend/design/forms.css +1156 -0
  356. package/dist/modules/backend/design/foundation.css +423 -0
  357. package/dist/modules/backend/design/lists.css +1462 -0
  358. package/dist/modules/backend/design/record.css +526 -0
  359. package/dist/modules/backend/design/responsive.css +326 -0
  360. package/dist/modules/backend/design/tokens.css +317 -92
  361. package/dist/modules/backend/forms.d.ts +38 -1
  362. package/dist/modules/backend/forms.d.ts.map +1 -1
  363. package/dist/modules/backend/forms.js +29 -0
  364. package/dist/modules/backend/forms.js.map +1 -1
  365. package/dist/modules/backend/index.d.ts +14 -6
  366. package/dist/modules/backend/index.d.ts.map +1 -1
  367. package/dist/modules/backend/index.js +33 -16
  368. package/dist/modules/backend/index.js.map +1 -1
  369. package/dist/modules/backend/islands.d.ts.map +1 -1
  370. package/dist/modules/backend/islands.js +22 -4
  371. package/dist/modules/backend/islands.js.map +1 -1
  372. package/dist/modules/backend/joints.d.ts +1 -1
  373. package/dist/modules/backend/joints.d.ts.map +1 -1
  374. package/dist/modules/backend/joints.js +14 -6
  375. package/dist/modules/backend/joints.js.map +1 -1
  376. package/dist/modules/backend/list-search.d.ts +33 -0
  377. package/dist/modules/backend/list-search.d.ts.map +1 -0
  378. package/dist/modules/backend/list-search.js +232 -0
  379. package/dist/modules/backend/list-search.js.map +1 -0
  380. package/dist/modules/backend/menus.d.ts.map +1 -1
  381. package/dist/modules/backend/menus.js +3 -12
  382. package/dist/modules/backend/menus.js.map +1 -1
  383. package/dist/modules/backend/messages.d.ts +1 -1
  384. package/dist/modules/backend/messages.d.ts.map +1 -1
  385. package/dist/modules/backend/messages.js +86 -35
  386. package/dist/modules/backend/messages.js.map +1 -1
  387. package/dist/modules/backend/paging.d.ts +1 -1
  388. package/dist/modules/backend/paging.d.ts.map +1 -1
  389. package/dist/modules/backend/paging.js +1 -1
  390. package/dist/modules/backend/paging.js.map +1 -1
  391. package/dist/modules/backend/relation-select.d.ts +2 -57
  392. package/dist/modules/backend/relation-select.d.ts.map +1 -1
  393. package/dist/modules/backend/relation-select.js +2 -0
  394. package/dist/modules/backend/relation-select.js.map +1 -1
  395. package/dist/modules/backend/routes.d.ts +1 -8
  396. package/dist/modules/backend/routes.d.ts.map +1 -1
  397. package/dist/modules/backend/routes.js +36 -111
  398. package/dist/modules/backend/routes.js.map +1 -1
  399. package/dist/modules/backend/screen.d.ts +130 -0
  400. package/dist/modules/backend/screen.d.ts.map +1 -0
  401. package/dist/modules/backend/screen.js +205 -0
  402. package/dist/modules/backend/screen.js.map +1 -0
  403. package/dist/modules/backend/screens.d.ts +11 -14
  404. package/dist/modules/backend/screens.d.ts.map +1 -1
  405. package/dist/modules/backend/screens.js +13 -70
  406. package/dist/modules/backend/screens.js.map +1 -1
  407. package/dist/modules/business_report_staff_channel/channel-routes.d.ts +2 -0
  408. package/dist/modules/business_report_staff_channel/channel-routes.d.ts.map +1 -0
  409. package/dist/modules/business_report_staff_channel/channel-routes.js +438 -0
  410. package/dist/modules/business_report_staff_channel/channel-routes.js.map +1 -0
  411. package/dist/modules/business_report_staff_channel/index.d.ts +5 -0
  412. package/dist/modules/business_report_staff_channel/index.d.ts.map +1 -0
  413. package/dist/modules/business_report_staff_channel/index.js +18 -0
  414. package/dist/modules/business_report_staff_channel/index.js.map +1 -0
  415. package/dist/modules/calendar/index.d.ts.map +1 -1
  416. package/dist/modules/calendar/index.js +0 -1
  417. package/dist/modules/calendar/index.js.map +1 -1
  418. package/dist/modules/calendar/recurrence.d.ts.map +1 -1
  419. package/dist/modules/calendar/recurrence.js +3 -11
  420. package/dist/modules/calendar/recurrence.js.map +1 -1
  421. package/dist/modules/calendar_activity/index.d.ts.map +1 -1
  422. package/dist/modules/calendar_activity/index.js +0 -2
  423. package/dist/modules/calendar_activity/index.js.map +1 -1
  424. package/dist/modules/calendar_backend/index.d.ts +1 -1
  425. package/dist/modules/calendar_backend/index.d.ts.map +1 -1
  426. package/dist/modules/calendar_backend/index.js +1 -3
  427. package/dist/modules/calendar_backend/index.js.map +1 -1
  428. package/dist/modules/calendar_backend/routes.d.ts.map +1 -1
  429. package/dist/modules/calendar_backend/routes.js +10 -22
  430. package/dist/modules/calendar_backend/routes.js.map +1 -1
  431. package/dist/modules/calendar_backend/screens/calendar.d.ts +5 -0
  432. package/dist/modules/calendar_backend/screens/calendar.d.ts.map +1 -0
  433. package/dist/modules/calendar_backend/screens/calendar.js +10 -0
  434. package/dist/modules/calendar_backend/screens/calendar.js.map +1 -0
  435. package/dist/modules/calendar_backend/screens/index.d.ts +2 -0
  436. package/dist/modules/calendar_backend/screens/index.d.ts.map +1 -0
  437. package/dist/modules/calendar_backend/screens/index.js +2 -0
  438. package/dist/modules/calendar_backend/screens/index.js.map +1 -0
  439. package/dist/modules/calendar_mail_transport/index.d.ts.map +1 -1
  440. package/dist/modules/calendar_mail_transport/index.js +0 -2
  441. package/dist/modules/calendar_mail_transport/index.js.map +1 -1
  442. package/dist/modules/channel_api/core.d.ts +283 -0
  443. package/dist/modules/channel_api/core.d.ts.map +1 -0
  444. package/dist/modules/channel_api/core.js +615 -0
  445. package/dist/modules/channel_api/core.js.map +1 -0
  446. package/dist/modules/channel_api/customer.d.ts +21 -0
  447. package/dist/modules/channel_api/customer.d.ts.map +1 -0
  448. package/dist/modules/channel_api/customer.js +368 -0
  449. package/dist/modules/channel_api/customer.js.map +1 -0
  450. package/dist/modules/channel_api/index.d.ts +6 -0
  451. package/dist/modules/channel_api/index.d.ts.map +1 -0
  452. package/dist/modules/channel_api/index.js +66 -0
  453. package/dist/modules/channel_api/index.js.map +1 -0
  454. package/dist/modules/channel_api/openapi.d.ts +17 -0
  455. package/dist/modules/channel_api/openapi.d.ts.map +1 -0
  456. package/dist/modules/channel_api/openapi.js +105 -0
  457. package/dist/modules/channel_api/openapi.js.map +1 -0
  458. package/dist/modules/channel_api/staff.d.ts +7 -0
  459. package/dist/modules/channel_api/staff.d.ts.map +1 -0
  460. package/dist/modules/channel_api/staff.js +209 -0
  461. package/dist/modules/channel_api/staff.js.map +1 -0
  462. package/dist/modules/company/functions.d.ts.map +1 -1
  463. package/dist/modules/company/functions.js +93 -12
  464. package/dist/modules/company/functions.js.map +1 -1
  465. package/dist/modules/company/index.js +3 -3
  466. package/dist/modules/company/index.js.map +1 -1
  467. package/dist/modules/company/messages.d.ts +8 -0
  468. package/dist/modules/company/messages.d.ts.map +1 -1
  469. package/dist/modules/company/messages.js +8 -0
  470. package/dist/modules/company/messages.js.map +1 -1
  471. package/dist/modules/company/models.d.ts +2 -2
  472. package/dist/modules/company/models.d.ts.map +1 -1
  473. package/dist/modules/company/models.js +12 -2
  474. package/dist/modules/company/models.js.map +1 -1
  475. package/dist/modules/company_backend/index.d.ts +2 -1
  476. package/dist/modules/company_backend/index.d.ts.map +1 -1
  477. package/dist/modules/company_backend/index.js +25 -4
  478. package/dist/modules/company_backend/index.js.map +1 -1
  479. package/dist/modules/company_backend/routes.d.ts.map +1 -1
  480. package/dist/modules/company_backend/routes.js +314 -96
  481. package/dist/modules/company_backend/routes.js.map +1 -1
  482. package/dist/modules/company_backend/screens/branch-form.d.ts +18 -0
  483. package/dist/modules/company_backend/screens/branch-form.d.ts.map +1 -0
  484. package/dist/modules/company_backend/screens/branch-form.js +63 -0
  485. package/dist/modules/company_backend/screens/branch-form.js.map +1 -0
  486. package/dist/modules/company_backend/screens/companies-list.d.ts +18 -0
  487. package/dist/modules/company_backend/screens/companies-list.d.ts.map +1 -0
  488. package/dist/modules/company_backend/screens/companies-list.js +49 -0
  489. package/dist/modules/company_backend/screens/companies-list.js.map +1 -0
  490. package/dist/modules/company_backend/screens/company-form.d.ts +25 -0
  491. package/dist/modules/company_backend/screens/company-form.d.ts.map +1 -0
  492. package/dist/modules/company_backend/screens/company-form.js +159 -0
  493. package/dist/modules/company_backend/screens/company-form.js.map +1 -0
  494. package/dist/modules/company_backend/screens/context.d.ts +30 -0
  495. package/dist/modules/company_backend/screens/context.d.ts.map +1 -0
  496. package/dist/modules/company_backend/screens/context.js +48 -0
  497. package/dist/modules/company_backend/screens/context.js.map +1 -0
  498. package/dist/modules/company_backend/screens/hierarchy.d.ts +16 -0
  499. package/dist/modules/company_backend/screens/hierarchy.d.ts.map +1 -0
  500. package/dist/modules/company_backend/screens/hierarchy.js +41 -0
  501. package/dist/modules/company_backend/screens/hierarchy.js.map +1 -0
  502. package/dist/modules/company_backend/screens/index.d.ts +7 -0
  503. package/dist/modules/company_backend/screens/index.d.ts.map +1 -0
  504. package/dist/modules/company_backend/screens/index.js +6 -0
  505. package/dist/modules/company_backend/screens/index.js.map +1 -0
  506. package/dist/modules/company_backend/screens/types.d.ts +22 -0
  507. package/dist/modules/company_backend/screens/types.d.ts.map +1 -0
  508. package/dist/modules/company_backend/screens/types.js +2 -0
  509. package/dist/modules/company_backend/screens/types.js.map +1 -0
  510. package/dist/modules/crm/functions.d.ts +1 -1
  511. package/dist/modules/crm/functions.d.ts.map +1 -1
  512. package/dist/modules/crm/functions.js +534 -75
  513. package/dist/modules/crm/functions.js.map +1 -1
  514. package/dist/modules/crm/index.d.ts +2 -1
  515. package/dist/modules/crm/index.d.ts.map +1 -1
  516. package/dist/modules/crm/index.js +3 -4
  517. package/dist/modules/crm/index.js.map +1 -1
  518. package/dist/modules/crm/jobs.d.ts +10 -0
  519. package/dist/modules/crm/jobs.d.ts.map +1 -1
  520. package/dist/modules/crm/jobs.js +50 -1
  521. package/dist/modules/crm/jobs.js.map +1 -1
  522. package/dist/modules/crm/messages.d.ts +14 -1
  523. package/dist/modules/crm/messages.d.ts.map +1 -1
  524. package/dist/modules/crm/messages.js +26 -0
  525. package/dist/modules/crm/messages.js.map +1 -1
  526. package/dist/modules/crm/models.d.ts.map +1 -1
  527. package/dist/modules/crm/models.js +25 -0
  528. package/dist/modules/crm/models.js.map +1 -1
  529. package/dist/modules/crm/operations.d.ts +110 -1
  530. package/dist/modules/crm/operations.d.ts.map +1 -1
  531. package/dist/modules/crm/operations.js +612 -84
  532. package/dist/modules/crm/operations.js.map +1 -1
  533. package/dist/modules/crm_backend/client/crm-kanban-view.d.mts.map +1 -1
  534. package/dist/modules/crm_backend/client/crm-kanban-view.mjs +132 -32
  535. package/dist/modules/crm_backend/client/crm-kanban-view.mjs.map +1 -1
  536. package/dist/modules/crm_backend/client/crm.css +398 -63
  537. package/dist/modules/crm_backend/index.d.ts.map +1 -1
  538. package/dist/modules/crm_backend/index.js +12 -4
  539. package/dist/modules/crm_backend/index.js.map +1 -1
  540. package/dist/modules/crm_backend/messages.d.ts +212 -0
  541. package/dist/modules/crm_backend/messages.d.ts.map +1 -1
  542. package/dist/modules/crm_backend/messages.js +212 -0
  543. package/dist/modules/crm_backend/messages.js.map +1 -1
  544. package/dist/modules/crm_backend/relation-control.d.ts +51 -0
  545. package/dist/modules/crm_backend/relation-control.d.ts.map +1 -0
  546. package/dist/modules/crm_backend/relation-control.js +107 -0
  547. package/dist/modules/crm_backend/relation-control.js.map +1 -0
  548. package/dist/modules/crm_backend/routes.d.ts.map +1 -1
  549. package/dist/modules/crm_backend/routes.js +1068 -260
  550. package/dist/modules/crm_backend/routes.js.map +1 -1
  551. package/dist/modules/crm_backend/screens/activity-planner.d.ts +22 -0
  552. package/dist/modules/crm_backend/screens/activity-planner.d.ts.map +1 -0
  553. package/dist/modules/crm_backend/screens/activity-planner.js +159 -0
  554. package/dist/modules/crm_backend/screens/activity-planner.js.map +1 -0
  555. package/dist/modules/crm_backend/screens/case-create.d.ts +15 -0
  556. package/dist/modules/crm_backend/screens/case-create.d.ts.map +1 -0
  557. package/dist/modules/crm_backend/screens/case-create.js +19 -0
  558. package/dist/modules/crm_backend/screens/case-create.js.map +1 -0
  559. package/dist/modules/crm_backend/screens/case-detail.d.ts +46 -0
  560. package/dist/modules/crm_backend/screens/case-detail.d.ts.map +1 -0
  561. package/dist/modules/crm_backend/screens/case-detail.js +506 -0
  562. package/dist/modules/crm_backend/screens/case-detail.js.map +1 -0
  563. package/dist/modules/crm_backend/screens/cases-list.d.ts +16 -0
  564. package/dist/modules/crm_backend/screens/cases-list.d.ts.map +1 -0
  565. package/dist/modules/crm_backend/screens/cases-list.js +86 -0
  566. package/dist/modules/crm_backend/screens/cases-list.js.map +1 -0
  567. package/dist/modules/crm_backend/screens/configuration.d.ts +28 -0
  568. package/dist/modules/crm_backend/screens/configuration.d.ts.map +1 -0
  569. package/dist/modules/crm_backend/screens/configuration.js +115 -0
  570. package/dist/modules/crm_backend/screens/configuration.js.map +1 -0
  571. package/dist/modules/crm_backend/screens/index.d.ts +14 -0
  572. package/dist/modules/crm_backend/screens/index.d.ts.map +1 -0
  573. package/dist/modules/crm_backend/screens/index.js +8 -0
  574. package/dist/modules/crm_backend/screens/index.js.map +1 -0
  575. package/dist/modules/crm_backend/screens/leaderboard.d.ts +12 -0
  576. package/dist/modules/crm_backend/screens/leaderboard.d.ts.map +1 -0
  577. package/dist/modules/crm_backend/screens/leaderboard.js +89 -0
  578. package/dist/modules/crm_backend/screens/leaderboard.js.map +1 -0
  579. package/dist/modules/crm_backend/screens/pipeline.d.ts +21 -0
  580. package/dist/modules/crm_backend/screens/pipeline.d.ts.map +1 -0
  581. package/dist/modules/crm_backend/screens/pipeline.js +22 -0
  582. package/dist/modules/crm_backend/screens/pipeline.js.map +1 -0
  583. package/dist/modules/crm_sale/index.d.ts.map +1 -1
  584. package/dist/modules/crm_sale/index.js +3 -4
  585. package/dist/modules/crm_sale/index.js.map +1 -1
  586. package/dist/modules/crm_sale/messages.d.ts +3 -1
  587. package/dist/modules/crm_sale/messages.d.ts.map +1 -1
  588. package/dist/modules/crm_sale/messages.js +4 -0
  589. package/dist/modules/crm_sale/messages.js.map +1 -1
  590. package/dist/modules/crm_sale/sale-functions.d.ts +8 -1
  591. package/dist/modules/crm_sale/sale-functions.d.ts.map +1 -1
  592. package/dist/modules/crm_sale/sale-functions.js +184 -55
  593. package/dist/modules/crm_sale/sale-functions.js.map +1 -1
  594. package/dist/modules/crm_staff_channel/channel-routes.d.ts +2 -0
  595. package/dist/modules/crm_staff_channel/channel-routes.d.ts.map +1 -0
  596. package/dist/modules/crm_staff_channel/channel-routes.js +777 -0
  597. package/dist/modules/crm_staff_channel/channel-routes.js.map +1 -0
  598. package/dist/modules/crm_staff_channel/index.d.ts +5 -0
  599. package/dist/modules/crm_staff_channel/index.d.ts.map +1 -0
  600. package/dist/modules/crm_staff_channel/index.js +30 -0
  601. package/dist/modules/crm_staff_channel/index.js.map +1 -0
  602. package/dist/modules/crm_website/functions.d.ts.map +1 -1
  603. package/dist/modules/crm_website/functions.js +89 -10
  604. package/dist/modules/crm_website/functions.js.map +1 -1
  605. package/dist/modules/crm_website/index.js +1 -2
  606. package/dist/modules/crm_website/index.js.map +1 -1
  607. package/dist/modules/crm_website/messages.d.ts +4 -1
  608. package/dist/modules/crm_website/messages.d.ts.map +1 -1
  609. package/dist/modules/crm_website/messages.js +6 -0
  610. package/dist/modules/crm_website/messages.js.map +1 -1
  611. package/dist/modules/crm_website/models.d.ts.map +1 -1
  612. package/dist/modules/crm_website/models.js +18 -0
  613. package/dist/modules/crm_website/models.js.map +1 -1
  614. package/dist/modules/crm_website/routes.d.ts.map +1 -1
  615. package/dist/modules/crm_website/routes.js +44 -12
  616. package/dist/modules/crm_website/routes.js.map +1 -1
  617. package/dist/modules/crm_website/screens.d.ts +7 -1
  618. package/dist/modules/crm_website/screens.d.ts.map +1 -1
  619. package/dist/modules/crm_website/screens.js +13 -8
  620. package/dist/modules/crm_website/screens.js.map +1 -1
  621. package/dist/modules/flow/functions.d.ts +3 -0
  622. package/dist/modules/flow/functions.d.ts.map +1 -0
  623. package/dist/modules/flow/functions.js +1876 -0
  624. package/dist/modules/flow/functions.js.map +1 -0
  625. package/dist/modules/flow/index.d.ts +12 -0
  626. package/dist/modules/flow/index.d.ts.map +1 -0
  627. package/dist/modules/flow/index.js +30 -0
  628. package/dist/modules/flow/index.js.map +1 -0
  629. package/dist/modules/flow/jobs.d.ts +3 -0
  630. package/dist/modules/flow/jobs.d.ts.map +1 -0
  631. package/dist/modules/flow/jobs.js +136 -0
  632. package/dist/modules/flow/jobs.js.map +1 -0
  633. package/dist/modules/flow/membership.d.ts +72 -0
  634. package/dist/modules/flow/membership.d.ts.map +1 -0
  635. package/dist/modules/flow/membership.js +182 -0
  636. package/dist/modules/flow/membership.js.map +1 -0
  637. package/dist/modules/flow/messages.d.ts +79 -0
  638. package/dist/modules/flow/messages.d.ts.map +1 -0
  639. package/dist/modules/flow/messages.js +152 -0
  640. package/dist/modules/flow/messages.js.map +1 -0
  641. package/dist/modules/flow/models.d.ts +3 -0
  642. package/dist/modules/flow/models.d.ts.map +1 -0
  643. package/dist/modules/flow/models.js +453 -0
  644. package/dist/modules/flow/models.js.map +1 -0
  645. package/dist/modules/flow/operations.d.ts +414 -0
  646. package/dist/modules/flow/operations.d.ts.map +1 -0
  647. package/dist/modules/flow/operations.js +1671 -0
  648. package/dist/modules/flow/operations.js.map +1 -0
  649. package/dist/modules/flow/pages.d.ts +146 -0
  650. package/dist/modules/flow/pages.d.ts.map +1 -0
  651. package/dist/modules/flow/pages.js +394 -0
  652. package/dist/modules/flow/pages.js.map +1 -0
  653. package/dist/modules/flow/projects.d.ts +41 -0
  654. package/dist/modules/flow/projects.d.ts.map +1 -0
  655. package/dist/modules/flow/projects.js +74 -0
  656. package/dist/modules/flow/projects.js.map +1 -0
  657. package/dist/modules/flow/search.d.ts +57 -0
  658. package/dist/modules/flow/search.d.ts.map +1 -0
  659. package/dist/modules/flow/search.js +110 -0
  660. package/dist/modules/flow/search.js.map +1 -0
  661. package/dist/modules/flow/types.d.ts +17 -0
  662. package/dist/modules/flow/types.d.ts.map +1 -0
  663. package/dist/modules/flow/types.js +13 -0
  664. package/dist/modules/flow/types.js.map +1 -0
  665. package/dist/modules/flow_backend/functions.d.ts +3 -0
  666. package/dist/modules/flow_backend/functions.d.ts.map +1 -0
  667. package/dist/modules/flow_backend/functions.js +162 -0
  668. package/dist/modules/flow_backend/functions.js.map +1 -0
  669. package/dist/modules/flow_backend/index.d.ts +3 -0
  670. package/dist/modules/flow_backend/index.d.ts.map +1 -0
  671. package/dist/modules/flow_backend/index.js +96 -0
  672. package/dist/modules/flow_backend/index.js.map +1 -0
  673. package/dist/modules/flow_backend/islands.d.ts +3 -0
  674. package/dist/modules/flow_backend/islands.d.ts.map +1 -0
  675. package/dist/modules/flow_backend/islands.js +31 -0
  676. package/dist/modules/flow_backend/islands.js.map +1 -0
  677. package/dist/modules/flow_backend/messages.d.ts +248 -0
  678. package/dist/modules/flow_backend/messages.d.ts.map +1 -0
  679. package/dist/modules/flow_backend/messages.js +470 -0
  680. package/dist/modules/flow_backend/messages.js.map +1 -0
  681. package/dist/modules/flow_backend/relation-control.d.ts +53 -0
  682. package/dist/modules/flow_backend/relation-control.d.ts.map +1 -0
  683. package/dist/modules/flow_backend/relation-control.js +106 -0
  684. package/dist/modules/flow_backend/relation-control.js.map +1 -0
  685. package/dist/modules/flow_backend/routes.d.ts +3 -0
  686. package/dist/modules/flow_backend/routes.d.ts.map +1 -0
  687. package/dist/modules/flow_backend/routes.js +2519 -0
  688. package/dist/modules/flow_backend/routes.js.map +1 -0
  689. package/dist/modules/flow_backend/screens/all-epics.d.ts +19 -0
  690. package/dist/modules/flow_backend/screens/all-epics.d.ts.map +1 -0
  691. package/dist/modules/flow_backend/screens/all-epics.js +59 -0
  692. package/dist/modules/flow_backend/screens/all-epics.js.map +1 -0
  693. package/dist/modules/flow_backend/screens/all-pages.d.ts +19 -0
  694. package/dist/modules/flow_backend/screens/all-pages.d.ts.map +1 -0
  695. package/dist/modules/flow_backend/screens/all-pages.js +65 -0
  696. package/dist/modules/flow_backend/screens/all-pages.js.map +1 -0
  697. package/dist/modules/flow_backend/screens/board.d.ts +5 -0
  698. package/dist/modules/flow_backend/screens/board.d.ts.map +1 -0
  699. package/dist/modules/flow_backend/screens/board.js +7 -0
  700. package/dist/modules/flow_backend/screens/board.js.map +1 -0
  701. package/dist/modules/flow_backend/screens/epic-detail.d.ts +22 -0
  702. package/dist/modules/flow_backend/screens/epic-detail.d.ts.map +1 -0
  703. package/dist/modules/flow_backend/screens/epic-detail.js +41 -0
  704. package/dist/modules/flow_backend/screens/epic-detail.js.map +1 -0
  705. package/dist/modules/flow_backend/screens/gantt.d.ts +21 -0
  706. package/dist/modules/flow_backend/screens/gantt.d.ts.map +1 -0
  707. package/dist/modules/flow_backend/screens/gantt.js +42 -0
  708. package/dist/modules/flow_backend/screens/gantt.js.map +1 -0
  709. package/dist/modules/flow_backend/screens/index.d.ts +29 -0
  710. package/dist/modules/flow_backend/screens/index.d.ts.map +1 -0
  711. package/dist/modules/flow_backend/screens/index.js +23 -0
  712. package/dist/modules/flow_backend/screens/index.js.map +1 -0
  713. package/dist/modules/flow_backend/screens/issue-detail.d.ts +38 -0
  714. package/dist/modules/flow_backend/screens/issue-detail.d.ts.map +1 -0
  715. package/dist/modules/flow_backend/screens/issue-detail.js +336 -0
  716. package/dist/modules/flow_backend/screens/issue-detail.js.map +1 -0
  717. package/dist/modules/flow_backend/screens/issues.d.ts +34 -0
  718. package/dist/modules/flow_backend/screens/issues.d.ts.map +1 -0
  719. package/dist/modules/flow_backend/screens/issues.js +118 -0
  720. package/dist/modules/flow_backend/screens/issues.js.map +1 -0
  721. package/dist/modules/flow_backend/screens/map.d.ts +13 -0
  722. package/dist/modules/flow_backend/screens/map.d.ts.map +1 -0
  723. package/dist/modules/flow_backend/screens/map.js +16 -0
  724. package/dist/modules/flow_backend/screens/map.js.map +1 -0
  725. package/dist/modules/flow_backend/screens/my-work.d.ts +42 -0
  726. package/dist/modules/flow_backend/screens/my-work.d.ts.map +1 -0
  727. package/dist/modules/flow_backend/screens/my-work.js +157 -0
  728. package/dist/modules/flow_backend/screens/my-work.js.map +1 -0
  729. package/dist/modules/flow_backend/screens/nav.d.ts +3 -0
  730. package/dist/modules/flow_backend/screens/nav.d.ts.map +1 -0
  731. package/dist/modules/flow_backend/screens/nav.js +79 -0
  732. package/dist/modules/flow_backend/screens/nav.js.map +1 -0
  733. package/dist/modules/flow_backend/screens/page-detail.d.ts +31 -0
  734. package/dist/modules/flow_backend/screens/page-detail.d.ts.map +1 -0
  735. package/dist/modules/flow_backend/screens/page-detail.js +113 -0
  736. package/dist/modules/flow_backend/screens/page-detail.js.map +1 -0
  737. package/dist/modules/flow_backend/screens/project-create.d.ts +26 -0
  738. package/dist/modules/flow_backend/screens/project-create.d.ts.map +1 -0
  739. package/dist/modules/flow_backend/screens/project-create.js +56 -0
  740. package/dist/modules/flow_backend/screens/project-create.js.map +1 -0
  741. package/dist/modules/flow_backend/screens/project-epics.d.ts +33 -0
  742. package/dist/modules/flow_backend/screens/project-epics.d.ts.map +1 -0
  743. package/dist/modules/flow_backend/screens/project-epics.js +90 -0
  744. package/dist/modules/flow_backend/screens/project-epics.js.map +1 -0
  745. package/dist/modules/flow_backend/screens/project-pages.d.ts +34 -0
  746. package/dist/modules/flow_backend/screens/project-pages.d.ts.map +1 -0
  747. package/dist/modules/flow_backend/screens/project-pages.js +66 -0
  748. package/dist/modules/flow_backend/screens/project-pages.js.map +1 -0
  749. package/dist/modules/flow_backend/screens/project-settings.d.ts +69 -0
  750. package/dist/modules/flow_backend/screens/project-settings.d.ts.map +1 -0
  751. package/dist/modules/flow_backend/screens/project-settings.js +248 -0
  752. package/dist/modules/flow_backend/screens/project-settings.js.map +1 -0
  753. package/dist/modules/flow_backend/screens/projects-list.d.ts +30 -0
  754. package/dist/modules/flow_backend/screens/projects-list.d.ts.map +1 -0
  755. package/dist/modules/flow_backend/screens/projects-list.js +121 -0
  756. package/dist/modules/flow_backend/screens/projects-list.js.map +1 -0
  757. package/dist/modules/flow_backend/screens/shared.d.ts +28 -0
  758. package/dist/modules/flow_backend/screens/shared.d.ts.map +1 -0
  759. package/dist/modules/flow_backend/screens/shared.js +46 -0
  760. package/dist/modules/flow_backend/screens/shared.js.map +1 -0
  761. package/dist/modules/flow_backend/screens/sprints.d.ts +33 -0
  762. package/dist/modules/flow_backend/screens/sprints.d.ts.map +1 -0
  763. package/dist/modules/flow_backend/screens/sprints.js +159 -0
  764. package/dist/modules/flow_backend/screens/sprints.js.map +1 -0
  765. package/dist/modules/flow_staff_channel/channel-routes.d.ts +2 -0
  766. package/dist/modules/flow_staff_channel/channel-routes.d.ts.map +1 -0
  767. package/dist/modules/flow_staff_channel/channel-routes.js +425 -0
  768. package/dist/modules/flow_staff_channel/channel-routes.js.map +1 -0
  769. package/dist/modules/flow_staff_channel/index.d.ts +5 -0
  770. package/dist/modules/flow_staff_channel/index.d.ts.map +1 -0
  771. package/dist/modules/flow_staff_channel/index.js +30 -0
  772. package/dist/modules/flow_staff_channel/index.js.map +1 -0
  773. package/dist/modules/hospitality_billing/functions.d.ts +18 -0
  774. package/dist/modules/hospitality_billing/functions.d.ts.map +1 -0
  775. package/dist/modules/hospitality_billing/functions.js +426 -0
  776. package/dist/modules/hospitality_billing/functions.js.map +1 -0
  777. package/dist/modules/hospitality_billing/index.d.ts +3 -0
  778. package/dist/modules/hospitality_billing/index.d.ts.map +1 -0
  779. package/dist/modules/hospitality_billing/index.js +25 -0
  780. package/dist/modules/hospitality_billing/index.js.map +1 -0
  781. package/dist/modules/hospitality_billing/jobs.d.ts +17 -0
  782. package/dist/modules/hospitality_billing/jobs.d.ts.map +1 -0
  783. package/dist/modules/hospitality_billing/jobs.js +83 -0
  784. package/dist/modules/hospitality_billing/jobs.js.map +1 -0
  785. package/dist/modules/hospitality_billing/menus.d.ts +9 -0
  786. package/dist/modules/hospitality_billing/menus.d.ts.map +1 -0
  787. package/dist/modules/hospitality_billing/menus.js +25 -0
  788. package/dist/modules/hospitality_billing/menus.js.map +1 -0
  789. package/dist/modules/hospitality_billing/messages.d.ts +3 -0
  790. package/dist/modules/hospitality_billing/messages.d.ts.map +1 -0
  791. package/dist/modules/hospitality_billing/messages.js +163 -0
  792. package/dist/modules/hospitality_billing/messages.js.map +1 -0
  793. package/dist/modules/hospitality_billing/models.d.ts +3 -0
  794. package/dist/modules/hospitality_billing/models.d.ts.map +1 -0
  795. package/dist/modules/hospitality_billing/models.js +65 -0
  796. package/dist/modules/hospitality_billing/models.js.map +1 -0
  797. package/dist/modules/hospitality_billing/routes.d.ts +3 -0
  798. package/dist/modules/hospitality_billing/routes.d.ts.map +1 -0
  799. package/dist/modules/hospitality_billing/routes.js +189 -0
  800. package/dist/modules/hospitality_billing/routes.js.map +1 -0
  801. package/dist/modules/hospitality_billing/screens/billing.d.ts +3 -0
  802. package/dist/modules/hospitality_billing/screens/billing.d.ts.map +1 -0
  803. package/dist/modules/hospitality_billing/screens/billing.js +20 -0
  804. package/dist/modules/hospitality_billing/screens/billing.js.map +1 -0
  805. package/dist/modules/hospitality_billing/screens/charge-rules.d.ts +12 -0
  806. package/dist/modules/hospitality_billing/screens/charge-rules.d.ts.map +1 -0
  807. package/dist/modules/hospitality_billing/screens/charge-rules.js +86 -0
  808. package/dist/modules/hospitality_billing/screens/charge-rules.js.map +1 -0
  809. package/dist/modules/hospitality_billing/screens/index.d.ts +4 -0
  810. package/dist/modules/hospitality_billing/screens/index.d.ts.map +1 -0
  811. package/dist/modules/hospitality_billing/screens/index.js +4 -0
  812. package/dist/modules/hospitality_billing/screens/index.js.map +1 -0
  813. package/dist/modules/hospitality_billing/screens/page-frame.d.ts +14 -0
  814. package/dist/modules/hospitality_billing/screens/page-frame.d.ts.map +1 -0
  815. package/dist/modules/hospitality_billing/screens/page-frame.js +6 -0
  816. package/dist/modules/hospitality_billing/screens/page-frame.js.map +1 -0
  817. package/dist/modules/hospitality_billing/screens/shared.d.ts +64 -0
  818. package/dist/modules/hospitality_billing/screens/shared.d.ts.map +1 -0
  819. package/dist/modules/hospitality_billing/screens/shared.js +117 -0
  820. package/dist/modules/hospitality_billing/screens/shared.js.map +1 -0
  821. package/dist/modules/hospitality_core/calendar.d.ts.map +1 -1
  822. package/dist/modules/hospitality_core/calendar.js +2 -1
  823. package/dist/modules/hospitality_core/calendar.js.map +1 -1
  824. package/dist/modules/hospitality_core/functions.d.ts.map +1 -1
  825. package/dist/modules/hospitality_core/functions.js +114 -14
  826. package/dist/modules/hospitality_core/functions.js.map +1 -1
  827. package/dist/modules/hospitality_core/index.d.ts +2 -2
  828. package/dist/modules/hospitality_core/index.d.ts.map +1 -1
  829. package/dist/modules/hospitality_core/index.js +3 -2
  830. package/dist/modules/hospitality_core/index.js.map +1 -1
  831. package/dist/modules/hospitality_core/inventory.d.ts +53 -4
  832. package/dist/modules/hospitality_core/inventory.d.ts.map +1 -1
  833. package/dist/modules/hospitality_core/inventory.js +121 -14
  834. package/dist/modules/hospitality_core/inventory.js.map +1 -1
  835. package/dist/modules/hospitality_core/menus.d.ts.map +1 -1
  836. package/dist/modules/hospitality_core/menus.js +31 -0
  837. package/dist/modules/hospitality_core/menus.js.map +1 -1
  838. package/dist/modules/hospitality_core/messages.d.ts.map +1 -1
  839. package/dist/modules/hospitality_core/messages.js +427 -183
  840. package/dist/modules/hospitality_core/messages.js.map +1 -1
  841. package/dist/modules/hospitality_core/models.d.ts +1 -1
  842. package/dist/modules/hospitality_core/models.d.ts.map +1 -1
  843. package/dist/modules/hospitality_core/models.js +47 -2
  844. package/dist/modules/hospitality_core/models.js.map +1 -1
  845. package/dist/modules/hospitality_core/night-audit.d.ts +1 -0
  846. package/dist/modules/hospitality_core/night-audit.d.ts.map +1 -1
  847. package/dist/modules/hospitality_core/night-audit.js +46 -1
  848. package/dist/modules/hospitality_core/night-audit.js.map +1 -1
  849. package/dist/modules/hospitality_core/online-booking.d.ts +5 -0
  850. package/dist/modules/hospitality_core/online-booking.d.ts.map +1 -0
  851. package/dist/modules/hospitality_core/online-booking.js +775 -0
  852. package/dist/modules/hospitality_core/online-booking.js.map +1 -0
  853. package/dist/modules/hospitality_core/operations.d.ts +21 -1
  854. package/dist/modules/hospitality_core/operations.d.ts.map +1 -1
  855. package/dist/modules/hospitality_core/operations.js +549 -74
  856. package/dist/modules/hospitality_core/operations.js.map +1 -1
  857. package/dist/modules/hospitality_core/routes.d.ts.map +1 -1
  858. package/dist/modules/hospitality_core/routes.js +526 -107
  859. package/dist/modules/hospitality_core/routes.js.map +1 -1
  860. package/dist/modules/hospitality_core/screens/amenities.d.ts +10 -0
  861. package/dist/modules/hospitality_core/screens/amenities.d.ts.map +1 -0
  862. package/dist/modules/hospitality_core/screens/amenities.js +65 -0
  863. package/dist/modules/hospitality_core/screens/amenities.js.map +1 -0
  864. package/dist/modules/hospitality_core/screens/building-detail.d.ts +3 -0
  865. package/dist/modules/hospitality_core/screens/building-detail.d.ts.map +1 -0
  866. package/dist/modules/hospitality_core/screens/building-detail.js +69 -0
  867. package/dist/modules/hospitality_core/screens/building-detail.js.map +1 -0
  868. package/dist/modules/hospitality_core/screens/check-out-prep.d.ts +46 -0
  869. package/dist/modules/hospitality_core/screens/check-out-prep.d.ts.map +1 -0
  870. package/dist/modules/hospitality_core/screens/check-out-prep.js +133 -0
  871. package/dist/modules/hospitality_core/screens/check-out-prep.js.map +1 -0
  872. package/dist/modules/hospitality_core/screens/cleaning-task-detail.d.ts +7 -0
  873. package/dist/modules/hospitality_core/screens/cleaning-task-detail.d.ts.map +1 -0
  874. package/dist/modules/hospitality_core/screens/cleaning-task-detail.js +109 -0
  875. package/dist/modules/hospitality_core/screens/cleaning-task-detail.js.map +1 -0
  876. package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts +20 -0
  877. package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts.map +1 -0
  878. package/dist/modules/hospitality_core/screens/cleaning-tasks.js +139 -0
  879. package/dist/modules/hospitality_core/screens/cleaning-tasks.js.map +1 -0
  880. package/dist/modules/hospitality_core/screens/content.d.ts +3 -0
  881. package/dist/modules/hospitality_core/screens/content.d.ts.map +1 -0
  882. package/dist/modules/hospitality_core/screens/content.js +114 -0
  883. package/dist/modules/hospitality_core/screens/content.js.map +1 -0
  884. package/dist/modules/hospitality_core/screens/floor-detail.d.ts +3 -0
  885. package/dist/modules/hospitality_core/screens/floor-detail.d.ts.map +1 -0
  886. package/dist/modules/hospitality_core/screens/floor-detail.js +74 -0
  887. package/dist/modules/hospitality_core/screens/floor-detail.js.map +1 -0
  888. package/dist/modules/hospitality_core/screens/folio-detail.d.ts +3 -0
  889. package/dist/modules/hospitality_core/screens/folio-detail.d.ts.map +1 -0
  890. package/dist/modules/hospitality_core/screens/folio-detail.js +140 -0
  891. package/dist/modules/hospitality_core/screens/folio-detail.js.map +1 -0
  892. package/dist/modules/hospitality_core/screens/folios.d.ts +3 -0
  893. package/dist/modules/hospitality_core/screens/folios.d.ts.map +1 -0
  894. package/dist/modules/hospitality_core/screens/folios.js +7 -0
  895. package/dist/modules/hospitality_core/screens/folios.js.map +1 -0
  896. package/dist/modules/hospitality_core/screens/front-desk.d.ts +35 -0
  897. package/dist/modules/hospitality_core/screens/front-desk.d.ts.map +1 -0
  898. package/dist/modules/hospitality_core/screens/front-desk.js +195 -0
  899. package/dist/modules/hospitality_core/screens/front-desk.js.map +1 -0
  900. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.d.ts +3 -0
  901. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.d.ts.map +1 -0
  902. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.js +121 -0
  903. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.js.map +1 -0
  904. package/dist/modules/hospitality_core/screens/housekeeping-rooms.d.ts +9 -0
  905. package/dist/modules/hospitality_core/screens/housekeeping-rooms.d.ts.map +1 -0
  906. package/dist/modules/hospitality_core/screens/housekeeping-rooms.js +54 -0
  907. package/dist/modules/hospitality_core/screens/housekeeping-rooms.js.map +1 -0
  908. package/dist/modules/hospitality_core/screens/index.d.ts +35 -0
  909. package/dist/modules/hospitality_core/screens/index.d.ts.map +1 -0
  910. package/dist/modules/hospitality_core/screens/index.js +34 -0
  911. package/dist/modules/hospitality_core/screens/index.js.map +1 -0
  912. package/dist/modules/hospitality_core/screens/inventory.d.ts +8 -0
  913. package/dist/modules/hospitality_core/screens/inventory.d.ts.map +1 -0
  914. package/dist/modules/hospitality_core/screens/inventory.js +122 -0
  915. package/dist/modules/hospitality_core/screens/inventory.js.map +1 -0
  916. package/dist/modules/hospitality_core/screens/new-property.d.ts +3 -0
  917. package/dist/modules/hospitality_core/screens/new-property.d.ts.map +1 -0
  918. package/dist/modules/hospitality_core/screens/new-property.js +8 -0
  919. package/dist/modules/hospitality_core/screens/new-property.js.map +1 -0
  920. package/dist/modules/hospitality_core/screens/new-room-type.d.ts +3 -0
  921. package/dist/modules/hospitality_core/screens/new-room-type.d.ts.map +1 -0
  922. package/dist/modules/hospitality_core/screens/new-room-type.js +8 -0
  923. package/dist/modules/hospitality_core/screens/new-room-type.js.map +1 -0
  924. package/dist/modules/hospitality_core/screens/new-room.d.ts +3 -0
  925. package/dist/modules/hospitality_core/screens/new-room.d.ts.map +1 -0
  926. package/dist/modules/hospitality_core/screens/new-room.js +8 -0
  927. package/dist/modules/hospitality_core/screens/new-room.js.map +1 -0
  928. package/dist/modules/hospitality_core/screens/night-audit.d.ts +10 -0
  929. package/dist/modules/hospitality_core/screens/night-audit.d.ts.map +1 -0
  930. package/dist/modules/hospitality_core/screens/night-audit.js +67 -0
  931. package/dist/modules/hospitality_core/screens/night-audit.js.map +1 -0
  932. package/dist/modules/hospitality_core/screens/page-frame.d.ts +15 -0
  933. package/dist/modules/hospitality_core/screens/page-frame.d.ts.map +1 -0
  934. package/dist/modules/hospitality_core/screens/page-frame.js +10 -0
  935. package/dist/modules/hospitality_core/screens/page-frame.js.map +1 -0
  936. package/dist/modules/hospitality_core/screens/policies.d.ts +10 -0
  937. package/dist/modules/hospitality_core/screens/policies.d.ts.map +1 -0
  938. package/dist/modules/hospitality_core/screens/policies.js +72 -0
  939. package/dist/modules/hospitality_core/screens/policies.js.map +1 -0
  940. package/dist/modules/hospitality_core/screens/properties.d.ts +7 -0
  941. package/dist/modules/hospitality_core/screens/properties.d.ts.map +1 -0
  942. package/dist/modules/hospitality_core/screens/properties.js +45 -0
  943. package/dist/modules/hospitality_core/screens/properties.js.map +1 -0
  944. package/dist/modules/hospitality_core/screens/property-detail.d.ts +3 -0
  945. package/dist/modules/hospitality_core/screens/property-detail.d.ts.map +1 -0
  946. package/dist/modules/hospitality_core/screens/property-detail.js +92 -0
  947. package/dist/modules/hospitality_core/screens/property-detail.js.map +1 -0
  948. package/dist/modules/hospitality_core/screens/rate-plans.d.ts +10 -0
  949. package/dist/modules/hospitality_core/screens/rate-plans.d.ts.map +1 -0
  950. package/dist/modules/hospitality_core/screens/rate-plans.js +123 -0
  951. package/dist/modules/hospitality_core/screens/rate-plans.js.map +1 -0
  952. package/dist/modules/hospitality_core/screens/reservation-detail.d.ts +11 -0
  953. package/dist/modules/hospitality_core/screens/reservation-detail.d.ts.map +1 -0
  954. package/dist/modules/hospitality_core/screens/reservation-detail.js +244 -0
  955. package/dist/modules/hospitality_core/screens/reservation-detail.js.map +1 -0
  956. package/dist/modules/hospitality_core/screens/reservations.d.ts +17 -0
  957. package/dist/modules/hospitality_core/screens/reservations.d.ts.map +1 -0
  958. package/dist/modules/hospitality_core/screens/reservations.js +166 -0
  959. package/dist/modules/hospitality_core/screens/reservations.js.map +1 -0
  960. package/dist/modules/hospitality_core/screens/room-detail.d.ts +3 -0
  961. package/dist/modules/hospitality_core/screens/room-detail.d.ts.map +1 -0
  962. package/dist/modules/hospitality_core/screens/room-detail.js +75 -0
  963. package/dist/modules/hospitality_core/screens/room-detail.js.map +1 -0
  964. package/dist/modules/hospitality_core/screens/room-type-detail.d.ts +3 -0
  965. package/dist/modules/hospitality_core/screens/room-type-detail.d.ts.map +1 -0
  966. package/dist/modules/hospitality_core/screens/room-type-detail.js +91 -0
  967. package/dist/modules/hospitality_core/screens/room-type-detail.js.map +1 -0
  968. package/dist/modules/hospitality_core/screens/room-types.d.ts +3 -0
  969. package/dist/modules/hospitality_core/screens/room-types.d.ts.map +1 -0
  970. package/dist/modules/hospitality_core/screens/room-types.js +61 -0
  971. package/dist/modules/hospitality_core/screens/room-types.js.map +1 -0
  972. package/dist/modules/hospitality_core/screens/rooms.d.ts +10 -0
  973. package/dist/modules/hospitality_core/screens/rooms.d.ts.map +1 -0
  974. package/dist/modules/hospitality_core/screens/rooms.js +150 -0
  975. package/dist/modules/hospitality_core/screens/rooms.js.map +1 -0
  976. package/dist/modules/hospitality_core/screens/services.d.ts +18 -0
  977. package/dist/modules/hospitality_core/screens/services.d.ts.map +1 -0
  978. package/dist/modules/hospitality_core/screens/services.js +196 -0
  979. package/dist/modules/hospitality_core/screens/services.js.map +1 -0
  980. package/dist/modules/hospitality_core/screens/shared.d.ts +789 -0
  981. package/dist/modules/hospitality_core/screens/shared.d.ts.map +1 -0
  982. package/dist/modules/hospitality_core/screens/shared.js +1607 -0
  983. package/dist/modules/hospitality_core/screens/shared.js.map +1 -0
  984. package/dist/modules/hospitality_core/screens/stay-detail.d.ts +3 -0
  985. package/dist/modules/hospitality_core/screens/stay-detail.d.ts.map +1 -0
  986. package/dist/modules/hospitality_core/screens/stay-detail.js +233 -0
  987. package/dist/modules/hospitality_core/screens/stay-detail.js.map +1 -0
  988. package/dist/modules/hospitality_core/screens/stay-notices.d.ts +9 -0
  989. package/dist/modules/hospitality_core/screens/stay-notices.d.ts.map +1 -0
  990. package/dist/modules/hospitality_core/screens/stay-notices.js +87 -0
  991. package/dist/modules/hospitality_core/screens/stay-notices.js.map +1 -0
  992. package/dist/modules/hospitality_core/screens/stays.d.ts +3 -0
  993. package/dist/modules/hospitality_core/screens/stays.d.ts.map +1 -0
  994. package/dist/modules/hospitality_core/screens/stays.js +7 -0
  995. package/dist/modules/hospitality_core/screens/stays.js.map +1 -0
  996. package/dist/modules/hospitality_core/screens/tape-chart.d.ts +7 -0
  997. package/dist/modules/hospitality_core/screens/tape-chart.d.ts.map +1 -0
  998. package/dist/modules/hospitality_core/screens/tape-chart.js +99 -0
  999. package/dist/modules/hospitality_core/screens/tape-chart.js.map +1 -0
  1000. package/dist/modules/hospitality_core/services.d.ts +48 -0
  1001. package/dist/modules/hospitality_core/services.d.ts.map +1 -1
  1002. package/dist/modules/hospitality_core/services.js +203 -30
  1003. package/dist/modules/hospitality_core/services.js.map +1 -1
  1004. package/dist/modules/hospitality_core/stay-notices.js +2 -2
  1005. package/dist/modules/hospitality_core/stay-notices.js.map +1 -1
  1006. package/dist/modules/hospitality_core/types.d.ts +26 -5
  1007. package/dist/modules/hospitality_core/types.d.ts.map +1 -1
  1008. package/dist/modules/hospitality_core/types.js +47 -5
  1009. package/dist/modules/hospitality_core/types.js.map +1 -1
  1010. package/dist/modules/hospitality_staff_channel/channel-routes.d.ts +2 -0
  1011. package/dist/modules/hospitality_staff_channel/channel-routes.d.ts.map +1 -0
  1012. package/dist/modules/hospitality_staff_channel/channel-routes.js +1216 -0
  1013. package/dist/modules/hospitality_staff_channel/channel-routes.js.map +1 -0
  1014. package/dist/modules/hospitality_staff_channel/index.d.ts +5 -0
  1015. package/dist/modules/hospitality_staff_channel/index.d.ts.map +1 -0
  1016. package/dist/modules/hospitality_staff_channel/index.js +34 -0
  1017. package/dist/modules/hospitality_staff_channel/index.js.map +1 -0
  1018. package/dist/modules/hr/functions.d.ts.map +1 -1
  1019. package/dist/modules/hr/functions.js +108 -44
  1020. package/dist/modules/hr/functions.js.map +1 -1
  1021. package/dist/modules/hr/index.d.ts.map +1 -1
  1022. package/dist/modules/hr/index.js +0 -1
  1023. package/dist/modules/hr/index.js.map +1 -1
  1024. package/dist/modules/hr_backend/index.d.ts +2 -1
  1025. package/dist/modules/hr_backend/index.d.ts.map +1 -1
  1026. package/dist/modules/hr_backend/index.js +39 -7
  1027. package/dist/modules/hr_backend/index.js.map +1 -1
  1028. package/dist/modules/hr_backend/routes.d.ts.map +1 -1
  1029. package/dist/modules/hr_backend/routes.js +279 -42
  1030. package/dist/modules/hr_backend/routes.js.map +1 -1
  1031. package/dist/modules/hr_backend/screens/employee-form.d.ts +28 -0
  1032. package/dist/modules/hr_backend/screens/employee-form.d.ts.map +1 -0
  1033. package/dist/modules/hr_backend/screens/employee-form.js +110 -0
  1034. package/dist/modules/hr_backend/screens/employee-form.js.map +1 -0
  1035. package/dist/modules/hr_backend/screens/employees-list.d.ts +22 -0
  1036. package/dist/modules/hr_backend/screens/employees-list.d.ts.map +1 -0
  1037. package/dist/modules/hr_backend/screens/employees-list.js +53 -0
  1038. package/dist/modules/hr_backend/screens/employees-list.js.map +1 -0
  1039. package/dist/modules/hr_backend/screens/index.d.ts +5 -0
  1040. package/dist/modules/hr_backend/screens/index.d.ts.map +1 -0
  1041. package/dist/modules/hr_backend/screens/index.js +5 -0
  1042. package/dist/modules/hr_backend/screens/index.js.map +1 -0
  1043. package/dist/modules/hr_backend/screens/leaves-list.d.ts +22 -0
  1044. package/dist/modules/hr_backend/screens/leaves-list.d.ts.map +1 -0
  1045. package/dist/modules/hr_backend/screens/leaves-list.js +78 -0
  1046. package/dist/modules/hr_backend/screens/leaves-list.js.map +1 -0
  1047. package/dist/modules/hr_backend/screens/roster.d.ts +19 -0
  1048. package/dist/modules/hr_backend/screens/roster.d.ts.map +1 -0
  1049. package/dist/modules/hr_backend/screens/roster.js +83 -0
  1050. package/dist/modules/hr_backend/screens/roster.js.map +1 -0
  1051. package/dist/modules/inventory_staff_channel/channel-routes.d.ts +2 -0
  1052. package/dist/modules/inventory_staff_channel/channel-routes.d.ts.map +1 -0
  1053. package/dist/modules/inventory_staff_channel/channel-routes.js +713 -0
  1054. package/dist/modules/inventory_staff_channel/channel-routes.js.map +1 -0
  1055. package/dist/modules/inventory_staff_channel/index.d.ts +5 -0
  1056. package/dist/modules/inventory_staff_channel/index.d.ts.map +1 -0
  1057. package/dist/modules/inventory_staff_channel/index.js +38 -0
  1058. package/dist/modules/inventory_staff_channel/index.js.map +1 -0
  1059. package/dist/modules/livedoc/documents.d.ts +48 -0
  1060. package/dist/modules/livedoc/documents.d.ts.map +1 -0
  1061. package/dist/modules/livedoc/documents.js +99 -0
  1062. package/dist/modules/livedoc/documents.js.map +1 -0
  1063. package/dist/modules/livedoc/functions.d.ts +3 -0
  1064. package/dist/modules/livedoc/functions.d.ts.map +1 -0
  1065. package/dist/modules/livedoc/functions.js +47 -0
  1066. package/dist/modules/livedoc/functions.js.map +1 -0
  1067. package/dist/modules/livedoc/index.d.ts +22 -0
  1068. package/dist/modules/livedoc/index.d.ts.map +1 -0
  1069. package/dist/modules/livedoc/index.js +37 -0
  1070. package/dist/modules/livedoc/index.js.map +1 -0
  1071. package/dist/modules/livedoc/islands.d.ts +3 -0
  1072. package/dist/modules/livedoc/islands.d.ts.map +1 -0
  1073. package/dist/modules/livedoc/islands.js +22 -0
  1074. package/dist/modules/livedoc/islands.js.map +1 -0
  1075. package/dist/modules/livedoc/routes.d.ts +11 -0
  1076. package/dist/modules/livedoc/routes.d.ts.map +1 -0
  1077. package/dist/modules/livedoc/routes.js +232 -0
  1078. package/dist/modules/livedoc/routes.js.map +1 -0
  1079. package/dist/modules/livedoc/sync.d.ts +124 -0
  1080. package/dist/modules/livedoc/sync.d.ts.map +1 -0
  1081. package/dist/modules/livedoc/sync.js +218 -0
  1082. package/dist/modules/livedoc/sync.js.map +1 -0
  1083. package/dist/modules/loyalty/admin-functions.d.ts.map +1 -1
  1084. package/dist/modules/loyalty/admin-functions.js +42 -6
  1085. package/dist/modules/loyalty/admin-functions.js.map +1 -1
  1086. package/dist/modules/loyalty/engine.d.ts +1 -0
  1087. package/dist/modules/loyalty/engine.d.ts.map +1 -1
  1088. package/dist/modules/loyalty/engine.js +88 -28
  1089. package/dist/modules/loyalty/engine.js.map +1 -1
  1090. package/dist/modules/loyalty/index.d.ts.map +1 -1
  1091. package/dist/modules/loyalty/index.js +10 -2
  1092. package/dist/modules/loyalty/index.js.map +1 -1
  1093. package/dist/modules/loyalty/ledger.d.ts.map +1 -1
  1094. package/dist/modules/loyalty/ledger.js +11 -0
  1095. package/dist/modules/loyalty/ledger.js.map +1 -1
  1096. package/dist/modules/loyalty/membership-functions.d.ts.map +1 -1
  1097. package/dist/modules/loyalty/membership-functions.js +23 -7
  1098. package/dist/modules/loyalty/membership-functions.js.map +1 -1
  1099. package/dist/modules/loyalty/messages.d.ts +8 -0
  1100. package/dist/modules/loyalty/messages.d.ts.map +1 -1
  1101. package/dist/modules/loyalty/messages.js +8 -0
  1102. package/dist/modules/loyalty/messages.js.map +1 -1
  1103. package/dist/modules/loyalty/models.d.ts.map +1 -1
  1104. package/dist/modules/loyalty/models.js +20 -0
  1105. package/dist/modules/loyalty/models.js.map +1 -1
  1106. package/dist/modules/loyalty/order-functions.d.ts +16 -1
  1107. package/dist/modules/loyalty/order-functions.d.ts.map +1 -1
  1108. package/dist/modules/loyalty/order-functions.js +513 -291
  1109. package/dist/modules/loyalty/order-functions.js.map +1 -1
  1110. package/dist/modules/loyalty/stats.d.ts +17 -0
  1111. package/dist/modules/loyalty/stats.d.ts.map +1 -0
  1112. package/dist/modules/loyalty/stats.js +178 -0
  1113. package/dist/modules/loyalty/stats.js.map +1 -0
  1114. package/dist/modules/loyalty/stored-value.d.ts +42 -0
  1115. package/dist/modules/loyalty/stored-value.d.ts.map +1 -0
  1116. package/dist/modules/loyalty/stored-value.js +368 -0
  1117. package/dist/modules/loyalty/stored-value.js.map +1 -0
  1118. package/dist/modules/loyalty/types.d.ts +6 -4
  1119. package/dist/modules/loyalty/types.d.ts.map +1 -1
  1120. package/dist/modules/loyalty/types.js +1 -1
  1121. package/dist/modules/loyalty/types.js.map +1 -1
  1122. package/dist/modules/loyalty_backend/index.js +443 -172
  1123. package/dist/modules/loyalty_backend/index.js.map +1 -1
  1124. package/dist/modules/loyalty_backend/messages.d.ts +58 -1
  1125. package/dist/modules/loyalty_backend/messages.d.ts.map +1 -1
  1126. package/dist/modules/loyalty_backend/messages.js +114 -0
  1127. package/dist/modules/loyalty_backend/messages.js.map +1 -1
  1128. package/dist/modules/loyalty_backend/screens/index.d.ts +90 -0
  1129. package/dist/modules/loyalty_backend/screens/index.d.ts.map +1 -0
  1130. package/dist/modules/loyalty_backend/screens/index.js +912 -0
  1131. package/dist/modules/loyalty_backend/screens/index.js.map +1 -0
  1132. package/dist/modules/loyalty_backend/screens/page-frame.d.ts +14 -0
  1133. package/dist/modules/loyalty_backend/screens/page-frame.d.ts.map +1 -0
  1134. package/dist/modules/loyalty_backend/screens/page-frame.js +13 -0
  1135. package/dist/modules/loyalty_backend/screens/page-frame.js.map +1 -0
  1136. package/dist/modules/loyalty_pos/channel.d.ts +2 -0
  1137. package/dist/modules/loyalty_pos/channel.d.ts.map +1 -0
  1138. package/dist/modules/loyalty_pos/channel.js +270 -0
  1139. package/dist/modules/loyalty_pos/channel.js.map +1 -0
  1140. package/dist/modules/loyalty_pos/functions.d.ts +11 -17
  1141. package/dist/modules/loyalty_pos/functions.d.ts.map +1 -1
  1142. package/dist/modules/loyalty_pos/functions.js +454 -94
  1143. package/dist/modules/loyalty_pos/functions.js.map +1 -1
  1144. package/dist/modules/loyalty_pos/index.js +6 -16
  1145. package/dist/modules/loyalty_pos/index.js.map +1 -1
  1146. package/dist/modules/loyalty_pos/jobs.d.ts +3 -0
  1147. package/dist/modules/loyalty_pos/jobs.d.ts.map +1 -0
  1148. package/dist/modules/loyalty_pos/jobs.js +30 -0
  1149. package/dist/modules/loyalty_pos/jobs.js.map +1 -0
  1150. package/dist/modules/loyalty_sale/functions.d.ts +2 -2
  1151. package/dist/modules/loyalty_sale/functions.d.ts.map +1 -1
  1152. package/dist/modules/loyalty_sale/functions.js +53 -34
  1153. package/dist/modules/loyalty_sale/functions.js.map +1 -1
  1154. package/dist/modules/loyalty_sale/index.js +0 -2
  1155. package/dist/modules/loyalty_sale/index.js.map +1 -1
  1156. package/dist/modules/mail/functions.d.ts.map +1 -1
  1157. package/dist/modules/mail/functions.js +48 -6
  1158. package/dist/modules/mail/functions.js.map +1 -1
  1159. package/dist/modules/mail/index.d.ts.map +1 -1
  1160. package/dist/modules/mail/index.js +0 -1
  1161. package/dist/modules/mail/index.js.map +1 -1
  1162. package/dist/modules/mail/operations.d.ts +19 -0
  1163. package/dist/modules/mail/operations.d.ts.map +1 -1
  1164. package/dist/modules/mail/operations.js +69 -0
  1165. package/dist/modules/mail/operations.js.map +1 -1
  1166. package/dist/modules/mail_backend/index.d.ts +1 -1
  1167. package/dist/modules/mail_backend/index.d.ts.map +1 -1
  1168. package/dist/modules/mail_backend/index.js +5 -14
  1169. package/dist/modules/mail_backend/index.js.map +1 -1
  1170. package/dist/modules/mail_backend/islands.js +2 -2
  1171. package/dist/modules/mail_backend/islands.js.map +1 -1
  1172. package/dist/modules/mail_backend/routes.d.ts.map +1 -1
  1173. package/dist/modules/mail_backend/routes.js +25 -20
  1174. package/dist/modules/mail_backend/routes.js.map +1 -1
  1175. package/dist/modules/mail_backend/screens/inbox-list.d.ts +9 -0
  1176. package/dist/modules/mail_backend/screens/inbox-list.d.ts.map +1 -0
  1177. package/dist/modules/mail_backend/screens/inbox-list.js +13 -0
  1178. package/dist/modules/mail_backend/screens/inbox-list.js.map +1 -0
  1179. package/dist/modules/mail_backend/screens/index.d.ts +3 -0
  1180. package/dist/modules/mail_backend/screens/index.d.ts.map +1 -0
  1181. package/dist/modules/mail_backend/screens/index.js +2 -0
  1182. package/dist/modules/mail_backend/screens/index.js.map +1 -0
  1183. package/dist/modules/mail_inbound/index.d.ts.map +1 -1
  1184. package/dist/modules/mail_inbound/index.js +0 -1
  1185. package/dist/modules/mail_inbound/index.js.map +1 -1
  1186. package/dist/modules/mail_inbound_backend/index.d.ts +1 -1
  1187. package/dist/modules/mail_inbound_backend/index.d.ts.map +1 -1
  1188. package/dist/modules/mail_inbound_backend/index.js +3 -12
  1189. package/dist/modules/mail_inbound_backend/index.js.map +1 -1
  1190. package/dist/modules/mail_inbound_backend/routes.d.ts.map +1 -1
  1191. package/dist/modules/mail_inbound_backend/routes.js +6 -21
  1192. package/dist/modules/mail_inbound_backend/routes.js.map +1 -1
  1193. package/dist/modules/mail_inbound_backend/screens/inbound-list.d.ts +8 -0
  1194. package/dist/modules/mail_inbound_backend/screens/inbound-list.d.ts.map +1 -0
  1195. package/dist/modules/mail_inbound_backend/screens/inbound-list.js +20 -0
  1196. package/dist/modules/mail_inbound_backend/screens/inbound-list.js.map +1 -0
  1197. package/dist/modules/mail_inbound_backend/screens/index.d.ts +3 -0
  1198. package/dist/modules/mail_inbound_backend/screens/index.d.ts.map +1 -0
  1199. package/dist/modules/mail_inbound_backend/screens/index.js +2 -0
  1200. package/dist/modules/mail_inbound_backend/screens/index.js.map +1 -0
  1201. package/dist/modules/mail_staff_channel/channel-routes.d.ts +2 -0
  1202. package/dist/modules/mail_staff_channel/channel-routes.d.ts.map +1 -0
  1203. package/dist/modules/mail_staff_channel/channel-routes.js +183 -0
  1204. package/dist/modules/mail_staff_channel/channel-routes.js.map +1 -0
  1205. package/dist/modules/mail_staff_channel/index.d.ts +5 -0
  1206. package/dist/modules/mail_staff_channel/index.d.ts.map +1 -0
  1207. package/dist/modules/mail_staff_channel/index.js +28 -0
  1208. package/dist/modules/mail_staff_channel/index.js.map +1 -0
  1209. package/dist/modules/mail_transport/index.d.ts.map +1 -1
  1210. package/dist/modules/mail_transport/index.js +0 -1
  1211. package/dist/modules/mail_transport/index.js.map +1 -1
  1212. package/dist/modules/mail_transport_backend/index.d.ts +1 -1
  1213. package/dist/modules/mail_transport_backend/index.d.ts.map +1 -1
  1214. package/dist/modules/mail_transport_backend/index.js +3 -12
  1215. package/dist/modules/mail_transport_backend/index.js.map +1 -1
  1216. package/dist/modules/mail_transport_backend/routes.d.ts.map +1 -1
  1217. package/dist/modules/mail_transport_backend/routes.js +23 -22
  1218. package/dist/modules/mail_transport_backend/routes.js.map +1 -1
  1219. package/dist/modules/mail_transport_backend/screens/index.d.ts +3 -0
  1220. package/dist/modules/mail_transport_backend/screens/index.d.ts.map +1 -0
  1221. package/dist/modules/mail_transport_backend/screens/index.js +2 -0
  1222. package/dist/modules/mail_transport_backend/screens/index.js.map +1 -0
  1223. package/dist/modules/mail_transport_backend/screens/outbox-list.d.ts +9 -0
  1224. package/dist/modules/mail_transport_backend/screens/outbox-list.d.ts.map +1 -0
  1225. package/dist/modules/mail_transport_backend/screens/outbox-list.js +29 -0
  1226. package/dist/modules/mail_transport_backend/screens/outbox-list.js.map +1 -0
  1227. package/dist/modules/manufacturing/functions.d.ts +3 -0
  1228. package/dist/modules/manufacturing/functions.d.ts.map +1 -0
  1229. package/dist/modules/manufacturing/functions.js +912 -0
  1230. package/dist/modules/manufacturing/functions.js.map +1 -0
  1231. package/dist/modules/manufacturing/index.d.ts +6 -0
  1232. package/dist/modules/manufacturing/index.d.ts.map +1 -0
  1233. package/dist/modules/manufacturing/index.js +42 -0
  1234. package/dist/modules/manufacturing/index.js.map +1 -0
  1235. package/dist/modules/manufacturing/models.d.ts +8 -0
  1236. package/dist/modules/manufacturing/models.d.ts.map +1 -0
  1237. package/dist/modules/manufacturing/models.js +145 -0
  1238. package/dist/modules/manufacturing/models.js.map +1 -0
  1239. package/dist/modules/manufacturing/relations.d.ts.map +1 -0
  1240. package/dist/modules/manufacturing/relations.js +37 -0
  1241. package/dist/modules/manufacturing/relations.js.map +1 -0
  1242. package/dist/modules/manufacturing/types.d.ts +7 -0
  1243. package/dist/modules/manufacturing/types.d.ts.map +1 -0
  1244. package/dist/modules/manufacturing/types.js +11 -0
  1245. package/dist/modules/manufacturing/types.js.map +1 -0
  1246. package/dist/modules/manufacturing_backend/index.d.ts +5 -0
  1247. package/dist/modules/manufacturing_backend/index.d.ts.map +1 -0
  1248. package/dist/modules/manufacturing_backend/index.js +146 -0
  1249. package/dist/modules/manufacturing_backend/index.js.map +1 -0
  1250. package/dist/modules/manufacturing_backend/routes.d.ts +3 -0
  1251. package/dist/modules/manufacturing_backend/routes.d.ts.map +1 -0
  1252. package/dist/modules/manufacturing_backend/routes.js +477 -0
  1253. package/dist/modules/manufacturing_backend/routes.js.map +1 -0
  1254. package/dist/modules/manufacturing_backend/screens/bom-create.d.ts +15 -0
  1255. package/dist/modules/manufacturing_backend/screens/bom-create.d.ts.map +1 -0
  1256. package/dist/modules/manufacturing_backend/screens/bom-create.js +39 -0
  1257. package/dist/modules/manufacturing_backend/screens/bom-create.js.map +1 -0
  1258. package/dist/modules/manufacturing_backend/screens/boms-list.d.ts +18 -0
  1259. package/dist/modules/manufacturing_backend/screens/boms-list.d.ts.map +1 -0
  1260. package/dist/modules/manufacturing_backend/screens/boms-list.js +36 -0
  1261. package/dist/modules/manufacturing_backend/screens/boms-list.js.map +1 -0
  1262. package/dist/modules/manufacturing_backend/screens/index.d.ts +8 -0
  1263. package/dist/modules/manufacturing_backend/screens/index.d.ts.map +1 -0
  1264. package/dist/modules/manufacturing_backend/screens/index.js +8 -0
  1265. package/dist/modules/manufacturing_backend/screens/index.js.map +1 -0
  1266. package/dist/modules/manufacturing_backend/screens/order-create.d.ts +13 -0
  1267. package/dist/modules/manufacturing_backend/screens/order-create.d.ts.map +1 -0
  1268. package/dist/modules/manufacturing_backend/screens/order-create.js +20 -0
  1269. package/dist/modules/manufacturing_backend/screens/order-create.js.map +1 -0
  1270. package/dist/modules/manufacturing_backend/screens/order-execution.d.ts +7 -0
  1271. package/dist/modules/manufacturing_backend/screens/order-execution.d.ts.map +1 -0
  1272. package/dist/modules/manufacturing_backend/screens/order-execution.js +129 -0
  1273. package/dist/modules/manufacturing_backend/screens/order-execution.js.map +1 -0
  1274. package/dist/modules/manufacturing_backend/screens/orders-list.d.ts +21 -0
  1275. package/dist/modules/manufacturing_backend/screens/orders-list.d.ts.map +1 -0
  1276. package/dist/modules/manufacturing_backend/screens/orders-list.js +49 -0
  1277. package/dist/modules/manufacturing_backend/screens/orders-list.js.map +1 -0
  1278. package/dist/modules/manufacturing_backend/screens/work-center-form.d.ts +24 -0
  1279. package/dist/modules/manufacturing_backend/screens/work-center-form.d.ts.map +1 -0
  1280. package/dist/modules/manufacturing_backend/screens/work-center-form.js +80 -0
  1281. package/dist/modules/manufacturing_backend/screens/work-center-form.js.map +1 -0
  1282. package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts +23 -0
  1283. package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts.map +1 -0
  1284. package/dist/modules/manufacturing_backend/screens/work-centers-list.js +61 -0
  1285. package/dist/modules/manufacturing_backend/screens/work-centers-list.js.map +1 -0
  1286. package/dist/modules/oauth/index.d.ts.map +1 -1
  1287. package/dist/modules/oauth/index.js +0 -1
  1288. package/dist/modules/oauth/index.js.map +1 -1
  1289. package/dist/modules/oauth/models.d.ts.map +1 -1
  1290. package/dist/modules/oauth/models.js +2 -1
  1291. package/dist/modules/oauth/models.js.map +1 -1
  1292. package/dist/modules/oauth_backend/index.d.ts +1 -1
  1293. package/dist/modules/oauth_backend/index.d.ts.map +1 -1
  1294. package/dist/modules/oauth_backend/index.js +3 -5
  1295. package/dist/modules/oauth_backend/index.js.map +1 -1
  1296. package/dist/modules/oauth_backend/messages.d.ts +4 -0
  1297. package/dist/modules/oauth_backend/messages.d.ts.map +1 -1
  1298. package/dist/modules/oauth_backend/messages.js +4 -0
  1299. package/dist/modules/oauth_backend/messages.js.map +1 -1
  1300. package/dist/modules/oauth_backend/routes.d.ts.map +1 -1
  1301. package/dist/modules/oauth_backend/routes.js +28 -30
  1302. package/dist/modules/oauth_backend/routes.js.map +1 -1
  1303. package/dist/modules/oauth_backend/screens/index.d.ts +66 -0
  1304. package/dist/modules/oauth_backend/screens/index.d.ts.map +1 -0
  1305. package/dist/modules/oauth_backend/screens/index.js +306 -0
  1306. package/dist/modules/oauth_backend/screens/index.js.map +1 -0
  1307. package/dist/modules/partner/functions.d.ts.map +1 -1
  1308. package/dist/modules/partner/functions.js +74 -6
  1309. package/dist/modules/partner/functions.js.map +1 -1
  1310. package/dist/modules/partner/index.d.ts.map +1 -1
  1311. package/dist/modules/partner/index.js +0 -1
  1312. package/dist/modules/partner/index.js.map +1 -1
  1313. package/dist/modules/partner/models.d.ts +4 -4
  1314. package/dist/modules/partner/models.d.ts.map +1 -1
  1315. package/dist/modules/partner/models.js +9 -7
  1316. package/dist/modules/partner/models.js.map +1 -1
  1317. package/dist/modules/partner/types.d.ts +2 -2
  1318. package/dist/modules/partner/types.js +2 -2
  1319. package/dist/modules/partner_backend/client/address-view.mjs +5 -5
  1320. package/dist/modules/partner_backend/client/address-view.mjs.map +1 -1
  1321. package/dist/modules/partner_backend/client/address.css +22 -10
  1322. package/dist/modules/partner_backend/client/partner.css +116 -0
  1323. package/dist/modules/partner_backend/index.d.ts +1 -1
  1324. package/dist/modules/partner_backend/index.d.ts.map +1 -1
  1325. package/dist/modules/partner_backend/index.js +34 -4
  1326. package/dist/modules/partner_backend/index.js.map +1 -1
  1327. package/dist/modules/partner_backend/menus.js +2 -2
  1328. package/dist/modules/partner_backend/menus.js.map +1 -1
  1329. package/dist/modules/partner_backend/routes.d.ts +3 -1
  1330. package/dist/modules/partner_backend/routes.d.ts.map +1 -1
  1331. package/dist/modules/partner_backend/routes.js +236 -91
  1332. package/dist/modules/partner_backend/routes.js.map +1 -1
  1333. package/dist/modules/partner_backend/screens/form.d.ts +21 -0
  1334. package/dist/modules/partner_backend/screens/form.d.ts.map +1 -0
  1335. package/dist/modules/partner_backend/screens/form.js +101 -0
  1336. package/dist/modules/partner_backend/screens/form.js.map +1 -0
  1337. package/dist/modules/partner_backend/screens/index.d.ts +5 -0
  1338. package/dist/modules/partner_backend/screens/index.d.ts.map +1 -0
  1339. package/dist/modules/partner_backend/screens/index.js +4 -0
  1340. package/dist/modules/partner_backend/screens/index.js.map +1 -0
  1341. package/dist/modules/partner_backend/screens/list.d.ts +6 -0
  1342. package/dist/modules/partner_backend/screens/list.d.ts.map +1 -0
  1343. package/dist/modules/partner_backend/screens/list.js +94 -0
  1344. package/dist/modules/partner_backend/screens/list.js.map +1 -0
  1345. package/dist/modules/partner_backend/screens/new.d.ts +5 -0
  1346. package/dist/modules/partner_backend/screens/new.d.ts.map +1 -0
  1347. package/dist/modules/partner_backend/screens/new.js +58 -0
  1348. package/dist/modules/partner_backend/screens/new.js.map +1 -0
  1349. package/dist/modules/partner_backend/screens/types.d.ts +44 -0
  1350. package/dist/modules/partner_backend/screens/types.d.ts.map +1 -0
  1351. package/dist/modules/partner_backend/screens/types.js +2 -0
  1352. package/dist/modules/partner_backend/screens/types.js.map +1 -0
  1353. package/dist/modules/partner_mail_backend/index.d.ts +5 -0
  1354. package/dist/modules/partner_mail_backend/index.d.ts.map +1 -0
  1355. package/dist/modules/partner_mail_backend/index.js +29 -0
  1356. package/dist/modules/partner_mail_backend/index.js.map +1 -0
  1357. package/dist/modules/pos/functions.d.ts +18 -2
  1358. package/dist/modules/pos/functions.d.ts.map +1 -1
  1359. package/dist/modules/pos/functions.js +3279 -345
  1360. package/dist/modules/pos/functions.js.map +1 -1
  1361. package/dist/modules/pos/index.d.ts +2 -1
  1362. package/dist/modules/pos/index.d.ts.map +1 -1
  1363. package/dist/modules/pos/index.js +5 -5
  1364. package/dist/modules/pos/index.js.map +1 -1
  1365. package/dist/modules/pos/models.d.ts.map +1 -1
  1366. package/dist/modules/pos/models.js +189 -1
  1367. package/dist/modules/pos/models.js.map +1 -1
  1368. package/dist/modules/pos/relations.d.ts.map +1 -1
  1369. package/dist/modules/pos/relations.js +11 -0
  1370. package/dist/modules/pos/relations.js.map +1 -1
  1371. package/dist/modules/pos_backend/index.js +182 -154
  1372. package/dist/modules/pos_backend/index.js.map +1 -1
  1373. package/dist/modules/pos_backend/screens.d.ts +1 -0
  1374. package/dist/modules/pos_backend/screens.d.ts.map +1 -1
  1375. package/dist/modules/pos_backend/screens.js +28 -38
  1376. package/dist/modules/pos_backend/screens.js.map +1 -1
  1377. package/dist/modules/pos_channel/catalog.d.ts +27 -0
  1378. package/dist/modules/pos_channel/catalog.d.ts.map +1 -0
  1379. package/dist/modules/pos_channel/catalog.js +310 -0
  1380. package/dist/modules/pos_channel/catalog.js.map +1 -0
  1381. package/dist/modules/pos_channel/index.d.ts +7 -0
  1382. package/dist/modules/pos_channel/index.d.ts.map +1 -0
  1383. package/dist/modules/pos_channel/index.js +61 -0
  1384. package/dist/modules/pos_channel/index.js.map +1 -0
  1385. package/dist/modules/pos_channel/offline.d.ts +66 -0
  1386. package/dist/modules/pos_channel/offline.d.ts.map +1 -0
  1387. package/dist/modules/pos_channel/offline.js +16 -0
  1388. package/dist/modules/pos_channel/offline.js.map +1 -0
  1389. package/dist/modules/pos_channel/operations.d.ts +422 -0
  1390. package/dist/modules/pos_channel/operations.d.ts.map +1 -0
  1391. package/dist/modules/pos_channel/operations.js +1781 -0
  1392. package/dist/modules/pos_channel/operations.js.map +1 -0
  1393. package/dist/modules/pos_channel/sync.d.ts +6 -0
  1394. package/dist/modules/pos_channel/sync.d.ts.map +1 -0
  1395. package/dist/modules/pos_channel/sync.js +1161 -0
  1396. package/dist/modules/pos_channel/sync.js.map +1 -0
  1397. package/dist/modules/pricing/index.d.ts.map +1 -1
  1398. package/dist/modules/pricing/index.js +3 -4
  1399. package/dist/modules/pricing/index.js.map +1 -1
  1400. package/dist/modules/pricing_backend/index.js +135 -78
  1401. package/dist/modules/pricing_backend/index.js.map +1 -1
  1402. package/dist/modules/pricing_backend/screens/index.d.ts +5 -0
  1403. package/dist/modules/pricing_backend/screens/index.d.ts.map +1 -0
  1404. package/dist/modules/pricing_backend/screens/index.js +4 -0
  1405. package/dist/modules/pricing_backend/screens/index.js.map +1 -0
  1406. package/dist/modules/pricing_backend/screens/pricelist-create.d.ts +10 -0
  1407. package/dist/modules/pricing_backend/screens/pricelist-create.d.ts.map +1 -0
  1408. package/dist/modules/pricing_backend/screens/pricelist-create.js +30 -0
  1409. package/dist/modules/pricing_backend/screens/pricelist-create.js.map +1 -0
  1410. package/dist/modules/pricing_backend/screens/pricelist-detail.d.ts +15 -0
  1411. package/dist/modules/pricing_backend/screens/pricelist-detail.d.ts.map +1 -0
  1412. package/dist/modules/pricing_backend/screens/pricelist-detail.js +164 -0
  1413. package/dist/modules/pricing_backend/screens/pricelist-detail.js.map +1 -0
  1414. package/dist/modules/pricing_backend/screens/pricelists-list.d.ts +11 -0
  1415. package/dist/modules/pricing_backend/screens/pricelists-list.d.ts.map +1 -0
  1416. package/dist/modules/pricing_backend/screens/pricelists-list.js +27 -0
  1417. package/dist/modules/pricing_backend/screens/pricelists-list.js.map +1 -0
  1418. package/dist/modules/pricing_backend/screens/shared.d.ts +21 -0
  1419. package/dist/modules/pricing_backend/screens/shared.d.ts.map +1 -0
  1420. package/dist/modules/pricing_backend/screens/shared.js +3 -0
  1421. package/dist/modules/pricing_backend/screens/shared.js.map +1 -0
  1422. package/dist/modules/product/functions.d.ts.map +1 -1
  1423. package/dist/modules/product/functions.js +679 -50
  1424. package/dist/modules/product/functions.js.map +1 -1
  1425. package/dist/modules/product/index.d.ts +2 -0
  1426. package/dist/modules/product/index.d.ts.map +1 -1
  1427. package/dist/modules/product/index.js +2 -2
  1428. package/dist/modules/product/index.js.map +1 -1
  1429. package/dist/modules/product/models.d.ts +1 -1
  1430. package/dist/modules/product/models.d.ts.map +1 -1
  1431. package/dist/modules/product/models.js +27 -4
  1432. package/dist/modules/product/models.js.map +1 -1
  1433. package/dist/modules/product/relations.d.ts.map +1 -1
  1434. package/dist/modules/product/relations.js +4 -0
  1435. package/dist/modules/product/relations.js.map +1 -1
  1436. package/dist/modules/product/sellable.d.ts +26 -0
  1437. package/dist/modules/product/sellable.d.ts.map +1 -0
  1438. package/dist/modules/product/sellable.js +56 -0
  1439. package/dist/modules/product/sellable.js.map +1 -0
  1440. package/dist/modules/product/types.d.ts +2 -2
  1441. package/dist/modules/product/views.d.ts.map +1 -1
  1442. package/dist/modules/product/views.js +5 -1
  1443. package/dist/modules/product/views.js.map +1 -1
  1444. package/dist/modules/product_activity_backend/index.d.ts.map +1 -1
  1445. package/dist/modules/product_activity_backend/index.js +2 -3
  1446. package/dist/modules/product_activity_backend/index.js.map +1 -1
  1447. package/dist/modules/product_backend/client/media-upload-view.d.mts.map +1 -1
  1448. package/dist/modules/product_backend/client/media-upload-view.mjs +1 -0
  1449. package/dist/modules/product_backend/client/media-upload-view.mjs.map +1 -1
  1450. package/dist/modules/product_backend/client/product.css +964 -0
  1451. package/dist/modules/product_backend/index.d.ts +5 -6
  1452. package/dist/modules/product_backend/index.d.ts.map +1 -1
  1453. package/dist/modules/product_backend/index.js +203 -14
  1454. package/dist/modules/product_backend/index.js.map +1 -1
  1455. package/dist/modules/product_backend/menus.js +2 -2
  1456. package/dist/modules/product_backend/menus.js.map +1 -1
  1457. package/dist/modules/product_backend/relation-control.d.ts +85 -0
  1458. package/dist/modules/product_backend/relation-control.d.ts.map +1 -0
  1459. package/dist/modules/product_backend/relation-control.js +129 -0
  1460. package/dist/modules/product_backend/relation-control.js.map +1 -0
  1461. package/dist/modules/product_backend/routes.d.ts.map +1 -1
  1462. package/dist/modules/product_backend/routes.js +502 -196
  1463. package/dist/modules/product_backend/routes.js.map +1 -1
  1464. package/dist/modules/product_backend/screens/attributes.d.ts +7 -0
  1465. package/dist/modules/product_backend/screens/attributes.d.ts.map +1 -0
  1466. package/dist/modules/product_backend/screens/attributes.js +66 -0
  1467. package/dist/modules/product_backend/screens/attributes.js.map +1 -0
  1468. package/dist/modules/product_backend/screens/create.d.ts +16 -0
  1469. package/dist/modules/product_backend/screens/create.d.ts.map +1 -0
  1470. package/dist/modules/product_backend/screens/create.js +86 -0
  1471. package/dist/modules/product_backend/screens/create.js.map +1 -0
  1472. package/dist/modules/product_backend/screens/detail.d.ts +87 -0
  1473. package/dist/modules/product_backend/screens/detail.d.ts.map +1 -0
  1474. package/dist/modules/product_backend/screens/detail.js +381 -0
  1475. package/dist/modules/product_backend/screens/detail.js.map +1 -0
  1476. package/dist/modules/product_backend/screens/favorite.d.ts +6 -0
  1477. package/dist/modules/product_backend/screens/favorite.d.ts.map +1 -0
  1478. package/dist/modules/product_backend/screens/favorite.js +43 -0
  1479. package/dist/modules/product_backend/screens/favorite.js.map +1 -0
  1480. package/dist/modules/product_backend/screens/index.d.ts +10 -0
  1481. package/dist/modules/product_backend/screens/index.d.ts.map +1 -0
  1482. package/dist/modules/product_backend/screens/index.js +7 -0
  1483. package/dist/modules/product_backend/screens/index.js.map +1 -0
  1484. package/dist/modules/product_backend/screens/list.d.ts +54 -0
  1485. package/dist/modules/product_backend/screens/list.d.ts.map +1 -0
  1486. package/dist/modules/product_backend/screens/list.js +124 -0
  1487. package/dist/modules/product_backend/screens/list.js.map +1 -0
  1488. package/dist/modules/product_backend/screens/variant.d.ts +9 -0
  1489. package/dist/modules/product_backend/screens/variant.d.ts.map +1 -0
  1490. package/dist/modules/product_backend/screens/variant.js +113 -0
  1491. package/dist/modules/product_backend/screens/variant.js.map +1 -0
  1492. package/dist/modules/product_mail_backend/index.d.ts.map +1 -1
  1493. package/dist/modules/product_mail_backend/index.js +2 -3
  1494. package/dist/modules/product_mail_backend/index.js.map +1 -1
  1495. package/dist/modules/product_media/functions.d.ts.map +1 -1
  1496. package/dist/modules/product_media/functions.js +59 -6
  1497. package/dist/modules/product_media/functions.js.map +1 -1
  1498. package/dist/modules/product_media/index.js +0 -1
  1499. package/dist/modules/product_media/index.js.map +1 -1
  1500. package/dist/modules/product_variant_activity_backend/index.d.ts.map +1 -1
  1501. package/dist/modules/product_variant_activity_backend/index.js +2 -3
  1502. package/dist/modules/product_variant_activity_backend/index.js.map +1 -1
  1503. package/dist/modules/product_variant_mail_backend/index.d.ts.map +1 -1
  1504. package/dist/modules/product_variant_mail_backend/index.js +2 -3
  1505. package/dist/modules/product_variant_mail_backend/index.js.map +1 -1
  1506. package/dist/modules/purchase/functions.d.ts.map +1 -1
  1507. package/dist/modules/purchase/functions.js +852 -225
  1508. package/dist/modules/purchase/functions.js.map +1 -1
  1509. package/dist/modules/purchase/index.d.ts.map +1 -1
  1510. package/dist/modules/purchase/index.js +30 -5
  1511. package/dist/modules/purchase/index.js.map +1 -1
  1512. package/dist/modules/purchase/models.d.ts.map +1 -1
  1513. package/dist/modules/purchase/models.js +1 -0
  1514. package/dist/modules/purchase/models.js.map +1 -1
  1515. package/dist/modules/purchase/reports.d.ts +4 -0
  1516. package/dist/modules/purchase/reports.d.ts.map +1 -0
  1517. package/dist/modules/purchase/reports.js +86 -0
  1518. package/dist/modules/purchase/reports.js.map +1 -0
  1519. package/dist/modules/purchase_backend/index.js +513 -112
  1520. package/dist/modules/purchase_backend/index.js.map +1 -1
  1521. package/dist/modules/purchase_backend/screens/index.d.ts +10 -0
  1522. package/dist/modules/purchase_backend/screens/index.d.ts.map +1 -0
  1523. package/dist/modules/purchase_backend/screens/index.js +10 -0
  1524. package/dist/modules/purchase_backend/screens/index.js.map +1 -0
  1525. package/dist/modules/purchase_backend/screens/order-detail.d.ts +31 -0
  1526. package/dist/modules/purchase_backend/screens/order-detail.d.ts.map +1 -0
  1527. package/dist/modules/purchase_backend/screens/order-detail.js +204 -0
  1528. package/dist/modules/purchase_backend/screens/order-detail.js.map +1 -0
  1529. package/dist/modules/purchase_backend/screens/order-list-shared.d.ts +7 -0
  1530. package/dist/modules/purchase_backend/screens/order-list-shared.d.ts.map +1 -0
  1531. package/dist/modules/purchase_backend/screens/order-list-shared.js +58 -0
  1532. package/dist/modules/purchase_backend/screens/order-list-shared.js.map +1 -0
  1533. package/dist/modules/purchase_backend/screens/overview.d.ts +19 -0
  1534. package/dist/modules/purchase_backend/screens/overview.d.ts.map +1 -0
  1535. package/dist/modules/purchase_backend/screens/overview.js +52 -0
  1536. package/dist/modules/purchase_backend/screens/overview.js.map +1 -0
  1537. package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts +14 -0
  1538. package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts.map +1 -0
  1539. package/dist/modules/purchase_backend/screens/purchase-orders-list.js +26 -0
  1540. package/dist/modules/purchase_backend/screens/purchase-orders-list.js.map +1 -0
  1541. package/dist/modules/purchase_backend/screens/rfq-create.d.ts +16 -0
  1542. package/dist/modules/purchase_backend/screens/rfq-create.d.ts.map +1 -0
  1543. package/dist/modules/purchase_backend/screens/rfq-create.js +24 -0
  1544. package/dist/modules/purchase_backend/screens/rfq-create.js.map +1 -0
  1545. package/dist/modules/purchase_backend/screens/rfqs-list.d.ts +18 -0
  1546. package/dist/modules/purchase_backend/screens/rfqs-list.d.ts.map +1 -0
  1547. package/dist/modules/purchase_backend/screens/rfqs-list.js +28 -0
  1548. package/dist/modules/purchase_backend/screens/rfqs-list.js.map +1 -0
  1549. package/dist/modules/purchase_backend/screens/shared.d.ts +18 -0
  1550. package/dist/modules/purchase_backend/screens/shared.d.ts.map +1 -0
  1551. package/dist/modules/purchase_backend/screens/shared.js +30 -0
  1552. package/dist/modules/purchase_backend/screens/shared.js.map +1 -0
  1553. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.d.ts +20 -0
  1554. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.d.ts.map +1 -0
  1555. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.js +25 -0
  1556. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.js.map +1 -0
  1557. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts +33 -0
  1558. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts.map +1 -0
  1559. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js +73 -0
  1560. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js.map +1 -0
  1561. package/dist/modules/purchase_staff_channel/channel-routes.d.ts +2 -0
  1562. package/dist/modules/purchase_staff_channel/channel-routes.d.ts.map +1 -0
  1563. package/dist/modules/purchase_staff_channel/channel-routes.js +119 -0
  1564. package/dist/modules/purchase_staff_channel/channel-routes.js.map +1 -0
  1565. package/dist/modules/purchase_staff_channel/index.d.ts +8 -0
  1566. package/dist/modules/purchase_staff_channel/index.d.ts.map +1 -0
  1567. package/dist/modules/purchase_staff_channel/index.js +45 -0
  1568. package/dist/modules/purchase_staff_channel/index.js.map +1 -0
  1569. package/dist/modules/purchase_staff_channel/order-routes.d.ts +2 -0
  1570. package/dist/modules/purchase_staff_channel/order-routes.d.ts.map +1 -0
  1571. package/dist/modules/purchase_staff_channel/order-routes.js +743 -0
  1572. package/dist/modules/purchase_staff_channel/order-routes.js.map +1 -0
  1573. package/dist/modules/purchase_staff_channel/product-routes.d.ts +2 -0
  1574. package/dist/modules/purchase_staff_channel/product-routes.d.ts.map +1 -0
  1575. package/dist/modules/purchase_staff_channel/product-routes.js +183 -0
  1576. package/dist/modules/purchase_staff_channel/product-routes.js.map +1 -0
  1577. package/dist/modules/purchase_staff_channel/vendor-bill-routes.d.ts +2 -0
  1578. package/dist/modules/purchase_staff_channel/vendor-bill-routes.d.ts.map +1 -0
  1579. package/dist/modules/purchase_staff_channel/vendor-bill-routes.js +189 -0
  1580. package/dist/modules/purchase_staff_channel/vendor-bill-routes.js.map +1 -0
  1581. package/dist/modules/quality/functions.d.ts +3 -0
  1582. package/dist/modules/quality/functions.d.ts.map +1 -0
  1583. package/dist/modules/quality/functions.js +381 -0
  1584. package/dist/modules/quality/functions.js.map +1 -0
  1585. package/dist/modules/quality/index.d.ts +5 -0
  1586. package/dist/modules/quality/index.d.ts.map +1 -0
  1587. package/dist/modules/quality/index.js +19 -0
  1588. package/dist/modules/quality/index.js.map +1 -0
  1589. package/dist/modules/quality/models.d.ts +3 -0
  1590. package/dist/modules/quality/models.d.ts.map +1 -0
  1591. package/dist/modules/quality/models.js +91 -0
  1592. package/dist/modules/quality/models.js.map +1 -0
  1593. package/dist/modules/quality_staff_channel/channel-routes.d.ts +2 -0
  1594. package/dist/modules/quality_staff_channel/channel-routes.d.ts.map +1 -0
  1595. package/dist/modules/quality_staff_channel/channel-routes.js +484 -0
  1596. package/dist/modules/quality_staff_channel/channel-routes.js.map +1 -0
  1597. package/dist/modules/quality_staff_channel/index.d.ts +5 -0
  1598. package/dist/modules/quality_staff_channel/index.d.ts.map +1 -0
  1599. package/dist/modules/quality_staff_channel/index.js +30 -0
  1600. package/dist/modules/quality_staff_channel/index.js.map +1 -0
  1601. package/dist/modules/report/functions.d.ts +3 -0
  1602. package/dist/modules/report/functions.d.ts.map +1 -0
  1603. package/dist/modules/report/functions.js +197 -0
  1604. package/dist/modules/report/functions.js.map +1 -0
  1605. package/dist/modules/report/index.d.ts +3 -0
  1606. package/dist/modules/report/index.d.ts.map +1 -0
  1607. package/dist/modules/report/index.js +21 -0
  1608. package/dist/modules/report/index.js.map +1 -0
  1609. package/dist/modules/report/jobs.d.ts +3 -0
  1610. package/dist/modules/report/jobs.d.ts.map +1 -0
  1611. package/dist/modules/report/jobs.js +18 -0
  1612. package/dist/modules/report/jobs.js.map +1 -0
  1613. package/dist/modules/report/models.d.ts +3 -0
  1614. package/dist/modules/report/models.d.ts.map +1 -0
  1615. package/dist/modules/report/models.js +45 -0
  1616. package/dist/modules/report/models.js.map +1 -0
  1617. package/dist/modules/report/routes.d.ts +19 -0
  1618. package/dist/modules/report/routes.d.ts.map +1 -0
  1619. package/dist/modules/report/routes.js +138 -0
  1620. package/dist/modules/report/routes.js.map +1 -0
  1621. package/dist/modules/report_backend/index.d.ts +3 -0
  1622. package/dist/modules/report_backend/index.d.ts.map +1 -0
  1623. package/dist/modules/report_backend/index.js +67 -0
  1624. package/dist/modules/report_backend/index.js.map +1 -0
  1625. package/dist/modules/report_backend/routes.d.ts +10 -0
  1626. package/dist/modules/report_backend/routes.d.ts.map +1 -0
  1627. package/dist/modules/report_backend/routes.js +87 -0
  1628. package/dist/modules/report_backend/routes.js.map +1 -0
  1629. package/dist/modules/report_backend/screens/index.d.ts +13 -0
  1630. package/dist/modules/report_backend/screens/index.d.ts.map +1 -0
  1631. package/dist/modules/report_backend/screens/index.js +91 -0
  1632. package/dist/modules/report_backend/screens/index.js.map +1 -0
  1633. package/dist/modules/sale/functions.d.ts.map +1 -1
  1634. package/dist/modules/sale/functions.js +806 -238
  1635. package/dist/modules/sale/functions.js.map +1 -1
  1636. package/dist/modules/sale/index.d.ts.map +1 -1
  1637. package/dist/modules/sale/index.js +44 -5
  1638. package/dist/modules/sale/index.js.map +1 -1
  1639. package/dist/modules/sale/models.d.ts.map +1 -1
  1640. package/dist/modules/sale/models.js +47 -1
  1641. package/dist/modules/sale/models.js.map +1 -1
  1642. package/dist/modules/sale/relations.d.ts.map +1 -1
  1643. package/dist/modules/sale/relations.js +6 -0
  1644. package/dist/modules/sale/relations.js.map +1 -1
  1645. package/dist/modules/sale/reports.d.ts +4 -0
  1646. package/dist/modules/sale/reports.d.ts.map +1 -0
  1647. package/dist/modules/sale/reports.js +132 -0
  1648. package/dist/modules/sale/reports.js.map +1 -0
  1649. package/dist/modules/sale/scope.d.ts +31 -0
  1650. package/dist/modules/sale/scope.d.ts.map +1 -0
  1651. package/dist/modules/sale/scope.js +34 -0
  1652. package/dist/modules/sale/scope.js.map +1 -0
  1653. package/dist/modules/sale_activity_backend/index.d.ts.map +1 -1
  1654. package/dist/modules/sale_activity_backend/index.js +0 -1
  1655. package/dist/modules/sale_activity_backend/index.js.map +1 -1
  1656. package/dist/modules/sale_backend/index.js +338 -121
  1657. package/dist/modules/sale_backend/index.js.map +1 -1
  1658. package/dist/modules/sale_backend/screens/index.d.ts +9 -0
  1659. package/dist/modules/sale_backend/screens/index.d.ts.map +1 -0
  1660. package/dist/modules/sale_backend/screens/index.js +9 -0
  1661. package/dist/modules/sale_backend/screens/index.js.map +1 -0
  1662. package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts +14 -0
  1663. package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts.map +1 -0
  1664. package/dist/modules/sale_backend/screens/invoicing-policies-list.js +48 -0
  1665. package/dist/modules/sale_backend/screens/invoicing-policies-list.js.map +1 -0
  1666. package/dist/modules/sale_backend/screens/invoicing-policy-create.d.ts +14 -0
  1667. package/dist/modules/sale_backend/screens/invoicing-policy-create.d.ts.map +1 -0
  1668. package/dist/modules/sale_backend/screens/invoicing-policy-create.js +38 -0
  1669. package/dist/modules/sale_backend/screens/invoicing-policy-create.js.map +1 -0
  1670. package/dist/modules/sale_backend/screens/order-detail.d.ts +43 -0
  1671. package/dist/modules/sale_backend/screens/order-detail.d.ts.map +1 -0
  1672. package/dist/modules/sale_backend/screens/order-detail.js +226 -0
  1673. package/dist/modules/sale_backend/screens/order-detail.js.map +1 -0
  1674. package/dist/modules/sale_backend/screens/overview.d.ts +31 -0
  1675. package/dist/modules/sale_backend/screens/overview.d.ts.map +1 -0
  1676. package/dist/modules/sale_backend/screens/overview.js +73 -0
  1677. package/dist/modules/sale_backend/screens/overview.js.map +1 -0
  1678. package/dist/modules/sale_backend/screens/quotation-create.d.ts +13 -0
  1679. package/dist/modules/sale_backend/screens/quotation-create.d.ts.map +1 -0
  1680. package/dist/modules/sale_backend/screens/quotation-create.js +19 -0
  1681. package/dist/modules/sale_backend/screens/quotation-create.js.map +1 -0
  1682. package/dist/modules/sale_backend/screens/quotations-list.d.ts +25 -0
  1683. package/dist/modules/sale_backend/screens/quotations-list.d.ts.map +1 -0
  1684. package/dist/modules/sale_backend/screens/quotations-list.js +96 -0
  1685. package/dist/modules/sale_backend/screens/quotations-list.js.map +1 -0
  1686. package/dist/modules/sale_backend/screens/sales-orders-list.d.ts +25 -0
  1687. package/dist/modules/sale_backend/screens/sales-orders-list.d.ts.map +1 -0
  1688. package/dist/modules/sale_backend/screens/sales-orders-list.js +100 -0
  1689. package/dist/modules/sale_backend/screens/sales-orders-list.js.map +1 -0
  1690. package/dist/modules/sale_backend/screens/shared.d.ts +4 -0
  1691. package/dist/modules/sale_backend/screens/shared.d.ts.map +1 -0
  1692. package/dist/modules/sale_backend/screens/shared.js +4 -0
  1693. package/dist/modules/sale_backend/screens/shared.js.map +1 -0
  1694. package/dist/modules/sale_mail_backend/index.d.ts.map +1 -1
  1695. package/dist/modules/sale_mail_backend/index.js +0 -1
  1696. package/dist/modules/sale_mail_backend/index.js.map +1 -1
  1697. package/dist/modules/sale_staff_channel/channel-routes.d.ts +2 -0
  1698. package/dist/modules/sale_staff_channel/channel-routes.d.ts.map +1 -0
  1699. package/dist/modules/sale_staff_channel/channel-routes.js +285 -0
  1700. package/dist/modules/sale_staff_channel/channel-routes.js.map +1 -0
  1701. package/dist/modules/sale_staff_channel/index.d.ts +7 -0
  1702. package/dist/modules/sale_staff_channel/index.d.ts.map +1 -0
  1703. package/dist/modules/sale_staff_channel/index.js +44 -0
  1704. package/dist/modules/sale_staff_channel/index.js.map +1 -0
  1705. package/dist/modules/sale_staff_channel/order-routes.d.ts +2 -0
  1706. package/dist/modules/sale_staff_channel/order-routes.d.ts.map +1 -0
  1707. package/dist/modules/sale_staff_channel/order-routes.js +647 -0
  1708. package/dist/modules/sale_staff_channel/order-routes.js.map +1 -0
  1709. package/dist/modules/sale_staff_channel/product-routes.d.ts +2 -0
  1710. package/dist/modules/sale_staff_channel/product-routes.d.ts.map +1 -0
  1711. package/dist/modules/sale_staff_channel/product-routes.js +183 -0
  1712. package/dist/modules/sale_staff_channel/product-routes.js.map +1 -0
  1713. package/dist/modules/stock/functions.d.ts.map +1 -1
  1714. package/dist/modules/stock/functions.js +1239 -332
  1715. package/dist/modules/stock/functions.js.map +1 -1
  1716. package/dist/modules/stock/index.d.ts +2 -0
  1717. package/dist/modules/stock/index.d.ts.map +1 -1
  1718. package/dist/modules/stock/index.js +29 -6
  1719. package/dist/modules/stock/index.js.map +1 -1
  1720. package/dist/modules/stock/models.d.ts.map +1 -1
  1721. package/dist/modules/stock/models.js +1 -0
  1722. package/dist/modules/stock/models.js.map +1 -1
  1723. package/dist/modules/stock/reports.d.ts +4 -0
  1724. package/dist/modules/stock/reports.d.ts.map +1 -0
  1725. package/dist/modules/stock/reports.js +100 -0
  1726. package/dist/modules/stock/reports.js.map +1 -0
  1727. package/dist/modules/stock/routing.d.ts +1 -1
  1728. package/dist/modules/stock/routing.d.ts.map +1 -1
  1729. package/dist/modules/stock/routing.js +35 -30
  1730. package/dist/modules/stock/routing.js.map +1 -1
  1731. package/dist/modules/stock/scope.d.ts +23 -0
  1732. package/dist/modules/stock/scope.d.ts.map +1 -0
  1733. package/dist/modules/stock/scope.js +26 -0
  1734. package/dist/modules/stock/scope.js.map +1 -0
  1735. package/dist/modules/stock/units.d.ts +14 -0
  1736. package/dist/modules/stock/units.d.ts.map +1 -0
  1737. package/dist/modules/stock/units.js +50 -0
  1738. package/dist/modules/stock/units.js.map +1 -0
  1739. package/dist/modules/stock_activity_backend/index.d.ts.map +1 -1
  1740. package/dist/modules/stock_activity_backend/index.js +0 -1
  1741. package/dist/modules/stock_activity_backend/index.js.map +1 -1
  1742. package/dist/modules/stock_backend/client/editor-view.d.mts.map +1 -1
  1743. package/dist/modules/stock_backend/client/editor-view.mjs +12 -10
  1744. package/dist/modules/stock_backend/client/editor-view.mjs.map +1 -1
  1745. package/dist/modules/stock_backend/index.js +27 -20
  1746. package/dist/modules/stock_backend/index.js.map +1 -1
  1747. package/dist/modules/stock_backend/routes.d.ts.map +1 -1
  1748. package/dist/modules/stock_backend/routes.js +485 -232
  1749. package/dist/modules/stock_backend/routes.js.map +1 -1
  1750. package/dist/modules/stock_backend/screens/forecast.d.ts +28 -0
  1751. package/dist/modules/stock_backend/screens/forecast.d.ts.map +1 -0
  1752. package/dist/modules/stock_backend/screens/forecast.js +108 -0
  1753. package/dist/modules/stock_backend/screens/forecast.js.map +1 -0
  1754. package/dist/modules/stock_backend/screens/index.d.ts +22 -0
  1755. package/dist/modules/stock_backend/screens/index.d.ts.map +1 -0
  1756. package/dist/modules/stock_backend/screens/index.js +22 -0
  1757. package/dist/modules/stock_backend/screens/index.js.map +1 -0
  1758. package/dist/modules/stock_backend/screens/inventory.d.ts +27 -0
  1759. package/dist/modules/stock_backend/screens/inventory.d.ts.map +1 -0
  1760. package/dist/modules/stock_backend/screens/inventory.js +128 -0
  1761. package/dist/modules/stock_backend/screens/inventory.js.map +1 -0
  1762. package/dist/modules/stock_backend/screens/location-create.d.ts +15 -0
  1763. package/dist/modules/stock_backend/screens/location-create.d.ts.map +1 -0
  1764. package/dist/modules/stock_backend/screens/location-create.js +75 -0
  1765. package/dist/modules/stock_backend/screens/location-create.js.map +1 -0
  1766. package/dist/modules/stock_backend/screens/locations-list.d.ts +21 -0
  1767. package/dist/modules/stock_backend/screens/locations-list.d.ts.map +1 -0
  1768. package/dist/modules/stock_backend/screens/locations-list.js +62 -0
  1769. package/dist/modules/stock_backend/screens/locations-list.js.map +1 -0
  1770. package/dist/modules/stock_backend/screens/lot-create.d.ts +14 -0
  1771. package/dist/modules/stock_backend/screens/lot-create.d.ts.map +1 -0
  1772. package/dist/modules/stock_backend/screens/lot-create.js +60 -0
  1773. package/dist/modules/stock_backend/screens/lot-create.js.map +1 -0
  1774. package/dist/modules/stock_backend/screens/lot-detail.d.ts +30 -0
  1775. package/dist/modules/stock_backend/screens/lot-detail.d.ts.map +1 -0
  1776. package/dist/modules/stock_backend/screens/lot-detail.js +84 -0
  1777. package/dist/modules/stock_backend/screens/lot-detail.js.map +1 -0
  1778. package/dist/modules/stock_backend/screens/lots-list.d.ts +25 -0
  1779. package/dist/modules/stock_backend/screens/lots-list.d.ts.map +1 -0
  1780. package/dist/modules/stock_backend/screens/lots-list.js +54 -0
  1781. package/dist/modules/stock_backend/screens/lots-list.js.map +1 -0
  1782. package/dist/modules/stock_backend/screens/picking-type-create.d.ts +15 -0
  1783. package/dist/modules/stock_backend/screens/picking-type-create.d.ts.map +1 -0
  1784. package/dist/modules/stock_backend/screens/picking-type-create.js +89 -0
  1785. package/dist/modules/stock_backend/screens/picking-type-create.js.map +1 -0
  1786. package/dist/modules/stock_backend/screens/picking-types-list.d.ts +22 -0
  1787. package/dist/modules/stock_backend/screens/picking-types-list.d.ts.map +1 -0
  1788. package/dist/modules/stock_backend/screens/picking-types-list.js +80 -0
  1789. package/dist/modules/stock_backend/screens/picking-types-list.js.map +1 -0
  1790. package/dist/modules/stock_backend/screens/replenishment-create.d.ts +17 -0
  1791. package/dist/modules/stock_backend/screens/replenishment-create.d.ts.map +1 -0
  1792. package/dist/modules/stock_backend/screens/replenishment-create.js +74 -0
  1793. package/dist/modules/stock_backend/screens/replenishment-create.js.map +1 -0
  1794. package/dist/modules/stock_backend/screens/replenishment-list.d.ts +29 -0
  1795. package/dist/modules/stock_backend/screens/replenishment-list.d.ts.map +1 -0
  1796. package/dist/modules/stock_backend/screens/replenishment-list.js +84 -0
  1797. package/dist/modules/stock_backend/screens/replenishment-list.js.map +1 -0
  1798. package/dist/modules/stock_backend/screens/shared.d.ts +12 -0
  1799. package/dist/modules/stock_backend/screens/shared.d.ts.map +1 -0
  1800. package/dist/modules/stock_backend/screens/shared.js +29 -0
  1801. package/dist/modules/stock_backend/screens/shared.js.map +1 -0
  1802. package/dist/modules/stock_backend/screens/stock-route-create.d.ts +13 -0
  1803. package/dist/modules/stock_backend/screens/stock-route-create.d.ts.map +1 -0
  1804. package/dist/modules/stock_backend/screens/stock-route-create.js +52 -0
  1805. package/dist/modules/stock_backend/screens/stock-route-create.js.map +1 -0
  1806. package/dist/modules/stock_backend/screens/stock-route-detail.d.ts +30 -0
  1807. package/dist/modules/stock_backend/screens/stock-route-detail.d.ts.map +1 -0
  1808. package/dist/modules/stock_backend/screens/stock-route-detail.js +131 -0
  1809. package/dist/modules/stock_backend/screens/stock-route-detail.js.map +1 -0
  1810. package/dist/modules/stock_backend/screens/stock-routes-list.d.ts +22 -0
  1811. package/dist/modules/stock_backend/screens/stock-routes-list.d.ts.map +1 -0
  1812. package/dist/modules/stock_backend/screens/stock-routes-list.js +51 -0
  1813. package/dist/modules/stock_backend/screens/stock-routes-list.js.map +1 -0
  1814. package/dist/modules/stock_backend/screens/stock.d.ts +7 -0
  1815. package/dist/modules/stock_backend/screens/stock.d.ts.map +1 -0
  1816. package/dist/modules/stock_backend/screens/stock.js +13 -0
  1817. package/dist/modules/stock_backend/screens/stock.js.map +1 -0
  1818. package/dist/modules/stock_backend/screens/transfer-create.d.ts +13 -0
  1819. package/dist/modules/stock_backend/screens/transfer-create.d.ts.map +1 -0
  1820. package/dist/modules/stock_backend/screens/transfer-create.js +38 -0
  1821. package/dist/modules/stock_backend/screens/transfer-create.js.map +1 -0
  1822. package/dist/modules/stock_backend/screens/transfer-detail.d.ts +27 -0
  1823. package/dist/modules/stock_backend/screens/transfer-detail.d.ts.map +1 -0
  1824. package/dist/modules/stock_backend/screens/transfer-detail.js +91 -0
  1825. package/dist/modules/stock_backend/screens/transfer-detail.js.map +1 -0
  1826. package/dist/modules/stock_backend/screens/transfers-list.d.ts +25 -0
  1827. package/dist/modules/stock_backend/screens/transfers-list.d.ts.map +1 -0
  1828. package/dist/modules/stock_backend/screens/transfers-list.js +81 -0
  1829. package/dist/modules/stock_backend/screens/transfers-list.js.map +1 -0
  1830. package/dist/modules/stock_backend/screens/warehouse-create.d.ts +13 -0
  1831. package/dist/modules/stock_backend/screens/warehouse-create.d.ts.map +1 -0
  1832. package/dist/modules/stock_backend/screens/warehouse-create.js +79 -0
  1833. package/dist/modules/stock_backend/screens/warehouse-create.js.map +1 -0
  1834. package/dist/modules/stock_backend/screens/warehouses-list.d.ts +21 -0
  1835. package/dist/modules/stock_backend/screens/warehouses-list.d.ts.map +1 -0
  1836. package/dist/modules/stock_backend/screens/warehouses-list.js +60 -0
  1837. package/dist/modules/stock_backend/screens/warehouses-list.js.map +1 -0
  1838. package/dist/modules/stock_lot_activity_backend/index.d.ts.map +1 -1
  1839. package/dist/modules/stock_lot_activity_backend/index.js +0 -1
  1840. package/dist/modules/stock_lot_activity_backend/index.js.map +1 -1
  1841. package/dist/modules/stock_lot_mail_backend/index.d.ts.map +1 -1
  1842. package/dist/modules/stock_lot_mail_backend/index.js +0 -1
  1843. package/dist/modules/stock_lot_mail_backend/index.js.map +1 -1
  1844. package/dist/modules/stock_mail_backend/index.d.ts.map +1 -1
  1845. package/dist/modules/stock_mail_backend/index.js +0 -1
  1846. package/dist/modules/stock_mail_backend/index.js.map +1 -1
  1847. package/dist/modules/stock_mail_inbound/index.d.ts.map +1 -1
  1848. package/dist/modules/stock_mail_inbound/index.js +0 -2
  1849. package/dist/modules/stock_mail_inbound/index.js.map +1 -1
  1850. package/dist/modules/stock_staff_channel/channel-routes.d.ts +656 -0
  1851. package/dist/modules/stock_staff_channel/channel-routes.d.ts.map +1 -0
  1852. package/dist/modules/stock_staff_channel/channel-routes.js +445 -0
  1853. package/dist/modules/stock_staff_channel/channel-routes.js.map +1 -0
  1854. package/dist/modules/stock_staff_channel/functions.d.ts +3 -0
  1855. package/dist/modules/stock_staff_channel/functions.d.ts.map +1 -0
  1856. package/dist/modules/stock_staff_channel/functions.js +954 -0
  1857. package/dist/modules/stock_staff_channel/functions.js.map +1 -0
  1858. package/dist/modules/stock_staff_channel/index.d.ts +8 -0
  1859. package/dist/modules/stock_staff_channel/index.d.ts.map +1 -0
  1860. package/dist/modules/stock_staff_channel/index.js +37 -0
  1861. package/dist/modules/stock_staff_channel/index.js.map +1 -0
  1862. package/dist/modules/stock_staff_channel/models.d.ts +4 -0
  1863. package/dist/modules/stock_staff_channel/models.d.ts.map +1 -0
  1864. package/dist/modules/stock_staff_channel/models.js +119 -0
  1865. package/dist/modules/stock_staff_channel/models.js.map +1 -0
  1866. package/dist/modules/stock_staff_channel/operation-routes.d.ts +2 -0
  1867. package/dist/modules/stock_staff_channel/operation-routes.d.ts.map +1 -0
  1868. package/dist/modules/stock_staff_channel/operation-routes.js +1258 -0
  1869. package/dist/modules/stock_staff_channel/operation-routes.js.map +1 -0
  1870. package/dist/modules/storage/functions.d.ts.map +1 -1
  1871. package/dist/modules/storage/functions.js +18 -5
  1872. package/dist/modules/storage/functions.js.map +1 -1
  1873. package/dist/modules/storage/index.js +0 -1
  1874. package/dist/modules/storage/index.js.map +1 -1
  1875. package/dist/modules/storage/jobs.d.ts +21 -1
  1876. package/dist/modules/storage/jobs.d.ts.map +1 -1
  1877. package/dist/modules/storage/jobs.js +142 -2
  1878. package/dist/modules/storage/jobs.js.map +1 -1
  1879. package/dist/modules/storage/models.d.ts.map +1 -1
  1880. package/dist/modules/storage/models.js +2 -0
  1881. package/dist/modules/storage/models.js.map +1 -1
  1882. package/dist/modules/storage/policy.d.ts +5 -0
  1883. package/dist/modules/storage/policy.d.ts.map +1 -0
  1884. package/dist/modules/storage/policy.js +13 -0
  1885. package/dist/modules/storage/policy.js.map +1 -0
  1886. package/dist/modules/storage/routes.d.ts +1 -0
  1887. package/dist/modules/storage/routes.d.ts.map +1 -1
  1888. package/dist/modules/storage/routes.js +19 -15
  1889. package/dist/modules/storage/routes.js.map +1 -1
  1890. package/dist/modules/uom/convert.d.ts +1 -1
  1891. package/dist/modules/uom/convert.js +2 -2
  1892. package/dist/modules/uom/convert.js.map +1 -1
  1893. package/dist/modules/uom/functions.d.ts.map +1 -1
  1894. package/dist/modules/uom/functions.js +39 -4
  1895. package/dist/modules/uom/functions.js.map +1 -1
  1896. package/dist/modules/uom/index.d.ts.map +1 -1
  1897. package/dist/modules/uom/index.js +1 -2
  1898. package/dist/modules/uom/index.js.map +1 -1
  1899. package/dist/modules/uom/messages.js +2 -2
  1900. package/dist/modules/uom/messages.js.map +1 -1
  1901. package/dist/modules/uom/models.d.ts +1 -1
  1902. package/dist/modules/uom/models.d.ts.map +1 -1
  1903. package/dist/modules/uom/models.js +1 -1
  1904. package/dist/modules/uom/models.js.map +1 -1
  1905. package/dist/modules/user/authorization.d.ts +80 -0
  1906. package/dist/modules/user/authorization.d.ts.map +1 -0
  1907. package/dist/modules/user/authorization.js +1039 -0
  1908. package/dist/modules/user/authorization.js.map +1 -0
  1909. package/dist/modules/user/functions.d.ts.map +1 -1
  1910. package/dist/modules/user/functions.js +188 -32
  1911. package/dist/modules/user/functions.js.map +1 -1
  1912. package/dist/modules/user/index.d.ts +4 -1
  1913. package/dist/modules/user/index.d.ts.map +1 -1
  1914. package/dist/modules/user/index.js +2 -3
  1915. package/dist/modules/user/index.js.map +1 -1
  1916. package/dist/modules/user/login.d.ts +1 -27
  1917. package/dist/modules/user/login.d.ts.map +1 -1
  1918. package/dist/modules/user/login.js +5 -45
  1919. package/dist/modules/user/login.js.map +1 -1
  1920. package/dist/modules/user/messages.d.ts +6 -0
  1921. package/dist/modules/user/messages.d.ts.map +1 -1
  1922. package/dist/modules/user/messages.js +6 -0
  1923. package/dist/modules/user/messages.js.map +1 -1
  1924. package/dist/modules/user/models.d.ts +1 -1
  1925. package/dist/modules/user/models.d.ts.map +1 -1
  1926. package/dist/modules/user/models.js +73 -9
  1927. package/dist/modules/user/models.js.map +1 -1
  1928. package/dist/modules/user/relations.d.ts.map +1 -1
  1929. package/dist/modules/user/relations.js +6 -0
  1930. package/dist/modules/user/relations.js.map +1 -1
  1931. package/dist/modules/user/roles.d.ts +11 -1
  1932. package/dist/modules/user/roles.d.ts.map +1 -1
  1933. package/dist/modules/user/roles.js +402 -117
  1934. package/dist/modules/user/roles.js.map +1 -1
  1935. package/dist/modules/user/routes.js +1 -1
  1936. package/dist/modules/user/routes.js.map +1 -1
  1937. package/dist/modules/user_backend/index.d.ts +1 -1
  1938. package/dist/modules/user_backend/index.d.ts.map +1 -1
  1939. package/dist/modules/user_backend/index.js +1 -3
  1940. package/dist/modules/user_backend/index.js.map +1 -1
  1941. package/dist/modules/user_backend/messages.d.ts +64 -0
  1942. package/dist/modules/user_backend/messages.d.ts.map +1 -1
  1943. package/dist/modules/user_backend/messages.js +64 -0
  1944. package/dist/modules/user_backend/messages.js.map +1 -1
  1945. package/dist/modules/user_backend/routes.d.ts.map +1 -1
  1946. package/dist/modules/user_backend/routes.js +379 -69
  1947. package/dist/modules/user_backend/routes.js.map +1 -1
  1948. package/dist/modules/user_backend/screens/index.d.ts +11 -0
  1949. package/dist/modules/user_backend/screens/index.d.ts.map +1 -0
  1950. package/dist/modules/user_backend/screens/index.js +8 -0
  1951. package/dist/modules/user_backend/screens/index.js.map +1 -0
  1952. package/dist/modules/user_backend/screens/presets-form.d.ts +16 -0
  1953. package/dist/modules/user_backend/screens/presets-form.d.ts.map +1 -0
  1954. package/dist/modules/user_backend/screens/presets-form.js +37 -0
  1955. package/dist/modules/user_backend/screens/presets-form.js.map +1 -0
  1956. package/dist/modules/user_backend/screens/profile-form.d.ts +14 -0
  1957. package/dist/modules/user_backend/screens/profile-form.d.ts.map +1 -0
  1958. package/dist/modules/user_backend/screens/profile-form.js +37 -0
  1959. package/dist/modules/user_backend/screens/profile-form.js.map +1 -0
  1960. package/dist/modules/user_backend/screens/role-form.d.ts +21 -0
  1961. package/dist/modules/user_backend/screens/role-form.d.ts.map +1 -0
  1962. package/dist/modules/user_backend/screens/role-form.js +93 -0
  1963. package/dist/modules/user_backend/screens/role-form.js.map +1 -0
  1964. package/dist/modules/user_backend/screens/roles-list.d.ts +15 -0
  1965. package/dist/modules/user_backend/screens/roles-list.d.ts.map +1 -0
  1966. package/dist/modules/user_backend/screens/roles-list.js +48 -0
  1967. package/dist/modules/user_backend/screens/roles-list.js.map +1 -0
  1968. package/dist/modules/user_backend/screens/sessions.d.ts +5 -0
  1969. package/dist/modules/user_backend/screens/sessions.d.ts.map +1 -0
  1970. package/dist/modules/user_backend/screens/sessions.js +35 -0
  1971. package/dist/modules/user_backend/screens/sessions.js.map +1 -0
  1972. package/dist/modules/user_backend/screens/types.d.ts +68 -0
  1973. package/dist/modules/user_backend/screens/types.d.ts.map +1 -0
  1974. package/dist/modules/user_backend/screens/types.js +2 -0
  1975. package/dist/modules/user_backend/screens/types.js.map +1 -0
  1976. package/dist/modules/user_backend/screens/user-form.d.ts +56 -0
  1977. package/dist/modules/user_backend/screens/user-form.d.ts.map +1 -0
  1978. package/dist/modules/user_backend/screens/user-form.js +202 -0
  1979. package/dist/modules/user_backend/screens/user-form.js.map +1 -0
  1980. package/dist/modules/user_backend/screens/users-list.d.ts +17 -0
  1981. package/dist/modules/user_backend/screens/users-list.d.ts.map +1 -0
  1982. package/dist/modules/user_backend/screens/users-list.js +56 -0
  1983. package/dist/modules/user_backend/screens/users-list.js.map +1 -0
  1984. package/dist/modules/website/cms.d.ts +18 -1
  1985. package/dist/modules/website/cms.d.ts.map +1 -1
  1986. package/dist/modules/website/cms.js +655 -43
  1987. package/dist/modules/website/cms.js.map +1 -1
  1988. package/dist/modules/website/customer.d.ts.map +1 -1
  1989. package/dist/modules/website/customer.js +249 -1
  1990. package/dist/modules/website/customer.js.map +1 -1
  1991. package/dist/modules/website/index.d.ts.map +1 -1
  1992. package/dist/modules/website/index.js +38 -4
  1993. package/dist/modules/website/index.js.map +1 -1
  1994. package/dist/modules/website/media-usage.d.ts +38 -0
  1995. package/dist/modules/website/media-usage.d.ts.map +1 -0
  1996. package/dist/modules/website/media-usage.js +87 -0
  1997. package/dist/modules/website/media-usage.js.map +1 -0
  1998. package/dist/modules/website/models.d.ts.map +1 -1
  1999. package/dist/modules/website/models.js +101 -0
  2000. package/dist/modules/website/models.js.map +1 -1
  2001. package/dist/modules/website/paths.d.ts +31 -0
  2002. package/dist/modules/website/paths.d.ts.map +1 -0
  2003. package/dist/modules/website/paths.js +48 -0
  2004. package/dist/modules/website/paths.js.map +1 -0
  2005. package/dist/modules/website/publication.d.ts +3 -0
  2006. package/dist/modules/website/publication.d.ts.map +1 -0
  2007. package/dist/modules/website/publication.js +366 -0
  2008. package/dist/modules/website/publication.js.map +1 -0
  2009. package/dist/modules/website/renderable.d.ts +32 -0
  2010. package/dist/modules/website/renderable.d.ts.map +1 -0
  2011. package/dist/modules/website/renderable.js +59 -0
  2012. package/dist/modules/website/renderable.js.map +1 -0
  2013. package/dist/modules/website/sections.d.ts.map +1 -1
  2014. package/dist/modules/website/sections.js +25 -1
  2015. package/dist/modules/website/sections.js.map +1 -1
  2016. package/dist/modules/website_backend/csv.d.ts +23 -0
  2017. package/dist/modules/website_backend/csv.d.ts.map +1 -0
  2018. package/dist/modules/website_backend/csv.js +31 -0
  2019. package/dist/modules/website_backend/csv.js.map +1 -0
  2020. package/dist/modules/website_backend/index.js +398 -2
  2021. package/dist/modules/website_backend/index.js.map +1 -1
  2022. package/dist/modules/website_backend/menus.d.ts.map +1 -1
  2023. package/dist/modules/website_backend/menus.js +39 -6
  2024. package/dist/modules/website_backend/menus.js.map +1 -1
  2025. package/dist/modules/website_backend/routes.d.ts.map +1 -1
  2026. package/dist/modules/website_backend/routes.js +1079 -138
  2027. package/dist/modules/website_backend/routes.js.map +1 -1
  2028. package/dist/modules/website_backend/screens/index.d.ts +425 -0
  2029. package/dist/modules/website_backend/screens/index.d.ts.map +1 -0
  2030. package/dist/modules/website_backend/screens/index.js +1778 -0
  2031. package/dist/modules/website_backend/screens/index.js.map +1 -0
  2032. package/dist/modules/website_backend/screens/page-frame.d.ts +16 -0
  2033. package/dist/modules/website_backend/screens/page-frame.d.ts.map +1 -0
  2034. package/dist/modules/website_backend/screens/page-frame.js +13 -0
  2035. package/dist/modules/website_backend/screens/page-frame.js.map +1 -0
  2036. package/dist/modules/website_form/audit.d.ts +27 -0
  2037. package/dist/modules/website_form/audit.d.ts.map +1 -0
  2038. package/dist/modules/website_form/audit.js +30 -0
  2039. package/dist/modules/website_form/audit.js.map +1 -0
  2040. package/dist/modules/website_form/functions.d.ts.map +1 -1
  2041. package/dist/modules/website_form/functions.js +416 -12
  2042. package/dist/modules/website_form/functions.js.map +1 -1
  2043. package/dist/modules/website_form/index.js +24 -2
  2044. package/dist/modules/website_form/index.js.map +1 -1
  2045. package/dist/modules/website_form/jobs.d.ts +11 -0
  2046. package/dist/modules/website_form/jobs.d.ts.map +1 -0
  2047. package/dist/modules/website_form/jobs.js +80 -0
  2048. package/dist/modules/website_form/jobs.js.map +1 -0
  2049. package/dist/modules/website_form/models.d.ts.map +1 -1
  2050. package/dist/modules/website_form/models.js +89 -0
  2051. package/dist/modules/website_form/models.js.map +1 -1
  2052. package/dist/modules/website_form/purge.d.ts +22 -0
  2053. package/dist/modules/website_form/purge.d.ts.map +1 -0
  2054. package/dist/modules/website_form/purge.js +59 -0
  2055. package/dist/modules/website_form/purge.js.map +1 -0
  2056. package/dist/modules/website_form/retention.d.ts +70 -0
  2057. package/dist/modules/website_form/retention.d.ts.map +1 -0
  2058. package/dist/modules/website_form/retention.js +145 -0
  2059. package/dist/modules/website_form/retention.js.map +1 -0
  2060. package/dist/modules/website_form/routes.d.ts.map +1 -1
  2061. package/dist/modules/website_form/routes.js +37 -3
  2062. package/dist/modules/website_form/routes.js.map +1 -1
  2063. package/dist/modules/website_form_mail/index.d.ts +36 -0
  2064. package/dist/modules/website_form_mail/index.d.ts.map +1 -0
  2065. package/dist/modules/website_form_mail/index.js +137 -0
  2066. package/dist/modules/website_form_mail/index.js.map +1 -0
  2067. package/dist/modules/website_hospitality/channel-routes.d.ts +2 -0
  2068. package/dist/modules/website_hospitality/channel-routes.d.ts.map +1 -0
  2069. package/dist/modules/website_hospitality/channel-routes.js +355 -0
  2070. package/dist/modules/website_hospitality/channel-routes.js.map +1 -0
  2071. package/dist/modules/website_hospitality/functions.d.ts.map +1 -1
  2072. package/dist/modules/website_hospitality/functions.js +27 -2
  2073. package/dist/modules/website_hospitality/functions.js.map +1 -1
  2074. package/dist/modules/website_hospitality/index.js +4 -3
  2075. package/dist/modules/website_hospitality/index.js.map +1 -1
  2076. package/dist/modules/website_hospitality/models.d.ts.map +1 -1
  2077. package/dist/modules/website_hospitality/models.js +2 -0
  2078. package/dist/modules/website_hospitality/models.js.map +1 -1
  2079. package/dist/modules/website_menu/functions.d.ts.map +1 -1
  2080. package/dist/modules/website_menu/functions.js +235 -9
  2081. package/dist/modules/website_menu/functions.js.map +1 -1
  2082. package/dist/modules/website_menu/index.js +8 -1
  2083. package/dist/modules/website_menu/index.js.map +1 -1
  2084. package/dist/modules/website_retail/channel-routes.d.ts +2 -0
  2085. package/dist/modules/website_retail/channel-routes.d.ts.map +1 -0
  2086. package/dist/modules/website_retail/channel-routes.js +305 -0
  2087. package/dist/modules/website_retail/channel-routes.js.map +1 -0
  2088. package/dist/modules/website_retail/functions.d.ts +14 -1
  2089. package/dist/modules/website_retail/functions.d.ts.map +1 -1
  2090. package/dist/modules/website_retail/functions.js +6 -6
  2091. package/dist/modules/website_retail/functions.js.map +1 -1
  2092. package/dist/modules/website_retail/index.js +24 -3
  2093. package/dist/modules/website_retail/index.js.map +1 -1
  2094. package/dist/modules/website_retail/models.d.ts.map +1 -1
  2095. package/dist/modules/website_retail/models.js +30 -0
  2096. package/dist/modules/website_retail/models.js.map +1 -1
  2097. package/dist/modules/website_retail/online.d.ts +3 -0
  2098. package/dist/modules/website_retail/online.d.ts.map +1 -0
  2099. package/dist/modules/website_retail/online.js +710 -0
  2100. package/dist/modules/website_retail/online.js.map +1 -0
  2101. package/dist/modules/website_search/client/search.d.mts +16 -2
  2102. package/dist/modules/website_search/client/search.d.mts.map +1 -1
  2103. package/dist/modules/website_search/client/search.mjs +112 -6
  2104. package/dist/modules/website_search/client/search.mjs.map +1 -1
  2105. package/dist/modules/website_search/functions.d.ts +3 -0
  2106. package/dist/modules/website_search/functions.d.ts.map +1 -0
  2107. package/dist/modules/website_search/functions.js +129 -0
  2108. package/dist/modules/website_search/functions.js.map +1 -0
  2109. package/dist/modules/website_search/index.js +6 -1
  2110. package/dist/modules/website_search/index.js.map +1 -1
  2111. package/dist/modules/website_search/islands.d.ts +6 -0
  2112. package/dist/modules/website_search/islands.d.ts.map +1 -1
  2113. package/dist/modules/website_search/islands.js +8 -2
  2114. package/dist/modules/website_search/islands.js.map +1 -1
  2115. package/dist/modules/website_search/jobs.d.ts +3 -0
  2116. package/dist/modules/website_search/jobs.d.ts.map +1 -0
  2117. package/dist/modules/website_search/jobs.js +101 -0
  2118. package/dist/modules/website_search/jobs.js.map +1 -0
  2119. package/dist/modules/website_search/models.d.ts +15 -0
  2120. package/dist/modules/website_search/models.d.ts.map +1 -0
  2121. package/dist/modules/website_search/models.js +58 -0
  2122. package/dist/modules/website_search/models.js.map +1 -0
  2123. package/dist/modules/website_search/rebuild.d.ts +33 -0
  2124. package/dist/modules/website_search/rebuild.d.ts.map +1 -0
  2125. package/dist/modules/website_search/rebuild.js +125 -0
  2126. package/dist/modules/website_search/rebuild.js.map +1 -0
  2127. package/dist/modules/website_seo/functions.d.ts +3 -0
  2128. package/dist/modules/website_seo/functions.d.ts.map +1 -0
  2129. package/dist/modules/website_seo/functions.js +164 -0
  2130. package/dist/modules/website_seo/functions.js.map +1 -0
  2131. package/dist/modules/website_seo/index.js +15 -5
  2132. package/dist/modules/website_seo/index.js.map +1 -1
  2133. package/dist/modules/website_seo/projection.d.ts +52 -0
  2134. package/dist/modules/website_seo/projection.d.ts.map +1 -0
  2135. package/dist/modules/website_seo/projection.js +129 -0
  2136. package/dist/modules/website_seo/projection.js.map +1 -0
  2137. package/dist/modules/website_seo/routes.d.ts +3 -0
  2138. package/dist/modules/website_seo/routes.d.ts.map +1 -0
  2139. package/dist/modules/website_seo/routes.js +56 -0
  2140. package/dist/modules/website_seo/routes.js.map +1 -0
  2141. package/dist/permission-catalogue.d.ts +5 -0
  2142. package/dist/permission-catalogue.d.ts.map +1 -0
  2143. package/dist/permission-catalogue.js +1518 -0
  2144. package/dist/permission-catalogue.js.map +1 -0
  2145. package/dist/scaffold/index.d.ts +2 -0
  2146. package/dist/scaffold/index.d.ts.map +1 -0
  2147. package/dist/scaffold/index.js +31 -0
  2148. package/dist/scaffold/index.js.map +1 -0
  2149. package/dist/scaffold/templates/README.md.tmpl +17 -0
  2150. package/dist/scaffold/templates/gitignore.tmpl +2 -0
  2151. package/dist/scaffold/templates/ket.workspace.mjs.tmpl +1 -0
  2152. package/dist/scaffold/templates/package.json.tmpl +15 -0
  2153. package/dist/themes/hospitality/templates/website.columns.ktl +4 -0
  2154. package/dist/themes/paper/templates/website.columns.ktl +4 -0
  2155. package/dist/ui/actions.d.ts +4 -0
  2156. package/dist/ui/actions.d.ts.map +1 -1
  2157. package/dist/ui/actions.js +1 -1
  2158. package/dist/ui/actions.js.map +1 -1
  2159. package/dist/ui/activity.d.ts +1 -1
  2160. package/dist/ui/activity.d.ts.map +1 -1
  2161. package/dist/ui/activity.js +3 -5
  2162. package/dist/ui/activity.js.map +1 -1
  2163. package/dist/ui/attachments.js +1 -1
  2164. package/dist/ui/attachments.js.map +1 -1
  2165. package/dist/ui/auth.d.ts +36 -0
  2166. package/dist/ui/auth.d.ts.map +1 -1
  2167. package/dist/ui/auth.js +55 -0
  2168. package/dist/ui/auth.js.map +1 -1
  2169. package/dist/ui/board-page.d.ts +6 -0
  2170. package/dist/ui/board-page.d.ts.map +1 -0
  2171. package/dist/ui/board-page.js +4 -0
  2172. package/dist/ui/board-page.js.map +1 -0
  2173. package/dist/ui/charts.d.ts +83 -0
  2174. package/dist/ui/charts.d.ts.map +1 -0
  2175. package/dist/ui/charts.js +105 -0
  2176. package/dist/ui/charts.js.map +1 -0
  2177. package/dist/ui/chrome.d.ts +45 -2
  2178. package/dist/ui/chrome.d.ts.map +1 -1
  2179. package/dist/ui/chrome.js +47 -5
  2180. package/dist/ui/chrome.js.map +1 -1
  2181. package/dist/ui/client/activity-view.mjs +7 -7
  2182. package/dist/ui/client/activity-view.mjs.map +1 -1
  2183. package/dist/ui/client/activity.css +6 -34
  2184. package/dist/ui/client/calendar-view.d.mts.map +1 -1
  2185. package/dist/ui/client/calendar-view.mjs +7 -6
  2186. package/dist/ui/client/calendar-view.mjs.map +1 -1
  2187. package/dist/ui/client/calendar.css +4 -14
  2188. package/dist/ui/client/chart-view.d.ts +51 -0
  2189. package/dist/ui/client/chart-view.d.ts.map +1 -0
  2190. package/dist/ui/client/chart-view.js +192 -0
  2191. package/dist/ui/client/chart-view.js.map +1 -0
  2192. package/dist/ui/client/flow-app.css +387 -0
  2193. package/dist/ui/client/flow-board-view.d.mts +8 -0
  2194. package/dist/ui/client/flow-board-view.d.mts.map +1 -0
  2195. package/dist/ui/client/flow-board-view.mjs +161 -0
  2196. package/dist/ui/client/flow-board-view.mjs.map +1 -0
  2197. package/dist/ui/client/flow-board.d.mts +3 -0
  2198. package/dist/ui/client/flow-board.d.mts.map +1 -0
  2199. package/dist/ui/client/flow-board.mjs +7 -0
  2200. package/dist/ui/client/flow-board.mjs.map +1 -0
  2201. package/dist/ui/client/flow-map-view.d.mts +2 -0
  2202. package/dist/ui/client/flow-map-view.d.mts.map +1 -0
  2203. package/dist/ui/client/flow-map-view.mjs +235 -0
  2204. package/dist/ui/client/flow-map-view.mjs.map +1 -0
  2205. package/dist/ui/client/flow-map.d.mts +3 -0
  2206. package/dist/ui/client/flow-map.d.mts.map +1 -0
  2207. package/dist/ui/client/flow-map.mjs +7 -0
  2208. package/dist/ui/client/flow-map.mjs.map +1 -0
  2209. package/dist/ui/client/live-doc-blocks.d.ts +19 -0
  2210. package/dist/ui/client/live-doc-blocks.d.ts.map +1 -0
  2211. package/dist/ui/client/live-doc-blocks.js +23 -0
  2212. package/dist/ui/client/live-doc-blocks.js.map +1 -0
  2213. package/dist/ui/client/live-doc-markdown.d.ts +18 -0
  2214. package/dist/ui/client/live-doc-markdown.d.ts.map +1 -0
  2215. package/dist/ui/client/live-doc-markdown.js +175 -0
  2216. package/dist/ui/client/live-doc-markdown.js.map +1 -0
  2217. package/dist/ui/client/live-doc-shell.d.ts +101 -0
  2218. package/dist/ui/client/live-doc-shell.d.ts.map +1 -0
  2219. package/dist/ui/client/live-doc-shell.js +251 -0
  2220. package/dist/ui/client/live-doc-shell.js.map +1 -0
  2221. package/dist/ui/client/live-doc-view.d.ts +33 -0
  2222. package/dist/ui/client/live-doc-view.d.ts.map +1 -0
  2223. package/dist/ui/client/live-doc-view.js +1237 -0
  2224. package/dist/ui/client/live-doc-view.js.map +1 -0
  2225. package/dist/ui/client/live-doc.css +243 -0
  2226. package/dist/ui/client/live-doc.d.mts +12 -0
  2227. package/dist/ui/client/live-doc.d.mts.map +1 -0
  2228. package/dist/ui/client/live-doc.mjs +11 -0
  2229. package/dist/ui/client/live-doc.mjs.map +7 -0
  2230. package/dist/ui/client/mail-bundle.d.mts +9 -0
  2231. package/dist/ui/client/mail-bundle.d.mts.map +1 -0
  2232. package/dist/ui/client/mail-bundle.mjs +50 -0
  2233. package/dist/ui/client/mail-bundle.mjs.map +7 -0
  2234. package/dist/ui/client/mail-entry.d.mts +11 -0
  2235. package/dist/ui/client/mail-entry.d.mts.map +1 -0
  2236. package/dist/ui/client/mail-entry.mjs +9 -0
  2237. package/dist/ui/client/mail-entry.mjs.map +1 -0
  2238. package/dist/ui/client/mail-view.d.mts.map +1 -1
  2239. package/dist/ui/client/mail-view.mjs +5 -3
  2240. package/dist/ui/client/mail-view.mjs.map +1 -1
  2241. package/dist/ui/client/mail.css +3 -3
  2242. package/dist/ui/client/relation-select-view.d.ts +77 -0
  2243. package/dist/ui/client/relation-select-view.d.ts.map +1 -0
  2244. package/dist/ui/client/relation-select-view.js +216 -0
  2245. package/dist/ui/client/relation-select-view.js.map +1 -0
  2246. package/dist/ui/client/table-selection-view.d.ts +4 -0
  2247. package/dist/ui/client/table-selection-view.d.ts.map +1 -0
  2248. package/dist/ui/client/table-selection-view.js +345 -0
  2249. package/dist/ui/client/table-selection-view.js.map +1 -0
  2250. package/dist/ui/dashboard-page.d.ts +6 -0
  2251. package/dist/ui/dashboard-page.d.ts.map +1 -0
  2252. package/dist/ui/dashboard-page.js +4 -0
  2253. package/dist/ui/dashboard-page.js.map +1 -0
  2254. package/dist/ui/data.d.ts +51 -1
  2255. package/dist/ui/data.d.ts.map +1 -1
  2256. package/dist/ui/data.js +87 -1
  2257. package/dist/ui/data.js.map +1 -1
  2258. package/dist/ui/date-picker.d.ts.map +1 -1
  2259. package/dist/ui/date-picker.js +2 -2
  2260. package/dist/ui/date-picker.js.map +1 -1
  2261. package/dist/ui/form-page.d.ts +6 -0
  2262. package/dist/ui/form-page.d.ts.map +1 -0
  2263. package/dist/ui/form-page.js +5 -0
  2264. package/dist/ui/form-page.js.map +1 -0
  2265. package/dist/ui/form.d.ts +6 -1
  2266. package/dist/ui/form.d.ts.map +1 -1
  2267. package/dist/ui/form.js +8 -5
  2268. package/dist/ui/form.js.map +1 -1
  2269. package/dist/ui/format.d.ts +13 -2
  2270. package/dist/ui/format.d.ts.map +1 -1
  2271. package/dist/ui/format.js +28 -7
  2272. package/dist/ui/format.js.map +1 -1
  2273. package/dist/ui/gantt.d.ts +52 -0
  2274. package/dist/ui/gantt.d.ts.map +1 -0
  2275. package/dist/ui/gantt.js +92 -0
  2276. package/dist/ui/gantt.js.map +1 -0
  2277. package/dist/ui/hooks.d.ts.map +1 -1
  2278. package/dist/ui/hooks.js +14 -0
  2279. package/dist/ui/hooks.js.map +1 -1
  2280. package/dist/ui/icons.d.ts.map +1 -1
  2281. package/dist/ui/icons.js +6 -1
  2282. package/dist/ui/icons.js.map +1 -1
  2283. package/dist/ui/index.d.ts +96 -15
  2284. package/dist/ui/index.d.ts.map +1 -1
  2285. package/dist/ui/index.js +79 -14
  2286. package/dist/ui/index.js.map +1 -1
  2287. package/dist/ui/layout.d.ts +43 -38
  2288. package/dist/ui/layout.d.ts.map +1 -1
  2289. package/dist/ui/layout.js +29 -37
  2290. package/dist/ui/layout.js.map +1 -1
  2291. package/dist/ui/list-page.d.ts +19 -0
  2292. package/dist/ui/list-page.d.ts.map +1 -0
  2293. package/dist/ui/list-page.js +21 -0
  2294. package/dist/ui/list-page.js.map +1 -0
  2295. package/dist/ui/media.d.ts.map +1 -1
  2296. package/dist/ui/media.js +1 -1
  2297. package/dist/ui/media.js.map +1 -1
  2298. package/dist/ui/modal.d.ts +26 -1
  2299. package/dist/ui/modal.d.ts.map +1 -1
  2300. package/dist/ui/modal.js +18 -2
  2301. package/dist/ui/modal.js.map +1 -1
  2302. package/dist/ui/nav.d.ts +21 -1
  2303. package/dist/ui/nav.d.ts.map +1 -1
  2304. package/dist/ui/nav.js +43 -8
  2305. package/dist/ui/nav.js.map +1 -1
  2306. package/dist/ui/navigation.d.ts +36 -2
  2307. package/dist/ui/navigation.d.ts.map +1 -1
  2308. package/dist/ui/navigation.js +60 -5
  2309. package/dist/ui/navigation.js.map +1 -1
  2310. package/dist/ui/partner.d.ts +18 -0
  2311. package/dist/ui/partner.d.ts.map +1 -0
  2312. package/dist/ui/partner.js +11 -0
  2313. package/dist/ui/partner.js.map +1 -0
  2314. package/dist/ui/primitives.d.ts +28 -10
  2315. package/dist/ui/primitives.d.ts.map +1 -1
  2316. package/dist/ui/primitives.js +21 -7
  2317. package/dist/ui/primitives.js.map +1 -1
  2318. package/dist/ui/product-media.d.ts +47 -0
  2319. package/dist/ui/product-media.d.ts.map +1 -0
  2320. package/dist/ui/product-media.js +67 -0
  2321. package/dist/ui/product-media.js.map +1 -0
  2322. package/dist/ui/product-variants.d.ts +68 -0
  2323. package/dist/ui/product-variants.d.ts.map +1 -0
  2324. package/dist/ui/product-variants.js +81 -0
  2325. package/dist/ui/product-variants.js.map +1 -0
  2326. package/dist/ui/record-detail.d.ts +70 -0
  2327. package/dist/ui/record-detail.d.ts.map +1 -0
  2328. package/dist/ui/record-detail.js +35 -0
  2329. package/dist/ui/record-detail.js.map +1 -0
  2330. package/dist/ui/record-page.d.ts +16 -0
  2331. package/dist/ui/record-page.d.ts.map +1 -0
  2332. package/dist/ui/record-page.js +13 -0
  2333. package/dist/ui/record-page.js.map +1 -0
  2334. package/dist/ui/record.d.ts +15 -3
  2335. package/dist/ui/record.d.ts.map +1 -1
  2336. package/dist/ui/record.js +6 -5
  2337. package/dist/ui/record.js.map +1 -1
  2338. package/dist/ui/state.d.ts +20 -1
  2339. package/dist/ui/state.d.ts.map +1 -1
  2340. package/dist/ui/state.js +17 -0
  2341. package/dist/ui/state.js.map +1 -1
  2342. package/dist/ui/surfaces.d.ts +30 -2
  2343. package/dist/ui/surfaces.d.ts.map +1 -1
  2344. package/dist/ui/surfaces.js +39 -2
  2345. package/dist/ui/surfaces.js.map +1 -1
  2346. package/dist/ui/table.d.ts +25 -2
  2347. package/dist/ui/table.d.ts.map +1 -1
  2348. package/dist/ui/table.js +10 -6
  2349. package/dist/ui/table.js.map +1 -1
  2350. package/dist/ui/timeframe.d.ts +39 -0
  2351. package/dist/ui/timeframe.d.ts.map +1 -0
  2352. package/dist/ui/timeframe.js +36 -0
  2353. package/dist/ui/timeframe.js.map +1 -0
  2354. package/dist/ui/workspace-page.d.ts +16 -0
  2355. package/dist/ui/workspace-page.d.ts.map +1 -0
  2356. package/dist/ui/workspace-page.js +15 -0
  2357. package/dist/ui/workspace-page.js.map +1 -0
  2358. package/package.json +16 -3
  2359. package/dist/modules/account/tt99.d.ts +0 -30
  2360. package/dist/modules/account/tt99.d.ts.map +0 -1
  2361. package/dist/modules/account/tt99.js +0 -1661
  2362. package/dist/modules/account/tt99.js.map +0 -1
  2363. package/dist/modules/account_backend/accounting-overview-screen.d.ts +0 -18
  2364. package/dist/modules/account_backend/accounting-overview-screen.d.ts.map +0 -1
  2365. package/dist/modules/account_backend/accounting-overview-screen.js +0 -104
  2366. package/dist/modules/account_backend/accounting-overview-screen.js.map +0 -1
  2367. package/dist/modules/account_backend/accounts-screen.d.ts +0 -13
  2368. package/dist/modules/account_backend/accounts-screen.d.ts.map +0 -1
  2369. package/dist/modules/account_backend/accounts-screen.js +0 -49
  2370. package/dist/modules/account_backend/accounts-screen.js.map +0 -1
  2371. package/dist/modules/account_backend/customer-invoices-screen.d.ts +0 -14
  2372. package/dist/modules/account_backend/customer-invoices-screen.d.ts.map +0 -1
  2373. package/dist/modules/account_backend/customer-invoices-screen.js +0 -63
  2374. package/dist/modules/account_backend/customer-invoices-screen.js.map +0 -1
  2375. package/dist/modules/account_backend/general-ledger-screen.d.ts +0 -13
  2376. package/dist/modules/account_backend/general-ledger-screen.d.ts.map +0 -1
  2377. package/dist/modules/account_backend/general-ledger-screen.js +0 -56
  2378. package/dist/modules/account_backend/general-ledger-screen.js.map +0 -1
  2379. package/dist/modules/account_backend/journal-entries-screen.d.ts +0 -14
  2380. package/dist/modules/account_backend/journal-entries-screen.d.ts.map +0 -1
  2381. package/dist/modules/account_backend/journal-entries-screen.js +0 -45
  2382. package/dist/modules/account_backend/journal-entries-screen.js.map +0 -1
  2383. package/dist/modules/account_backend/journals-screen.d.ts +0 -14
  2384. package/dist/modules/account_backend/journals-screen.d.ts.map +0 -1
  2385. package/dist/modules/account_backend/journals-screen.js +0 -53
  2386. package/dist/modules/account_backend/journals-screen.js.map +0 -1
  2387. package/dist/modules/account_backend/move-detail-screen.d.ts +0 -10
  2388. package/dist/modules/account_backend/move-detail-screen.d.ts.map +0 -1
  2389. package/dist/modules/account_backend/move-detail-screen.js +0 -100
  2390. package/dist/modules/account_backend/move-detail-screen.js.map +0 -1
  2391. package/dist/modules/account_backend/partner-ledger-screen.d.ts +0 -14
  2392. package/dist/modules/account_backend/partner-ledger-screen.d.ts.map +0 -1
  2393. package/dist/modules/account_backend/partner-ledger-screen.js +0 -69
  2394. package/dist/modules/account_backend/partner-ledger-screen.js.map +0 -1
  2395. package/dist/modules/account_backend/payment-terms-screen.d.ts +0 -14
  2396. package/dist/modules/account_backend/payment-terms-screen.d.ts.map +0 -1
  2397. package/dist/modules/account_backend/payment-terms-screen.js +0 -40
  2398. package/dist/modules/account_backend/payment-terms-screen.js.map +0 -1
  2399. package/dist/modules/account_backend/payments-screen.d.ts +0 -14
  2400. package/dist/modules/account_backend/payments-screen.d.ts.map +0 -1
  2401. package/dist/modules/account_backend/payments-screen.js +0 -54
  2402. package/dist/modules/account_backend/payments-screen.js.map +0 -1
  2403. package/dist/modules/account_backend/screens.d.ts +0 -7
  2404. package/dist/modules/account_backend/screens.d.ts.map +0 -1
  2405. package/dist/modules/account_backend/screens.js +0 -7
  2406. package/dist/modules/account_backend/screens.js.map +0 -1
  2407. package/dist/modules/account_backend/taxes-screen.d.ts +0 -15
  2408. package/dist/modules/account_backend/taxes-screen.d.ts.map +0 -1
  2409. package/dist/modules/account_backend/taxes-screen.js +0 -73
  2410. package/dist/modules/account_backend/taxes-screen.js.map +0 -1
  2411. package/dist/modules/account_backend/trial-balance-screen.d.ts +0 -13
  2412. package/dist/modules/account_backend/trial-balance-screen.d.ts.map +0 -1
  2413. package/dist/modules/account_backend/trial-balance-screen.js +0 -62
  2414. package/dist/modules/account_backend/trial-balance-screen.js.map +0 -1
  2415. package/dist/modules/account_backend/vendor-bills-screen.d.ts +0 -14
  2416. package/dist/modules/account_backend/vendor-bills-screen.d.ts.map +0 -1
  2417. package/dist/modules/account_backend/vendor-bills-screen.js +0 -59
  2418. package/dist/modules/account_backend/vendor-bills-screen.js.map +0 -1
  2419. package/dist/modules/account_partner_backend/screens.d.ts +0 -16
  2420. package/dist/modules/account_partner_backend/screens.d.ts.map +0 -1
  2421. package/dist/modules/account_partner_backend/screens.js +0 -26
  2422. package/dist/modules/account_partner_backend/screens.js.map +0 -1
  2423. package/dist/modules/activity_backend/screens.d.ts +0 -5
  2424. package/dist/modules/activity_backend/screens.d.ts.map +0 -1
  2425. package/dist/modules/activity_backend/screens.js +0 -52
  2426. package/dist/modules/activity_backend/screens.js.map +0 -1
  2427. package/dist/modules/address_backend/screens.d.ts +0 -31
  2428. package/dist/modules/address_backend/screens.d.ts.map +0 -1
  2429. package/dist/modules/address_backend/screens.js +0 -147
  2430. package/dist/modules/address_backend/screens.js.map +0 -1
  2431. package/dist/modules/backend/design/admin.css +0 -4229
  2432. package/dist/modules/backend/design/client/relation-select-view.d.mts +0 -5
  2433. package/dist/modules/backend/design/client/relation-select-view.d.mts.map +0 -1
  2434. package/dist/modules/backend/design/client/relation-select-view.mjs +0 -335
  2435. package/dist/modules/backend/design/client/relation-select-view.mjs.map +0 -1
  2436. package/dist/modules/calendar_backend/screens.d.ts +0 -5
  2437. package/dist/modules/calendar_backend/screens.d.ts.map +0 -1
  2438. package/dist/modules/calendar_backend/screens.js +0 -4
  2439. package/dist/modules/calendar_backend/screens.js.map +0 -1
  2440. package/dist/modules/company_backend/screens.d.ts +0 -62
  2441. package/dist/modules/company_backend/screens.d.ts.map +0 -1
  2442. package/dist/modules/company_backend/screens.js +0 -268
  2443. package/dist/modules/company_backend/screens.js.map +0 -1
  2444. package/dist/modules/crm_backend/list-search.d.ts +0 -21
  2445. package/dist/modules/crm_backend/list-search.d.ts.map +0 -1
  2446. package/dist/modules/crm_backend/list-search.js +0 -220
  2447. package/dist/modules/crm_backend/list-search.js.map +0 -1
  2448. package/dist/modules/crm_backend/screens.d.ts +0 -32
  2449. package/dist/modules/crm_backend/screens.d.ts.map +0 -1
  2450. package/dist/modules/crm_backend/screens.js +0 -405
  2451. package/dist/modules/crm_backend/screens.js.map +0 -1
  2452. package/dist/modules/hospitality_core/screens.d.ts +0 -773
  2453. package/dist/modules/hospitality_core/screens.d.ts.map +0 -1
  2454. package/dist/modules/hospitality_core/screens.js +0 -4152
  2455. package/dist/modules/hospitality_core/screens.js.map +0 -1
  2456. package/dist/modules/hr_backend/screens.d.ts +0 -9
  2457. package/dist/modules/hr_backend/screens.d.ts.map +0 -1
  2458. package/dist/modules/hr_backend/screens.js +0 -144
  2459. package/dist/modules/hr_backend/screens.js.map +0 -1
  2460. package/dist/modules/loyalty_backend/screens.d.ts +0 -33
  2461. package/dist/modules/loyalty_backend/screens.d.ts.map +0 -1
  2462. package/dist/modules/loyalty_backend/screens.js +0 -562
  2463. package/dist/modules/loyalty_backend/screens.js.map +0 -1
  2464. package/dist/modules/mail_backend/screens.d.ts +0 -5
  2465. package/dist/modules/mail_backend/screens.d.ts.map +0 -1
  2466. package/dist/modules/mail_backend/screens.js +0 -11
  2467. package/dist/modules/mail_backend/screens.js.map +0 -1
  2468. package/dist/modules/mail_inbound_backend/screens.d.ts +0 -5
  2469. package/dist/modules/mail_inbound_backend/screens.d.ts.map +0 -1
  2470. package/dist/modules/mail_inbound_backend/screens.js +0 -25
  2471. package/dist/modules/mail_inbound_backend/screens.js.map +0 -1
  2472. package/dist/modules/mail_transport_backend/screens.d.ts +0 -5
  2473. package/dist/modules/mail_transport_backend/screens.d.ts.map +0 -1
  2474. package/dist/modules/mail_transport_backend/screens.js +0 -35
  2475. package/dist/modules/mail_transport_backend/screens.js.map +0 -1
  2476. package/dist/modules/oauth_backend/screens.d.ts +0 -66
  2477. package/dist/modules/oauth_backend/screens.d.ts.map +0 -1
  2478. package/dist/modules/oauth_backend/screens.js +0 -323
  2479. package/dist/modules/oauth_backend/screens.js.map +0 -1
  2480. package/dist/modules/odoo_collaboration_import/functions.d.ts.map +0 -1
  2481. package/dist/modules/odoo_collaboration_import/functions.js +0 -128
  2482. package/dist/modules/odoo_collaboration_import/functions.js.map +0 -1
  2483. package/dist/modules/odoo_collaboration_import/index.d.ts +0 -6
  2484. package/dist/modules/odoo_collaboration_import/index.d.ts.map +0 -1
  2485. package/dist/modules/odoo_collaboration_import/index.js +0 -31
  2486. package/dist/modules/odoo_collaboration_import/index.js.map +0 -1
  2487. package/dist/modules/odoo_collaboration_import/models.d.ts.map +0 -1
  2488. package/dist/modules/odoo_collaboration_import/models.js +0 -76
  2489. package/dist/modules/odoo_collaboration_import/models.js.map +0 -1
  2490. package/dist/modules/odoo_collaboration_import/operations.d.ts +0 -14
  2491. package/dist/modules/odoo_collaboration_import/operations.d.ts.map +0 -1
  2492. package/dist/modules/odoo_collaboration_import/operations.js +0 -1139
  2493. package/dist/modules/odoo_collaboration_import/operations.js.map +0 -1
  2494. package/dist/modules/odoo_collaboration_import/relations.d.ts.map +0 -1
  2495. package/dist/modules/odoo_collaboration_import/relations.js +0 -19
  2496. package/dist/modules/odoo_collaboration_import/relations.js.map +0 -1
  2497. package/dist/modules/odoo_collaboration_import/types.d.ts +0 -58
  2498. package/dist/modules/odoo_collaboration_import/types.d.ts.map +0 -1
  2499. package/dist/modules/odoo_collaboration_import/types.js.map +0 -1
  2500. package/dist/modules/partner_backend/screens.d.ts +0 -53
  2501. package/dist/modules/partner_backend/screens.d.ts.map +0 -1
  2502. package/dist/modules/partner_backend/screens.js +0 -169
  2503. package/dist/modules/partner_backend/screens.js.map +0 -1
  2504. package/dist/modules/pricing_backend/screens.d.ts +0 -13
  2505. package/dist/modules/pricing_backend/screens.d.ts.map +0 -1
  2506. package/dist/modules/pricing_backend/screens.js +0 -182
  2507. package/dist/modules/pricing_backend/screens.js.map +0 -1
  2508. package/dist/modules/product_backend/attributes-screen.d.ts +0 -7
  2509. package/dist/modules/product_backend/attributes-screen.d.ts.map +0 -1
  2510. package/dist/modules/product_backend/attributes-screen.js +0 -76
  2511. package/dist/modules/product_backend/attributes-screen.js.map +0 -1
  2512. package/dist/modules/product_backend/create-screen.d.ts +0 -12
  2513. package/dist/modules/product_backend/create-screen.d.ts.map +0 -1
  2514. package/dist/modules/product_backend/create-screen.js +0 -83
  2515. package/dist/modules/product_backend/create-screen.js.map +0 -1
  2516. package/dist/modules/product_backend/screens.d.ts +0 -68
  2517. package/dist/modules/product_backend/screens.d.ts.map +0 -1
  2518. package/dist/modules/product_backend/screens.js +0 -388
  2519. package/dist/modules/product_backend/screens.js.map +0 -1
  2520. package/dist/modules/purchase_backend/screens.d.ts +0 -29
  2521. package/dist/modules/purchase_backend/screens.d.ts.map +0 -1
  2522. package/dist/modules/purchase_backend/screens.js +0 -324
  2523. package/dist/modules/purchase_backend/screens.js.map +0 -1
  2524. package/dist/modules/sale_backend/invoicing-policies-screen.d.ts +0 -14
  2525. package/dist/modules/sale_backend/invoicing-policies-screen.d.ts.map +0 -1
  2526. package/dist/modules/sale_backend/invoicing-policies-screen.js +0 -36
  2527. package/dist/modules/sale_backend/invoicing-policies-screen.js.map +0 -1
  2528. package/dist/modules/sale_backend/order-detail-screen.d.ts +0 -18
  2529. package/dist/modules/sale_backend/order-detail-screen.d.ts.map +0 -1
  2530. package/dist/modules/sale_backend/order-detail-screen.js +0 -217
  2531. package/dist/modules/sale_backend/order-detail-screen.js.map +0 -1
  2532. package/dist/modules/sale_backend/quotations-screen.d.ts +0 -15
  2533. package/dist/modules/sale_backend/quotations-screen.d.ts.map +0 -1
  2534. package/dist/modules/sale_backend/quotations-screen.js +0 -64
  2535. package/dist/modules/sale_backend/quotations-screen.js.map +0 -1
  2536. package/dist/modules/sale_backend/sales-orders-screen.d.ts +0 -12
  2537. package/dist/modules/sale_backend/sales-orders-screen.d.ts.map +0 -1
  2538. package/dist/modules/sale_backend/sales-orders-screen.js +0 -65
  2539. package/dist/modules/sale_backend/sales-orders-screen.js.map +0 -1
  2540. package/dist/modules/sale_backend/screens.d.ts +0 -23
  2541. package/dist/modules/sale_backend/screens.d.ts.map +0 -1
  2542. package/dist/modules/sale_backend/screens.js +0 -275
  2543. package/dist/modules/sale_backend/screens.js.map +0 -1
  2544. package/dist/modules/stock_backend/forecast-screen.d.ts +0 -28
  2545. package/dist/modules/stock_backend/forecast-screen.d.ts.map +0 -1
  2546. package/dist/modules/stock_backend/forecast-screen.js +0 -108
  2547. package/dist/modules/stock_backend/forecast-screen.js.map +0 -1
  2548. package/dist/modules/stock_backend/inventory-screen.d.ts +0 -27
  2549. package/dist/modules/stock_backend/inventory-screen.d.ts.map +0 -1
  2550. package/dist/modules/stock_backend/inventory-screen.js +0 -141
  2551. package/dist/modules/stock_backend/inventory-screen.js.map +0 -1
  2552. package/dist/modules/stock_backend/locations-screen.d.ts +0 -18
  2553. package/dist/modules/stock_backend/locations-screen.d.ts.map +0 -1
  2554. package/dist/modules/stock_backend/locations-screen.js +0 -92
  2555. package/dist/modules/stock_backend/locations-screen.js.map +0 -1
  2556. package/dist/modules/stock_backend/lot-screen.d.ts +0 -30
  2557. package/dist/modules/stock_backend/lot-screen.d.ts.map +0 -1
  2558. package/dist/modules/stock_backend/lot-screen.js +0 -86
  2559. package/dist/modules/stock_backend/lot-screen.js.map +0 -1
  2560. package/dist/modules/stock_backend/lots-screen.d.ts +0 -21
  2561. package/dist/modules/stock_backend/lots-screen.d.ts.map +0 -1
  2562. package/dist/modules/stock_backend/lots-screen.js +0 -79
  2563. package/dist/modules/stock_backend/lots-screen.js.map +0 -1
  2564. package/dist/modules/stock_backend/picking-types-screen.d.ts +0 -21
  2565. package/dist/modules/stock_backend/picking-types-screen.d.ts.map +0 -1
  2566. package/dist/modules/stock_backend/picking-types-screen.js +0 -110
  2567. package/dist/modules/stock_backend/picking-types-screen.js.map +0 -1
  2568. package/dist/modules/stock_backend/replenishment-screen.d.ts +0 -29
  2569. package/dist/modules/stock_backend/replenishment-screen.d.ts.map +0 -1
  2570. package/dist/modules/stock_backend/replenishment-screen.js +0 -131
  2571. package/dist/modules/stock_backend/replenishment-screen.js.map +0 -1
  2572. package/dist/modules/stock_backend/screens.d.ts +0 -14
  2573. package/dist/modules/stock_backend/screens.d.ts.map +0 -1
  2574. package/dist/modules/stock_backend/screens.js +0 -40
  2575. package/dist/modules/stock_backend/screens.js.map +0 -1
  2576. package/dist/modules/stock_backend/stock-route-screen.d.ts +0 -30
  2577. package/dist/modules/stock_backend/stock-route-screen.d.ts.map +0 -1
  2578. package/dist/modules/stock_backend/stock-route-screen.js +0 -129
  2579. package/dist/modules/stock_backend/stock-route-screen.js.map +0 -1
  2580. package/dist/modules/stock_backend/stock-routes-screen.d.ts +0 -17
  2581. package/dist/modules/stock_backend/stock-routes-screen.d.ts.map +0 -1
  2582. package/dist/modules/stock_backend/stock-routes-screen.js +0 -60
  2583. package/dist/modules/stock_backend/stock-routes-screen.js.map +0 -1
  2584. package/dist/modules/stock_backend/transfer-screen.d.ts +0 -26
  2585. package/dist/modules/stock_backend/transfer-screen.d.ts.map +0 -1
  2586. package/dist/modules/stock_backend/transfer-screen.js +0 -95
  2587. package/dist/modules/stock_backend/transfer-screen.js.map +0 -1
  2588. package/dist/modules/stock_backend/transfers-screen.d.ts +0 -21
  2589. package/dist/modules/stock_backend/transfers-screen.d.ts.map +0 -1
  2590. package/dist/modules/stock_backend/transfers-screen.js +0 -88
  2591. package/dist/modules/stock_backend/transfers-screen.js.map +0 -1
  2592. package/dist/modules/stock_backend/warehouses-screen.d.ts +0 -17
  2593. package/dist/modules/stock_backend/warehouses-screen.d.ts.map +0 -1
  2594. package/dist/modules/stock_backend/warehouses-screen.js +0 -96
  2595. package/dist/modules/stock_backend/warehouses-screen.js.map +0 -1
  2596. package/dist/modules/user_backend/screens.d.ts +0 -70
  2597. package/dist/modules/user_backend/screens.d.ts.map +0 -1
  2598. package/dist/modules/user_backend/screens.js +0 -308
  2599. package/dist/modules/user_backend/screens.js.map +0 -1
  2600. package/dist/modules/website/customer-routes.d.ts +0 -3
  2601. package/dist/modules/website/customer-routes.d.ts.map +0 -1
  2602. package/dist/modules/website/customer-routes.js +0 -322
  2603. package/dist/modules/website/customer-routes.js.map +0 -1
  2604. package/dist/modules/website_backend/screens.d.ts +0 -114
  2605. package/dist/modules/website_backend/screens.d.ts.map +0 -1
  2606. package/dist/modules/website_backend/screens.js +0 -625
  2607. package/dist/modules/website_backend/screens.js.map +0 -1
  2608. package/dist/ui/client/mail.d.mts +0 -11
  2609. package/dist/ui/client/mail.d.mts.map +0 -1
  2610. package/dist/ui/client/mail.mjs +0 -10
  2611. package/dist/ui/client/mail.mjs.map +0 -1
  2612. /package/dist/modules/{odoo_collaboration_import → account_staff_channel}/functions.d.ts +0 -0
  2613. /package/dist/modules/{odoo_collaboration_import → account_staff_channel}/models.d.ts +0 -0
  2614. /package/dist/modules/{odoo_collaboration_import → address_backend/screens}/types.js +0 -0
  2615. /package/dist/modules/{odoo_collaboration_import → manufacturing}/relations.d.ts +0 -0
@@ -1,15 +1,371 @@
1
- import { defineFn } from '@ketvietlab/ketjs';
2
- import { functions as accountFunctions } from '../account/functions.js';
1
+ import { createHash } from 'node:crypto';
2
+ import { and, defineFn, deleteFrom, desc, eq, from, gte, inArray, isNull, localDateTimeToUtc, lt, or, } from '@ketvietlab/ketjs';
3
+ import { addCivilDays } from '../account/date.js';
4
+ import { functions as accountFunctions, insertDraftMove, ledgerOf, quoteTaxLine, } from '../account/functions.js';
5
+ import { absDecimalText, compareDecimals, minorText, moneyMinor, scaleOf, sumMoneyMinor, } from '../account/money.js';
3
6
  import { functions as pricingFunctions } from '../pricing/functions.js';
7
+ import { sellableProduct } from '../product/sellable.js';
4
8
  import { functions as stockFunctions } from '../stock/functions.js';
9
+ import { toProductUnit } from '../stock/units.js';
5
10
  export const POS_ORDER_STATES = ['draft', 'cancel', 'paid', 'done'];
6
- export const POS_SESSION_STATES = ['opening_control', 'opened', 'closing_control', 'closed'];
11
+ export const POS_SESSION_STATES = [
12
+ 'opening_control',
13
+ 'opened',
14
+ 'closing_control',
15
+ 'pending_approval',
16
+ 'closed',
17
+ ];
18
+ export const POS_TENDER_STATES = ['captured', 'voided'];
7
19
  export const POS_INVOICE_STATUSES = ['invoiced', 'to_invoice'];
20
+ export const POS_PAYMENT_SETTLEMENT_KINDS = ['liquidity', 'stored_value'];
8
21
  const invalid = (field, message) => ({ ok: false, errors: [{ field, message }] });
9
22
  const n = (value) => Number(value ?? 0);
10
23
  const money = (value) => Math.round((value + Number.EPSILON) * 100) / 100;
11
24
  const decimal = (value) => String(money(value));
12
25
  const now = () => new Date().toISOString();
26
+ const traceHash = (kind, value) => {
27
+ const held = String(value ?? '').trim();
28
+ return held ? createHash('sha256').update(`pos:${kind}\n${held}`).digest('hex') : null;
29
+ };
30
+ /**
31
+ * Sensitive POS commands are retryable, so their audit identity must be retryable too.
32
+ * Callers derive the id from the command/domain identity and this helper never updates
33
+ * an existing event.
34
+ */
35
+ const appendAudit = (ctx, event) => ctx.db.insertIfAbsent('pos.AuditEvent', {
36
+ id: event.id,
37
+ subjectType: event.subjectType,
38
+ subjectId: event.subjectId,
39
+ configId: event.configId,
40
+ sessionId: event.sessionId,
41
+ action: event.action,
42
+ actorId: event.actorId ?? ctx.actor ?? null,
43
+ deviceId: event.deviceId ?? null,
44
+ reason: event.reason == null ? null : String(event.reason).trim().slice(0, 500),
45
+ relatedId: event.relatedId ?? null,
46
+ details: event.details ?? {},
47
+ correlationHash: traceHash('correlation', ctx.correlationId),
48
+ actorHash: traceHash('actor', event.actorId),
49
+ subjectHash: traceHash(event.subjectType, event.subjectId),
50
+ relatedHash: traceHash('related', event.relatedId),
51
+ sessionHash: traceHash('session', event.sessionId),
52
+ deviceHash: traceHash('device', event.deviceId),
53
+ occurredAt: event.occurredAt ?? now(),
54
+ });
55
+ const projectedAudit = (event) => ({
56
+ id: traceHash('audit-event', event.id),
57
+ subjectType: String(event.subjectType ?? 'unknown'),
58
+ subjectHash: event.subjectHash ?? traceHash(String(event.subjectType ?? 'unknown'), event.subjectId),
59
+ action: String(event.action ?? ''),
60
+ actorHash: event.actorHash ?? traceHash('actor', event.actorId),
61
+ correlationHash: event.correlationHash ?? null,
62
+ relatedHash: event.relatedHash ?? traceHash('related', event.relatedId),
63
+ sessionHash: event.sessionHash ?? traceHash('session', event.sessionId),
64
+ deviceHash: event.deviceHash ?? traceHash('device', event.deviceId),
65
+ reason: event.reason ?? null,
66
+ occurredAt: String(event.occurredAt),
67
+ });
68
+ const POS_OPERATIONS_MAX_DAYS = 31;
69
+ const DAY_MS = 86_400_000;
70
+ const operationsWindow = (dateFrom, dateTo, timezone) => {
71
+ const startDay = String(dateFrom);
72
+ const endDay = String(dateTo);
73
+ const start = Date.parse(`${startDay}T00:00:00.000Z`);
74
+ const end = Date.parse(`${endDay}T00:00:00.000Z`) + DAY_MS;
75
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start)
76
+ return invalid('dateTo', 'operations report end date must not precede its start date');
77
+ if (end - start > POS_OPERATIONS_MAX_DAYS * DAY_MS)
78
+ return invalid('dateTo', `operations report is limited to ${POS_OPERATIONS_MAX_DAYS} days`);
79
+ return {
80
+ ok: true,
81
+ from: localDateTimeToUtc(`${startDay}T00:00`, timezone),
82
+ to: localDateTimeToUtc(`${addCivilDays(endDay, 1)}T00:00`, timezone),
83
+ };
84
+ };
85
+ const aggregateDecimal = (value) => String(value ?? '0');
86
+ const PROVIDER_FINALIZATION_LEASE_MS = 5 * 60_000;
87
+ const stableJson = (value) => {
88
+ if (Array.isArray(value))
89
+ return `[${value.map(stableJson).join(',')}]`;
90
+ if (value && typeof value === 'object')
91
+ return `{${Object.entries(value)
92
+ .sort(([left], [right]) => left.localeCompare(right))
93
+ .map(([key, held]) => `${JSON.stringify(key)}:${stableJson(held)}`)
94
+ .join(',')}}`;
95
+ return JSON.stringify(value) ?? 'null';
96
+ };
97
+ const receiptHash = (document) => createHash('sha256').update(stableJson(document)).digest('hex');
98
+ const receiptDocumentFor = async (ctx, order, config, session, customer, lines, payments, accountMoveId, issuedAt) => {
99
+ const methodIds = [...new Set(payments.map((payment) => String(payment.paymentMethodId)))];
100
+ const methods = new Map((await Promise.all(methodIds.map(async (id) => (await ctx.db.select('pos.PaymentMethod', { id }))[0] ?? null)))
101
+ .filter(Boolean)
102
+ .map((method) => [String(method.id), method]));
103
+ return {
104
+ schema: 'ketviet.pos.receipt.v1',
105
+ company: { id: String(ctx.scope.company ?? '') },
106
+ config: { id: String(config.id), name: String(config.name) },
107
+ shift: { id: String(session.id), name: String(session.name) },
108
+ cashier: { id: String(order.operatorId ?? session.userId) },
109
+ customer: { id: String(customer.id), name: String(customer.name) },
110
+ order: {
111
+ id: String(order.id),
112
+ name: String(order.name),
113
+ reference: String(order.posReference),
114
+ orderedAt: String(order.dateOrder),
115
+ isReturn: order.isRefund === true,
116
+ originalOrderId: order.refundedOrderId == null ? null : String(order.refundedOrderId),
117
+ },
118
+ currency: String(order.currency),
119
+ lines: [...lines]
120
+ .sort((left, right) => n(left.sequence) - n(right.sequence) || String(left.id).localeCompare(String(right.id)))
121
+ .map((line) => {
122
+ const evidence = line.taxEvidence && typeof line.taxEvidence === 'object' ? line.taxEvidence : null;
123
+ return {
124
+ id: String(line.id),
125
+ productId: String(line.productId),
126
+ uomId: String(line.productUomId),
127
+ name: String(line.name),
128
+ quantity: String(line.qty),
129
+ unitPrice: String(line.priceUnit),
130
+ discount: String(line.discount),
131
+ amountUntaxed: String(line.priceSubtotal),
132
+ amountTax: decimal(n(line.priceSubtotalIncl) - n(line.priceSubtotal)),
133
+ amountTotal: String(line.priceSubtotalIncl),
134
+ taxes: (Array.isArray(evidence?.taxes) ? evidence.taxes : []).map((tax) => ({
135
+ id: String(tax.taxId ?? ''),
136
+ name: String(tax.name ?? tax.taxId ?? ''),
137
+ amount: String(tax.share ?? '0'),
138
+ })),
139
+ };
140
+ }),
141
+ tenders: payments
142
+ .filter((payment) => (payment.state ?? 'captured') === 'captured')
143
+ .sort((left, right) => String(left.paymentDate).localeCompare(String(right.paymentDate)) ||
144
+ String(left.id).localeCompare(String(right.id)))
145
+ .map((payment) => ({
146
+ paymentMethodId: String(payment.paymentMethodId),
147
+ paymentMethodName: String(methods.get(String(payment.paymentMethodId))?.name ?? ''),
148
+ tenderedAmount: String(payment.tenderedAmount ?? payment.amount),
149
+ appliedAmount: String(payment.appliedAmount ?? payment.amount),
150
+ change: decimal(n(payment.tenderedAmount ?? payment.amount) - n(payment.appliedAmount ?? payment.amount)),
151
+ paidAt: String(payment.paymentDate),
152
+ })),
153
+ totals: {
154
+ untaxed: String(order.amountUntaxed),
155
+ tax: String(order.amountTax),
156
+ exact: String(order.amountExact),
157
+ rounding: String(order.amountRounding),
158
+ total: String(order.amountTotal),
159
+ paid: String(order.amountPaid),
160
+ change: String(order.amountReturn),
161
+ },
162
+ invoice: { id: accountMoveId },
163
+ issuedAt,
164
+ };
165
+ };
166
+ class AtomicFailure extends Error {
167
+ result;
168
+ constructor(result) {
169
+ super('POS command rejected');
170
+ this.result = result;
171
+ }
172
+ }
173
+ const activeAtomicContexts = new WeakSet();
174
+ const atomic = async (ctx, body) => {
175
+ try {
176
+ // Composite POS commands reuse the transaction-bound context handed to the
177
+ // outer command. Opening another adapter transaction here would fail on
178
+ // PostgreSQL and would split one retail intent into partial commits.
179
+ if (activeAtomicContexts.has(ctx)) {
180
+ const result = await body(ctx);
181
+ if (result.ok !== true)
182
+ throw new AtomicFailure(result);
183
+ return result;
184
+ }
185
+ return await ctx.tx(async (tx) => {
186
+ activeAtomicContexts.add(tx);
187
+ try {
188
+ const result = await body(tx);
189
+ if (result.ok !== true)
190
+ throw new AtomicFailure(result);
191
+ return result;
192
+ }
193
+ finally {
194
+ activeAtomicContexts.delete(tx);
195
+ }
196
+ });
197
+ }
198
+ catch (error) {
199
+ if (error instanceof AtomicFailure)
200
+ return error.result;
201
+ throw error;
202
+ }
203
+ };
204
+ export async function claimDraftRevision(ctx, id, expectedRevision) {
205
+ const order = (await ctx.db.select('pos.Order', { id }))[0];
206
+ if (!order)
207
+ return invalid('orderId', 'order does not exist');
208
+ if (order.state !== 'draft')
209
+ return invalid('state', 'only a draft order can be changed');
210
+ const current = n(order.revision);
211
+ if (expectedRevision !== undefined && n(expectedRevision) !== current)
212
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
213
+ const changed = await ctx.db.compareAndSet('pos.Order', { id: order.id }, { revision: order.revision ?? null }, { revision: current + 1 });
214
+ if (!('dryRun' in changed) && !changed.matched)
215
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
216
+ return { ok: true, order, revision: current + 1 };
217
+ }
218
+ async function providerSettlementReplay(ctx, args) {
219
+ const attemptId = String(args.providerAttemptId ?? '').trim();
220
+ const [byId, byAttempt, order, reservation] = await Promise.all([
221
+ ctx.db.select('pos.Payment', { id: args.id }),
222
+ ctx.db.select('pos.Payment', { providerAttemptId: attemptId }),
223
+ ctx.db.select('pos.Order', { id: args.orderId }),
224
+ ctx.db.select('pos.ProviderPaymentLock', { id: attemptId }),
225
+ ]);
226
+ if (byId[0] && byAttempt[0] && byId[0].id !== byAttempt[0].id)
227
+ return invalid('providerAttemptId', 'provider attempt is already linked to another tender');
228
+ const existing = byId[0] ?? byAttempt[0];
229
+ if (!existing)
230
+ return null;
231
+ const currentOrder = order[0];
232
+ const lock = reservation[0];
233
+ const same = Boolean(currentOrder) &&
234
+ existing.id === args.id &&
235
+ existing.orderId === args.orderId &&
236
+ existing.paymentMethodId === args.paymentMethodId &&
237
+ existing.kind === 'provider' &&
238
+ (existing.state ?? 'captured') === 'captured' &&
239
+ existing.reversalOfId == null &&
240
+ n(existing.appliedAmount ?? existing.amount) === n(args.amount) &&
241
+ String(existing.providerAttemptId ?? '') === attemptId &&
242
+ String(existing.reference ?? '') === String(args.providerReference ?? '').trim() &&
243
+ currentOrder.currency === String(args.currency) &&
244
+ lock?.orderId === args.orderId &&
245
+ lock.paymentMethodId === args.paymentMethodId &&
246
+ n(lock.amount) === n(args.amount) &&
247
+ lock.currency === String(args.currency) &&
248
+ ['settled', 'finalizing', 'finalized'].includes(String(lock.state)) &&
249
+ lock.settledPaymentId === existing.id;
250
+ return same
251
+ ? {
252
+ ok: true,
253
+ id: existing.id,
254
+ revision: n(currentOrder.revision),
255
+ appliedAmount: existing.appliedAmount ?? existing.amount,
256
+ providerAttemptId: attemptId,
257
+ }
258
+ : invalid('id', 'provider tender id is already used by a different settlement');
259
+ }
260
+ async function providerFinalizationLocks(ctx, order) {
261
+ const [locks, payments] = await Promise.all([
262
+ ctx.db.select('pos.ProviderPaymentLock', { orderId: order.id }),
263
+ ctx.db.select('pos.Payment', { orderId: order.id }),
264
+ ]);
265
+ const captured = payments.filter((payment) => payment.kind === 'provider' &&
266
+ (payment.state ?? 'captured') === 'captured' &&
267
+ payment.reversalOfId == null);
268
+ const active = locks
269
+ .filter((lock) => !['released', 'reversed'].includes(String(lock.state)))
270
+ .sort((left, right) => String(left.id).localeCompare(String(right.id)));
271
+ if (active.some((lock) => !['settled', 'finalizing'].includes(String(lock.state))))
272
+ return invalid('paymentLockId', 'external payment is still pending reconciliation');
273
+ if (captured.length !== active.length)
274
+ return invalid('paymentLockId', 'external payment membership is incomplete');
275
+ for (const lock of active) {
276
+ const payment = captured.find((candidate) => String(candidate.providerAttemptId ?? '') === String(lock.id));
277
+ if (!payment ||
278
+ lock.orderId !== order.id ||
279
+ lock.paymentMethodId !== payment.paymentMethodId ||
280
+ n(lock.amount) !== n(payment.appliedAmount ?? payment.amount) ||
281
+ lock.currency !== order.currency ||
282
+ lock.settledPaymentId !== payment.id)
283
+ return invalid('paymentLockId', 'external payment membership is inconsistent');
284
+ }
285
+ return { ok: true, locks: active };
286
+ }
287
+ async function claimProviderFinalization(ctx, id, expectedRevision) {
288
+ return (await atomic(ctx, async (tx) => {
289
+ const order = (await tx.db.select('pos.Order', { id }))[0];
290
+ if (!order)
291
+ return invalid('orderId', 'order does not exist');
292
+ if (order.state !== 'draft')
293
+ return invalid('state', 'only a draft order can be finalized');
294
+ const current = n(order.revision);
295
+ const membership = await providerFinalizationLocks(tx, order);
296
+ if (membership.ok !== true)
297
+ return membership;
298
+ if (!membership.locks.length)
299
+ return invalid('paymentLockId', 'provider payment lock is missing');
300
+ const finalizing = membership.locks.filter((lock) => lock.state === 'finalizing');
301
+ if (finalizing.length) {
302
+ if (finalizing.length !== membership.locks.length)
303
+ return invalid('paymentLockId', 'external payment finalization membership is inconsistent');
304
+ const previousToken = String(finalizing[0].updatedAt ?? '');
305
+ if (finalizing.some((lock) => String(lock.updatedAt ?? '') !== previousToken))
306
+ return invalid('paymentLockId', 'external payment finalization membership is inconsistent');
307
+ const leaseAge = Date.now() - Date.parse(previousToken);
308
+ if (!Number.isFinite(leaseAge) || leaseAge < PROVIDER_FINALIZATION_LEASE_MS)
309
+ return invalid('paymentLockId', 'external payment finalization is already in progress');
310
+ if (expectedRevision !== undefined &&
311
+ ![current, Math.max(0, current - 1)].includes(n(expectedRevision)))
312
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
313
+ const token = now();
314
+ for (const lock of finalizing) {
315
+ const resumed = await tx.db.compareAndSet('pos.ProviderPaymentLock', { id: lock.id }, { state: 'finalizing', updatedAt: previousToken }, { updatedAt: token });
316
+ if (!('dryRun' in resumed) && !resumed.matched)
317
+ return invalid('paymentLockId', 'external payment finalization recovery was already claimed');
318
+ }
319
+ return {
320
+ ok: true,
321
+ order,
322
+ revision: current,
323
+ leases: finalizing.map((lock) => ({ id: String(lock.id), token })),
324
+ };
325
+ }
326
+ if (expectedRevision !== undefined && n(expectedRevision) !== current)
327
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
328
+ const token = now();
329
+ for (const lock of membership.locks) {
330
+ const lockChanged = await tx.db.compareAndSet('pos.ProviderPaymentLock', { id: lock.id }, { state: 'settled' }, { state: 'finalizing', updatedAt: token });
331
+ if (!('dryRun' in lockChanged) && !lockChanged.matched)
332
+ return invalid('paymentLockId', 'external payment reconciliation changed before finalization');
333
+ }
334
+ const orderChanged = await tx.db.compareAndSet('pos.Order', { id: order.id }, { revision: order.revision ?? null }, { revision: current + 1 });
335
+ if (!('dryRun' in orderChanged) && !orderChanged.matched)
336
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
337
+ return {
338
+ ok: true,
339
+ order,
340
+ revision: current + 1,
341
+ leases: membership.locks.map((lock) => ({ id: String(lock.id), token })),
342
+ };
343
+ }));
344
+ }
345
+ async function claimOrderRevision(ctx, id, expectedRevision) {
346
+ const order = (await ctx.db.select('pos.Order', { id }))[0];
347
+ if (!order)
348
+ return invalid('orderId', 'order does not exist');
349
+ const current = n(order.revision);
350
+ if (expectedRevision !== undefined && n(expectedRevision) !== current)
351
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
352
+ const changed = await ctx.db.compareAndSet('pos.Order', { id: order.id }, { revision: order.revision ?? null }, { revision: current + 1 });
353
+ if (!('dryRun' in changed) && !changed.matched)
354
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
355
+ return { ok: true, order, revision: current + 1 };
356
+ }
357
+ async function claimSessionRevision(ctx, id, expectedRevision) {
358
+ const session = (await ctx.db.select('pos.Session', { id }))[0];
359
+ if (!session)
360
+ return invalid('id', 'session does not exist');
361
+ const current = n(session.revision);
362
+ if (expectedRevision !== undefined && n(expectedRevision) !== current)
363
+ return invalid('expectedRevision', 'the shift changed; reload it before continuing');
364
+ const changed = await ctx.db.compareAndSet('pos.Session', { id: session.id }, { revision: session.revision ?? null }, { revision: current + 1 });
365
+ if (!('dryRun' in changed) && !changed.matched)
366
+ return invalid('expectedRevision', 'the shift changed; reload it before continuing');
367
+ return { ok: true, session, revision: current + 1 };
368
+ }
13
369
  async function currencyOf(ctx) {
14
370
  if (!ctx.scope.company)
15
371
  throw new Error('point of sale requires an active company');
@@ -18,11 +374,51 @@ async function currencyOf(ctx) {
18
374
  throw new Error(`company ${ctx.scope.company} does not exist`);
19
375
  return String(company.currency);
20
376
  }
377
+ const absoluteMinor = (value) => (value < 0n ? -value : value);
378
+ async function sessionCashMinor(ctx, session, scale) {
379
+ let expected = moneyMinor(session.cashRegisterBalanceStart, scale);
380
+ const orders = await ctx.db.select('pos.Order', { sessionId: session.id });
381
+ for (const order of orders)
382
+ for (const payment of await ctx.db.select('pos.Payment', { orderId: order.id })) {
383
+ if ((payment.state ?? 'captured') !== 'captured')
384
+ continue;
385
+ const method = (await ctx.db.select('pos.PaymentMethod', { id: payment.paymentMethodId }))[0];
386
+ if (method?.isCash)
387
+ expected += moneyMinor(payment.appliedAmount ?? payment.amount, scale);
388
+ }
389
+ for (const movement of await ctx.db.select('pos.CashMovement', { sessionId: session.id })) {
390
+ const amount = moneyMinor(movement.amount, scale);
391
+ expected += movement.direction === 'in' ? amount : -amount;
392
+ }
393
+ return expected;
394
+ }
21
395
  async function productOf(ctx, id) {
22
396
  const product = (await ctx.db.select('product.Product', { id }))[0];
23
397
  const template = product && (await ctx.db.select('product.Template', { id: product.templateId }))[0];
24
398
  return product && template ? { product, template } : null;
25
399
  }
400
+ async function trackingAvailability(ctx, order, line) {
401
+ const config = (await ctx.db.select('pos.Config', { id: order.configId }))[0];
402
+ if (!config)
403
+ throw new Error(`POS configuration ${String(order.configId)} does not exist`);
404
+ const based = await toProductUnit(ctx, line.productId, line.productUomId, Math.abs(n(line.qty)));
405
+ if (!based)
406
+ throw new Error(`POS line ${String(line.id)} has an incompatible unit`);
407
+ const availability = (await stockFunctions.trackedAvailability.handler(ctx, {
408
+ productId: line.productId,
409
+ warehouseId: config.warehouseId,
410
+ at: order.dateOrder,
411
+ }));
412
+ return {
413
+ orderId: String(order.id),
414
+ lineId: String(line.id),
415
+ productId: String(line.productId),
416
+ tracking: String(availability.tracking ?? 'none'),
417
+ requiredQuantity: String(based.quantity),
418
+ selections: Array.isArray(line.lotSelections) ? line.lotSelections : [],
419
+ lots: Array.isArray(availability.lots) ? availability.lots : [],
420
+ };
421
+ }
26
422
  async function nextOrderNumber(ctx, sessionId) {
27
423
  const key = String(sessionId);
28
424
  await ctx.db.insertIfAbsent('pos.Sequence', { id: key, nextNumber: 1 });
@@ -35,64 +431,70 @@ async function nextOrderNumber(ctx, sessionId) {
35
431
  }
36
432
  throw new Error('POS order sequence did not settle after concurrent updates');
37
433
  }
38
- function taxAmounts(tax, gross, quantity) {
39
- if (!tax)
40
- return { untaxed: money(gross), tax: 0, total: money(gross) };
41
- if (tax.amountType === 'group')
42
- throw new Error('group taxes are outside the supported Odoo 19 POS subset');
43
- const amount = n(tax.amount), rate = amount / 100;
44
- let untaxed = money(gross), taxAmount = 0;
45
- if (tax.amountType === 'fixed') {
46
- taxAmount = money(amount * quantity);
47
- if (tax.priceInclude)
48
- untaxed = money(gross - taxAmount);
49
- return { untaxed, tax: taxAmount, total: tax.priceInclude ? money(gross) : money(gross + taxAmount) };
50
- }
51
- if (tax.amountType === 'division') {
52
- if (tax.priceInclude) {
53
- untaxed = money(gross * (1 - rate));
54
- taxAmount = money(gross - untaxed);
55
- }
56
- else
57
- taxAmount = money(gross / (1 - rate) - gross);
58
- }
59
- else if (tax.priceInclude) {
60
- untaxed = money(gross / (1 + rate));
61
- taxAmount = money(gross - untaxed);
62
- }
63
- else
64
- taxAmount = money(gross * rate);
65
- return { untaxed, tax: taxAmount, total: money(untaxed + taxAmount) };
66
- }
67
434
  async function recompute(ctx, orderId) {
68
- let untaxed = 0, tax = 0;
69
- for (const line of await ctx.db.select('pos.OrderLine', { orderId })) {
70
- const held = line.taxId ? ((await ctx.db.select('account.Tax', { id: line.taxId }))[0] ?? null) : null;
71
- const amounts = taxAmounts(held, money(n(line.qty) * n(line.priceUnit) * (1 - n(line.discount) / 100)), n(line.qty));
72
- untaxed = money(untaxed + amounts.untaxed);
73
- tax = money(tax + amounts.tax);
74
- await ctx.db.update('pos.OrderLine', { id: line.id }, { priceSubtotal: decimal(amounts.untaxed), priceSubtotalIncl: decimal(amounts.total) });
75
- }
76
- const payments = await ctx.db.select('pos.Payment', { orderId }), paid = money(payments.reduce((sum, payment) => sum + n(payment.amount), 0));
435
+ const order = (await ctx.db.select('pos.Order', { id: orderId }))[0];
436
+ if (!order)
437
+ throw new Error(`POS order ${String(orderId)} does not exist`);
438
+ const scale = scaleOf(order.currency);
439
+ const lines = await ctx.db.select('pos.OrderLine', { orderId });
440
+ const untaxed = sumMoneyMinor(lines.map((line) => line.priceSubtotal), scale);
441
+ const total = sumMoneyMinor(lines.map((line) => line.priceSubtotalIncl), scale);
442
+ const tax = total - untaxed;
443
+ const payments = await ctx.db.select('pos.Payment', { orderId }), captured = payments.filter((payment) => (payment.state ?? 'captured') === 'captured'), paid = sumMoneyMinor(captured.map((payment) => payment.appliedAmount ?? payment.amount), scale), returned = captured.reduce((sum, payment) => sum +
444
+ moneyMinor(payment.tenderedAmount ?? payment.amount, scale) -
445
+ moneyMinor(payment.appliedAmount ?? payment.amount, scale), 0n);
77
446
  await ctx.db.update('pos.Order', { id: orderId }, {
78
- amountUntaxed: decimal(untaxed),
79
- amountTax: decimal(tax),
80
- amountTotal: decimal(untaxed + tax),
81
- amountPaid: decimal(paid),
82
- amountReturn: decimal(paid - untaxed - tax),
447
+ amountUntaxed: minorText(untaxed, scale),
448
+ amountTax: minorText(tax, scale),
449
+ amountExact: minorText(total, scale),
450
+ amountRounding: minorText(0n, scale),
451
+ amountTotal: minorText(total, scale),
452
+ amountPaid: minorText(paid, scale),
453
+ amountReturn: minorText(returned, scale),
83
454
  });
84
455
  }
456
+ async function consumerPartner(ctx) {
457
+ const name = 'Bán cho người tiêu dùng';
458
+ const existing = (await ctx.db.select('partner.Partner', { name })).find((row) => row.active !== false);
459
+ if (existing)
460
+ return existing;
461
+ const id = `pos-consumer-${String(ctx.scope.company)}`;
462
+ await ctx.db.insertIfAbsent('partner.Partner', {
463
+ id,
464
+ kind: 'person',
465
+ name,
466
+ parentId: null,
467
+ vat: null,
468
+ ref: null,
469
+ email: null,
470
+ phone: null,
471
+ lang: 'vi',
472
+ active: true,
473
+ });
474
+ return (await ctx.db.select('partner.Partner', { id }))[0];
475
+ }
85
476
  async function createAccounting(ctx, order, config, lines, payments) {
86
477
  const id = `${String(order.id)}:account`, existing = (await ctx.db.select('account.Move', { id }))[0];
87
478
  if (existing)
88
479
  return id;
89
- const invoice = Boolean(order.toInvoice), refund = n(order.amountTotal) < 0, date = String(order.dateOrder), total = Math.abs(n(order.amountTotal)), untaxed = Math.abs(n(order.amountUntaxed)), tax = Math.abs(n(order.amountTax));
480
+ const invoice = Boolean(order.toInvoice);
481
+ const date = String(order.dateOrder);
482
+ const scale = scaleOf(order.currency);
483
+ const signedTotal = moneyMinor(order.amountTotal, scale);
484
+ const refund = signedTotal < 0n;
485
+ const total = refund ? -signedTotal : signedTotal;
486
+ const signedUntaxed = moneyMinor(order.amountUntaxed, scale);
487
+ const untaxed = signedUntaxed < 0n ? -signedUntaxed : signedUntaxed;
488
+ const signedTax = moneyMinor(order.amountTax, scale);
489
+ const tax = signedTax < 0n ? -signedTax : signedTax;
90
490
  if (invoice && !order.partnerId)
91
491
  throw new Error('a customer is required to invoice a POS order');
92
- if (tax && !config.taxAccountId)
492
+ if (tax > 0n && !config.taxAccountId)
93
493
  throw new Error('a tax account is required for taxed POS orders');
94
494
  await ctx.tx(async (tx) => {
95
- await tx.db.insert('account.Move', {
495
+ const zero = minorText(0n, scale);
496
+ const totalText = minorText(total, scale);
497
+ const move = {
96
498
  id,
97
499
  name: id,
98
500
  ref: order.posReference,
@@ -106,18 +508,23 @@ async function createAccounting(ctx, order, config, lines, payments) {
106
508
  paymentTermId: null,
107
509
  paymentState: invoice ? 'not_paid' : 'paid',
108
510
  currency: order.currency,
109
- amountUntaxed: decimal(untaxed),
110
- amountTax: decimal(tax),
111
- amountTotal: decimal(total),
511
+ amountUntaxed: minorText(untaxed, scale),
512
+ amountTax: minorText(tax, scale),
513
+ amountTotal: totalText,
112
514
  postedAt: null,
113
- });
515
+ revision: 0,
516
+ };
517
+ const moveLines = [];
114
518
  let sequence = 10;
115
519
  for (const line of lines) {
116
520
  // Revenue follows the signed line subtotal. A negative Loyalty line is a
117
521
  // contra-revenue debit on a sale, and becomes a credit when a refund
118
522
  // reverses it. Looking only at the order direction would overstate revenue.
119
- const balance = -n(line.priceSubtotal), debit = Math.max(0, balance), credit = Math.max(0, -balance);
120
- await tx.db.insert('account.MoveLine', {
523
+ const subtotal = moneyMinor(line.priceSubtotal, scale);
524
+ const balance = -subtotal;
525
+ const debit = balance > 0n ? balance : 0n;
526
+ const credit = balance < 0n ? -balance : 0n;
527
+ moveLines.push({
121
528
  id: `${id}:line:${String(line.id)}`,
122
529
  moveId: id,
123
530
  name: line.name,
@@ -125,24 +532,24 @@ async function createAccounting(ctx, order, config, lines, payments) {
125
532
  partnerId: order.partnerId ?? null,
126
533
  productId: line.productId,
127
534
  productUomId: line.productUomId,
128
- quantity: decimal(Math.abs(n(line.qty))),
535
+ quantity: absDecimalText(line.qty),
129
536
  priceUnit: line.priceUnit,
130
537
  discount: line.discount,
131
538
  taxId: line.taxId,
132
- debit: decimal(debit),
133
- credit: decimal(credit),
134
- balance: decimal(balance),
539
+ debit: minorText(debit, scale),
540
+ credit: minorText(credit, scale),
541
+ balance: minorText(balance, scale),
135
542
  dateMaturity: null,
136
543
  displayType: null,
137
544
  reconciled: false,
138
- amountResidual: '0',
545
+ amountResidual: zero,
139
546
  sequence,
140
547
  posLineId: line.id,
141
548
  });
142
549
  sequence += 10;
143
550
  }
144
- if (tax)
145
- await tx.db.insert('account.MoveLine', {
551
+ if (tax > 0n)
552
+ moveLines.push({
146
553
  id: `${id}:tax`,
147
554
  moveId: id,
148
555
  name: 'Tax',
@@ -151,20 +558,20 @@ async function createAccounting(ctx, order, config, lines, payments) {
151
558
  productId: null,
152
559
  productUomId: null,
153
560
  quantity: '1',
154
- priceUnit: decimal(tax),
561
+ priceUnit: minorText(tax, scale),
155
562
  discount: '0',
156
563
  taxId: null,
157
- debit: refund ? decimal(tax) : '0',
158
- credit: refund ? '0' : decimal(tax),
159
- balance: decimal(refund ? tax : -tax),
564
+ debit: refund ? minorText(tax, scale) : zero,
565
+ credit: refund ? zero : minorText(tax, scale),
566
+ balance: minorText(refund ? tax : -tax, scale),
160
567
  dateMaturity: null,
161
568
  displayType: null,
162
569
  reconciled: false,
163
- amountResidual: '0',
570
+ amountResidual: zero,
164
571
  sequence: 900,
165
572
  });
166
573
  if (invoice) {
167
- await tx.db.insert('account.MoveLine', {
574
+ moveLines.push({
168
575
  id: `${id}:counterpart`,
169
576
  moveId: id,
170
577
  name: order.posReference,
@@ -173,16 +580,16 @@ async function createAccounting(ctx, order, config, lines, payments) {
173
580
  productId: null,
174
581
  productUomId: null,
175
582
  quantity: '1',
176
- priceUnit: decimal(total),
583
+ priceUnit: totalText,
177
584
  discount: '0',
178
585
  taxId: null,
179
- debit: refund ? '0' : decimal(total),
180
- credit: refund ? decimal(total) : '0',
181
- balance: decimal(refund ? -total : total),
586
+ debit: refund ? zero : totalText,
587
+ credit: refund ? totalText : zero,
588
+ balance: minorText(refund ? -total : total, scale),
182
589
  dateMaturity: date,
183
590
  displayType: null,
184
591
  reconciled: false,
185
- amountResidual: decimal(total),
592
+ amountResidual: totalText,
186
593
  sequence: 1000,
187
594
  });
188
595
  }
@@ -190,8 +597,9 @@ async function createAccounting(ctx, order, config, lines, payments) {
190
597
  let paymentSequence = 1000;
191
598
  for (const payment of payments) {
192
599
  const method = (await tx.db.select('pos.PaymentMethod', { id: payment.paymentMethodId }))[0], journal = (await tx.db.select('account.Journal', { id: method.journalId }))[0];
193
- const amount = Math.abs(n(payment.amount));
194
- await tx.db.insert('account.MoveLine', {
600
+ const signedAmount = moneyMinor(payment.amount, scale);
601
+ const amount = signedAmount < 0n ? -signedAmount : signedAmount;
602
+ moveLines.push({
195
603
  id: `${id}:payment:${String(payment.id)}`,
196
604
  moveId: id,
197
605
  name: method.name,
@@ -200,21 +608,22 @@ async function createAccounting(ctx, order, config, lines, payments) {
200
608
  productId: null,
201
609
  productUomId: null,
202
610
  quantity: '1',
203
- priceUnit: decimal(amount),
611
+ priceUnit: minorText(amount, scale),
204
612
  discount: '0',
205
613
  taxId: null,
206
- debit: refund ? '0' : decimal(amount),
207
- credit: refund ? decimal(amount) : '0',
208
- balance: decimal(refund ? -amount : amount),
614
+ debit: refund ? zero : minorText(amount, scale),
615
+ credit: refund ? minorText(amount, scale) : zero,
616
+ balance: minorText(refund ? -amount : amount, scale),
209
617
  dateMaturity: null,
210
618
  displayType: null,
211
619
  reconciled: false,
212
- amountResidual: '0',
620
+ amountResidual: zero,
213
621
  sequence: paymentSequence,
214
622
  });
215
623
  paymentSequence += 10;
216
624
  }
217
625
  }
626
+ await insertDraftMove(tx, { move, lines: moveLines });
218
627
  });
219
628
  const posted = (await accountFunctions.postMove.handler(ctx, { id }));
220
629
  if (posted.ok !== true)
@@ -230,9 +639,13 @@ async function createAccounting(ctx, order, config, lines, payments) {
230
639
  partnerId: order.partnerId,
231
640
  journalId: method.journalId,
232
641
  destinationAccountId: config.receivableAccountId,
233
- amount: decimal(Math.abs(n(payment.amount))),
642
+ amount: minorText((() => {
643
+ const held = moneyMinor(payment.amount, scale);
644
+ return held < 0n ? -held : held;
645
+ })(), scale),
234
646
  date,
235
647
  paymentReference: order.posReference,
648
+ settlementKind: method.settlementKind ?? 'liquidity',
236
649
  reconcileLineId: `${id}:counterpart`,
237
650
  }));
238
651
  if (result.ok !== true)
@@ -241,19 +654,483 @@ async function createAccounting(ctx, order, config, lines, payments) {
241
654
  }
242
655
  return id;
243
656
  }
657
+ async function createCashAdjustmentAccounting(ctx, session, config, adjustmentId, difference) {
658
+ if (!config.cashOverShortAccountId)
659
+ throw new Error('a cash over/short clearing account is required before approving variance');
660
+ const links = await ctx.db.select('pos.ConfigPaymentMethod', { configId: config.id });
661
+ let method;
662
+ for (const link of links) {
663
+ const held = (await ctx.db.select('pos.PaymentMethod', { id: link.paymentMethodId }))[0];
664
+ if (held?.isCash) {
665
+ method = held;
666
+ break;
667
+ }
668
+ }
669
+ if (!method)
670
+ throw new Error('the POS configuration needs a cash payment method');
671
+ const journal = (await ctx.db.select('account.Journal', { id: method.journalId }))[0];
672
+ if (!journal?.defaultAccountId)
673
+ throw new Error('the cash journal needs a default account');
674
+ const moveId = `${adjustmentId}:account`;
675
+ if (!(await ctx.db.select('account.Move', { id: moveId }))[0]) {
676
+ const currency = await currencyOf(ctx);
677
+ const scale = scaleOf(currency);
678
+ const signed = moneyMinor(difference, scale);
679
+ const amount = signed < 0n ? -signed : signed;
680
+ const zero = minorText(0n, scale);
681
+ const amountText = minorText(amount, scale);
682
+ await ctx.tx(async (tx) => {
683
+ const move = {
684
+ id: moveId,
685
+ name: moveId,
686
+ ref: `POS cash variance ${String(session.name)}`,
687
+ date: now(),
688
+ moveType: 'entry',
689
+ state: 'draft',
690
+ journalId: method.journalId,
691
+ partnerId: null,
692
+ invoiceDate: null,
693
+ invoiceDateDue: null,
694
+ paymentTermId: null,
695
+ paymentState: 'paid',
696
+ currency,
697
+ amountUntaxed: amountText,
698
+ amountTax: zero,
699
+ amountTotal: amountText,
700
+ postedAt: null,
701
+ revision: 0,
702
+ };
703
+ const lines = [
704
+ {
705
+ id: `${moveId}:cash`,
706
+ moveId,
707
+ name: method.name,
708
+ accountId: journal.defaultAccountId,
709
+ partnerId: null,
710
+ productId: null,
711
+ productUomId: null,
712
+ quantity: '1',
713
+ priceUnit: amountText,
714
+ discount: '0',
715
+ taxId: null,
716
+ debit: signed > 0n ? amountText : zero,
717
+ credit: signed < 0n ? amountText : zero,
718
+ balance: minorText(signed, scale),
719
+ dateMaturity: null,
720
+ displayType: null,
721
+ reconciled: false,
722
+ amountResidual: zero,
723
+ sequence: 10,
724
+ },
725
+ {
726
+ id: `${moveId}:clearing`,
727
+ moveId,
728
+ name: 'Cash over/short',
729
+ accountId: config.cashOverShortAccountId,
730
+ partnerId: null,
731
+ productId: null,
732
+ productUomId: null,
733
+ quantity: '1',
734
+ priceUnit: amountText,
735
+ discount: '0',
736
+ taxId: null,
737
+ debit: signed < 0n ? amountText : zero,
738
+ credit: signed > 0n ? amountText : zero,
739
+ balance: minorText(-signed, scale),
740
+ dateMaturity: null,
741
+ displayType: null,
742
+ reconciled: false,
743
+ amountResidual: zero,
744
+ sequence: 20,
745
+ },
746
+ ];
747
+ await insertDraftMove(tx, { move, lines });
748
+ });
749
+ }
750
+ const posted = (await accountFunctions.postMove.handler(ctx, { id: moveId }));
751
+ if (posted.ok !== true)
752
+ throw new Error('cash variance accounting move could not be posted');
753
+ return moveId;
754
+ }
755
+ const scaledTaxEvidence = (evidence, factor) => {
756
+ if (!evidence || typeof evidence !== 'object' || !Array.isArray(evidence.taxes))
757
+ return null;
758
+ const source = evidence;
759
+ return {
760
+ ...source,
761
+ taxes: source.taxes.map((tax) => ({
762
+ ...tax,
763
+ share: decimal(n(tax.share) * factor),
764
+ })),
765
+ };
766
+ };
767
+ const returnTaxEvidence = (evidence, previousLines, ratio, exhaustsLine) => {
768
+ if (!exhaustsLine)
769
+ return scaledTaxEvidence(evidence, ratio * -1);
770
+ if (!evidence || typeof evidence !== 'object' || !Array.isArray(evidence.taxes))
771
+ return null;
772
+ const source = evidence;
773
+ const previousTaxes = previousLines.flatMap((line) => {
774
+ const held = line.taxEvidence;
775
+ return held && typeof held === 'object' && Array.isArray(held.taxes)
776
+ ? held.taxes
777
+ : [];
778
+ });
779
+ return {
780
+ ...source,
781
+ taxes: source.taxes.map((tax) => ({
782
+ ...tax,
783
+ share: decimal(-(n(tax.share) +
784
+ previousTaxes
785
+ .filter((previous) => String(previous.taxId ?? '') === String(tax.taxId ?? ''))
786
+ .reduce((sum, previous) => sum + n(previous.share), 0))),
787
+ })),
788
+ };
789
+ };
790
+ const taxGroupKey = (line) => JSON.stringify((Array.isArray(line.taxIds) ? line.taxIds : line.taxId ? [line.taxId] : []).map(String).sort());
791
+ async function returnableLines(ctx, original) {
792
+ const originalLines = await ctx.db.select('pos.OrderLine', { orderId: original.id });
793
+ const refunds = (await ctx.db.select('pos.Order', { refundedOrderId: original.id })).filter((order) => order.state !== 'cancel');
794
+ const returned = new Map();
795
+ for (const refund of refunds)
796
+ for (const line of await ctx.db.select('pos.OrderLine', { orderId: refund.id })) {
797
+ if (!line.refundedOrderlineId)
798
+ continue;
799
+ const key = String(line.refundedOrderlineId);
800
+ returned.set(key, (returned.get(key) ?? 0) + Math.abs(n(line.qty)));
801
+ }
802
+ return originalLines
803
+ .filter((line) => String(line.lineKind ?? 'product') !== 'reward')
804
+ .map((line) => {
805
+ const purchasedQuantity = Math.abs(n(line.qty));
806
+ const refundedQuantity = Math.min(purchasedQuantity, returned.get(String(line.id)) ?? 0);
807
+ return {
808
+ line,
809
+ purchasedQuantity,
810
+ refundedQuantity,
811
+ remainingQuantity: Math.max(0, purchasedQuantity - refundedQuantity),
812
+ };
813
+ });
814
+ }
815
+ async function completedLotSelections(ctx, originalLine, requestedQuantity) {
816
+ if (String(originalLine.tracking ?? 'none') === 'none')
817
+ return [];
818
+ const based = await toProductUnit(ctx, originalLine.productId, originalLine.productUomId, requestedQuantity);
819
+ if (!based)
820
+ return invalid('quantity', 'return quantity uses an incompatible product unit');
821
+ const move = (await ctx.db.select('stock.Move', { posLineId: originalLine.id }))[0];
822
+ const moveLines = move ? await ctx.db.select('stock.MoveLine', { moveId: move.id }) : [];
823
+ const delivered = new Map();
824
+ for (const line of moveLines) {
825
+ if (!line.lotId || line.picked === false || !(n(line.quantity) > 0))
826
+ continue;
827
+ const lotId = String(line.lotId);
828
+ delivered.set(lotId, (delivered.get(lotId) ?? 0) + n(line.quantity));
829
+ }
830
+ if (!delivered.size)
831
+ return invalid('originalOrderId', `tracked line ${String(originalLine.id)} has no completed lot evidence`);
832
+ const previous = new Map();
833
+ const refunds = await ctx.db.select('pos.Order', { refundedOrderId: originalLine.orderId });
834
+ for (const refund of refunds.filter((order) => order.state !== 'cancel'))
835
+ for (const line of await ctx.db.select('pos.OrderLine', { orderId: refund.id })) {
836
+ if (String(line.refundedOrderlineId ?? '') !== String(originalLine.id))
837
+ continue;
838
+ for (const selection of (Array.isArray(line.lotSelections) ? line.lotSelections : [])) {
839
+ const lotId = String(selection.lotId);
840
+ previous.set(lotId, (previous.get(lotId) ?? 0) + n(selection.quantity));
841
+ }
842
+ }
843
+ let remaining = based.quantity;
844
+ const selections = [];
845
+ for (const [lotId, deliveredQuantity] of [...delivered.entries()].sort(([left], [right]) => left.localeCompare(right))) {
846
+ const available = Math.max(0, deliveredQuantity - (previous.get(lotId) ?? 0));
847
+ const quantity = Math.min(available, remaining);
848
+ if (quantity > 0)
849
+ selections.push({ lotId, quantity: decimal(quantity), stockRevision: null });
850
+ remaining -= quantity;
851
+ if (remaining <= 0.000001)
852
+ break;
853
+ }
854
+ if (remaining > 0.000001)
855
+ return invalid('quantity', `return quantity exceeds delivered lot/serial evidence for ${String(originalLine.id)}`);
856
+ if (String(originalLine.tracking) === 'serial' &&
857
+ selections.some((selection) => Math.abs(n(selection.quantity) - 1) > 0.000001))
858
+ return invalid('quantity', 'serial returns must select complete serial numbers');
859
+ return selections;
860
+ }
244
861
  const stockEffects = [
245
862
  ...(stockFunctions.createPicking.effects ?? []),
246
863
  ...(stockFunctions.addMove.effects ?? []),
247
864
  ...(stockFunctions.confirmPicking.effects ?? []),
248
- ...(stockFunctions.reserveMove.effects ?? []),
865
+ ...(stockFunctions.reserveMoves.effects ?? []),
249
866
  ...(stockFunctions.saveMoveLine.effects ?? []),
250
867
  ...(stockFunctions.completePicking.effects ?? []),
251
868
  ];
869
+ const trackingAvailabilityEffects = stockFunctions.trackedAvailability.effects ?? [];
252
870
  const accountEffects = [
253
871
  ...(accountFunctions.postMove.effects ?? []),
254
872
  ...(accountFunctions.registerPayment.effects ?? []),
255
873
  ];
874
+ const createOrderEffects = [
875
+ 'read:pos.Sequence',
876
+ 'write:pos.Sequence',
877
+ 'read:pos.Session',
878
+ 'read:pos.Config',
879
+ 'read:pos.Order',
880
+ 'write:pos.Order',
881
+ 'read:partner.Partner',
882
+ 'read:company.Company',
883
+ ];
884
+ const refundOrderEffects = [
885
+ 'read:pos.Order',
886
+ 'read:pos.OrderLine',
887
+ 'write:pos.Order',
888
+ 'write:pos.OrderLine',
889
+ 'read:pos.Payment',
890
+ 'read:pos.Sequence',
891
+ 'write:pos.Sequence',
892
+ 'read:pos.Session',
893
+ 'read:pos.Config',
894
+ 'read:partner.Partner',
895
+ 'read:company.Company',
896
+ 'read:stock.Move',
897
+ 'read:stock.MoveLine',
898
+ 'read:product.Product',
899
+ 'read:product.Template',
900
+ 'read:product.TemplateUom',
901
+ 'read:product.ProductUom',
902
+ 'read:uom.Unit',
903
+ 'write:pos.AuditEvent',
904
+ ];
256
905
  export const functions = {
906
+ listAuditEvents: defineFn({
907
+ input: {
908
+ subjectType: 'text?',
909
+ subjectId: 'text?',
910
+ configId: 'id?',
911
+ sessionId: 'id?',
912
+ action: 'text?',
913
+ from: 'datetime?',
914
+ to: 'datetime?',
915
+ limit: 'int?',
916
+ },
917
+ effects: ['read:pos.AuditEvent'],
918
+ agent: true,
919
+ handler: async (ctx, args) => {
920
+ const event = ctx.table('pos.AuditEvent');
921
+ const filters = [
922
+ ...(args.subjectType ? [eq(event.subjectType, args.subjectType)] : []),
923
+ ...(args.subjectId ? [eq(event.subjectId, args.subjectId)] : []),
924
+ ...(args.configId ? [eq(event.configId, args.configId)] : []),
925
+ ...(args.sessionId ? [eq(event.sessionId, args.sessionId)] : []),
926
+ ...(args.action ? [eq(event.action, args.action)] : []),
927
+ ...(args.from ? [gte(event.occurredAt, args.from)] : []),
928
+ ...(args.to ? [lt(event.occurredAt, args.to)] : []),
929
+ ];
930
+ const base = from(event)
931
+ .orderBy(desc(event.occurredAt), desc(event.id))
932
+ .limit(Math.max(1, Math.min(200, Math.trunc(n(args.limit ?? 100)) || 100)));
933
+ return ctx.db.all(filters.length ? base.where(and(...filters)) : base);
934
+ },
935
+ }),
936
+ operationsReport: defineFn({
937
+ input: { dateFrom: 'date', dateTo: 'date', configId: 'id?', auditLimit: 'int?' },
938
+ output: { ok: 'bool', report: 'json?', errors: 'json?' },
939
+ effects: [
940
+ 'read:pos.Config',
941
+ 'read:pos.Order',
942
+ 'read:pos.Payment',
943
+ 'read:pos.CashMovement',
944
+ 'read:pos.AuditEvent',
945
+ 'read:company.Company',
946
+ ],
947
+ agent: true,
948
+ handler: async (ctx, args) => {
949
+ const ledger = await ledgerOf(ctx);
950
+ const window = operationsWindow(args.dateFrom, args.dateTo, ledger.timezone);
951
+ if (window.ok !== true)
952
+ return window;
953
+ if (args.configId && !(await ctx.db.select('pos.Config', { id: args.configId }))[0])
954
+ return invalid('configId', 'point of sale configuration does not exist');
955
+ const order = ctx.table('pos.Order');
956
+ const payment = ctx.table('pos.Payment');
957
+ const movement = ctx.table('pos.CashMovement');
958
+ const event = ctx.table('pos.AuditEvent');
959
+ const orderScope = args.configId ? [eq(order.configId, args.configId)] : [];
960
+ const financialOrderBase = from(order).where(inArray(order.state, ['paid', 'done']), or(and(gte(order.finalizedAt, window.from), lt(order.finalizedAt, window.to)), and(isNull(order.finalizedAt), gte(order.dateOrder, window.from), lt(order.dateOrder, window.to))), ...orderScope);
961
+ const missingFinalizedAt = from(order).where(inArray(order.state, ['paid', 'done']), isNull(order.finalizedAt), ...(args.configId ? [eq(order.configId, args.configId)] : []));
962
+ const paymentWindow = from(payment).where(gte(payment.paymentDate, window.from), lt(payment.paymentDate, window.to));
963
+ const paymentBase = args.configId
964
+ ? paymentWindow.where(eq(payment.configId, args.configId))
965
+ : paymentWindow;
966
+ const movementWindow = from(movement).where(gte(movement.occurredAt, window.from), lt(movement.occurredAt, window.to));
967
+ const movementBase = args.configId
968
+ ? movementWindow.where(eq(movement.configId, args.configId))
969
+ : movementWindow;
970
+ const auditWindow = from(event).where(gte(event.occurredAt, window.from), lt(event.occurredAt, window.to));
971
+ const auditBase = args.configId ? auditWindow.where(eq(event.configId, args.configId)) : auditWindow;
972
+ const auditLimit = Math.max(1, Math.min(200, Math.trunc(n(args.auditLimit ?? 100)) || 100));
973
+ const [orderGroups, paymentGroups, movementGroups, auditGroups, auditRows, missingPaymentScope, missingPaymentCurrency, missingMovementScope, missingAuditScope, missingOrderFinalizedAt, auditTotal, auditTraceGaps,] = await Promise.all([
974
+ ctx.db.group(financialOrderBase
975
+ .groupBy({ col: order.isRefund }, { col: order.currency })
976
+ .aggregate({ fn: 'sum', col: order.amountTotal, as: 'amount' })),
977
+ ctx.db.group(paymentBase
978
+ .groupBy({ col: payment.state }, { col: payment.kind }, { col: payment.currency })
979
+ .aggregate({ fn: 'sum', col: payment.appliedAmount, as: 'amount' })),
980
+ ctx.db.group(movementBase
981
+ .groupBy({ col: movement.direction })
982
+ .aggregate({ fn: 'sum', col: movement.amount, as: 'amount' })),
983
+ ctx.db.group(auditBase.groupBy({ col: event.action })),
984
+ ctx.db.all(auditBase.orderBy(desc(event.occurredAt), desc(event.id)).limit(auditLimit + 1)),
985
+ ctx.db.count(paymentWindow.where(isNull(payment.configId))),
986
+ ctx.db.count(paymentWindow.where(isNull(payment.currency))),
987
+ ctx.db.count(movementWindow.where(isNull(movement.configId))),
988
+ ctx.db.count(auditWindow.where(isNull(event.configId))),
989
+ ctx.db.count(missingFinalizedAt),
990
+ ctx.db.count(auditBase),
991
+ ctx.db.count(auditBase.where(isNull(event.correlationHash))),
992
+ ]);
993
+ const currency = ledger.currency;
994
+ const orderCurrencies = new Map();
995
+ for (const group of orderGroups) {
996
+ const [isRefund, heldCurrency] = group.key;
997
+ const code = String(heldCurrency);
998
+ const current = orderCurrencies.get(code) ?? {
999
+ currency: code,
1000
+ sales: [],
1001
+ refunds: [],
1002
+ saleCount: 0,
1003
+ returnCount: 0,
1004
+ };
1005
+ if (isRefund === true) {
1006
+ current.refunds.push(aggregateDecimal(group.aggregates.amount));
1007
+ current.returnCount += group.count;
1008
+ }
1009
+ else {
1010
+ current.sales.push(aggregateDecimal(group.aggregates.amount));
1011
+ current.saleCount += group.count;
1012
+ }
1013
+ orderCurrencies.set(code, current);
1014
+ }
1015
+ const sales = [...orderCurrencies.values()].map((row) => {
1016
+ const scale = scaleOf(row.currency);
1017
+ const gross = sumMoneyMinor(row.sales, scale);
1018
+ const refunds = sumMoneyMinor(row.refunds, scale);
1019
+ return {
1020
+ currency: row.currency,
1021
+ saleCount: row.saleCount,
1022
+ returnCount: row.returnCount,
1023
+ grossSales: minorText(gross, scale),
1024
+ refunds: minorText(refunds, scale),
1025
+ netSales: minorText(gross + refunds, scale),
1026
+ };
1027
+ });
1028
+ const tenderMap = new Map();
1029
+ for (const group of paymentGroups) {
1030
+ const state = String(group.key[0]);
1031
+ const kind = String(group.key[1]);
1032
+ const code = group.key[2] == null ? currency : String(group.key[2]);
1033
+ const key = `${state}\0${kind}\0${code}`;
1034
+ const held = tenderMap.get(key) ?? { state, kind, currency: code, count: 0, amount: 0n };
1035
+ held.count += group.count;
1036
+ held.amount += moneyMinor(aggregateDecimal(group.aggregates.amount), scaleOf(code));
1037
+ tenderMap.set(key, held);
1038
+ }
1039
+ const tenders = [...tenderMap.values()].map((row) => ({
1040
+ state: row.state,
1041
+ kind: row.kind,
1042
+ currency: row.currency,
1043
+ count: row.count,
1044
+ amount: minorText(row.amount, scaleOf(row.currency)),
1045
+ }));
1046
+ const cashScale = scaleOf(currency);
1047
+ let cashIn = 0n;
1048
+ let cashOut = 0n;
1049
+ let cashCount = 0;
1050
+ for (const group of movementGroups) {
1051
+ const amount = moneyMinor(aggregateDecimal(group.aggregates.amount), cashScale);
1052
+ cashCount += group.count;
1053
+ if (group.key[0] === 'in')
1054
+ cashIn += amount;
1055
+ else if (group.key[0] === 'out')
1056
+ cashOut += amount;
1057
+ }
1058
+ const actions = Object.fromEntries(auditGroups.map((group) => [String(group.key[0]), group.count]));
1059
+ const unscopedAudit = args.configId ? missingAuditScope : 0;
1060
+ const coreAuditTotal = auditTotal + unscopedAudit;
1061
+ const coreTraceGaps = auditTraceGaps + unscopedAudit;
1062
+ const traceRatio = coreAuditTotal
1063
+ ? Number(((coreAuditTotal - coreTraceGaps) / coreAuditTotal).toFixed(6))
1064
+ : 1;
1065
+ return {
1066
+ ok: true,
1067
+ report: {
1068
+ scope: {
1069
+ companyId: String(ctx.scope.company ?? ''),
1070
+ configId: args.configId ?? null,
1071
+ dateFrom: String(args.dateFrom),
1072
+ dateTo: String(args.dateTo),
1073
+ from: window.from,
1074
+ toExclusive: window.to,
1075
+ timezone: ledger.timezone,
1076
+ },
1077
+ scopeCoverage: {
1078
+ complete: missingPaymentScope === 0 &&
1079
+ missingPaymentCurrency === 0 &&
1080
+ missingMovementScope === 0 &&
1081
+ missingAuditScope === 0 &&
1082
+ missingOrderFinalizedAt === 0 &&
1083
+ coreTraceGaps === 0,
1084
+ missingPaymentScope,
1085
+ missingPaymentCurrency,
1086
+ missingMovementScope,
1087
+ missingAuditScope,
1088
+ missingOrderFinalizedAt,
1089
+ missingAuditCorrelation: coreTraceGaps,
1090
+ },
1091
+ orders: { sales, cancelledCount: actions['order.cancelled'] ?? 0 },
1092
+ tenders,
1093
+ cash: {
1094
+ currency,
1095
+ count: cashCount,
1096
+ cashIn: minorText(cashIn, cashScale),
1097
+ cashOut: minorText(cashOut, cashScale),
1098
+ net: minorText(cashIn - cashOut, cashScale),
1099
+ },
1100
+ shifts: {
1101
+ opened: actions['session.opened'] ?? 0,
1102
+ closed: actions['session.closed'] ?? 0,
1103
+ variancePending: actions['session.variance_pending'] ?? 0,
1104
+ varianceApproved: actions['session.variance_approved'] ?? 0,
1105
+ },
1106
+ exceptions: {
1107
+ cancelledOrders: actions['order.cancelled'] ?? 0,
1108
+ voidedTenders: actions['payment.voided'] ?? 0,
1109
+ reversedCashMovements: actions['cash_movement.reversed'] ?? 0,
1110
+ pendingVariances: actions['session.variance_pending'] ?? 0,
1111
+ },
1112
+ observability: {
1113
+ metrics: {
1114
+ auditEventTotal: coreAuditTotal,
1115
+ exceptionTotal: (actions['order.cancelled'] ?? 0) +
1116
+ (actions['payment.voided'] ?? 0) +
1117
+ (actions['cash_movement.reversed'] ?? 0) +
1118
+ (actions['session.variance_pending'] ?? 0),
1119
+ },
1120
+ traceCoverage: { coreAuditTotal, coreTraceGaps, ratio: traceRatio },
1121
+ alerts: coreTraceGaps
1122
+ ? [{ code: 'core_trace_gap', severity: 'warning', count: coreTraceGaps }]
1123
+ : [],
1124
+ },
1125
+ audit: {
1126
+ events: auditRows.slice(0, auditLimit).map(projectedAudit),
1127
+ limit: auditLimit,
1128
+ truncated: auditRows.length > auditLimit,
1129
+ },
1130
+ },
1131
+ };
1132
+ },
1133
+ }),
257
1134
  listConfigs: defineFn({
258
1135
  input: {},
259
1136
  effects: ['read:pos.Config'],
@@ -270,6 +1147,8 @@ export const functions = {
270
1147
  revenueAccountId: 'id',
271
1148
  receivableAccountId: 'id',
272
1149
  taxAccountId: 'id?',
1150
+ cashOverShortAccountId: 'id?',
1151
+ cashRoundingIncrement: 'decimal?',
273
1152
  maximumDifference: 'decimal?',
274
1153
  },
275
1154
  output: { ok: 'bool', id: 'id?', errors: 'json?' },
@@ -296,6 +1175,13 @@ export const functions = {
296
1175
  return invalid('receivableAccountId', 'a receivable account is required');
297
1176
  if (args.taxAccountId && !(await ctx.db.select('account.Account', { id: args.taxAccountId }))[0])
298
1177
  return invalid('taxAccountId', 'tax account does not exist');
1178
+ if (args.cashOverShortAccountId &&
1179
+ !(await ctx.db.select('account.Account', { id: args.cashOverShortAccountId }))[0])
1180
+ return invalid('cashOverShortAccountId', 'cash over/short account does not exist');
1181
+ if (compareDecimals(args.cashRoundingIncrement ?? '0', '0') !== 0)
1182
+ return invalid('cashRoundingIncrement', 'cash rounding is modeled but disabled for the pilot');
1183
+ if (compareDecimals(args.maximumDifference ?? '0', '0') < 0)
1184
+ return invalid('maximumDifference', 'maximum cash difference cannot be negative');
299
1185
  const existing = (await ctx.db.select('pos.Config', { id: args.id }))[0], values = {
300
1186
  name: args.name,
301
1187
  warehouseId: args.warehouseId,
@@ -304,6 +1190,8 @@ export const functions = {
304
1190
  revenueAccountId: args.revenueAccountId,
305
1191
  receivableAccountId: args.receivableAccountId,
306
1192
  taxAccountId: args.taxAccountId ?? null,
1193
+ cashOverShortAccountId: args.cashOverShortAccountId ?? existing?.cashOverShortAccountId ?? null,
1194
+ cashRoundingIncrement: args.cashRoundingIncrement ?? existing?.cashRoundingIncrement ?? '0',
307
1195
  maximumDifference: args.maximumDifference ?? '0',
308
1196
  active: true,
309
1197
  };
@@ -321,16 +1209,39 @@ export const functions = {
321
1209
  handler: (ctx) => ctx.db.select('pos.PaymentMethod', { active: true }),
322
1210
  }),
323
1211
  savePaymentMethod: defineFn({
324
- input: { id: 'id', name: 'text', journalId: 'id', isCash: 'bool?' },
1212
+ input: { id: 'id', name: 'text', journalId: 'id', settlementKind: 'text?', isCash: 'bool?' },
325
1213
  output: { ok: 'bool', id: 'id?', errors: 'json?' },
326
- effects: ['read:pos.PaymentMethod', 'write:pos.PaymentMethod', 'read:account.Journal'],
1214
+ effects: [
1215
+ 'read:pos.PaymentMethod',
1216
+ 'write:pos.PaymentMethod',
1217
+ 'read:account.Journal',
1218
+ 'read:account.Account',
1219
+ ],
327
1220
  idempotent: true,
328
1221
  agent: true,
329
1222
  handler: async (ctx, args) => {
330
1223
  const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
331
- if (!journal?.defaultAccountId || !['cash', 'bank'].includes(String(journal.type)))
332
- return invalid('journalId', 'payment method requires a cash or bank journal with a default account');
333
- const existing = (await ctx.db.select('pos.PaymentMethod', { id: args.id }))[0], values = { name: args.name, journalId: args.journalId, isCash: Boolean(args.isCash), active: true };
1224
+ const settlementKind = String(args.settlementKind ?? 'liquidity');
1225
+ if (!POS_PAYMENT_SETTLEMENT_KINDS.includes(settlementKind))
1226
+ return invalid('settlementKind', 'settlement kind must be liquidity or stored value');
1227
+ if (!journal?.defaultAccountId)
1228
+ return invalid('journalId', 'payment method requires a journal with a default account');
1229
+ const settlementAccount = (await ctx.db.select('account.Account', { id: journal.defaultAccountId }))[0];
1230
+ if (settlementKind === 'liquidity' && !['cash', 'bank'].includes(String(journal.type)))
1231
+ return invalid('journalId', 'liquidity payment method requires a cash or bank journal');
1232
+ if (settlementKind === 'stored_value' &&
1233
+ (String(journal.type) !== 'general' ||
1234
+ !String(settlementAccount?.accountType ?? '').startsWith('liability')))
1235
+ return invalid('journalId', 'stored value payment method requires a general liability journal');
1236
+ if (settlementKind === 'stored_value' && args.isCash === true)
1237
+ return invalid('isCash', 'stored value cannot be counted as cash');
1238
+ const existing = (await ctx.db.select('pos.PaymentMethod', { id: args.id }))[0], values = {
1239
+ name: args.name,
1240
+ journalId: args.journalId,
1241
+ settlementKind,
1242
+ isCash: settlementKind === 'liquidity' && Boolean(args.isCash),
1243
+ active: true,
1244
+ };
334
1245
  if (existing)
335
1246
  await ctx.db.update('pos.PaymentMethod', { id: args.id }, values);
336
1247
  else
@@ -373,91 +1284,341 @@ export const functions = {
373
1284
  }),
374
1285
  getSession: defineFn({
375
1286
  input: { id: 'id' },
376
- effects: ['read:pos.Session', 'read:pos.Order', 'read:pos.Payment', 'read:pos.PaymentMethod'],
1287
+ effects: [
1288
+ 'read:pos.Session',
1289
+ 'read:pos.Order',
1290
+ 'read:pos.Payment',
1291
+ 'read:pos.PaymentMethod',
1292
+ 'read:pos.CashMovement',
1293
+ 'read:company.Company',
1294
+ ],
377
1295
  agent: true,
378
1296
  handler: async (ctx, args) => {
379
1297
  const session = (await ctx.db.select('pos.Session', { id: args.id }))[0];
380
1298
  if (!session)
381
1299
  return null;
382
1300
  const orders = await ctx.db.select('pos.Order', { sessionId: args.id });
383
- let expectedCash = n(session.cashRegisterBalanceStart);
384
- for (const order of orders)
385
- for (const payment of await ctx.db.select('pos.Payment', { orderId: order.id })) {
386
- const method = (await ctx.db.select('pos.PaymentMethod', { id: payment.paymentMethodId }))[0];
387
- if (method?.isCash)
388
- expectedCash += n(payment.amount);
389
- }
390
- return { ...session, cashRegisterBalanceEnd: decimal(expectedCash), orders };
1301
+ const scale = scaleOf(await currencyOf(ctx));
1302
+ const expectedCash = await sessionCashMinor(ctx, session, scale);
1303
+ const cashMovements = await ctx.db.select('pos.CashMovement', { sessionId: args.id });
1304
+ return { ...session, cashRegisterBalanceEnd: minorText(expectedCash, scale), orders, cashMovements };
391
1305
  },
392
1306
  }),
393
1307
  createSession: defineFn({
394
- input: { id: 'id', configId: 'id', userId: 'id', openingCash: 'decimal?', openingNotes: 'text?' },
395
- output: { ok: 'bool', id: 'id?', errors: 'json?' },
396
- effects: ['read:pos.Session', 'write:pos.Session', 'read:pos.Config', 'read:user.User'],
1308
+ input: {
1309
+ id: 'id',
1310
+ configId: 'id',
1311
+ userId: 'id',
1312
+ deviceId: 'text?',
1313
+ openingCash: 'decimal?',
1314
+ openingNotes: 'text?',
1315
+ },
1316
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
1317
+ effects: [
1318
+ 'read:pos.Session',
1319
+ 'write:pos.Session',
1320
+ 'read:pos.SessionLock',
1321
+ 'write:pos.SessionLock',
1322
+ 'read:pos.Config',
1323
+ 'read:user.User',
1324
+ 'read:company.Company',
1325
+ 'write:pos.AuditEvent',
1326
+ ],
397
1327
  idempotent: true,
398
1328
  agent: true,
399
1329
  handler: async (ctx, args) => {
1330
+ const scale = scaleOf(await currencyOf(ctx));
1331
+ const openingCash = moneyMinor(args.openingCash ?? '0', scale);
400
1332
  const existing = (await ctx.db.select('pos.Session', { id: args.id }))[0];
401
- if (existing)
402
- return { ok: true, id: args.id };
1333
+ if (existing) {
1334
+ const same = existing.configId === args.configId &&
1335
+ existing.userId === args.userId &&
1336
+ (args.deviceId === undefined || existing.deviceId === args.deviceId) &&
1337
+ (args.openingCash === undefined ||
1338
+ moneyMinor(existing.cashRegisterBalanceStart, scale) === openingCash) &&
1339
+ (args.openingNotes === undefined || existing.openingNotes === args.openingNotes);
1340
+ return same
1341
+ ? { ok: true, id: args.id, revision: n(existing.revision) }
1342
+ : invalid('id', 'session id is already used by a different command');
1343
+ }
403
1344
  if (!(await ctx.db.select('pos.Config', { id: args.configId }))[0])
404
1345
  return invalid('configId', 'point of sale does not exist');
405
1346
  if (!(await ctx.db.select('user.User', { id: args.userId }))[0])
406
1347
  return invalid('userId', 'operator does not exist');
407
- const active = (await ctx.db.select('pos.Session', { configId: args.configId })).find((row) => row.state !== 'closed');
408
- if (active)
409
- return invalid('configId', 'this point of sale already has an active session');
1348
+ let lock = (await ctx.db.select('pos.SessionLock', { id: args.configId }))[0];
1349
+ if (!lock) {
1350
+ await ctx.db.insertIfAbsent('pos.SessionLock', { id: args.configId, sessionId: args.id });
1351
+ lock = (await ctx.db.select('pos.SessionLock', { id: args.configId }))[0];
1352
+ }
1353
+ if (lock?.sessionId !== args.id) {
1354
+ const active = (await ctx.db.select('pos.Session', { id: lock?.sessionId }))[0];
1355
+ if (active && !['closed', 'pending_approval'].includes(String(active.state)))
1356
+ return invalid('configId', 'this point of sale already has an active session');
1357
+ const changed = await ctx.db.compareAndSet('pos.SessionLock', { id: args.configId }, { sessionId: lock?.sessionId }, { sessionId: args.id });
1358
+ if (!('dryRun' in changed) && !changed.matched)
1359
+ return invalid('configId', 'this point of sale already has an active session');
1360
+ }
410
1361
  await ctx.db.insert('pos.Session', {
411
1362
  id: args.id,
412
1363
  name: `POS/${String(args.id)}`,
413
1364
  configId: args.configId,
414
1365
  userId: args.userId,
1366
+ deviceId: args.deviceId ?? null,
415
1367
  state: 'opening_control',
416
1368
  startAt: null,
417
1369
  stopAt: null,
418
1370
  openingNotes: args.openingNotes ?? null,
419
1371
  closingNotes: null,
420
- cashRegisterBalanceStart: args.openingCash ?? '0',
421
- cashRegisterBalanceEnd: args.openingCash ?? '0',
422
- cashRegisterBalanceEndReal: args.openingCash ?? '0',
423
- cashRegisterDifference: '0',
1372
+ cashRegisterBalanceStart: minorText(openingCash, scale),
1373
+ cashRegisterBalanceEnd: minorText(openingCash, scale),
1374
+ cashRegisterBalanceEndReal: minorText(openingCash, scale),
1375
+ cashRegisterDifference: minorText(0n, scale),
1376
+ varianceStatus: 'none',
1377
+ varianceReason: null,
1378
+ varianceNote: null,
1379
+ varianceApprovedBy: null,
1380
+ varianceApprovedAt: null,
1381
+ cashAdjustmentId: null,
1382
+ revision: 0,
424
1383
  });
425
- return { ok: true, id: args.id };
1384
+ await appendAudit(ctx, {
1385
+ id: `session:${String(args.id)}:created`,
1386
+ subjectType: 'session',
1387
+ subjectId: String(args.id),
1388
+ configId: args.configId,
1389
+ sessionId: args.id,
1390
+ action: 'session.created',
1391
+ actorId: args.userId,
1392
+ deviceId: args.deviceId,
1393
+ details: { configId: args.configId, openingCash: minorText(openingCash, scale) },
1394
+ });
1395
+ return { ok: true, id: args.id, revision: 0 };
426
1396
  },
427
1397
  }),
428
1398
  openSession: defineFn({
429
- input: { id: 'id' },
430
- output: { ok: 'bool', id: 'id?', errors: 'json?' },
431
- effects: ['read:pos.Session', 'write:pos.Session'],
1399
+ input: { id: 'id', expectedRevision: 'int?' },
1400
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
1401
+ effects: ['read:pos.Session', 'write:pos.Session', 'write:pos.AuditEvent'],
432
1402
  idempotent: true,
433
1403
  agent: true,
434
1404
  handler: async (ctx, args) => {
435
- const session = (await ctx.db.select('pos.Session', { id: args.id }))[0];
436
- if (!session || !['opening_control', 'opened'].includes(String(session.state)))
1405
+ const held = (await ctx.db.select('pos.Session', { id: args.id }))[0];
1406
+ if (held?.state === 'opened')
1407
+ return { ok: true, id: args.id, revision: n(held.revision) };
1408
+ if (held?.state !== 'opening_control')
437
1409
  return invalid('state', 'only opening control can be opened');
438
- await ctx.db.update('pos.Session', { id: args.id }, { state: 'opened', startAt: session.startAt ?? now() });
439
- return { ok: true, id: args.id };
1410
+ const claim = await claimSessionRevision(ctx, args.id, args.expectedRevision);
1411
+ if (claim.ok !== true)
1412
+ return claim;
1413
+ await ctx.db.update('pos.Session', { id: args.id }, { state: 'opened', startAt: held.startAt ?? now() });
1414
+ await appendAudit(ctx, {
1415
+ id: `session:${String(args.id)}:opened`,
1416
+ subjectType: 'session',
1417
+ subjectId: String(args.id),
1418
+ configId: held.configId,
1419
+ sessionId: args.id,
1420
+ action: 'session.opened',
1421
+ actorId: held.userId,
1422
+ deviceId: held.deviceId,
1423
+ details: { revision: claim.revision },
1424
+ });
1425
+ return { ok: true, id: args.id, revision: claim.revision };
1426
+ },
1427
+ }),
1428
+ recordCashMovement: defineFn({
1429
+ input: {
1430
+ id: 'id',
1431
+ sessionId: 'id',
1432
+ direction: 'text',
1433
+ amount: 'decimal',
1434
+ reason: 'text',
1435
+ note: 'text?',
1436
+ actorId: 'text',
1437
+ deviceId: 'text?',
1438
+ expectedRevision: 'int',
1439
+ },
1440
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
1441
+ effects: [
1442
+ 'read:pos.Session',
1443
+ 'write:pos.Session',
1444
+ 'read:pos.CashMovement',
1445
+ 'write:pos.CashMovement',
1446
+ 'read:company.Company',
1447
+ 'write:pos.AuditEvent',
1448
+ ],
1449
+ idempotent: true,
1450
+ agent: true,
1451
+ handler: async (ctx, args) => {
1452
+ if (!['in', 'out'].includes(String(args.direction)))
1453
+ return invalid('direction', 'cash movement direction must be in or out');
1454
+ if (!String(args.reason).trim())
1455
+ return invalid('reason', 'cash movement requires a reason');
1456
+ const session = (await ctx.db.select('pos.Session', { id: args.sessionId }))[0];
1457
+ if (session?.state !== 'opened')
1458
+ return invalid('state', 'cash movement requires an open shift');
1459
+ const scale = scaleOf(await currencyOf(ctx));
1460
+ const amount = moneyMinor(args.amount, scale);
1461
+ if (amount <= 0n)
1462
+ return invalid('amount', 'cash movement amount must be positive');
1463
+ const existing = (await ctx.db.select('pos.CashMovement', { id: args.id }))[0];
1464
+ if (existing) {
1465
+ const same = existing.sessionId === args.sessionId &&
1466
+ existing.direction === args.direction &&
1467
+ moneyMinor(existing.amount, scale) === amount;
1468
+ return same
1469
+ ? { ok: true, id: args.id, revision: n(session.revision) }
1470
+ : invalid('id', 'cash movement id is already used by a different command');
1471
+ }
1472
+ const claim = await claimSessionRevision(ctx, args.sessionId, args.expectedRevision);
1473
+ if (claim.ok !== true)
1474
+ return claim;
1475
+ await ctx.db.insert('pos.CashMovement', {
1476
+ id: args.id,
1477
+ sessionId: args.sessionId,
1478
+ configId: session.configId,
1479
+ direction: args.direction,
1480
+ amount: minorText(amount, scale),
1481
+ reason: String(args.reason),
1482
+ note: args.note ?? null,
1483
+ actorId: args.actorId,
1484
+ deviceId: args.deviceId ?? null,
1485
+ occurredAt: now(),
1486
+ reversalOfId: null,
1487
+ });
1488
+ await appendAudit(ctx, {
1489
+ id: `cash-movement:${String(args.id)}:recorded`,
1490
+ subjectType: 'cash_movement',
1491
+ subjectId: String(args.id),
1492
+ configId: session.configId,
1493
+ sessionId: args.sessionId,
1494
+ action: 'cash_movement.recorded',
1495
+ actorId: args.actorId,
1496
+ deviceId: args.deviceId,
1497
+ reason: args.reason,
1498
+ relatedId: args.sessionId,
1499
+ details: { direction: args.direction, amount: minorText(amount, scale), revision: claim.revision },
1500
+ });
1501
+ return { ok: true, id: args.id, revision: claim.revision };
1502
+ },
1503
+ }),
1504
+ reverseCashMovement: defineFn({
1505
+ input: {
1506
+ id: 'id',
1507
+ sessionId: 'id',
1508
+ movementId: 'id',
1509
+ expectedRevision: 'int',
1510
+ reason: 'text',
1511
+ note: 'text?',
1512
+ actorId: 'text',
1513
+ deviceId: 'text?',
1514
+ },
1515
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
1516
+ effects: [
1517
+ 'read:pos.Session',
1518
+ 'write:pos.Session',
1519
+ 'read:pos.CashMovement',
1520
+ 'write:pos.CashMovement',
1521
+ 'write:pos.AuditEvent',
1522
+ ],
1523
+ idempotent: true,
1524
+ agent: true,
1525
+ handler: async (ctx, args) => {
1526
+ if (!String(args.reason).trim())
1527
+ return invalid('reason', 'cash movement reversal requires a reason');
1528
+ const session = (await ctx.db.select('pos.Session', { id: args.sessionId }))[0];
1529
+ if (session?.state !== 'opened')
1530
+ return invalid('state', 'cash movement reversal requires an open shift');
1531
+ const original = (await ctx.db.select('pos.CashMovement', { id: args.movementId }))[0];
1532
+ if (!original || original.sessionId !== args.sessionId)
1533
+ return invalid('movementId', 'cash movement does not belong to this shift');
1534
+ if (original.reversalOfId)
1535
+ return invalid('movementId', 'a reversal cannot itself be reversed');
1536
+ const prior = (await ctx.db.select('pos.CashMovement', { reversalOfId: args.movementId }))[0];
1537
+ if (prior)
1538
+ return prior.id === args.id
1539
+ ? { ok: true, id: prior.id, revision: n(session.revision) }
1540
+ : invalid('movementId', 'cash movement is already reversed');
1541
+ const claim = await claimSessionRevision(ctx, args.sessionId, args.expectedRevision);
1542
+ if (claim.ok !== true)
1543
+ return claim;
1544
+ await ctx.db.insert('pos.CashMovement', {
1545
+ id: args.id,
1546
+ sessionId: args.sessionId,
1547
+ configId: session.configId,
1548
+ direction: original.direction === 'in' ? 'out' : 'in',
1549
+ amount: original.amount,
1550
+ reason: String(args.reason),
1551
+ note: args.note ?? null,
1552
+ actorId: args.actorId,
1553
+ deviceId: args.deviceId ?? null,
1554
+ occurredAt: now(),
1555
+ reversalOfId: original.id,
1556
+ });
1557
+ await appendAudit(ctx, {
1558
+ id: `cash-movement:${String(args.id)}:reversed`,
1559
+ subjectType: 'cash_movement',
1560
+ subjectId: String(args.id),
1561
+ configId: session.configId,
1562
+ sessionId: args.sessionId,
1563
+ action: 'cash_movement.reversed',
1564
+ actorId: args.actorId,
1565
+ deviceId: args.deviceId,
1566
+ reason: args.reason,
1567
+ relatedId: original.id,
1568
+ details: { sessionId: args.sessionId, amount: original.amount, revision: claim.revision },
1569
+ });
1570
+ return { ok: true, id: args.id, revision: claim.revision };
440
1571
  },
441
1572
  }),
442
1573
  startClosing: defineFn({
443
- input: { id: 'id' },
444
- output: { ok: 'bool', id: 'id?', errors: 'json?' },
445
- effects: ['read:pos.Session', 'read:pos.Order', 'write:pos.Session'],
1574
+ input: { id: 'id', expectedRevision: 'int?' },
1575
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
1576
+ effects: ['read:pos.Session', 'read:pos.Order', 'write:pos.Session', 'write:pos.AuditEvent'],
446
1577
  idempotent: true,
447
1578
  agent: true,
448
1579
  handler: async (ctx, args) => {
449
1580
  const session = (await ctx.db.select('pos.Session', { id: args.id }))[0];
450
- if (!session || !['opened', 'closing_control'].includes(String(session.state)))
1581
+ if (session?.state === 'closing_control')
1582
+ return { ok: true, id: args.id, revision: n(session.revision) };
1583
+ if (session?.state !== 'opened')
451
1584
  return invalid('state', 'only an open session can enter closing control');
452
1585
  if ((await ctx.db.select('pos.Order', { sessionId: args.id })).some((order) => order.state === 'draft'))
453
1586
  return invalid('orders', 'pay or cancel every draft order before closing');
1587
+ const claim = await claimSessionRevision(ctx, args.id, args.expectedRevision);
1588
+ if (claim.ok !== true)
1589
+ return claim;
454
1590
  await ctx.db.update('pos.Session', { id: args.id }, { state: 'closing_control' });
455
- return { ok: true, id: args.id };
1591
+ await appendAudit(ctx, {
1592
+ id: `session:${String(args.id)}:closing`,
1593
+ subjectType: 'session',
1594
+ subjectId: String(args.id),
1595
+ configId: session.configId,
1596
+ sessionId: args.id,
1597
+ action: 'session.closing_started',
1598
+ actorId: session.userId,
1599
+ deviceId: session.deviceId,
1600
+ details: { revision: claim.revision },
1601
+ });
1602
+ return { ok: true, id: args.id, revision: claim.revision };
456
1603
  },
457
1604
  }),
458
1605
  closeSession: defineFn({
459
- input: { id: 'id', closingCash: 'decimal', closingNotes: 'text?' },
460
- output: { ok: 'bool', id: 'id?', difference: 'decimal?', errors: 'json?' },
1606
+ input: {
1607
+ id: 'id',
1608
+ closingCash: 'decimal',
1609
+ closingNotes: 'text?',
1610
+ varianceReason: 'text?',
1611
+ varianceNote: 'text?',
1612
+ expectedRevision: 'int?',
1613
+ },
1614
+ output: {
1615
+ ok: 'bool',
1616
+ id: 'id?',
1617
+ revision: 'int?',
1618
+ difference: 'decimal?',
1619
+ pendingApproval: 'bool?',
1620
+ errors: 'json?',
1621
+ },
461
1622
  effects: [
462
1623
  'read:pos.Session',
463
1624
  'write:pos.Session',
@@ -465,7 +1626,10 @@ export const functions = {
465
1626
  'read:pos.Order',
466
1627
  'read:pos.Payment',
467
1628
  'read:pos.PaymentMethod',
1629
+ 'read:pos.CashMovement',
468
1630
  'write:pos.Order',
1631
+ 'read:company.Company',
1632
+ 'write:pos.AuditEvent',
469
1633
  ],
470
1634
  idempotent: true,
471
1635
  agent: true,
@@ -473,90 +1637,386 @@ export const functions = {
473
1637
  const session = (await ctx.db.select('pos.Session', { id: args.id }))[0];
474
1638
  if (!session)
475
1639
  return invalid('id', 'session does not exist');
476
- if (session.state === 'closed')
477
- return { ok: true, id: args.id, difference: session.cashRegisterDifference };
1640
+ if (['closed', 'pending_approval'].includes(String(session.state)))
1641
+ return {
1642
+ ok: true,
1643
+ id: args.id,
1644
+ revision: n(session.revision),
1645
+ difference: session.cashRegisterDifference,
1646
+ pendingApproval: session.state === 'pending_approval',
1647
+ };
478
1648
  if (session.state !== 'closing_control')
479
1649
  return invalid('state', 'session must be in closing control');
480
1650
  const config = (await ctx.db.select('pos.Config', { id: session.configId }))[0], orders = await ctx.db.select('pos.Order', { sessionId: args.id });
481
- let cash = n(session.cashRegisterBalanceStart);
482
- for (const order of orders)
483
- for (const payment of await ctx.db.select('pos.Payment', { orderId: order.id })) {
484
- const method = (await ctx.db.select('pos.PaymentMethod', { id: payment.paymentMethodId }))[0];
485
- if (method?.isCash)
486
- cash += n(payment.amount);
487
- }
488
- const difference = money(n(args.closingCash) - cash);
489
- if (Math.abs(difference) - n(config.maximumDifference) > 0.000001)
490
- return invalid('closingCash', 'cash difference exceeds the configured maximum');
1651
+ const scale = scaleOf(await currencyOf(ctx));
1652
+ const cash = await sessionCashMinor(ctx, session, scale);
1653
+ const closingCash = moneyMinor(args.closingCash, scale);
1654
+ const difference = closingCash - cash;
1655
+ const maximumDifference = moneyMinor(config.maximumDifference ?? '0', scale);
1656
+ const pendingApproval = absoluteMinor(difference) > maximumDifference;
1657
+ if (pendingApproval && !String(args.varianceReason ?? '').trim())
1658
+ return invalid('varianceReason', 'cash difference requires a reason before sealing the shift');
1659
+ const claim = await claimSessionRevision(ctx, args.id, args.expectedRevision);
1660
+ if (claim.ok !== true)
1661
+ return claim;
491
1662
  for (const order of orders)
492
1663
  if (order.state === 'paid')
493
1664
  await ctx.db.update('pos.Order', { id: order.id }, { state: 'done' });
494
1665
  await ctx.db.update('pos.Session', { id: args.id }, {
495
- state: 'closed',
1666
+ state: pendingApproval ? 'pending_approval' : 'closed',
496
1667
  stopAt: now(),
497
1668
  closingNotes: args.closingNotes ?? null,
498
- cashRegisterBalanceEnd: decimal(cash),
499
- cashRegisterBalanceEndReal: args.closingCash,
500
- cashRegisterDifference: decimal(difference),
1669
+ cashRegisterBalanceEnd: minorText(cash, scale),
1670
+ cashRegisterBalanceEndReal: minorText(closingCash, scale),
1671
+ cashRegisterDifference: minorText(difference, scale),
1672
+ varianceStatus: pendingApproval ? 'pending' : 'none',
1673
+ varianceReason: pendingApproval ? String(args.varianceReason) : null,
1674
+ varianceNote: pendingApproval ? (args.varianceNote ?? null) : null,
501
1675
  });
502
- return { ok: true, id: args.id, difference: decimal(difference) };
1676
+ await appendAudit(ctx, {
1677
+ id: `session:${String(args.id)}:sealed`,
1678
+ subjectType: 'session',
1679
+ subjectId: String(args.id),
1680
+ configId: session.configId,
1681
+ sessionId: args.id,
1682
+ action: pendingApproval ? 'session.variance_pending' : 'session.closed',
1683
+ actorId: session.userId,
1684
+ deviceId: session.deviceId,
1685
+ reason: pendingApproval ? args.varianceReason : undefined,
1686
+ details: {
1687
+ expectedCash: minorText(cash, scale),
1688
+ countedCash: minorText(closingCash, scale),
1689
+ difference: minorText(difference, scale),
1690
+ revision: claim.revision,
1691
+ },
1692
+ });
1693
+ return {
1694
+ ok: true,
1695
+ id: args.id,
1696
+ revision: claim.revision,
1697
+ difference: minorText(difference, scale),
1698
+ pendingApproval,
1699
+ };
503
1700
  },
504
1701
  }),
505
- listOrders: defineFn({
506
- input: { state: 'text?', sessionId: 'id?' },
507
- effects: ['read:pos.Order'],
508
- agent: true,
509
- handler: (ctx, args) => ctx.db.select('pos.Order', {
510
- ...(args.state ? { state: args.state } : {}),
511
- ...(args.sessionId ? { sessionId: args.sessionId } : {}),
512
- }),
513
- }),
514
- getOrder: defineFn({
515
- input: { id: 'id' },
516
- effects: ['read:pos.Order', 'read:pos.OrderLine', 'read:pos.Payment'],
517
- agent: true,
518
- handler: async (ctx, args) => {
519
- const order = (await ctx.db.select('pos.Order', { id: args.id }))[0];
520
- return order
521
- ? {
522
- ...order,
523
- lines: await ctx.db.select('pos.OrderLine', { orderId: args.id }),
524
- payments: await ctx.db.select('pos.Payment', { orderId: args.id }),
525
- }
526
- : null;
1702
+ recountSession: defineFn({
1703
+ input: { id: 'id', countedCash: 'decimal', expectedRevision: 'int', reviewedBy: 'text', note: 'text?' },
1704
+ output: {
1705
+ ok: 'bool',
1706
+ id: 'id?',
1707
+ revision: 'int?',
1708
+ difference: 'decimal?',
1709
+ pendingApproval: 'bool?',
1710
+ errors: 'json?',
527
1711
  },
528
- }),
529
- createOrder: defineFn({
530
- input: { id: 'id', uuid: 'text?', sessionId: 'id', partnerId: 'id?', toInvoice: 'bool?', note: 'text?' },
531
- output: { ok: 'bool', id: 'id?', name: 'text?', errors: 'json?' },
532
1712
  effects: [
533
- 'read:pos.Sequence',
534
- 'write:pos.Sequence',
535
1713
  'read:pos.Session',
1714
+ 'write:pos.Session',
536
1715
  'read:pos.Config',
1716
+ 'read:company.Company',
1717
+ 'write:pos.AuditEvent',
1718
+ ],
1719
+ idempotent: true,
1720
+ agent: true,
1721
+ handler: async (ctx, args) => {
1722
+ const session = (await ctx.db.select('pos.Session', { id: args.id }))[0];
1723
+ if (session?.state !== 'pending_approval')
1724
+ return invalid('state', 'only a sealed variance can be recounted');
1725
+ const config = (await ctx.db.select('pos.Config', { id: session.configId }))[0];
1726
+ const scale = scaleOf(await currencyOf(ctx));
1727
+ const countedCash = moneyMinor(args.countedCash, scale);
1728
+ const difference = countedCash - moneyMinor(session.cashRegisterBalanceEnd, scale);
1729
+ const maximumDifference = moneyMinor(config.maximumDifference ?? '0', scale);
1730
+ const pendingApproval = absoluteMinor(difference) > maximumDifference;
1731
+ const claim = await claimSessionRevision(ctx, args.id, args.expectedRevision);
1732
+ if (claim.ok !== true)
1733
+ return claim;
1734
+ await ctx.db.update('pos.Session', { id: args.id }, {
1735
+ state: pendingApproval ? 'pending_approval' : 'closed',
1736
+ cashRegisterBalanceEndReal: minorText(countedCash, scale),
1737
+ cashRegisterDifference: minorText(difference, scale),
1738
+ varianceStatus: pendingApproval ? 'pending' : 'corrected',
1739
+ varianceNote: args.note ?? session.varianceNote ?? null,
1740
+ varianceApprovedBy: pendingApproval ? null : args.reviewedBy,
1741
+ varianceApprovedAt: pendingApproval ? null : now(),
1742
+ });
1743
+ await appendAudit(ctx, {
1744
+ id: `session:${String(args.id)}:recount:${String(claim.revision)}`,
1745
+ subjectType: 'session',
1746
+ subjectId: String(args.id),
1747
+ configId: session.configId,
1748
+ sessionId: args.id,
1749
+ action: pendingApproval ? 'session.recount_pending' : 'session.recount_accepted',
1750
+ actorId: args.reviewedBy,
1751
+ deviceId: session.deviceId,
1752
+ reason: args.note,
1753
+ details: {
1754
+ countedCash: minorText(countedCash, scale),
1755
+ difference: minorText(difference, scale),
1756
+ revision: claim.revision,
1757
+ },
1758
+ });
1759
+ return {
1760
+ ok: true,
1761
+ id: args.id,
1762
+ revision: claim.revision,
1763
+ difference: minorText(difference, scale),
1764
+ pendingApproval,
1765
+ };
1766
+ },
1767
+ }),
1768
+ approveSessionVariance: defineFn({
1769
+ input: { id: 'id', expectedRevision: 'int', approvedBy: 'text', note: 'text?' },
1770
+ output: {
1771
+ ok: 'bool',
1772
+ id: 'id?',
1773
+ revision: 'int?',
1774
+ adjustmentId: 'id?',
1775
+ accountMoveId: 'id?',
1776
+ errors: 'json?',
1777
+ },
1778
+ effects: [
1779
+ 'read:pos.Session',
1780
+ 'write:pos.Session',
1781
+ 'read:pos.Config',
1782
+ 'read:pos.ConfigPaymentMethod',
1783
+ 'read:pos.PaymentMethod',
1784
+ 'read:pos.CashAdjustment',
1785
+ 'write:pos.CashAdjustment',
1786
+ 'read:account.Journal',
1787
+ 'read:account.Move',
1788
+ 'write:account.Move',
1789
+ 'write:account.MoveLine',
1790
+ 'read:company.Company',
1791
+ 'write:pos.AuditEvent',
1792
+ ...accountEffects,
1793
+ ],
1794
+ idempotent: true,
1795
+ agent: true,
1796
+ handler: async (ctx, args) => {
1797
+ const session = (await ctx.db.select('pos.Session', { id: args.id }))[0];
1798
+ if (!session)
1799
+ return invalid('id', 'session does not exist');
1800
+ if (session.varianceStatus === 'approved') {
1801
+ const adjustment = (await ctx.db.select('pos.CashAdjustment', { sessionId: args.id }))[0];
1802
+ return {
1803
+ ok: true,
1804
+ id: args.id,
1805
+ revision: n(session.revision),
1806
+ adjustmentId: adjustment?.id,
1807
+ accountMoveId: adjustment?.accountMoveId,
1808
+ };
1809
+ }
1810
+ if (session.state !== 'pending_approval')
1811
+ return invalid('state', 'only a sealed variance can be approved');
1812
+ const config = (await ctx.db.select('pos.Config', { id: session.configId }))[0];
1813
+ const claim = await claimSessionRevision(ctx, args.id, args.expectedRevision);
1814
+ if (claim.ok !== true)
1815
+ return claim;
1816
+ const adjustmentId = `${String(args.id)}:variance`;
1817
+ let accountMoveId;
1818
+ try {
1819
+ accountMoveId = await createCashAdjustmentAccounting(ctx, session, config, adjustmentId, session.cashRegisterDifference);
1820
+ }
1821
+ catch (error) {
1822
+ return invalid('accounting', error.message);
1823
+ }
1824
+ await ctx.db.insertIfAbsent('pos.CashAdjustment', {
1825
+ id: adjustmentId,
1826
+ sessionId: args.id,
1827
+ amount: session.cashRegisterDifference,
1828
+ reason: session.varianceReason,
1829
+ note: args.note ?? session.varianceNote ?? null,
1830
+ approvedBy: args.approvedBy,
1831
+ approvedAt: now(),
1832
+ accountMoveId,
1833
+ });
1834
+ await ctx.db.update('pos.Session', { id: args.id }, {
1835
+ state: 'closed',
1836
+ varianceStatus: 'approved',
1837
+ varianceNote: args.note ?? session.varianceNote ?? null,
1838
+ varianceApprovedBy: args.approvedBy,
1839
+ varianceApprovedAt: now(),
1840
+ cashAdjustmentId: adjustmentId,
1841
+ });
1842
+ await appendAudit(ctx, {
1843
+ id: `session:${String(args.id)}:variance-approved`,
1844
+ subjectType: 'session',
1845
+ subjectId: String(args.id),
1846
+ configId: session.configId,
1847
+ sessionId: args.id,
1848
+ action: 'session.variance_approved',
1849
+ actorId: args.approvedBy,
1850
+ deviceId: session.deviceId,
1851
+ reason: args.note ?? session.varianceReason,
1852
+ relatedId: adjustmentId,
1853
+ details: {
1854
+ difference: session.cashRegisterDifference,
1855
+ accountMoveId,
1856
+ revision: claim.revision,
1857
+ },
1858
+ });
1859
+ return { ok: true, id: args.id, revision: claim.revision, adjustmentId, accountMoveId };
1860
+ },
1861
+ }),
1862
+ listOrders: defineFn({
1863
+ input: { state: 'text?', sessionId: 'id?' },
1864
+ effects: ['read:pos.Order'],
1865
+ agent: true,
1866
+ handler: (ctx, args) => ctx.db.select('pos.Order', {
1867
+ ...(args.state ? { state: args.state } : {}),
1868
+ ...(args.sessionId ? { sessionId: args.sessionId } : {}),
1869
+ }),
1870
+ }),
1871
+ getOrder: defineFn({
1872
+ input: { id: 'id' },
1873
+ effects: ['read:pos.Order', 'read:pos.OrderLine', 'read:pos.Payment', 'read:pos.Exchange'],
1874
+ agent: true,
1875
+ handler: async (ctx, args) => {
1876
+ const order = (await ctx.db.select('pos.Order', { id: args.id }))[0];
1877
+ return order
1878
+ ? {
1879
+ ...order,
1880
+ lines: await ctx.db.select('pos.OrderLine', { orderId: args.id }),
1881
+ payments: await ctx.db.select('pos.Payment', { orderId: args.id }),
1882
+ exchange: order.exchangeId
1883
+ ? ((await ctx.db.select('pos.Exchange', { id: order.exchangeId }))[0] ?? null)
1884
+ : null,
1885
+ }
1886
+ : null;
1887
+ },
1888
+ }),
1889
+ getReceipt: defineFn({
1890
+ input: { orderId: 'id' },
1891
+ effects: ['read:pos.Order', 'read:pos.ReceiptDocument'],
1892
+ agent: true,
1893
+ handler: async (ctx, args) => {
1894
+ const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
1895
+ if (!order || !['paid', 'done'].includes(String(order.state)) || !order.receiptId)
1896
+ return null;
1897
+ const receipt = (await ctx.db.select('pos.ReceiptDocument', { id: order.receiptId }))[0];
1898
+ return receipt?.orderId === order.id ? receipt : null;
1899
+ },
1900
+ }),
1901
+ getLineTrackingAvailability: defineFn({
1902
+ input: { orderId: 'id', lineId: 'id' },
1903
+ effects: [
1904
+ 'read:pos.Order',
1905
+ 'read:pos.OrderLine',
1906
+ 'read:pos.Config',
1907
+ 'read:uom.Unit',
1908
+ ...trackingAvailabilityEffects,
1909
+ ],
1910
+ agent: true,
1911
+ handler: async (ctx, args) => {
1912
+ const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
1913
+ const line = (await ctx.db.select('pos.OrderLine', { id: args.lineId }))[0];
1914
+ return order && line?.orderId === order.id ? trackingAvailability(ctx, order, line) : null;
1915
+ },
1916
+ }),
1917
+ setLineLotSelections: defineFn({
1918
+ input: { orderId: 'id', lineId: 'id', expectedRevision: 'int', selections: 'json' },
1919
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
1920
+ effects: [
537
1921
  'read:pos.Order',
538
1922
  'write:pos.Order',
539
- 'read:partner.Partner',
540
- 'read:company.Company',
1923
+ 'read:pos.OrderLine',
1924
+ 'write:pos.OrderLine',
1925
+ 'read:pos.Config',
1926
+ 'read:uom.Unit',
1927
+ ...trackingAvailabilityEffects,
541
1928
  ],
542
1929
  idempotent: true,
543
1930
  agent: true,
1931
+ handler: async (ctx, args) => {
1932
+ const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
1933
+ const line = (await ctx.db.select('pos.OrderLine', { id: args.lineId }))[0];
1934
+ if (!order || !line || line.orderId !== order.id)
1935
+ return invalid('lineId', 'line does not belong to this order');
1936
+ if (order.state !== 'draft' || order.isRefund)
1937
+ return invalid('orderId', 'lot/serial selection is only editable on a new sale');
1938
+ if (order.paymentLockId)
1939
+ return invalid('orderId', 'order is locked by an external payment attempt');
1940
+ if (!Array.isArray(args.selections))
1941
+ return invalid('selections', 'selections must be an array');
1942
+ const availability = await trackingAvailability(ctx, order, line);
1943
+ const tracking = String(availability.tracking);
1944
+ if (tracking === 'none')
1945
+ return invalid('lineId', 'this product does not use lot/serial tracking');
1946
+ if (String(line.tracking ?? 'none') !== tracking)
1947
+ return invalid('tracking', 'product tracking changed; remove and add the line again');
1948
+ const selections = args.selections.map((selection) => ({
1949
+ lotId: String(selection.lotId ?? ''),
1950
+ quantity: n(selection.quantity),
1951
+ stockRevision: String(selection.stockRevision ?? ''),
1952
+ }));
1953
+ if (selections.some((selection) => !selection.lotId || !(selection.quantity > 0) || !selection.stockRevision))
1954
+ return invalid('selections', 'every selection needs lotId, positive quantity and stockRevision');
1955
+ if (new Set(selections.map((selection) => selection.lotId)).size !== selections.length)
1956
+ return invalid('selections', 'a lot/serial can only be selected once per line');
1957
+ if (tracking === 'serial' && selections.some((selection) => selection.quantity !== 1))
1958
+ return invalid('selections', 'every selected serial must have quantity 1');
1959
+ if (Math.abs(selections.reduce((sum, selection) => sum + selection.quantity, 0) -
1960
+ n(availability.requiredQuantity)) > 0.000001)
1961
+ return invalid('selections', 'selected quantity must equal line quantity in the product unit');
1962
+ const lots = new Map(availability.lots.map((lot) => [String(lot.lotId), lot]));
1963
+ for (const selection of selections) {
1964
+ const lot = lots.get(selection.lotId);
1965
+ if (lot?.selectable !== true)
1966
+ return invalid('lotId', `lot/serial ${selection.lotId} is not selectable`);
1967
+ if (String(lot.stockRevision) !== selection.stockRevision)
1968
+ return invalid('stockRevision', 'stock position changed; reload lot availability');
1969
+ if (n(lot.availableQuantity) + 0.000001 < selection.quantity)
1970
+ return invalid('quantity', `insufficient stock for lot/serial ${selection.lotId}`);
1971
+ }
1972
+ const claim = await claimDraftRevision(ctx, args.orderId, args.expectedRevision);
1973
+ if (claim.ok !== true)
1974
+ return claim;
1975
+ await ctx.db.update('pos.OrderLine', { id: args.lineId }, { lotSelections: selections });
1976
+ return { ok: true, id: args.lineId, revision: claim.revision };
1977
+ },
1978
+ }),
1979
+ createOrder: defineFn({
1980
+ input: {
1981
+ id: 'id',
1982
+ uuid: 'text?',
1983
+ sessionId: 'id',
1984
+ partnerId: 'id?',
1985
+ toInvoice: 'bool?',
1986
+ note: 'text?',
1987
+ operatorId: 'text?',
1988
+ deviceId: 'text?',
1989
+ priceBookRevision: 'text?',
1990
+ },
1991
+ output: { ok: 'bool', id: 'id?', name: 'text?', revision: 'int?', errors: 'json?' },
1992
+ effects: [...createOrderEffects],
1993
+ idempotent: true,
1994
+ agent: true,
544
1995
  handler: async (ctx, args) => {
545
1996
  const existing = (await ctx.db.select('pos.Order', { id: args.id }))[0];
546
- if (existing)
547
- return { ok: true, id: args.id, name: existing.name };
1997
+ if (existing) {
1998
+ const same = existing.sessionId === args.sessionId &&
1999
+ (args.uuid === undefined || existing.uuid === args.uuid) &&
2000
+ (args.deviceId === undefined || existing.deviceId === args.deviceId);
2001
+ return same
2002
+ ? { ok: true, id: args.id, name: existing.name, revision: n(existing.revision) }
2003
+ : invalid('id', 'order id is already used by a different command');
2004
+ }
548
2005
  if (args.uuid) {
549
2006
  const offline = (await ctx.db.select('pos.Order', { uuid: args.uuid }))[0];
550
- if (offline)
551
- return { ok: true, id: offline.id, name: offline.name };
2007
+ if (offline) {
2008
+ const same = offline.sessionId === args.sessionId &&
2009
+ (args.deviceId === undefined || offline.deviceId === args.deviceId);
2010
+ return same
2011
+ ? { ok: true, id: offline.id, name: offline.name, revision: n(offline.revision) }
2012
+ : invalid('uuid', 'order uuid is already used by a different command');
2013
+ }
552
2014
  }
553
2015
  const session = (await ctx.db.select('pos.Session', { id: args.sessionId }))[0];
554
2016
  if (session?.state !== 'opened')
555
2017
  return invalid('sessionId', 'orders require an open POS session');
556
2018
  if (args.partnerId && !(await ctx.db.select('partner.Partner', { id: args.partnerId }))[0])
557
2019
  return invalid('partnerId', 'customer does not exist');
558
- if (args.toInvoice && !args.partnerId)
559
- return invalid('partnerId', 'invoiced POS orders require a customer');
560
2020
  const sequenceNumber = await nextOrderNumber(ctx, args.sessionId), name = `Order ${String(sequenceNumber).padStart(5, '0')}`, posReference = `POS/${String(sequenceNumber).padStart(5, '0')}`;
561
2021
  await ctx.db.insert('pos.Order', {
562
2022
  id: args.id,
@@ -575,15 +2035,21 @@ export const functions = {
575
2035
  currency: await currencyOf(ctx),
576
2036
  amountUntaxed: '0',
577
2037
  amountTax: '0',
2038
+ amountExact: '0',
2039
+ amountRounding: '0',
578
2040
  amountTotal: '0',
579
2041
  amountPaid: '0',
580
2042
  amountReturn: '0',
581
- toInvoice: Boolean(args.toInvoice),
2043
+ toInvoice: true,
582
2044
  accountMoveId: null,
583
2045
  pickingId: null,
584
2046
  note: args.note ?? null,
2047
+ revision: 0,
2048
+ operatorId: args.operatorId ?? null,
2049
+ deviceId: args.deviceId ?? null,
2050
+ priceBookRevision: args.priceBookRevision ?? null,
585
2051
  });
586
- return { ok: true, id: args.id, name };
2052
+ return { ok: true, id: args.id, name, revision: 0 };
587
2053
  },
588
2054
  }),
589
2055
  addLine: defineFn({
@@ -596,8 +2062,11 @@ export const functions = {
596
2062
  priceUnit: 'decimal?',
597
2063
  discount: 'decimal?',
598
2064
  taxId: 'id?',
2065
+ taxIds: 'json?',
2066
+ quoteRevision: 'text?',
2067
+ expectedRevision: 'int?',
599
2068
  },
600
- output: { ok: 'bool', id: 'id?', priceUnit: 'decimal?', errors: 'json?' },
2069
+ output: { ok: 'bool', id: 'id?', priceUnit: 'decimal?', revision: 'int?', errors: 'json?' },
601
2070
  effects: [
602
2071
  'read:pos.Order',
603
2072
  'read:pos.Config',
@@ -607,12 +2076,16 @@ export const functions = {
607
2076
  'write:pos.Order',
608
2077
  'read:product.Product',
609
2078
  'read:product.Template',
2079
+ 'read:product.TemplateUom',
2080
+ 'read:product.ProductUom',
610
2081
  'read:product.Category',
611
2082
  'read:product.Cost',
612
2083
  'read:uom.Unit',
613
2084
  'read:pricing.Pricelist',
614
2085
  'read:pricing.PricelistItem',
615
2086
  'read:account.Tax',
2087
+ 'read:account.ProductTax',
2088
+ 'read:company.Company',
616
2089
  ],
617
2090
  idempotent: true,
618
2091
  agent: true,
@@ -620,13 +2093,14 @@ export const functions = {
620
2093
  const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
621
2094
  if (order?.state !== 'draft' || order.isRefund)
622
2095
  return invalid('orderId', 'products can only be added to a new non-refund order');
623
- if (!(n(args.qty) > 0))
2096
+ if (order.paymentLockId)
2097
+ return invalid('orderId', 'order is locked by an external payment attempt');
2098
+ if (compareDecimals(args.qty, '0') <= 0)
624
2099
  return invalid('qty', 'quantity must be positive');
625
- const product = await productOf(ctx, args.productId);
626
- if (!product?.template.saleOk)
627
- return invalid('productId', 'product is not available for sale');
628
- if (!(await ctx.db.select('uom.Unit', { id: args.productUomId }))[0])
629
- return invalid('productUomId', 'unit does not exist');
2100
+ const sellable = await sellableProduct(ctx, args.productId, args.productUomId);
2101
+ if (!sellable.ok)
2102
+ return invalid(sellable.field === 'uomId' ? 'productUomId' : sellable.field, sellable.message);
2103
+ const product = sellable.value;
630
2104
  const config = (await ctx.db.select('pos.Config', { id: order.configId }))[0], discount = args.discount ?? '0';
631
2105
  let priceUnit = args.priceUnit;
632
2106
  if (priceUnit === undefined && config.pricelistId) {
@@ -642,40 +2116,298 @@ export const functions = {
642
2116
  priceUnit = result.price;
643
2117
  }
644
2118
  priceUnit ??= product.template.listPrice;
645
- if (n(discount) < 0 || n(discount) > 100 || n(priceUnit) < 0)
2119
+ if (compareDecimals(discount, '0') < 0 ||
2120
+ compareDecimals(discount, '100') > 0 ||
2121
+ compareDecimals(priceUnit, '0') < 0)
646
2122
  return invalid('discount', 'price and discount are invalid');
647
- const tax = args.taxId ? (await ctx.db.select('account.Tax', { id: args.taxId }))[0] : null;
648
- if (args.taxId && (!tax || !['sale', 'none'].includes(String(tax.typeTaxUse))))
649
- return invalid('taxId', 'tax use does not match POS sales');
650
- try {
651
- taxAmounts(tax, n(args.qty) * n(priceUnit) * (1 - n(discount) / 100), n(args.qty));
2123
+ const taxIds = args.taxIds !== undefined ? args.taxIds : args.taxId ? [args.taxId] : undefined;
2124
+ const quote = await quoteTaxLine(ctx, {
2125
+ productId: args.productId,
2126
+ taxIds,
2127
+ quantity: args.qty,
2128
+ priceUnit,
2129
+ discount,
2130
+ });
2131
+ if (quote.ok !== true)
2132
+ return quote;
2133
+ const existing = (await ctx.db.select('pos.OrderLine', { id: args.id }))[0];
2134
+ if (existing) {
2135
+ const same = existing.orderId === args.orderId &&
2136
+ existing.productId === args.productId &&
2137
+ existing.productUomId === args.productUomId &&
2138
+ compareDecimals(existing.qty, args.qty) === 0 &&
2139
+ compareDecimals(existing.priceUnit, priceUnit) === 0 &&
2140
+ compareDecimals(existing.discount, discount) === 0 &&
2141
+ JSON.stringify(existing.taxIds ?? []) === JSON.stringify(quote.taxIds);
2142
+ return same
2143
+ ? { ok: true, id: args.id, priceUnit: String(priceUnit), revision: n(order.revision) }
2144
+ : invalid('id', 'line id is already used by a different command');
652
2145
  }
653
- catch (error) {
654
- return invalid('taxId', error.message);
2146
+ const claim = await claimDraftRevision(ctx, args.orderId, args.expectedRevision);
2147
+ if (claim.ok !== true)
2148
+ return claim;
2149
+ await ctx.db.insert('pos.OrderLine', {
2150
+ id: args.id,
2151
+ orderId: args.orderId,
2152
+ productId: args.productId,
2153
+ productUomId: args.productUomId,
2154
+ name: product.template.name,
2155
+ qty: args.qty,
2156
+ priceUnit: String(priceUnit),
2157
+ discount: String(discount),
2158
+ taxId: quote.taxIds[0] ?? null,
2159
+ taxIds: quote.taxIds,
2160
+ taxEvidence: { currency: quote.currency, scale: quote.scale, taxes: quote.taxes },
2161
+ quoteRevision: args.quoteRevision ?? null,
2162
+ tracking: String(product.template.tracking ?? 'none'),
2163
+ lotSelections: [],
2164
+ affectsStock: product.template.type !== 'service',
2165
+ priceSubtotal: quote.amountUntaxed,
2166
+ priceSubtotalIncl: quote.amountTotal,
2167
+ refundedOrderlineId: null,
2168
+ sequence: 10,
2169
+ });
2170
+ await recompute(ctx, args.orderId);
2171
+ return { ok: true, id: args.id, priceUnit: String(priceUnit), revision: claim.revision };
2172
+ },
2173
+ }),
2174
+ updateOrder: defineFn({
2175
+ input: {
2176
+ id: 'id',
2177
+ expectedRevision: 'int',
2178
+ partnerId: 'id?',
2179
+ clearPartner: 'bool?',
2180
+ note: 'text?',
2181
+ },
2182
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
2183
+ effects: ['read:pos.Order', 'write:pos.Order', 'read:partner.Partner'],
2184
+ idempotent: true,
2185
+ agent: true,
2186
+ handler: async (ctx, args) => {
2187
+ const order = (await ctx.db.select('pos.Order', { id: args.id }))[0];
2188
+ if (order?.paymentLockId)
2189
+ return invalid('id', 'order is locked by an external payment attempt');
2190
+ if (order?.isRefund && (args.partnerId || args.clearPartner))
2191
+ return invalid('partnerId', 'a return must keep the original invoice customer');
2192
+ if (args.partnerId && !(await ctx.db.select('partner.Partner', { id: args.partnerId }))[0])
2193
+ return invalid('partnerId', 'customer does not exist');
2194
+ const claim = await claimDraftRevision(ctx, args.id, args.expectedRevision);
2195
+ if (claim.ok !== true)
2196
+ return claim;
2197
+ await ctx.db.update('pos.Order', { id: args.id }, {
2198
+ ...(args.clearPartner ? { partnerId: null } : args.partnerId ? { partnerId: args.partnerId } : {}),
2199
+ ...(args.note !== undefined ? { note: args.note } : {}),
2200
+ });
2201
+ return { ok: true, id: args.id, revision: claim.revision };
2202
+ },
2203
+ }),
2204
+ updateLine: defineFn({
2205
+ input: {
2206
+ id: 'id',
2207
+ orderId: 'id',
2208
+ expectedRevision: 'int',
2209
+ qty: 'decimal',
2210
+ priceUnit: 'decimal?',
2211
+ discount: 'decimal?',
2212
+ taxIds: 'json?',
2213
+ quoteRevision: 'text?',
2214
+ sequence: 'int?',
2215
+ overrideReason: 'text?',
2216
+ overrideBy: 'text?',
2217
+ },
2218
+ output: { ok: 'bool', id: 'id?', priceUnit: 'decimal?', revision: 'int?', errors: 'json?' },
2219
+ effects: [
2220
+ 'read:pos.Order',
2221
+ 'write:pos.Order',
2222
+ 'read:pos.OrderLine',
2223
+ 'write:pos.OrderLine',
2224
+ 'read:pos.Payment',
2225
+ 'read:pos.Config',
2226
+ 'read:product.Product',
2227
+ 'read:product.Template',
2228
+ 'read:product.TemplateUom',
2229
+ 'read:product.ProductUom',
2230
+ 'read:product.Category',
2231
+ 'read:product.Cost',
2232
+ 'read:uom.Unit',
2233
+ 'read:pricing.Pricelist',
2234
+ 'read:pricing.PricelistItem',
2235
+ 'read:account.Tax',
2236
+ 'read:account.ProductTax',
2237
+ 'read:company.Company',
2238
+ 'write:pos.AuditEvent',
2239
+ ],
2240
+ idempotent: true,
2241
+ agent: true,
2242
+ handler: async (ctx, args) => {
2243
+ const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
2244
+ const line = (await ctx.db.select('pos.OrderLine', { id: args.id }))[0];
2245
+ if (!line || line.orderId !== args.orderId)
2246
+ return invalid('id', 'line does not belong to this order');
2247
+ if (order?.state !== 'draft' || order.isRefund)
2248
+ return invalid('orderId', 'only a new non-refund order can be changed');
2249
+ if (order.paymentLockId)
2250
+ return invalid('orderId', 'order is locked by an external payment attempt');
2251
+ if (compareDecimals(args.qty, '0') <= 0)
2252
+ return invalid('qty', 'quantity must be positive');
2253
+ const sellable = await sellableProduct(ctx, line.productId, line.productUomId);
2254
+ if (!sellable.ok)
2255
+ return invalid(sellable.field, sellable.message);
2256
+ const config = (await ctx.db.select('pos.Config', { id: order.configId }))[0];
2257
+ let priceUnit = args.priceUnit;
2258
+ if (priceUnit === undefined && config.pricelistId) {
2259
+ const priced = (await pricingFunctions.priceFor.handler(ctx, {
2260
+ pricelistId: config.pricelistId,
2261
+ productId: line.productId,
2262
+ quantity: args.qty,
2263
+ uomId: line.productUomId,
2264
+ date: order.dateOrder,
2265
+ }));
2266
+ if (priced.ok !== true)
2267
+ return priced;
2268
+ priceUnit = priced.price;
655
2269
  }
656
- if (!(await ctx.db.select('pos.OrderLine', { id: args.id }))[0])
657
- await ctx.db.insert('pos.OrderLine', {
658
- id: args.id,
659
- orderId: args.orderId,
660
- productId: args.productId,
661
- productUomId: args.productUomId,
662
- name: product.template.name,
663
- qty: args.qty,
664
- priceUnit: String(priceUnit),
665
- discount: String(discount),
666
- taxId: args.taxId ?? null,
667
- priceSubtotal: '0',
668
- priceSubtotalIncl: '0',
669
- refundedOrderlineId: null,
670
- sequence: 10,
2270
+ priceUnit ??= sellable.value.template.listPrice;
2271
+ const discount = args.discount ?? line.discount;
2272
+ if (compareDecimals(discount, '0') < 0 ||
2273
+ compareDecimals(discount, '100') > 0 ||
2274
+ compareDecimals(priceUnit, '0') < 0)
2275
+ return invalid('discount', 'price and discount are invalid');
2276
+ const taxIds = args.taxIds !== undefined ? args.taxIds : (line.taxIds ?? []);
2277
+ const quote = await quoteTaxLine(ctx, {
2278
+ productId: line.productId,
2279
+ taxIds,
2280
+ quantity: args.qty,
2281
+ priceUnit,
2282
+ discount,
2283
+ });
2284
+ if (quote.ok !== true)
2285
+ return quote;
2286
+ const claim = await claimDraftRevision(ctx, args.orderId, args.expectedRevision);
2287
+ if (claim.ok !== true)
2288
+ return claim;
2289
+ await ctx.db.update('pos.OrderLine', { id: args.id }, {
2290
+ qty: args.qty,
2291
+ priceUnit: String(priceUnit),
2292
+ discount: String(discount),
2293
+ taxId: quote.taxIds[0] ?? null,
2294
+ taxIds: quote.taxIds,
2295
+ taxEvidence: { currency: quote.currency, scale: quote.scale, taxes: quote.taxes },
2296
+ quoteRevision: args.quoteRevision ?? line.quoteRevision ?? null,
2297
+ overrideReason: args.priceUnit !== undefined || args.discount !== undefined
2298
+ ? (args.overrideReason ?? line.overrideReason ?? null)
2299
+ : (line.overrideReason ?? null),
2300
+ overrideBy: args.priceUnit !== undefined || args.discount !== undefined
2301
+ ? (args.overrideBy ?? line.overrideBy ?? null)
2302
+ : (line.overrideBy ?? null),
2303
+ priceSubtotal: quote.amountUntaxed,
2304
+ priceSubtotalIncl: quote.amountTotal,
2305
+ sequence: args.sequence ?? line.sequence,
2306
+ });
2307
+ await recompute(ctx, args.orderId);
2308
+ if (args.priceUnit !== undefined || args.discount !== undefined)
2309
+ await appendAudit(ctx, {
2310
+ id: `order-line:${String(args.id)}:adjusted:${String(claim.revision)}`,
2311
+ subjectType: 'order',
2312
+ subjectId: String(args.orderId),
2313
+ configId: order.configId,
2314
+ sessionId: order.sessionId,
2315
+ action: 'order.line_adjusted',
2316
+ actorId: args.overrideBy,
2317
+ deviceId: order.deviceId,
2318
+ reason: args.overrideReason,
2319
+ relatedId: args.id,
2320
+ details: {
2321
+ previousPriceUnit: line.priceUnit,
2322
+ priceUnit: String(priceUnit),
2323
+ previousDiscount: line.discount,
2324
+ discount: String(discount),
2325
+ revision: claim.revision,
2326
+ },
671
2327
  });
2328
+ return { ok: true, id: args.id, priceUnit: String(priceUnit), revision: claim.revision };
2329
+ },
2330
+ }),
2331
+ removeLine: defineFn({
2332
+ input: { id: 'id', orderId: 'id', expectedRevision: 'int' },
2333
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
2334
+ effects: [
2335
+ 'read:pos.Order',
2336
+ 'write:pos.Order',
2337
+ 'read:pos.OrderLine',
2338
+ 'write:pos.OrderLine',
2339
+ 'read:pos.Payment',
2340
+ ],
2341
+ idempotent: true,
2342
+ agent: true,
2343
+ handler: async (ctx, args) => {
2344
+ const line = (await ctx.db.select('pos.OrderLine', { id: args.id }))[0];
2345
+ if (!line)
2346
+ return invalid('id', 'line does not exist');
2347
+ if (line.orderId !== args.orderId)
2348
+ return invalid('id', 'line does not belong to this order');
2349
+ const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
2350
+ if (order?.isRefund)
2351
+ return invalid('orderId', 'return lines are immutable');
2352
+ if (order?.paymentLockId)
2353
+ return invalid('orderId', 'order is locked by an external payment attempt');
2354
+ const claim = await claimDraftRevision(ctx, args.orderId, args.expectedRevision);
2355
+ if (claim.ok !== true)
2356
+ return claim;
2357
+ const L = ctx.table('pos.OrderLine');
2358
+ await ctx.db.del(deleteFrom(L).where(eq(L.id, String(args.id))));
672
2359
  await recompute(ctx, args.orderId);
673
- return { ok: true, id: args.id, priceUnit: String(priceUnit) };
2360
+ return { ok: true, id: args.id, revision: claim.revision };
2361
+ },
2362
+ }),
2363
+ reorderLines: defineFn({
2364
+ input: { id: 'id', expectedRevision: 'int', lineIds: 'json' },
2365
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
2366
+ effects: ['read:pos.Order', 'write:pos.Order', 'read:pos.OrderLine', 'write:pos.OrderLine'],
2367
+ idempotent: true,
2368
+ agent: true,
2369
+ handler: async (ctx, args) => {
2370
+ if (!Array.isArray(args.lineIds))
2371
+ return invalid('lineIds', 'lineIds must be an array');
2372
+ const order = (await ctx.db.select('pos.Order', { id: args.id }))[0];
2373
+ if (order?.isRefund)
2374
+ return invalid('id', 'return lines are immutable');
2375
+ if (order?.paymentLockId)
2376
+ return invalid('id', 'order is locked by an external payment attempt');
2377
+ const lines = await ctx.db.select('pos.OrderLine', { orderId: args.id });
2378
+ const wanted = args.lineIds.map(String);
2379
+ if (new Set(wanted).size !== wanted.length ||
2380
+ lines.length !== wanted.length ||
2381
+ lines.some((line) => !wanted.includes(String(line.id))))
2382
+ return invalid('lineIds', 'lineIds must contain every line exactly once');
2383
+ const claim = await claimDraftRevision(ctx, args.id, args.expectedRevision);
2384
+ if (claim.ok !== true)
2385
+ return claim;
2386
+ for (const [index, lineId] of wanted.entries())
2387
+ await ctx.db.update('pos.OrderLine', { id: lineId }, { sequence: (index + 1) * 10 });
2388
+ return { ok: true, id: args.id, revision: claim.revision };
674
2389
  },
675
2390
  }),
676
2391
  addPayment: defineFn({
677
- input: { id: 'id', orderId: 'id', paymentMethodId: 'id', amount: 'decimal' },
678
- output: { ok: 'bool', id: 'id?', errors: 'json?' },
2392
+ input: {
2393
+ id: 'id',
2394
+ orderId: 'id',
2395
+ paymentMethodId: 'id',
2396
+ amount: 'decimal?',
2397
+ tenderedAmount: 'decimal?',
2398
+ reference: 'text?',
2399
+ operatorId: 'text?',
2400
+ deviceId: 'text?',
2401
+ expectedRevision: 'int?',
2402
+ },
2403
+ output: {
2404
+ ok: 'bool',
2405
+ id: 'id?',
2406
+ revision: 'int?',
2407
+ appliedAmount: 'decimal?',
2408
+ change: 'decimal?',
2409
+ errors: 'json?',
2410
+ },
679
2411
  effects: [
680
2412
  'read:pos.Order',
681
2413
  'read:pos.ConfigPaymentMethod',
@@ -683,9 +2415,7 @@ export const functions = {
683
2415
  'read:pos.Payment',
684
2416
  'write:pos.Payment',
685
2417
  'read:pos.OrderLine',
686
- 'write:pos.OrderLine',
687
2418
  'write:pos.Order',
688
- 'read:account.Tax',
689
2419
  ],
690
2420
  idempotent: true,
691
2421
  agent: true,
@@ -693,52 +2423,656 @@ export const functions = {
693
2423
  const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
694
2424
  if (order?.state !== 'draft')
695
2425
  return invalid('orderId', 'payments can only be added to a new order');
696
- if ((order.isRefund && n(args.amount) >= 0) || (!order.isRefund && n(args.amount) <= 0))
697
- return invalid('amount', order.isRefund ? 'refund payments must be negative' : 'payment must be positive');
2426
+ if (order.paymentLockId)
2427
+ return invalid('orderId', 'order is locked by an external payment attempt');
2428
+ const scale = scaleOf(order.currency);
2429
+ let tendered;
2430
+ try {
2431
+ tendered = moneyMinor(args.tenderedAmount ?? args.amount, scale);
2432
+ }
2433
+ catch {
2434
+ return invalid('tenderedAmount', 'payment must be a valid monetary amount');
2435
+ }
2436
+ if ((order.isRefund && tendered >= 0n) || (!order.isRefund && tendered <= 0n))
2437
+ return invalid('tenderedAmount', order.isRefund ? 'refund payments must be negative' : 'payment must be positive');
698
2438
  const linked = (await ctx.db.select('pos.ConfigPaymentMethod', {
699
2439
  configId: order.configId,
700
2440
  paymentMethodId: args.paymentMethodId,
701
2441
  }))[0];
702
- if (!linked || !(await ctx.db.select('pos.PaymentMethod', { id: args.paymentMethodId }))[0])
2442
+ const method = (await ctx.db.select('pos.PaymentMethod', { id: args.paymentMethodId }))[0];
2443
+ if (!linked || !method)
703
2444
  return invalid('paymentMethodId', 'payment method is not configured for this point of sale');
704
- if (!(await ctx.db.select('pos.Payment', { id: args.id }))[0])
705
- await ctx.db.insert('pos.Payment', {
706
- id: args.id,
707
- orderId: args.orderId,
708
- paymentMethodId: args.paymentMethodId,
709
- amount: args.amount,
710
- paymentDate: now(),
711
- });
2445
+ if (!method.isCash && !String(args.reference ?? '').trim())
2446
+ return invalid('reference', 'manual non-cash tender requires a reference');
2447
+ const existing = (await ctx.db.select('pos.Payment', { id: args.id }))[0];
2448
+ if (existing) {
2449
+ const same = existing.orderId === args.orderId &&
2450
+ existing.paymentMethodId === args.paymentMethodId &&
2451
+ moneyMinor(existing.tenderedAmount ?? existing.amount, scale) === tendered &&
2452
+ String(existing.reference ?? '') === String(args.reference ?? '');
2453
+ return same
2454
+ ? {
2455
+ ok: true,
2456
+ id: args.id,
2457
+ revision: n(order.revision),
2458
+ appliedAmount: existing.appliedAmount ?? existing.amount,
2459
+ change: minorText(moneyMinor(existing.tenderedAmount ?? existing.amount, scale) -
2460
+ moneyMinor(existing.appliedAmount ?? existing.amount, scale), scale),
2461
+ }
2462
+ : invalid('id', 'tender id is already used by a different command');
2463
+ }
2464
+ const captured = (await ctx.db.select('pos.Payment', { orderId: args.orderId })).filter((payment) => (payment.state ?? 'captured') === 'captured');
2465
+ const capturedAmount = captured.reduce((sum, payment) => sum + absoluteMinor(moneyMinor(payment.appliedAmount ?? payment.amount, scale)), 0n);
2466
+ const payable = absoluteMinor(moneyMinor(order.amountTotal, scale));
2467
+ const remaining = payable > capturedAmount ? payable - capturedAmount : 0n;
2468
+ if (remaining === 0n)
2469
+ return invalid('amount', 'the order is already fully covered');
2470
+ const tenderedAbsolute = absoluteMinor(tendered);
2471
+ if (!method.isCash && tenderedAbsolute > remaining)
2472
+ return invalid('tenderedAmount', 'manual non-cash tender cannot exceed the remaining payable');
2473
+ const appliedAbsolute = method.isCash && tenderedAbsolute > remaining ? remaining : tenderedAbsolute;
2474
+ const direction = order.isRefund ? -1n : 1n;
2475
+ const applied = direction * appliedAbsolute;
2476
+ const claim = await claimDraftRevision(ctx, args.orderId, args.expectedRevision);
2477
+ if (claim.ok !== true)
2478
+ return claim;
2479
+ await ctx.db.insert('pos.Payment', {
2480
+ id: args.id,
2481
+ orderId: args.orderId,
2482
+ configId: order.configId,
2483
+ sessionId: order.sessionId,
2484
+ paymentMethodId: args.paymentMethodId,
2485
+ currency: order.currency,
2486
+ amount: minorText(applied, scale),
2487
+ tenderedAmount: minorText(tendered, scale),
2488
+ appliedAmount: minorText(applied, scale),
2489
+ state: 'captured',
2490
+ kind: method.isCash ? 'cash' : 'manual',
2491
+ reference: args.reference ?? null,
2492
+ providerAttemptId: null,
2493
+ operatorId: args.operatorId ?? null,
2494
+ deviceId: args.deviceId ?? null,
2495
+ paymentDate: now(),
2496
+ });
712
2497
  await recompute(ctx, args.orderId);
713
- return { ok: true, id: args.id };
2498
+ return {
2499
+ ok: true,
2500
+ id: args.id,
2501
+ revision: claim.revision,
2502
+ appliedAmount: minorText(applied, scale),
2503
+ change: minorText(tendered - applied, scale),
2504
+ };
2505
+ },
2506
+ }),
2507
+ lockProviderPayment: defineFn({
2508
+ exposure: 'internal',
2509
+ input: {
2510
+ orderId: 'id',
2511
+ paymentMethodId: 'id',
2512
+ amount: 'decimal',
2513
+ providerAttemptId: 'text',
2514
+ expectedRevision: 'int',
2515
+ },
2516
+ output: {
2517
+ ok: 'bool',
2518
+ orderId: 'id?',
2519
+ revision: 'int?',
2520
+ amount: 'decimal?',
2521
+ currency: 'text?',
2522
+ configId: 'id?',
2523
+ errors: 'json?',
2524
+ },
2525
+ effects: [
2526
+ 'read:pos.Order',
2527
+ 'write:pos.Order',
2528
+ 'read:pos.ProviderPaymentLock',
2529
+ 'write:pos.ProviderPaymentLock',
2530
+ 'read:pos.ConfigPaymentMethod',
2531
+ 'read:pos.PaymentMethod',
2532
+ 'read:pos.Payment',
2533
+ ],
2534
+ idempotent: true,
2535
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
2536
+ const attemptId = String(args.providerAttemptId ?? '').trim();
2537
+ if (!attemptId)
2538
+ return invalid('providerAttemptId', 'provider attempt id is required');
2539
+ const order = (await tx.db.select('pos.Order', { id: args.orderId }))[0];
2540
+ if (!order)
2541
+ return invalid('orderId', 'order does not exist');
2542
+ const amount = n(args.amount);
2543
+ if ((order.isRefund && amount >= 0) || (!order.isRefund && amount <= 0))
2544
+ return invalid('amount', order.isRefund ? 'refund amount must be negative' : 'amount must be positive');
2545
+ const reservation = (await tx.db.select('pos.ProviderPaymentLock', { id: attemptId }))[0];
2546
+ if (reservation) {
2547
+ const same = reservation.orderId === args.orderId &&
2548
+ reservation.paymentMethodId === args.paymentMethodId &&
2549
+ n(reservation.amount) === amount &&
2550
+ reservation.currency === order.currency;
2551
+ if (!same)
2552
+ return invalid('providerAttemptId', 'provider attempt is bound to another payment intent');
2553
+ if (!['locked', 'settled', 'finalizing', 'finalized'].includes(String(reservation.state)))
2554
+ return invalid('providerAttemptId', 'provider attempt can no longer lock this order');
2555
+ if (reservation.state === 'locked' && String(order.paymentLockId ?? '') !== attemptId)
2556
+ return invalid('providerAttemptId', 'provider attempt lock membership is inconsistent');
2557
+ return {
2558
+ ok: true,
2559
+ orderId: order.id,
2560
+ revision: n(order.revision),
2561
+ amount: decimal(amount),
2562
+ currency: order.currency,
2563
+ configId: order.configId,
2564
+ };
2565
+ }
2566
+ if (order.state !== 'draft')
2567
+ return invalid('orderId', 'only a draft order can be locked');
2568
+ const unresolved = (await tx.db.select('pos.ProviderPaymentLock', { orderId: order.id })).find((lock) => ['locked', 'needs_review', 'reversing', 'finalizing'].includes(String(lock.state)));
2569
+ if (unresolved)
2570
+ return invalid('providerAttemptId', 'order has an unresolved external payment attempt');
2571
+ const linked = (await tx.db.select('pos.ConfigPaymentMethod', {
2572
+ configId: order.configId,
2573
+ paymentMethodId: args.paymentMethodId,
2574
+ }))[0];
2575
+ const method = (await tx.db.select('pos.PaymentMethod', { id: args.paymentMethodId }))[0];
2576
+ if (!linked || !method || method.isCash || method.active === false)
2577
+ return invalid('paymentMethodId', 'provider payment requires a configured non-cash method');
2578
+ const captured = (await tx.db.select('pos.Payment', { orderId: args.orderId })).filter((payment) => (payment.state ?? 'captured') === 'captured');
2579
+ const remaining = Math.max(0, Math.abs(n(order.amountTotal)) -
2580
+ captured.reduce((sum, payment) => sum + Math.abs(n(payment.appliedAmount ?? payment.amount)), 0));
2581
+ if (remaining <= 0.000001 || Math.abs(amount) > remaining + 0.000001)
2582
+ return invalid('amount', 'provider attempt exceeds the remaining payable');
2583
+ const createdAt = now();
2584
+ const inserted = await tx.db.insertIfAbsent('pos.ProviderPaymentLock', {
2585
+ id: attemptId,
2586
+ orderId: args.orderId,
2587
+ paymentMethodId: args.paymentMethodId,
2588
+ amount: decimal(amount),
2589
+ currency: order.currency,
2590
+ state: 'locked',
2591
+ settledPaymentId: null,
2592
+ reversalPaymentId: null,
2593
+ createdAt,
2594
+ updatedAt: createdAt,
2595
+ });
2596
+ if (!('dryRun' in inserted) && !inserted.inserted) {
2597
+ const winner = (await tx.db.select('pos.ProviderPaymentLock', { id: attemptId }))[0];
2598
+ const currentOrder = (await tx.db.select('pos.Order', { id: args.orderId }))[0];
2599
+ const same = winner?.orderId === args.orderId &&
2600
+ winner.paymentMethodId === args.paymentMethodId &&
2601
+ n(winner.amount) === amount &&
2602
+ winner.currency === order.currency &&
2603
+ ['locked', 'settled', 'finalizing', 'finalized'].includes(String(winner.state)) &&
2604
+ (winner.state !== 'locked' || String(currentOrder?.paymentLockId ?? '') === attemptId);
2605
+ return same
2606
+ ? {
2607
+ ok: true,
2608
+ orderId: currentOrder.id,
2609
+ revision: n(currentOrder.revision),
2610
+ amount: decimal(amount),
2611
+ currency: order.currency,
2612
+ configId: currentOrder.configId,
2613
+ }
2614
+ : invalid('providerAttemptId', 'provider attempt is bound to another payment intent');
2615
+ }
2616
+ const claim = await claimDraftRevision(tx, args.orderId, args.expectedRevision);
2617
+ if (claim.ok !== true)
2618
+ return claim;
2619
+ await tx.db.update('pos.Order', { id: args.orderId }, {
2620
+ paymentLockId: attemptId,
2621
+ paymentLockMethodId: args.paymentMethodId,
2622
+ paymentLockAmount: decimal(amount),
2623
+ });
2624
+ return {
2625
+ ok: true,
2626
+ orderId: order.id,
2627
+ revision: claim.revision,
2628
+ amount: decimal(amount),
2629
+ currency: order.currency,
2630
+ configId: order.configId,
2631
+ };
2632
+ }),
2633
+ }),
2634
+ unlockProviderPayment: defineFn({
2635
+ exposure: 'internal',
2636
+ input: { orderId: 'id', providerAttemptId: 'text', expectedRevision: 'int' },
2637
+ output: { ok: 'bool', orderId: 'id?', revision: 'int?', errors: 'json?' },
2638
+ effects: [
2639
+ 'read:pos.Order',
2640
+ 'write:pos.Order',
2641
+ 'read:pos.ProviderPaymentLock',
2642
+ 'write:pos.ProviderPaymentLock',
2643
+ 'read:pos.Payment',
2644
+ ],
2645
+ idempotent: true,
2646
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
2647
+ const attemptId = String(args.providerAttemptId ?? '').trim();
2648
+ if (!attemptId)
2649
+ return invalid('providerAttemptId', 'provider attempt id is required');
2650
+ const order = (await tx.db.select('pos.Order', { id: args.orderId }))[0];
2651
+ if (!order)
2652
+ return invalid('orderId', 'order does not exist');
2653
+ const reservation = (await tx.db.select('pos.ProviderPaymentLock', { id: attemptId }))[0];
2654
+ if (!order.paymentLockId) {
2655
+ return reservation?.orderId === args.orderId && reservation.state === 'released'
2656
+ ? { ok: true, orderId: order.id, revision: n(order.revision) }
2657
+ : invalid('providerAttemptId', 'payment attempt does not own an active order lock');
2658
+ }
2659
+ if (String(order.paymentLockId) !== attemptId)
2660
+ return invalid('providerAttemptId', 'payment attempt does not own the order lock');
2661
+ if (!reservation ||
2662
+ reservation.orderId !== args.orderId ||
2663
+ reservation.state !== 'locked' ||
2664
+ reservation.paymentMethodId !== order.paymentLockMethodId ||
2665
+ n(reservation.amount) !== n(order.paymentLockAmount) ||
2666
+ reservation.currency !== order.currency)
2667
+ return invalid('providerAttemptId', 'provider attempt lock membership is inconsistent');
2668
+ if ((await tx.db.select('pos.Payment', { providerAttemptId: attemptId }))[0])
2669
+ return invalid('providerAttemptId', 'a settled provider payment cannot be unlocked');
2670
+ const claim = await claimDraftRevision(tx, args.orderId, args.expectedRevision);
2671
+ if (claim.ok !== true)
2672
+ return claim;
2673
+ await tx.db.update('pos.Order', { id: args.orderId }, { paymentLockId: null, paymentLockMethodId: null, paymentLockAmount: null });
2674
+ await tx.db.update('pos.ProviderPaymentLock', { id: attemptId }, { state: 'released', updatedAt: now() });
2675
+ return { ok: true, orderId: order.id, revision: claim.revision };
2676
+ }),
2677
+ }),
2678
+ settleProviderPayment: defineFn({
2679
+ exposure: 'internal',
2680
+ input: {
2681
+ id: 'id',
2682
+ orderId: 'id',
2683
+ paymentMethodId: 'id',
2684
+ amount: 'decimal',
2685
+ currency: 'text',
2686
+ providerAttemptId: 'text',
2687
+ providerReference: 'text',
2688
+ operatorId: 'text?',
2689
+ deviceId: 'text?',
2690
+ expectedRevision: 'int',
2691
+ },
2692
+ output: {
2693
+ ok: 'bool',
2694
+ id: 'id?',
2695
+ revision: 'int?',
2696
+ appliedAmount: 'decimal?',
2697
+ providerAttemptId: 'text?',
2698
+ errors: 'json?',
2699
+ },
2700
+ effects: [
2701
+ 'read:pos.Order',
2702
+ 'read:pos.ConfigPaymentMethod',
2703
+ 'read:pos.PaymentMethod',
2704
+ 'read:pos.Payment',
2705
+ 'write:pos.Payment',
2706
+ 'read:pos.ProviderPaymentLock',
2707
+ 'write:pos.ProviderPaymentLock',
2708
+ 'read:pos.OrderLine',
2709
+ 'write:pos.Order',
2710
+ ],
2711
+ idempotent: true,
2712
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
2713
+ const attemptId = String(args.providerAttemptId ?? '').trim();
2714
+ const reference = String(args.providerReference ?? '').trim();
2715
+ if (!attemptId)
2716
+ return invalid('providerAttemptId', 'provider attempt id is required');
2717
+ if (!reference)
2718
+ return invalid('providerReference', 'provider settlement reference is required');
2719
+ const order = (await tx.db.select('pos.Order', { id: args.orderId }))[0];
2720
+ if (!order)
2721
+ return invalid('orderId', 'order does not exist');
2722
+ if (String(args.currency) !== String(order.currency))
2723
+ return invalid('currency', 'provider settlement currency does not match the locked order');
2724
+ const amount = n(args.amount);
2725
+ if ((order.isRefund && amount >= 0) || (!order.isRefund && amount <= 0))
2726
+ return invalid('amount', order.isRefund ? 'provider refunds must be negative' : 'provider payments must be positive');
2727
+ const replay = await providerSettlementReplay(tx, args);
2728
+ if (replay)
2729
+ return replay;
2730
+ if (order.state !== 'draft')
2731
+ return invalid('orderId', 'payments can only settle a new order');
2732
+ const linked = (await tx.db.select('pos.ConfigPaymentMethod', {
2733
+ configId: order.configId,
2734
+ paymentMethodId: args.paymentMethodId,
2735
+ }))[0];
2736
+ const method = (await tx.db.select('pos.PaymentMethod', { id: args.paymentMethodId }))[0];
2737
+ if (!linked || !method || method.isCash || method.active === false)
2738
+ return invalid('paymentMethodId', 'provider settlement requires a configured non-cash method');
2739
+ const reservation = (await tx.db.select('pos.ProviderPaymentLock', { id: attemptId }))[0];
2740
+ if (String(order.paymentLockId ?? '') !== attemptId ||
2741
+ String(order.paymentLockMethodId ?? '') !== String(args.paymentMethodId) ||
2742
+ n(order.paymentLockAmount) !== amount ||
2743
+ !reservation ||
2744
+ reservation.orderId !== args.orderId ||
2745
+ reservation.paymentMethodId !== args.paymentMethodId ||
2746
+ n(reservation.amount) !== amount ||
2747
+ reservation.currency !== args.currency ||
2748
+ reservation.state !== 'locked')
2749
+ return invalid('providerAttemptId', 'provider attempt does not own the current order lock');
2750
+ const captured = (await tx.db.select('pos.Payment', { orderId: args.orderId })).filter((payment) => (payment.state ?? 'captured') === 'captured');
2751
+ const remaining = Math.max(0, Math.abs(n(order.amountTotal)) -
2752
+ captured.reduce((sum, payment) => sum + Math.abs(n(payment.appliedAmount ?? payment.amount)), 0));
2753
+ if (remaining <= 0.000001)
2754
+ return invalid('amount', 'the order is already fully covered');
2755
+ if (Math.abs(amount) > remaining + 0.000001)
2756
+ return invalid('amount', 'provider settlement exceeds the remaining payable');
2757
+ const claim = await claimDraftRevision(tx, args.orderId, args.expectedRevision);
2758
+ if (claim.ok !== true) {
2759
+ const converged = await providerSettlementReplay(tx, args);
2760
+ return converged?.ok === true ? converged : claim;
2761
+ }
2762
+ await tx.db.insert('pos.Payment', {
2763
+ id: args.id,
2764
+ orderId: args.orderId,
2765
+ configId: order.configId,
2766
+ sessionId: order.sessionId,
2767
+ paymentMethodId: args.paymentMethodId,
2768
+ currency: order.currency,
2769
+ amount: decimal(amount),
2770
+ tenderedAmount: decimal(amount),
2771
+ appliedAmount: decimal(amount),
2772
+ state: 'captured',
2773
+ kind: 'provider',
2774
+ reference,
2775
+ providerAttemptId: attemptId,
2776
+ reversalOfId: null,
2777
+ operatorId: args.operatorId ?? null,
2778
+ deviceId: args.deviceId ?? null,
2779
+ paymentDate: now(),
2780
+ });
2781
+ await recompute(tx, args.orderId);
2782
+ await tx.db.update('pos.ProviderPaymentLock', { id: attemptId }, { state: 'settled', settledPaymentId: args.id, updatedAt: now() });
2783
+ return {
2784
+ ok: true,
2785
+ id: args.id,
2786
+ revision: claim.revision,
2787
+ appliedAmount: decimal(amount),
2788
+ providerAttemptId: attemptId,
2789
+ };
2790
+ }),
2791
+ }),
2792
+ reviewProviderPayment: defineFn({
2793
+ exposure: 'internal',
2794
+ input: {
2795
+ orderId: 'id',
2796
+ providerAttemptId: 'text',
2797
+ state: 'text',
2798
+ expectedRevision: 'int',
2799
+ },
2800
+ output: { ok: 'bool', orderId: 'id?', revision: 'int?', state: 'text?', errors: 'json?' },
2801
+ effects: [
2802
+ 'read:pos.Order',
2803
+ 'write:pos.Order',
2804
+ 'read:pos.Payment',
2805
+ 'read:pos.ProviderPaymentLock',
2806
+ 'write:pos.ProviderPaymentLock',
2807
+ ],
2808
+ idempotent: true,
2809
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
2810
+ const attemptId = String(args.providerAttemptId ?? '').trim();
2811
+ const targetState = String(args.state ?? '').trim();
2812
+ if (!attemptId)
2813
+ return invalid('providerAttemptId', 'provider attempt id is required');
2814
+ if (!['needs_review', 'reversing'].includes(targetState))
2815
+ return invalid('state', 'provider review state must be needs_review or reversing');
2816
+ const order = (await tx.db.select('pos.Order', { id: args.orderId }))[0];
2817
+ if (!order)
2818
+ return invalid('orderId', 'order does not exist');
2819
+ const reservation = (await tx.db.select('pos.ProviderPaymentLock', { id: attemptId }))[0];
2820
+ const payment = (await tx.db.select('pos.Payment', { providerAttemptId: attemptId }))[0];
2821
+ if (order.state !== 'draft' ||
2822
+ !reservation ||
2823
+ reservation.orderId !== order.id ||
2824
+ reservation.paymentMethodId !== payment?.paymentMethodId ||
2825
+ n(reservation.amount) !== n(payment?.appliedAmount ?? payment?.amount) ||
2826
+ reservation.currency !== order.currency ||
2827
+ reservation.settledPaymentId !== payment?.id ||
2828
+ payment?.orderId !== order.id ||
2829
+ payment.paymentMethodId !== reservation.paymentMethodId ||
2830
+ payment.kind !== 'provider' ||
2831
+ payment.state !== 'captured' ||
2832
+ payment.reversalOfId != null)
2833
+ return invalid('providerAttemptId', 'captured provider settlement is not reviewable');
2834
+ if (reservation.state === targetState)
2835
+ return {
2836
+ ok: true,
2837
+ orderId: order.id,
2838
+ revision: n(order.revision),
2839
+ state: targetState,
2840
+ };
2841
+ const allowed = (targetState === 'needs_review' && reservation.state === 'settled') ||
2842
+ (targetState === 'reversing' && reservation.state === 'needs_review');
2843
+ if (!allowed)
2844
+ return invalid('state', 'provider payment review state cannot move backwards or be reopened');
2845
+ const claim = await claimDraftRevision(tx, order.id, args.expectedRevision);
2846
+ if (claim.ok !== true)
2847
+ return claim;
2848
+ const changed = await tx.db.compareAndSet('pos.ProviderPaymentLock', { id: attemptId }, { state: reservation.state }, { state: targetState, updatedAt: now() });
2849
+ if (!('dryRun' in changed) && !changed.matched)
2850
+ return invalid('state', 'provider payment reconciliation changed; reload it before continuing');
2851
+ return { ok: true, orderId: order.id, revision: claim.revision, state: targetState };
2852
+ }),
2853
+ }),
2854
+ reverseProviderPayment: defineFn({
2855
+ exposure: 'internal',
2856
+ input: {
2857
+ id: 'id',
2858
+ orderId: 'id',
2859
+ providerAttemptId: 'text',
2860
+ providerReversalId: 'text',
2861
+ amount: 'decimal',
2862
+ currency: 'text',
2863
+ reversalReference: 'text',
2864
+ expectedRevision: 'int',
2865
+ operatorId: 'text?',
2866
+ },
2867
+ output: {
2868
+ ok: 'bool',
2869
+ id: 'id?',
2870
+ revision: 'int?',
2871
+ reversedPaymentId: 'id?',
2872
+ appliedAmount: 'decimal?',
2873
+ errors: 'json?',
2874
+ },
2875
+ effects: [
2876
+ 'read:pos.Order',
2877
+ 'write:pos.Order',
2878
+ 'read:pos.Payment',
2879
+ 'write:pos.Payment',
2880
+ 'read:pos.ProviderPaymentLock',
2881
+ 'write:pos.ProviderPaymentLock',
2882
+ 'read:pos.OrderLine',
2883
+ ],
2884
+ idempotent: true,
2885
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
2886
+ const attemptId = String(args.providerAttemptId ?? '').trim();
2887
+ const reversalId = String(args.providerReversalId ?? '').trim();
2888
+ const reference = String(args.reversalReference ?? '').trim();
2889
+ if (!attemptId)
2890
+ return invalid('providerAttemptId', 'provider attempt id is required');
2891
+ if (!reversalId || reversalId === attemptId)
2892
+ return invalid('providerReversalId', 'provider reversal id must be distinct and non-empty');
2893
+ if (!reference)
2894
+ return invalid('reversalReference', 'provider reversal reference is required');
2895
+ const order = (await tx.db.select('pos.Order', { id: args.orderId }))[0];
2896
+ if (!order)
2897
+ return invalid('orderId', 'order does not exist');
2898
+ if (String(args.currency) !== String(order.currency))
2899
+ return invalid('currency', 'provider reversal currency does not match the order');
2900
+ const original = (await tx.db.select('pos.Payment', { providerAttemptId: attemptId }))[0];
2901
+ if (!original ||
2902
+ original.orderId !== args.orderId ||
2903
+ original.kind !== 'provider' ||
2904
+ original.reversalOfId != null)
2905
+ return invalid('providerAttemptId', 'captured provider tender does not belong to this order');
2906
+ const amount = n(args.amount);
2907
+ if (amount === 0 || n(original.appliedAmount ?? original.amount) !== amount)
2908
+ return invalid('amount', 'provider reversal must exactly match the captured tender');
2909
+ const byId = (await tx.db.select('pos.Payment', { id: args.id }))[0];
2910
+ const byOriginal = (await tx.db.select('pos.Payment', { reversalOfId: original.id }))[0];
2911
+ if (byId && byOriginal && byId.id !== byOriginal.id)
2912
+ return invalid('id', 'provider tender is already linked to another reversal');
2913
+ const existing = byId ?? byOriginal;
2914
+ const reservation = (await tx.db.select('pos.ProviderPaymentLock', { id: attemptId }))[0];
2915
+ if (existing) {
2916
+ const same = existing.id === args.id &&
2917
+ existing.orderId === args.orderId &&
2918
+ existing.paymentMethodId === original.paymentMethodId &&
2919
+ existing.kind === 'provider_reversal' &&
2920
+ existing.state === 'reversed' &&
2921
+ n(existing.appliedAmount ?? existing.amount) === -amount &&
2922
+ existing.providerAttemptId === reversalId &&
2923
+ existing.reference === reference &&
2924
+ existing.reversalOfId === original.id &&
2925
+ original.state === 'reversed' &&
2926
+ reservation?.state === 'reversed' &&
2927
+ reservation.reversalPaymentId === existing.id &&
2928
+ String(order.paymentLockId ?? '') !== attemptId;
2929
+ return same
2930
+ ? {
2931
+ ok: true,
2932
+ id: existing.id,
2933
+ revision: n(order.revision),
2934
+ reversedPaymentId: original.id,
2935
+ appliedAmount: existing.appliedAmount ?? existing.amount,
2936
+ }
2937
+ : invalid('id', 'provider reversal id is already used by another command');
2938
+ }
2939
+ if (order.state !== 'draft')
2940
+ return invalid('orderId', 'only a captured tender on a draft order can be compensated');
2941
+ const otherUnresolved = (await tx.db.select('pos.ProviderPaymentLock', { orderId: args.orderId })).find((lock) => String(lock.id) !== attemptId &&
2942
+ ['locked', 'needs_review', 'reversing', 'finalizing'].includes(String(lock.state)));
2943
+ if (original.state !== 'captured' ||
2944
+ otherUnresolved ||
2945
+ reservation?.orderId !== args.orderId ||
2946
+ reservation.paymentMethodId !== original.paymentMethodId ||
2947
+ n(reservation.amount) !== amount ||
2948
+ reservation.currency !== args.currency ||
2949
+ reservation.state !== 'reversing' ||
2950
+ reservation.settledPaymentId !== original.id)
2951
+ return invalid('providerAttemptId', 'provider settlement is not eligible for compensation');
2952
+ const collision = (await tx.db.select('pos.Payment', { providerAttemptId: reversalId }))[0];
2953
+ if (collision)
2954
+ return invalid('providerReversalId', 'provider reversal id is already in use');
2955
+ const claim = await claimDraftRevision(tx, args.orderId, args.expectedRevision);
2956
+ if (claim.ok !== true)
2957
+ return claim;
2958
+ const reversedAmount = decimal(-amount);
2959
+ await tx.db.insert('pos.Payment', {
2960
+ id: args.id,
2961
+ orderId: args.orderId,
2962
+ configId: order.configId,
2963
+ sessionId: order.sessionId,
2964
+ paymentMethodId: original.paymentMethodId,
2965
+ currency: order.currency,
2966
+ amount: reversedAmount,
2967
+ tenderedAmount: reversedAmount,
2968
+ appliedAmount: reversedAmount,
2969
+ state: 'reversed',
2970
+ kind: 'provider_reversal',
2971
+ reference,
2972
+ providerAttemptId: reversalId,
2973
+ reversalOfId: original.id,
2974
+ operatorId: args.operatorId ?? null,
2975
+ deviceId: original.deviceId ?? null,
2976
+ paymentDate: now(),
2977
+ });
2978
+ await tx.db.update('pos.Payment', { id: original.id }, { state: 'reversed' });
2979
+ if (String(order.paymentLockId ?? '') === attemptId)
2980
+ await tx.db.update('pos.Order', { id: args.orderId }, { paymentLockId: null, paymentLockMethodId: null, paymentLockAmount: null });
2981
+ await tx.db.update('pos.ProviderPaymentLock', { id: attemptId }, { state: 'reversed', reversalPaymentId: args.id, updatedAt: now() });
2982
+ await recompute(tx, args.orderId);
2983
+ return {
2984
+ ok: true,
2985
+ id: args.id,
2986
+ revision: claim.revision,
2987
+ reversedPaymentId: original.id,
2988
+ appliedAmount: reversedAmount,
2989
+ };
2990
+ }),
2991
+ }),
2992
+ voidPayment: defineFn({
2993
+ input: { id: 'id', orderId: 'id', expectedRevision: 'int', reason: 'text', operatorId: 'text?' },
2994
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
2995
+ effects: [
2996
+ 'read:pos.Order',
2997
+ 'write:pos.Order',
2998
+ 'read:pos.OrderLine',
2999
+ 'read:pos.Payment',
3000
+ 'write:pos.Payment',
3001
+ 'write:pos.AuditEvent',
3002
+ ],
3003
+ idempotent: true,
3004
+ agent: true,
3005
+ handler: async (ctx, args) => {
3006
+ if (!String(args.reason).trim())
3007
+ return invalid('reason', 'voiding a tender requires a reason');
3008
+ const payment = (await ctx.db.select('pos.Payment', { id: args.id }))[0];
3009
+ if (!payment || payment.orderId !== args.orderId)
3010
+ return invalid('id', 'tender does not belong to this order');
3011
+ if (String(payment.kind).startsWith('provider'))
3012
+ return invalid('id', 'provider tenders must be reversed through their payment rail');
3013
+ const order = (await ctx.db.select('pos.Order', { id: args.orderId }))[0];
3014
+ if (payment.state === 'voided') {
3015
+ return { ok: true, id: args.id, revision: n(order?.revision) };
3016
+ }
3017
+ if (order?.paymentLockId)
3018
+ return invalid('orderId', 'manual tenders cannot change while an external payment is pending');
3019
+ const claim = await claimDraftRevision(ctx, args.orderId, args.expectedRevision);
3020
+ if (claim.ok !== true)
3021
+ return claim;
3022
+ await ctx.db.update('pos.Payment', { id: args.id }, { state: 'voided' });
3023
+ await recompute(ctx, args.orderId);
3024
+ await appendAudit(ctx, {
3025
+ id: `payment:${String(args.id)}:voided`,
3026
+ subjectType: 'payment',
3027
+ subjectId: String(args.id),
3028
+ configId: order.configId,
3029
+ sessionId: order.sessionId,
3030
+ action: 'payment.voided',
3031
+ actorId: args.operatorId,
3032
+ deviceId: payment.deviceId ?? order.deviceId,
3033
+ reason: args.reason,
3034
+ relatedId: args.orderId,
3035
+ details: { amount: payment.appliedAmount ?? payment.amount, revision: claim.revision },
3036
+ });
3037
+ return { ok: true, id: args.id, revision: claim.revision };
714
3038
  },
715
3039
  }),
716
3040
  validateOrder: defineFn({
717
- input: { id: 'id' },
3041
+ input: { id: 'id', expectedRevision: 'int?' },
718
3042
  output: {
719
3043
  ok: 'bool',
720
3044
  id: 'id?',
721
3045
  state: 'text?',
722
3046
  pickingId: 'id?',
723
3047
  accountMoveId: 'id?',
3048
+ receiptId: 'id?',
3049
+ revision: 'int?',
724
3050
  errors: 'json?',
725
3051
  },
726
3052
  effects: [
727
3053
  'read:pos.Order',
728
3054
  'write:pos.Order',
3055
+ 'read:pos.Exchange',
729
3056
  'read:pos.Session',
730
3057
  'read:pos.Config',
731
3058
  'read:pos.OrderLine',
732
3059
  'read:pos.Payment',
3060
+ 'read:pos.ProviderPaymentLock',
3061
+ 'write:pos.ProviderPaymentLock',
733
3062
  'read:pos.PaymentMethod',
3063
+ 'read:pos.ReceiptDocument',
3064
+ 'write:pos.ReceiptDocument',
734
3065
  'read:product.Product',
735
3066
  'read:product.Template',
3067
+ 'read:uom.Unit',
3068
+ 'read:partner.Partner',
3069
+ 'write:partner.Partner',
736
3070
  'read:account.Move',
737
3071
  'write:account.Move',
738
3072
  'write:account.MoveLine',
739
3073
  'read:account.Journal',
740
3074
  'read:account.Account',
741
- 'read:account.Tax',
3075
+ 'write:pos.AuditEvent',
742
3076
  ...stockEffects,
743
3077
  ...accountEffects,
744
3078
  ],
@@ -755,137 +3089,493 @@ export const functions = {
755
3089
  state: order.state,
756
3090
  pickingId: order.pickingId,
757
3091
  accountMoveId: order.accountMoveId,
3092
+ receiptId: order.receiptId,
3093
+ revision: n(order.revision),
758
3094
  };
759
3095
  if (order.state !== 'draft')
760
3096
  return invalid('state', 'only a new order can be paid');
3097
+ const providerMembership = await providerFinalizationLocks(ctx, order);
3098
+ if (providerMembership.ok !== true)
3099
+ return providerMembership;
3100
+ if (order.exchangeRole === 'replacement') {
3101
+ const exchange = order.exchangeId
3102
+ ? (await ctx.db.select('pos.Exchange', { id: order.exchangeId }))[0]
3103
+ : null;
3104
+ const exchangeReturn = exchange
3105
+ ? (await ctx.db.select('pos.Order', { id: exchange.returnOrderId }))[0]
3106
+ : null;
3107
+ if (!exchange ||
3108
+ !exchangeReturn ||
3109
+ exchange.replacementOrderId !== order.id ||
3110
+ exchangeReturn.exchangeRole !== 'return' ||
3111
+ exchangeReturn.exchangeId !== exchange.id ||
3112
+ exchangeReturn.isRefund !== true)
3113
+ return invalid('exchangeId', 'replacement sale is not linked to a valid return');
3114
+ if (!['paid', 'done'].includes(String(exchangeReturn.state)))
3115
+ return invalid('exchangeId', 'exchange return must be completed before its replacement sale');
3116
+ }
761
3117
  const session = (await ctx.db.select('pos.Session', { id: order.sessionId }))[0];
762
3118
  if (!session || !['opened', 'closing_control'].includes(String(session.state)))
763
3119
  return invalid('sessionId', 'session is not open');
764
3120
  const lines = await ctx.db.select('pos.OrderLine', { orderId: args.id });
765
3121
  if (!lines.length)
766
3122
  return invalid('lines', 'order needs at least one product');
767
- const payments = await ctx.db.select('pos.Payment', { orderId: args.id });
768
- if (Math.abs(n(order.amountPaid) - n(order.amountTotal)) > 0.000001)
3123
+ if (lines.some((line) => (order.isRefund ? !(n(line.qty) < -0.000001) : !(n(line.qty) > 0.000001))))
3124
+ return invalid('lines', 'sale and return orders cannot mix quantity directions');
3125
+ const payments = (await ctx.db.select('pos.Payment', { orderId: args.id })).filter((payment) => (payment.state ?? 'captured') === 'captured');
3126
+ const scale = scaleOf(order.currency);
3127
+ if (moneyMinor(order.amountPaid, scale) !== moneyMinor(order.amountTotal, scale))
769
3128
  return invalid('amountPaid', 'paid amount must equal order total');
770
3129
  const config = (await ctx.db.select('pos.Config', { id: order.configId }))[0];
771
- if (n(order.amountTax) && !config.taxAccountId)
3130
+ if (moneyMinor(order.amountTax, scale) !== 0n && !config.taxAccountId)
772
3131
  return invalid('taxAccountId', 'a tax account is required before stock is moved');
773
3132
  const goods = [];
3133
+ const selectedLots = new Set();
774
3134
  for (const line of lines) {
3135
+ if (line.affectsStock === false)
3136
+ continue;
775
3137
  const held = await productOf(ctx, line.productId);
776
3138
  if (held?.template.type !== 'service') {
777
- if (held && held.template.tracking !== 'none')
778
- return invalid('tracking', 'lot/serial selection is required for tracked POS products and is not supported by this retail subset');
779
- goods.push(line);
3139
+ const tracking = String(held?.template.tracking ?? 'none');
3140
+ if (tracking !== String(line.tracking ?? 'none'))
3141
+ return invalid('tracking', 'product tracking changed; remove and add the line again');
3142
+ if (tracking !== 'none') {
3143
+ const based = await toProductUnit(ctx, line.productId, line.productUomId, Math.abs(n(line.qty)));
3144
+ if (!based)
3145
+ return invalid('productUomId', 'line unit is incompatible with the product unit');
3146
+ const selections = Array.isArray(line.lotSelections) ? line.lotSelections : [];
3147
+ if (!selections.length ||
3148
+ Math.abs(selections.reduce((sum, selection) => sum + n(selection.quantity), 0) - based.quantity) > 0.000001)
3149
+ return invalid('lotSelections', 'selected lot/serial quantity must equal line quantity');
3150
+ if (new Set(selections.map((selection) => String(selection.lotId))).size !== selections.length)
3151
+ return invalid('lotSelections', 'a lot/serial can only be selected once per line');
3152
+ for (const selection of selections) {
3153
+ const lotId = String(selection.lotId);
3154
+ if (selectedLots.has(lotId))
3155
+ return invalid('lotSelections', 'a lot/serial can only be selected on one order line');
3156
+ selectedLots.add(lotId);
3157
+ }
3158
+ if (tracking === 'serial') {
3159
+ for (const selection of selections) {
3160
+ if (Math.abs(n(selection.quantity) - 1) > 0.000001)
3161
+ return invalid('lotSelections', 'every selected serial must have quantity 1');
3162
+ }
3163
+ }
3164
+ if (!order.isRefund) {
3165
+ const availability = await trackingAvailability(ctx, order, line);
3166
+ const lots = new Map(availability.lots.map((lot) => [String(lot.lotId), lot]));
3167
+ for (const selection of selections) {
3168
+ const lot = lots.get(String(selection.lotId));
3169
+ if (lot?.selectable !== true)
3170
+ return invalid('lotSelections', `lot/serial ${String(selection.lotId)} is not selectable`);
3171
+ if (String(lot.stockRevision) !== String(selection.stockRevision))
3172
+ return invalid('stockRevision', 'stock position changed; reload lot availability');
3173
+ if (n(lot.availableQuantity) + 0.000001 < n(selection.quantity))
3174
+ return invalid('stock', `insufficient stock for lot/serial ${String(selection.lotId)}`);
3175
+ }
3176
+ }
3177
+ }
3178
+ goods.push({ ...line, tracking });
780
3179
  }
781
3180
  }
782
- let pickingId = null;
783
- if (goods.length) {
784
- pickingId = `${String(order.id)}:picking`;
785
- const suffix = order.isRefund ? 'incoming' : 'outgoing';
786
- const created = (await stockFunctions.createPicking.handler(ctx, {
787
- id: pickingId,
788
- name: `${order.isRefund ? 'Refund' : 'POS'} ${String(order.posReference)}`,
789
- pickingTypeId: `${String(config.warehouseId)}:${suffix}`,
790
- scheduledDate: order.dateOrder,
791
- }));
792
- if (created.ok !== true)
793
- return created;
794
- for (const line of goods) {
795
- const moveId = `${String(line.id)}:move`, quantity = Math.abs(n(line.qty));
796
- const moved = (await stockFunctions.addMove.handler(ctx, {
797
- id: moveId,
798
- name: line.name,
799
- pickingId,
800
- productId: line.productId,
801
- productUomId: line.productUomId,
802
- productUomQty: decimal(quantity),
803
- origin: order.posReference,
804
- }));
805
- if (moved.ok !== true)
806
- return moved;
807
- await ctx.db.update('stock.Move', { id: moveId }, { posLineId: line.id });
808
- }
809
- const confirmed = (await stockFunctions.confirmPicking.handler(ctx, { id: pickingId }));
810
- if (confirmed.ok !== true)
811
- return confirmed;
812
- for (const line of goods) {
813
- const moveId = `${String(line.id)}:move`;
814
- if (order.isRefund) {
815
- const picking = (await ctx.db.select('stock.Picking', { id: pickingId }))[0];
816
- const saved = (await stockFunctions.saveMoveLine.handler(ctx, {
817
- id: `${moveId}:line`,
818
- moveId,
819
- productUomId: line.productUomId,
820
- quantity: decimal(Math.abs(n(line.qty))),
821
- locationId: picking.locationId,
822
- locationDestId: picking.locationDestId,
823
- picked: true,
824
- }));
825
- if (saved.ok !== true)
826
- return saved;
3181
+ const claim = providerMembership.locks.length
3182
+ ? await claimProviderFinalization(ctx, args.id, args.expectedRevision)
3183
+ : await claimDraftRevision(ctx, args.id, args.expectedRevision);
3184
+ if (claim.ok !== true)
3185
+ return claim;
3186
+ const providerLeases = ('leases' in claim ? claim.leases : []);
3187
+ let finalizationCommitted = false;
3188
+ try {
3189
+ const partner = order.partnerId
3190
+ ? (await ctx.db.select('partner.Partner', { id: order.partnerId }))[0]
3191
+ : await consumerPartner(ctx);
3192
+ if (!partner)
3193
+ return invalid('partnerId', 'invoice customer does not exist');
3194
+ const effectiveOrder = { ...order, partnerId: partner.id, toInvoice: true };
3195
+ await ctx.db.update('pos.Order', { id: args.id }, { partnerId: partner.id, toInvoice: true });
3196
+ let pickingId = null;
3197
+ if (goods.length) {
3198
+ pickingId = `${String(order.id)}:picking`;
3199
+ const suffix = order.isRefund ? 'incoming' : 'outgoing';
3200
+ const pickingTypeId = `${String(config.warehouseId)}:${suffix}`;
3201
+ const completedPicking = (await ctx.db.select('stock.Picking', { id: pickingId }))[0];
3202
+ if (completedPicking?.state === 'done') {
3203
+ const completedMoves = await ctx.db.select('stock.Move', { pickingId });
3204
+ let matches = completedPicking.pickingTypeId === pickingTypeId && completedMoves.length === goods.length;
3205
+ for (const line of goods) {
3206
+ const moveId = `${String(line.id)}:move`;
3207
+ const based = await toProductUnit(ctx, line.productId, line.productUomId, Math.abs(n(line.qty)));
3208
+ const move = completedMoves.find((candidate) => candidate.id === moveId);
3209
+ matches =
3210
+ matches &&
3211
+ based !== null &&
3212
+ move?.state === 'done' &&
3213
+ move.productId === line.productId &&
3214
+ move.productUomId === based.uomId &&
3215
+ move.posLineId === line.id &&
3216
+ move.origin === order.posReference &&
3217
+ Math.abs(n(move.productUomQty) - based.quantity) <= 0.000001;
3218
+ }
3219
+ if (!matches)
3220
+ return invalid('pickingId', 'completed stock transfer does not match this order retry');
827
3221
  }
828
3222
  else {
829
- const reserved = (await stockFunctions.reserveMove.handler(ctx, { id: moveId }));
830
- if (reserved.ok !== true || n(reserved.reserved) + 0.000001 < Math.abs(n(line.qty)))
831
- return invalid('stock', `insufficient stock for ${String(line.name)}`);
3223
+ const created = (await stockFunctions.createPicking.handler(ctx, {
3224
+ id: pickingId,
3225
+ name: `${order.isRefund ? 'Refund' : 'POS'} ${String(order.posReference)}`,
3226
+ pickingTypeId,
3227
+ scheduledDate: order.dateOrder,
3228
+ }));
3229
+ if (created.ok !== true)
3230
+ return created;
3231
+ for (const line of goods) {
3232
+ const moveId = `${String(line.id)}:move`, quantity = Math.abs(n(line.qty));
3233
+ const moved = (await stockFunctions.addMove.handler(ctx, {
3234
+ id: moveId,
3235
+ name: line.name,
3236
+ pickingId,
3237
+ productId: line.productId,
3238
+ productUomId: line.productUomId,
3239
+ productUomQty: decimal(quantity),
3240
+ origin: order.posReference,
3241
+ }));
3242
+ if (moved.ok !== true)
3243
+ return moved;
3244
+ await ctx.db.update('stock.Move', { id: moveId }, { posLineId: line.id });
3245
+ }
3246
+ const confirmed = (await stockFunctions.confirmPicking.handler(ctx, { id: pickingId }));
3247
+ if (confirmed.ok !== true)
3248
+ return confirmed;
3249
+ if (order.isRefund) {
3250
+ for (const line of goods) {
3251
+ const moveId = `${String(line.id)}:move`;
3252
+ const picking = (await ctx.db.select('stock.Picking', { id: pickingId }))[0];
3253
+ const based = await toProductUnit(ctx, line.productId, line.productUomId, Math.abs(n(line.qty)));
3254
+ if (!based)
3255
+ return invalid('productUomId', 'line unit is incompatible with the product unit');
3256
+ const selections = String(line.tracking) === 'none'
3257
+ ? [{ lotId: null, quantity: based.quantity }]
3258
+ : line.lotSelections;
3259
+ for (const [index, selection] of selections.entries()) {
3260
+ const saved = (await stockFunctions.saveMoveLine.handler(ctx, {
3261
+ id: `${moveId}:line:${String(index + 1)}`,
3262
+ moveId,
3263
+ productUomId: line.productUomId,
3264
+ quantity: decimal(n(selection.quantity)),
3265
+ locationId: picking.locationId,
3266
+ locationDestId: picking.locationDestId,
3267
+ ...(selection.lotId ? { lotId: selection.lotId } : {}),
3268
+ picked: true,
3269
+ }));
3270
+ if (saved.ok !== true)
3271
+ return saved;
3272
+ }
3273
+ }
3274
+ }
3275
+ else {
3276
+ const reserved = (await stockFunctions.reserveMoves.handler(ctx, {
3277
+ requireFull: true,
3278
+ moves: goods.map((line) => ({
3279
+ id: `${String(line.id)}:move`,
3280
+ ...(String(line.tracking) === 'none' ? {} : { selections: line.lotSelections }),
3281
+ })),
3282
+ }));
3283
+ if (reserved.ok !== true)
3284
+ return reserved;
3285
+ const results = Array.isArray(reserved.results) ? reserved.results : [];
3286
+ for (const line of goods) {
3287
+ const result = results.find((entry) => String(entry.id) === `${String(line.id)}:move`);
3288
+ const based = await toProductUnit(ctx, line.productId, line.productUomId, Math.abs(n(line.qty)));
3289
+ if (!based || !result || n(result.reserved) + 0.000001 < based.quantity)
3290
+ return invalid('stock', `insufficient stock for ${String(line.name)}`);
3291
+ }
3292
+ }
3293
+ const completed = (await stockFunctions.completePicking.handler(ctx, {
3294
+ id: pickingId,
3295
+ createBackorder: false,
3296
+ }));
3297
+ if (completed.ok !== true)
3298
+ return completed;
832
3299
  }
833
3300
  }
834
- const completed = (await stockFunctions.completePicking.handler(ctx, {
835
- id: pickingId,
836
- createBackorder: false,
837
- }));
838
- if (completed.ok !== true)
839
- return completed;
840
- }
841
- let accountMoveId;
842
- try {
843
- accountMoveId = await createAccounting(ctx, order, config, lines, payments);
3301
+ let accountMoveId;
3302
+ try {
3303
+ accountMoveId = await createAccounting(ctx, effectiveOrder, config, lines, payments);
3304
+ }
3305
+ catch (error) {
3306
+ return invalid('accounting', error.message);
3307
+ }
3308
+ const receiptId = `${String(order.id)}:receipt:v1`;
3309
+ const issuedAt = now();
3310
+ const receiptDocument = await receiptDocumentFor(ctx, effectiveOrder, config, session, partner, lines, payments, accountMoveId, issuedAt);
3311
+ const contentHash = receiptHash(receiptDocument);
3312
+ await ctx.tx(async (tx) => {
3313
+ const inserted = await tx.db.insertIfAbsent('pos.ReceiptDocument', {
3314
+ id: receiptId,
3315
+ orderId: args.id,
3316
+ version: 1,
3317
+ templateVersion: 'pos-receipt-v1',
3318
+ contentHash,
3319
+ document: receiptDocument,
3320
+ issuedAt,
3321
+ });
3322
+ if (!('dryRun' in inserted) && !inserted.inserted) {
3323
+ const existing = (await tx.db.select('pos.ReceiptDocument', { id: receiptId }))[0];
3324
+ if (existing?.orderId !== args.id ||
3325
+ n(existing.version) !== 1 ||
3326
+ existing.templateVersion !== 'pos-receipt-v1' ||
3327
+ existing.contentHash !== contentHash)
3328
+ throw new Error('receipt identity is already bound to different content');
3329
+ }
3330
+ for (const lease of providerLeases) {
3331
+ const finalized = await tx.db.compareAndSet('pos.ProviderPaymentLock', { id: lease.id }, { state: 'finalizing', updatedAt: lease.token }, { state: 'finalized', updatedAt: now() });
3332
+ if (!('dryRun' in finalized) && !finalized.matched)
3333
+ throw new Error('external payment finalization claim was lost');
3334
+ }
3335
+ await tx.db.update('pos.Order', { id: args.id }, {
3336
+ state: 'paid',
3337
+ finalizedAt: issuedAt,
3338
+ invoiceStatus: 'invoiced',
3339
+ pickingId,
3340
+ accountMoveId,
3341
+ receiptId,
3342
+ });
3343
+ await appendAudit(tx, {
3344
+ id: `order:${String(args.id)}:finalized`,
3345
+ subjectType: 'order',
3346
+ subjectId: String(args.id),
3347
+ configId: order.configId,
3348
+ sessionId: order.sessionId,
3349
+ action: order.isRefund ? 'order.refund_finalized' : 'order.finalized',
3350
+ actorId: order.operatorId ?? session.userId,
3351
+ deviceId: order.deviceId ?? session.deviceId,
3352
+ relatedId: receiptId,
3353
+ details: {
3354
+ amountTotal: order.amountTotal,
3355
+ accountMoveId,
3356
+ pickingId,
3357
+ receiptId,
3358
+ revision: claim.revision,
3359
+ },
3360
+ });
3361
+ });
3362
+ finalizationCommitted = true;
3363
+ return {
3364
+ ok: true,
3365
+ id: args.id,
3366
+ state: 'paid',
3367
+ revision: claim.revision,
3368
+ ...(pickingId ? { pickingId } : {}),
3369
+ accountMoveId,
3370
+ receiptId,
3371
+ };
844
3372
  }
845
- catch (error) {
846
- return invalid('accounting', error.message);
3373
+ finally {
3374
+ if (!finalizationCommitted)
3375
+ for (const lease of providerLeases)
3376
+ await ctx.db.compareAndSet('pos.ProviderPaymentLock', { id: lease.id }, { state: 'finalizing', updatedAt: lease.token }, { state: 'needs_review', updatedAt: now() });
847
3377
  }
848
- await ctx.db.update('pos.Order', { id: args.id }, {
849
- state: 'paid',
850
- invoiceStatus: order.toInvoice ? 'invoiced' : 'to_invoice',
851
- pickingId,
852
- accountMoveId,
853
- });
854
- return { ok: true, id: args.id, state: 'paid', ...(pickingId ? { pickingId } : {}), accountMoveId };
3378
+ },
3379
+ }),
3380
+ getReturnEligibility: defineFn({
3381
+ input: { id: 'id' },
3382
+ output: {
3383
+ ok: 'bool',
3384
+ originalOrderId: 'id?',
3385
+ revision: 'int?',
3386
+ refundable: 'bool?',
3387
+ requiresFullReturn: 'bool?',
3388
+ standaloneAllowed: 'bool?',
3389
+ lines: 'json?',
3390
+ errors: 'json?',
3391
+ },
3392
+ effects: ['read:pos.Order', 'read:pos.OrderLine'],
3393
+ agent: true,
3394
+ handler: async (ctx, args) => {
3395
+ const original = (await ctx.db.select('pos.Order', { id: args.id }))[0];
3396
+ if (!original || !['paid', 'done'].includes(String(original.state)) || original.isRefund)
3397
+ return invalid('id', 'only a paid sale can be returned');
3398
+ const lines = await returnableLines(ctx, original);
3399
+ const allLines = await ctx.db.select('pos.OrderLine', { orderId: original.id });
3400
+ const requiresFullReturn = allLines.some((line) => line.lineKind === 'reward' && line.affectsStock !== false);
3401
+ return {
3402
+ ok: true,
3403
+ originalOrderId: String(original.id),
3404
+ revision: n(original.revision),
3405
+ refundable: lines.some((entry) => entry.remainingQuantity > 0.000001),
3406
+ requiresFullReturn,
3407
+ standaloneAllowed: false,
3408
+ lines: lines.map((entry) => ({
3409
+ lineId: String(entry.line.id),
3410
+ productId: String(entry.line.productId),
3411
+ name: String(entry.line.name),
3412
+ uomId: String(entry.line.productUomId),
3413
+ purchasedQuantity: decimal(entry.purchasedQuantity),
3414
+ refundedQuantity: decimal(entry.refundedQuantity),
3415
+ remainingQuantity: decimal(entry.remainingQuantity),
3416
+ unitPrice: String(entry.line.priceUnit),
3417
+ amountTotal: String(entry.line.priceSubtotalIncl),
3418
+ tracking: String(entry.line.tracking ?? 'none'),
3419
+ })),
3420
+ };
855
3421
  },
856
3422
  }),
857
3423
  refundOrder: defineFn({
858
- input: { id: 'id', uuid: 'text?', originalOrderId: 'id', sessionId: 'id' },
859
- output: { ok: 'bool', id: 'id?', name: 'text?', errors: 'json?' },
860
- effects: [
861
- 'read:pos.Order',
862
- 'read:pos.OrderLine',
863
- 'write:pos.Order',
864
- 'write:pos.OrderLine',
865
- 'read:pos.Payment',
866
- 'write:pos.Order',
867
- 'read:account.Tax',
868
- 'read:pos.Sequence',
869
- 'write:pos.Sequence',
870
- 'read:pos.Session',
871
- 'read:pos.Config',
872
- 'read:partner.Partner',
873
- 'read:company.Company',
874
- ],
3424
+ input: {
3425
+ id: 'id',
3426
+ uuid: 'text?',
3427
+ originalOrderId: 'id',
3428
+ sessionId: 'id',
3429
+ expectedRevision: 'int?',
3430
+ lines: 'json?',
3431
+ reason: 'text?',
3432
+ operatorId: 'text?',
3433
+ deviceId: 'text?',
3434
+ },
3435
+ output: {
3436
+ ok: 'bool',
3437
+ id: 'id?',
3438
+ name: 'text?',
3439
+ revision: 'int?',
3440
+ originalRevision: 'int?',
3441
+ errors: 'json?',
3442
+ },
3443
+ effects: [...refundOrderEffects],
875
3444
  idempotent: true,
876
3445
  agent: true,
877
- handler: async (ctx, args) => {
878
- const existing = (await ctx.db.select('pos.Order', { id: args.id }))[0];
879
- if (existing)
880
- return { ok: true, id: args.id, name: existing.name };
881
- const original = (await ctx.db.select('pos.Order', { id: args.originalOrderId }))[0];
3446
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
3447
+ const existing = (await tx.db.select('pos.Order', { id: args.id }))[0];
3448
+ if (existing) {
3449
+ if (!existing.isRefund ||
3450
+ String(existing.refundedOrderId ?? '') !== String(args.originalOrderId) ||
3451
+ String(existing.sessionId) !== String(args.sessionId) ||
3452
+ (args.uuid !== undefined && String(existing.uuid) !== String(args.uuid)) ||
3453
+ (args.reason !== undefined && String(existing.note ?? '') !== String(args.reason).trim()))
3454
+ return invalid('id', 'return id is already used by a different command');
3455
+ if (Array.isArray(args.lines)) {
3456
+ const requested = new Map(args.lines.map((line) => [String(line.lineId), n(line.quantity)]));
3457
+ const held = (await tx.db.select('pos.OrderLine', { orderId: existing.id })).filter((line) => line.refundedOrderlineId && line.lineKind !== 'reward');
3458
+ if (held.length !== requested.size ||
3459
+ held.some((line) => Math.abs(Math.abs(n(line.qty)) - (requested.get(String(line.refundedOrderlineId)) ?? -1)) >
3460
+ 0.000001))
3461
+ return invalid('id', 'return id is already used by a different selection');
3462
+ }
3463
+ return { ok: true, id: args.id, name: existing.name, revision: n(existing.revision) };
3464
+ }
3465
+ if (args.uuid) {
3466
+ const duplicate = (await tx.db.select('pos.Order', { uuid: args.uuid }))[0];
3467
+ if (duplicate)
3468
+ return invalid('uuid', 'return uuid is already used by a different command');
3469
+ }
3470
+ const original = (await tx.db.select('pos.Order', { id: args.originalOrderId }))[0];
882
3471
  if (!original || !['paid', 'done'].includes(String(original.state)) || original.isRefund)
883
- return invalid('originalOrderId', 'only a paid sale can be refunded');
884
- const session = (await ctx.db.select('pos.Session', { id: args.sessionId }))[0];
3472
+ return invalid('originalOrderId', 'only a paid sale can be returned');
3473
+ if (args.expectedRevision !== undefined && n(args.expectedRevision) !== n(original.revision))
3474
+ return invalid('expectedRevision', 'the order changed; reload it before continuing');
3475
+ const session = (await tx.db.select('pos.Session', { id: args.sessionId }))[0];
885
3476
  if (session?.state !== 'opened')
886
- return invalid('sessionId', 'refund requires an open session');
887
- const sequenceNumber = await nextOrderNumber(ctx, args.sessionId), name = `Order ${String(sequenceNumber).padStart(5, '0')}`;
888
- await ctx.db.insert('pos.Order', {
3477
+ return invalid('sessionId', 'return requires an open session');
3478
+ if (String(session.configId) !== String(original.configId))
3479
+ return invalid('sessionId', 'return shift must use the original POS configuration and warehouse');
3480
+ const claim = await claimOrderRevision(tx, original.id, args.expectedRevision);
3481
+ if (claim.ok !== true)
3482
+ return claim;
3483
+ const eligibility = await returnableLines(tx, original);
3484
+ const eligible = new Map(eligibility.map((entry) => [String(entry.line.id), entry]));
3485
+ const rawLines = args.lines === undefined
3486
+ ? eligibility
3487
+ .filter((entry) => entry.remainingQuantity > 0.000001)
3488
+ .map((entry) => ({ lineId: String(entry.line.id), quantity: entry.remainingQuantity }))
3489
+ : Array.isArray(args.lines)
3490
+ ? args.lines
3491
+ : null;
3492
+ if (!rawLines?.length)
3493
+ return invalid('lines', 'return needs at least one refundable line');
3494
+ const requested = rawLines.map((selection) => ({
3495
+ lineId: String(selection.lineId ?? ''),
3496
+ quantity: n(selection.quantity),
3497
+ }));
3498
+ if (requested.some((selection) => !selection.lineId || !(selection.quantity > 0)) ||
3499
+ new Set(requested.map((selection) => selection.lineId)).size !== requested.length)
3500
+ return invalid('lines', 'return lines must be unique with positive quantities');
3501
+ for (const selection of requested) {
3502
+ const line = eligible.get(selection.lineId);
3503
+ if (!line)
3504
+ return invalid('lineId', `line ${selection.lineId} is not refundable merchandise`);
3505
+ if (selection.quantity > line.remainingQuantity + 0.000001)
3506
+ return invalid('quantity', `return quantity exceeds the remaining quantity for ${selection.lineId}`);
3507
+ }
3508
+ const originalLines = await tx.db.select('pos.OrderLine', { orderId: original.id });
3509
+ const linkedRefunds = (await tx.db.select('pos.Order', { refundedOrderId: original.id })).filter((order) => order.state !== 'cancel');
3510
+ const previousRefundLines = [];
3511
+ for (const refund of linkedRefunds)
3512
+ previousRefundLines.push(...(await tx.db.select('pos.OrderLine', { orderId: refund.id })));
3513
+ const completesReturn = eligibility.every((entry) => {
3514
+ const selected = requested.find((selection) => selection.lineId === String(entry.line.id));
3515
+ return (entry.remainingQuantity <= 0.000001 ||
3516
+ (selected?.quantity ?? 0) + 0.000001 >= entry.remainingQuantity);
3517
+ });
3518
+ const productReward = originalLines.some((line) => line.lineKind === 'reward' && line.affectsStock !== false);
3519
+ if (productReward && (!completesReturn || linkedRefunds.length))
3520
+ return invalid('lines', 'orders with a product reward require one complete return');
3521
+ const merchandiseTotal = eligibility.reduce((sum, entry) => sum + Math.abs(n(entry.line.priceSubtotalIncl)), 0);
3522
+ const returnedMerchandiseTotal = requested.reduce((sum, selection) => {
3523
+ const entry = eligible.get(selection.lineId);
3524
+ return (sum + Math.abs(n(entry.line.priceSubtotalIncl)) * (selection.quantity / entry.purchasedQuantity));
3525
+ }, 0);
3526
+ const quantityBasis = eligibility.reduce((sum, entry) => sum + entry.purchasedQuantity, 0);
3527
+ const returnedQuantity = requested.reduce((sum, selection) => sum + selection.quantity, 0);
3528
+ const returnPortion = Math.min(1, merchandiseTotal > 0
3529
+ ? returnedMerchandiseTotal / merchandiseTotal
3530
+ : returnedQuantity / Math.max(quantityBasis, returnedQuantity));
3531
+ const materialized = [];
3532
+ for (const selection of requested) {
3533
+ const entry = eligible.get(selection.lineId);
3534
+ const lotSelections = await completedLotSelections(tx, entry.line, selection.quantity);
3535
+ if (!Array.isArray(lotSelections))
3536
+ return lotSelections;
3537
+ materialized.push({
3538
+ source: entry.line,
3539
+ quantity: selection.quantity,
3540
+ ratio: selection.quantity / entry.purchasedQuantity,
3541
+ exhausts: selection.quantity + 0.000001 >= entry.remainingQuantity,
3542
+ selections: lotSelections,
3543
+ });
3544
+ }
3545
+ for (const reward of originalLines.filter((line) => line.lineKind === 'reward')) {
3546
+ const group = eligibility.filter((entry) => taxGroupKey(entry.line) === taxGroupKey(reward));
3547
+ const basis = group.length ? group : eligibility;
3548
+ const groupTotal = basis.reduce((sum, entry) => sum + Math.abs(n(entry.line.priceSubtotalIncl)), 0);
3549
+ const groupReturned = requested.reduce((sum, selection) => {
3550
+ const entry = eligible.get(selection.lineId);
3551
+ if (!basis.includes(entry))
3552
+ return sum;
3553
+ return (sum + Math.abs(n(entry.line.priceSubtotalIncl)) * (selection.quantity / entry.purchasedQuantity));
3554
+ }, 0);
3555
+ const groupComplete = basis.every((entry) => {
3556
+ const selected = requested.find((selection) => selection.lineId === String(entry.line.id));
3557
+ return (entry.remainingQuantity <= 0.000001 ||
3558
+ (selected?.quantity ?? 0) + 0.000001 >= entry.remainingQuantity);
3559
+ });
3560
+ const ratio = productReward
3561
+ ? 1
3562
+ : Math.min(1, groupTotal > 0 ? groupReturned / groupTotal : returnPortion);
3563
+ if (ratio <= 0.000001)
3564
+ continue;
3565
+ const lotSelections = await completedLotSelections(tx, reward, Math.abs(n(reward.qty)) * ratio);
3566
+ if (!Array.isArray(lotSelections))
3567
+ return lotSelections;
3568
+ materialized.push({
3569
+ source: reward,
3570
+ quantity: Math.abs(n(reward.qty)) * ratio,
3571
+ ratio,
3572
+ exhausts: productReward || groupComplete,
3573
+ selections: lotSelections,
3574
+ });
3575
+ }
3576
+ const sequenceNumber = await nextOrderNumber(tx, args.sessionId);
3577
+ const name = `Order ${String(sequenceNumber).padStart(5, '0')}`;
3578
+ await tx.db.insert('pos.Order', {
889
3579
  id: args.id,
890
3580
  uuid: args.uuid ?? args.id,
891
3581
  name,
@@ -898,56 +3588,300 @@ export const functions = {
898
3588
  invoiceStatus: 'to_invoice',
899
3589
  isRefund: true,
900
3590
  refundedOrderId: original.id,
3591
+ returnPortion: decimal(returnPortion),
3592
+ returnComplete: completesReturn,
901
3593
  dateOrder: now(),
902
3594
  currency: original.currency,
903
3595
  amountUntaxed: '0',
904
3596
  amountTax: '0',
3597
+ amountExact: '0',
3598
+ amountRounding: '0',
905
3599
  amountTotal: '0',
906
3600
  amountPaid: '0',
907
3601
  amountReturn: '0',
908
- toInvoice: false,
3602
+ toInvoice: true,
909
3603
  accountMoveId: null,
910
3604
  pickingId: null,
911
- note: `Refund ${String(original.posReference)}`,
3605
+ note: args.reason ? String(args.reason).trim() : `Return ${String(original.posReference)}`,
3606
+ revision: 0,
3607
+ operatorId: args.operatorId ?? null,
3608
+ deviceId: args.deviceId ?? session.deviceId ?? null,
3609
+ priceBookRevision: original.priceBookRevision ?? null,
912
3610
  });
913
3611
  let sequence = 10;
914
- for (const line of await ctx.db.select('pos.OrderLine', { orderId: original.id })) {
915
- await ctx.db.insert('pos.OrderLine', {
3612
+ for (const item of materialized) {
3613
+ const line = item.source;
3614
+ const previous = previousRefundLines.filter((entry) => String(entry.refundedOrderlineId ?? '') === String(line.id));
3615
+ const exhaustsLine = item.exhausts;
3616
+ const subtotal = exhaustsLine
3617
+ ? -(n(line.priceSubtotal) + previous.reduce((sum, entry) => sum + n(entry.priceSubtotal), 0))
3618
+ : -n(line.priceSubtotal) * item.ratio;
3619
+ const total = exhaustsLine
3620
+ ? -(n(line.priceSubtotalIncl) +
3621
+ previous.reduce((sum, entry) => sum + n(entry.priceSubtotalIncl), 0))
3622
+ : -n(line.priceSubtotalIncl) * item.ratio;
3623
+ await tx.db.insert('pos.OrderLine', {
916
3624
  id: `${String(args.id)}:${String(line.id)}`,
917
3625
  orderId: args.id,
918
3626
  productId: line.productId,
919
3627
  productUomId: line.productUomId,
920
3628
  name: line.name,
921
- qty: decimal(-n(line.qty)),
3629
+ qty: decimal(-item.quantity),
922
3630
  priceUnit: line.priceUnit,
923
3631
  discount: line.discount,
924
3632
  taxId: line.taxId,
925
- priceSubtotal: '0',
926
- priceSubtotalIncl: '0',
3633
+ taxIds: line.taxIds ?? (line.taxId ? [line.taxId] : []),
3634
+ taxEvidence: returnTaxEvidence(line.taxEvidence, previous, item.ratio, exhaustsLine),
3635
+ quoteRevision: line.quoteRevision ?? null,
3636
+ tracking: line.tracking ?? 'none',
3637
+ lotSelections: item.selections,
3638
+ affectsStock: line.affectsStock ?? null,
3639
+ priceSubtotal: decimal(subtotal),
3640
+ priceSubtotalIncl: decimal(total),
927
3641
  refundedOrderlineId: line.id,
928
3642
  sequence,
3643
+ ...(line.lineKind
3644
+ ? {
3645
+ lineKind: line.lineKind,
3646
+ loyaltyApplicationId: line.loyaltyApplicationId ?? null,
3647
+ loyaltyRewardId: line.loyaltyRewardId ?? null,
3648
+ loyaltyPointsCost: line.loyaltyPointsCost ?? null,
3649
+ }
3650
+ : {}),
929
3651
  });
930
3652
  sequence += 10;
931
3653
  }
932
- await recompute(ctx, args.id);
933
- return { ok: true, id: args.id, name };
3654
+ await recompute(tx, args.id);
3655
+ await appendAudit(tx, {
3656
+ id: `order:${String(args.id)}:refund-created`,
3657
+ subjectType: 'order',
3658
+ subjectId: String(args.id),
3659
+ configId: session.configId,
3660
+ sessionId: args.sessionId,
3661
+ action: 'order.refund_created',
3662
+ actorId: args.operatorId,
3663
+ deviceId: args.deviceId ?? session.deviceId,
3664
+ reason: args.reason,
3665
+ relatedId: original.id,
3666
+ details: {
3667
+ sessionId: args.sessionId,
3668
+ returnComplete: completesReturn,
3669
+ returnPortion: decimal(returnPortion),
3670
+ originalRevision: claim.revision,
3671
+ },
3672
+ });
3673
+ return {
3674
+ ok: true,
3675
+ id: args.id,
3676
+ name,
3677
+ revision: 0,
3678
+ originalRevision: claim.revision,
3679
+ };
3680
+ }),
3681
+ }),
3682
+ createExchange: defineFn({
3683
+ input: {
3684
+ id: 'id',
3685
+ uuid: 'text?',
3686
+ originalOrderId: 'id',
3687
+ sessionId: 'id',
3688
+ expectedRevision: 'int',
3689
+ lines: 'json',
3690
+ reason: 'text',
3691
+ replacementPriceBookRevision: 'text',
3692
+ replacementNote: 'text?',
3693
+ operatorId: 'text?',
3694
+ deviceId: 'text?',
3695
+ },
3696
+ output: {
3697
+ ok: 'bool',
3698
+ id: 'id?',
3699
+ uuid: 'text?',
3700
+ originalOrderId: 'id?',
3701
+ returnOrderId: 'id?',
3702
+ replacementOrderId: 'id?',
3703
+ originalRevision: 'int?',
3704
+ returnRevision: 'int?',
3705
+ replacementRevision: 'int?',
3706
+ reason: 'text?',
3707
+ createdAt: 'datetime?',
3708
+ errors: 'json?',
934
3709
  },
3710
+ effects: [...refundOrderEffects, ...createOrderEffects, 'read:pos.Exchange', 'write:pos.Exchange'],
3711
+ idempotent: true,
3712
+ agent: true,
3713
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
3714
+ const reason = String(args.reason ?? '').trim();
3715
+ if (!reason)
3716
+ return invalid('reason', 'exchange reason is required');
3717
+ const uuid = String(args.uuid ?? args.id);
3718
+ const byId = (await tx.db.select('pos.Exchange', { id: args.id }))[0];
3719
+ const byUuid = (await tx.db.select('pos.Exchange', { uuid }))[0];
3720
+ if (byId && byUuid && byId.id !== byUuid.id)
3721
+ return invalid('uuid', 'exchange uuid is already used by a different command');
3722
+ const existing = byId ?? byUuid;
3723
+ if (existing) {
3724
+ const returned = (await tx.db.select('pos.Order', { id: existing.returnOrderId }))[0];
3725
+ const replacement = (await tx.db.select('pos.Order', { id: existing.replacementOrderId }))[0];
3726
+ if (!returned ||
3727
+ !replacement ||
3728
+ String(existing.originalOrderId) !== String(args.originalOrderId) ||
3729
+ String(existing.uuid) !== uuid ||
3730
+ String(existing.reason ?? '') !== reason ||
3731
+ String(returned.sessionId) !== String(args.sessionId) ||
3732
+ String(replacement.sessionId) !== String(args.sessionId) ||
3733
+ returned.exchangeRole !== 'return' ||
3734
+ replacement.exchangeRole !== 'replacement' ||
3735
+ returned.exchangeId !== existing.id ||
3736
+ replacement.exchangeId !== existing.id ||
3737
+ String(replacement.priceBookRevision ?? '') !== String(args.replacementPriceBookRevision) ||
3738
+ (args.replacementNote !== undefined &&
3739
+ String(replacement.note ?? '') !== String(args.replacementNote)))
3740
+ return invalid('id', 'exchange id is already used by a different command');
3741
+ const replayedReturn = (await functions.refundOrder.handler(tx, {
3742
+ id: returned.id,
3743
+ uuid: returned.uuid,
3744
+ originalOrderId: args.originalOrderId,
3745
+ sessionId: args.sessionId,
3746
+ expectedRevision: args.expectedRevision,
3747
+ lines: args.lines,
3748
+ reason,
3749
+ operatorId: args.operatorId,
3750
+ deviceId: args.deviceId,
3751
+ }));
3752
+ if (replayedReturn.ok !== true)
3753
+ return replayedReturn;
3754
+ return {
3755
+ ok: true,
3756
+ id: existing.id,
3757
+ uuid: existing.uuid,
3758
+ originalOrderId: existing.originalOrderId,
3759
+ returnOrderId: existing.returnOrderId,
3760
+ replacementOrderId: existing.replacementOrderId,
3761
+ originalRevision: n(existing.originalRevision),
3762
+ returnRevision: n(returned.revision),
3763
+ replacementRevision: n(replacement.revision),
3764
+ reason: existing.reason,
3765
+ createdAt: existing.createdAt,
3766
+ };
3767
+ }
3768
+ const returnOrderId = `${String(args.id)}:return`;
3769
+ const replacementOrderId = `${String(args.id)}:replacement`;
3770
+ if ((await tx.db.select('pos.Order', { id: returnOrderId }))[0] ||
3771
+ (await tx.db.select('pos.Order', { id: replacementOrderId }))[0])
3772
+ return invalid('id', 'an exchange child order id is already in use');
3773
+ const original = (await tx.db.select('pos.Order', { id: args.originalOrderId }))[0];
3774
+ if (!original || original.isRefund || !['paid', 'done'].includes(String(original.state)))
3775
+ return invalid('originalOrderId', 'only a paid sale can be exchanged');
3776
+ const returned = (await functions.refundOrder.handler(tx, {
3777
+ id: returnOrderId,
3778
+ uuid: `${uuid}:return`,
3779
+ originalOrderId: args.originalOrderId,
3780
+ sessionId: args.sessionId,
3781
+ expectedRevision: args.expectedRevision,
3782
+ lines: args.lines,
3783
+ reason,
3784
+ operatorId: args.operatorId,
3785
+ deviceId: args.deviceId,
3786
+ }));
3787
+ if (returned.ok !== true)
3788
+ return returned;
3789
+ const replacement = (await functions.createOrder.handler(tx, {
3790
+ id: replacementOrderId,
3791
+ uuid: `${uuid}:replacement`,
3792
+ sessionId: args.sessionId,
3793
+ partnerId: original.partnerId ?? undefined,
3794
+ note: args.replacementNote ?? `Exchange replacement for ${String(original.posReference)}`,
3795
+ operatorId: args.operatorId,
3796
+ deviceId: args.deviceId,
3797
+ priceBookRevision: args.replacementPriceBookRevision,
3798
+ }));
3799
+ if (replacement.ok !== true)
3800
+ return replacement;
3801
+ const createdAt = now();
3802
+ await tx.db.insert('pos.Exchange', {
3803
+ id: args.id,
3804
+ uuid,
3805
+ originalOrderId: original.id,
3806
+ returnOrderId,
3807
+ replacementOrderId,
3808
+ originalRevision: returned.originalRevision,
3809
+ reason,
3810
+ createdAt,
3811
+ });
3812
+ await tx.db.update('pos.Order', { id: returnOrderId }, { exchangeId: args.id, exchangeRole: 'return' });
3813
+ await tx.db.update('pos.Order', { id: replacementOrderId }, { exchangeId: args.id, exchangeRole: 'replacement' });
3814
+ await appendAudit(tx, {
3815
+ id: `exchange:${String(args.id)}:created`,
3816
+ subjectType: 'exchange',
3817
+ subjectId: String(args.id),
3818
+ configId: original.configId,
3819
+ sessionId: args.sessionId,
3820
+ action: 'exchange.created',
3821
+ actorId: args.operatorId,
3822
+ deviceId: args.deviceId,
3823
+ reason,
3824
+ relatedId: original.id,
3825
+ details: { returnOrderId, replacementOrderId, originalRevision: returned.originalRevision },
3826
+ occurredAt: createdAt,
3827
+ });
3828
+ return {
3829
+ ok: true,
3830
+ id: args.id,
3831
+ uuid,
3832
+ originalOrderId: original.id,
3833
+ returnOrderId,
3834
+ replacementOrderId,
3835
+ originalRevision: n(returned.originalRevision),
3836
+ returnRevision: n(returned.revision),
3837
+ replacementRevision: n(replacement.revision),
3838
+ reason,
3839
+ createdAt,
3840
+ };
3841
+ }),
935
3842
  }),
936
3843
  cancelOrder: defineFn({
937
- input: { id: 'id' },
938
- output: { ok: 'bool', id: 'id?', errors: 'json?' },
939
- effects: ['read:pos.Order', 'write:pos.Order'],
3844
+ input: { id: 'id', expectedRevision: 'int?' },
3845
+ output: { ok: 'bool', id: 'id?', revision: 'int?', errors: 'json?' },
3846
+ effects: ['read:pos.Order', 'write:pos.Order', 'read:pos.Payment', 'write:pos.AuditEvent'],
940
3847
  idempotent: true,
941
3848
  agent: true,
942
- handler: async (ctx, args) => {
943
- const order = (await ctx.db.select('pos.Order', { id: args.id }))[0];
3849
+ handler: (ctx, args) => atomic(ctx, async (tx) => {
3850
+ const order = (await tx.db.select('pos.Order', { id: args.id }))[0];
944
3851
  if (!order)
945
3852
  return invalid('id', 'order does not exist');
946
- if (order.state !== 'draft' && order.state !== 'cancel')
3853
+ if (order.state === 'cancel')
3854
+ return { ok: true, id: args.id, revision: n(order.revision) };
3855
+ if (order.state !== 'draft')
947
3856
  return invalid('state', 'paid orders must be refunded, not cancelled');
948
- await ctx.db.update('pos.Order', { id: args.id }, { state: 'cancel' });
949
- return { ok: true, id: args.id };
950
- },
3857
+ if (order.paymentLockId)
3858
+ return invalid('paymentLockId', 'external payment must be reconciled before cancellation');
3859
+ const providerPayment = (await tx.db.select('pos.Payment', { orderId: args.id })).find((payment) => payment.kind === 'provider' && (payment.state ?? 'captured') === 'captured');
3860
+ if (providerPayment)
3861
+ return invalid('state', 'provider tenders must be reversed before cancellation');
3862
+ const claim = await claimDraftRevision(tx, args.id, args.expectedRevision);
3863
+ if (claim.ok !== true)
3864
+ return claim;
3865
+ if (order.isRefund && order.refundedOrderId) {
3866
+ const released = await claimOrderRevision(tx, order.refundedOrderId);
3867
+ if (released.ok !== true)
3868
+ return released;
3869
+ }
3870
+ await tx.db.update('pos.Order', { id: args.id }, { state: 'cancel' });
3871
+ await appendAudit(tx, {
3872
+ id: `order:${String(args.id)}:cancelled`,
3873
+ subjectType: 'order',
3874
+ subjectId: String(args.id),
3875
+ configId: order.configId,
3876
+ sessionId: order.sessionId,
3877
+ action: 'order.cancelled',
3878
+ actorId: order.operatorId,
3879
+ deviceId: order.deviceId,
3880
+ relatedId: order.sessionId,
3881
+ details: { revision: claim.revision },
3882
+ });
3883
+ return { ok: true, id: args.id, revision: claim.revision };
3884
+ }),
951
3885
  }),
952
3886
  };
953
3887
  //# sourceMappingURL=functions.js.map