@ketvietlab/ketsuite 0.1.2 → 0.1.3

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 (2590) 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 +152 -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 +77 -6
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +66 -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 +787 -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 +234 -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 +766 -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 +1134 -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 +331 -0
  360. package/dist/modules/backend/design/tokens.css +317 -92
  361. package/dist/modules/backend/index.d.ts +12 -5
  362. package/dist/modules/backend/index.d.ts.map +1 -1
  363. package/dist/modules/backend/index.js +32 -15
  364. package/dist/modules/backend/index.js.map +1 -1
  365. package/dist/modules/backend/islands.d.ts.map +1 -1
  366. package/dist/modules/backend/islands.js +22 -4
  367. package/dist/modules/backend/islands.js.map +1 -1
  368. package/dist/modules/backend/joints.d.ts +1 -1
  369. package/dist/modules/backend/joints.d.ts.map +1 -1
  370. package/dist/modules/backend/joints.js +14 -6
  371. package/dist/modules/backend/joints.js.map +1 -1
  372. package/dist/modules/backend/list-search.d.ts +33 -0
  373. package/dist/modules/backend/list-search.d.ts.map +1 -0
  374. package/dist/modules/backend/list-search.js +232 -0
  375. package/dist/modules/backend/list-search.js.map +1 -0
  376. package/dist/modules/backend/menus.d.ts.map +1 -1
  377. package/dist/modules/backend/menus.js +3 -12
  378. package/dist/modules/backend/menus.js.map +1 -1
  379. package/dist/modules/backend/messages.d.ts +1 -1
  380. package/dist/modules/backend/messages.d.ts.map +1 -1
  381. package/dist/modules/backend/messages.js +48 -35
  382. package/dist/modules/backend/messages.js.map +1 -1
  383. package/dist/modules/backend/paging.d.ts +1 -1
  384. package/dist/modules/backend/paging.d.ts.map +1 -1
  385. package/dist/modules/backend/paging.js +1 -1
  386. package/dist/modules/backend/paging.js.map +1 -1
  387. package/dist/modules/backend/relation-select.d.ts +2 -57
  388. package/dist/modules/backend/relation-select.d.ts.map +1 -1
  389. package/dist/modules/backend/relation-select.js +2 -0
  390. package/dist/modules/backend/relation-select.js.map +1 -1
  391. package/dist/modules/backend/routes.d.ts +1 -8
  392. package/dist/modules/backend/routes.d.ts.map +1 -1
  393. package/dist/modules/backend/routes.js +36 -111
  394. package/dist/modules/backend/routes.js.map +1 -1
  395. package/dist/modules/backend/screen.d.ts +130 -0
  396. package/dist/modules/backend/screen.d.ts.map +1 -0
  397. package/dist/modules/backend/screen.js +205 -0
  398. package/dist/modules/backend/screen.js.map +1 -0
  399. package/dist/modules/backend/screens.d.ts +11 -14
  400. package/dist/modules/backend/screens.d.ts.map +1 -1
  401. package/dist/modules/backend/screens.js +13 -70
  402. package/dist/modules/backend/screens.js.map +1 -1
  403. package/dist/modules/business_report_staff_channel/channel-routes.d.ts +2 -0
  404. package/dist/modules/business_report_staff_channel/channel-routes.d.ts.map +1 -0
  405. package/dist/modules/business_report_staff_channel/channel-routes.js +438 -0
  406. package/dist/modules/business_report_staff_channel/channel-routes.js.map +1 -0
  407. package/dist/modules/business_report_staff_channel/index.d.ts +5 -0
  408. package/dist/modules/business_report_staff_channel/index.d.ts.map +1 -0
  409. package/dist/modules/business_report_staff_channel/index.js +18 -0
  410. package/dist/modules/business_report_staff_channel/index.js.map +1 -0
  411. package/dist/modules/calendar/index.d.ts.map +1 -1
  412. package/dist/modules/calendar/index.js +0 -1
  413. package/dist/modules/calendar/index.js.map +1 -1
  414. package/dist/modules/calendar/recurrence.d.ts.map +1 -1
  415. package/dist/modules/calendar/recurrence.js +3 -11
  416. package/dist/modules/calendar/recurrence.js.map +1 -1
  417. package/dist/modules/calendar_activity/index.d.ts.map +1 -1
  418. package/dist/modules/calendar_activity/index.js +0 -2
  419. package/dist/modules/calendar_activity/index.js.map +1 -1
  420. package/dist/modules/calendar_backend/index.d.ts +1 -1
  421. package/dist/modules/calendar_backend/index.d.ts.map +1 -1
  422. package/dist/modules/calendar_backend/index.js +1 -3
  423. package/dist/modules/calendar_backend/index.js.map +1 -1
  424. package/dist/modules/calendar_backend/routes.d.ts.map +1 -1
  425. package/dist/modules/calendar_backend/routes.js +10 -22
  426. package/dist/modules/calendar_backend/routes.js.map +1 -1
  427. package/dist/modules/calendar_backend/screens/calendar.d.ts +5 -0
  428. package/dist/modules/calendar_backend/screens/calendar.d.ts.map +1 -0
  429. package/dist/modules/calendar_backend/screens/calendar.js +10 -0
  430. package/dist/modules/calendar_backend/screens/calendar.js.map +1 -0
  431. package/dist/modules/calendar_backend/screens/index.d.ts +2 -0
  432. package/dist/modules/calendar_backend/screens/index.d.ts.map +1 -0
  433. package/dist/modules/calendar_backend/screens/index.js +2 -0
  434. package/dist/modules/calendar_backend/screens/index.js.map +1 -0
  435. package/dist/modules/calendar_mail_transport/index.d.ts.map +1 -1
  436. package/dist/modules/calendar_mail_transport/index.js +0 -2
  437. package/dist/modules/calendar_mail_transport/index.js.map +1 -1
  438. package/dist/modules/channel_api/core.d.ts +253 -0
  439. package/dist/modules/channel_api/core.d.ts.map +1 -0
  440. package/dist/modules/channel_api/core.js +587 -0
  441. package/dist/modules/channel_api/core.js.map +1 -0
  442. package/dist/modules/channel_api/customer.d.ts +21 -0
  443. package/dist/modules/channel_api/customer.d.ts.map +1 -0
  444. package/dist/modules/channel_api/customer.js +368 -0
  445. package/dist/modules/channel_api/customer.js.map +1 -0
  446. package/dist/modules/channel_api/index.d.ts +6 -0
  447. package/dist/modules/channel_api/index.d.ts.map +1 -0
  448. package/dist/modules/channel_api/index.js +66 -0
  449. package/dist/modules/channel_api/index.js.map +1 -0
  450. package/dist/modules/channel_api/openapi.d.ts +17 -0
  451. package/dist/modules/channel_api/openapi.d.ts.map +1 -0
  452. package/dist/modules/channel_api/openapi.js +105 -0
  453. package/dist/modules/channel_api/openapi.js.map +1 -0
  454. package/dist/modules/channel_api/staff.d.ts +7 -0
  455. package/dist/modules/channel_api/staff.d.ts.map +1 -0
  456. package/dist/modules/channel_api/staff.js +209 -0
  457. package/dist/modules/channel_api/staff.js.map +1 -0
  458. package/dist/modules/company/functions.d.ts.map +1 -1
  459. package/dist/modules/company/functions.js +93 -12
  460. package/dist/modules/company/functions.js.map +1 -1
  461. package/dist/modules/company/index.js +3 -3
  462. package/dist/modules/company/index.js.map +1 -1
  463. package/dist/modules/company/messages.d.ts +8 -0
  464. package/dist/modules/company/messages.d.ts.map +1 -1
  465. package/dist/modules/company/messages.js +8 -0
  466. package/dist/modules/company/messages.js.map +1 -1
  467. package/dist/modules/company/models.d.ts +2 -2
  468. package/dist/modules/company/models.d.ts.map +1 -1
  469. package/dist/modules/company/models.js +12 -2
  470. package/dist/modules/company/models.js.map +1 -1
  471. package/dist/modules/company_backend/index.d.ts +2 -1
  472. package/dist/modules/company_backend/index.d.ts.map +1 -1
  473. package/dist/modules/company_backend/index.js +25 -4
  474. package/dist/modules/company_backend/index.js.map +1 -1
  475. package/dist/modules/company_backend/routes.d.ts.map +1 -1
  476. package/dist/modules/company_backend/routes.js +314 -96
  477. package/dist/modules/company_backend/routes.js.map +1 -1
  478. package/dist/modules/company_backend/screens/branch-form.d.ts +18 -0
  479. package/dist/modules/company_backend/screens/branch-form.d.ts.map +1 -0
  480. package/dist/modules/company_backend/screens/branch-form.js +63 -0
  481. package/dist/modules/company_backend/screens/branch-form.js.map +1 -0
  482. package/dist/modules/company_backend/screens/companies-list.d.ts +18 -0
  483. package/dist/modules/company_backend/screens/companies-list.d.ts.map +1 -0
  484. package/dist/modules/company_backend/screens/companies-list.js +49 -0
  485. package/dist/modules/company_backend/screens/companies-list.js.map +1 -0
  486. package/dist/modules/company_backend/screens/company-form.d.ts +25 -0
  487. package/dist/modules/company_backend/screens/company-form.d.ts.map +1 -0
  488. package/dist/modules/company_backend/screens/company-form.js +159 -0
  489. package/dist/modules/company_backend/screens/company-form.js.map +1 -0
  490. package/dist/modules/company_backend/screens/context.d.ts +30 -0
  491. package/dist/modules/company_backend/screens/context.d.ts.map +1 -0
  492. package/dist/modules/company_backend/screens/context.js +48 -0
  493. package/dist/modules/company_backend/screens/context.js.map +1 -0
  494. package/dist/modules/company_backend/screens/hierarchy.d.ts +16 -0
  495. package/dist/modules/company_backend/screens/hierarchy.d.ts.map +1 -0
  496. package/dist/modules/company_backend/screens/hierarchy.js +41 -0
  497. package/dist/modules/company_backend/screens/hierarchy.js.map +1 -0
  498. package/dist/modules/company_backend/screens/index.d.ts +7 -0
  499. package/dist/modules/company_backend/screens/index.d.ts.map +1 -0
  500. package/dist/modules/company_backend/screens/index.js +6 -0
  501. package/dist/modules/company_backend/screens/index.js.map +1 -0
  502. package/dist/modules/company_backend/screens/types.d.ts +22 -0
  503. package/dist/modules/company_backend/screens/types.d.ts.map +1 -0
  504. package/dist/modules/company_backend/screens/types.js +2 -0
  505. package/dist/modules/company_backend/screens/types.js.map +1 -0
  506. package/dist/modules/crm/functions.d.ts +1 -1
  507. package/dist/modules/crm/functions.d.ts.map +1 -1
  508. package/dist/modules/crm/functions.js +534 -75
  509. package/dist/modules/crm/functions.js.map +1 -1
  510. package/dist/modules/crm/index.d.ts +2 -1
  511. package/dist/modules/crm/index.d.ts.map +1 -1
  512. package/dist/modules/crm/index.js +3 -4
  513. package/dist/modules/crm/index.js.map +1 -1
  514. package/dist/modules/crm/jobs.d.ts +10 -0
  515. package/dist/modules/crm/jobs.d.ts.map +1 -1
  516. package/dist/modules/crm/jobs.js +50 -1
  517. package/dist/modules/crm/jobs.js.map +1 -1
  518. package/dist/modules/crm/messages.d.ts +14 -1
  519. package/dist/modules/crm/messages.d.ts.map +1 -1
  520. package/dist/modules/crm/messages.js +26 -0
  521. package/dist/modules/crm/messages.js.map +1 -1
  522. package/dist/modules/crm/models.d.ts.map +1 -1
  523. package/dist/modules/crm/models.js +25 -0
  524. package/dist/modules/crm/models.js.map +1 -1
  525. package/dist/modules/crm/operations.d.ts +110 -1
  526. package/dist/modules/crm/operations.d.ts.map +1 -1
  527. package/dist/modules/crm/operations.js +612 -84
  528. package/dist/modules/crm/operations.js.map +1 -1
  529. package/dist/modules/crm_backend/client/crm-kanban-view.d.mts.map +1 -1
  530. package/dist/modules/crm_backend/client/crm-kanban-view.mjs +132 -32
  531. package/dist/modules/crm_backend/client/crm-kanban-view.mjs.map +1 -1
  532. package/dist/modules/crm_backend/client/crm.css +398 -63
  533. package/dist/modules/crm_backend/index.d.ts.map +1 -1
  534. package/dist/modules/crm_backend/index.js +12 -4
  535. package/dist/modules/crm_backend/index.js.map +1 -1
  536. package/dist/modules/crm_backend/messages.d.ts +212 -0
  537. package/dist/modules/crm_backend/messages.d.ts.map +1 -1
  538. package/dist/modules/crm_backend/messages.js +212 -0
  539. package/dist/modules/crm_backend/messages.js.map +1 -1
  540. package/dist/modules/crm_backend/relation-control.d.ts +51 -0
  541. package/dist/modules/crm_backend/relation-control.d.ts.map +1 -0
  542. package/dist/modules/crm_backend/relation-control.js +107 -0
  543. package/dist/modules/crm_backend/relation-control.js.map +1 -0
  544. package/dist/modules/crm_backend/routes.d.ts.map +1 -1
  545. package/dist/modules/crm_backend/routes.js +1068 -260
  546. package/dist/modules/crm_backend/routes.js.map +1 -1
  547. package/dist/modules/crm_backend/screens/activity-planner.d.ts +22 -0
  548. package/dist/modules/crm_backend/screens/activity-planner.d.ts.map +1 -0
  549. package/dist/modules/crm_backend/screens/activity-planner.js +159 -0
  550. package/dist/modules/crm_backend/screens/activity-planner.js.map +1 -0
  551. package/dist/modules/crm_backend/screens/case-create.d.ts +15 -0
  552. package/dist/modules/crm_backend/screens/case-create.d.ts.map +1 -0
  553. package/dist/modules/crm_backend/screens/case-create.js +19 -0
  554. package/dist/modules/crm_backend/screens/case-create.js.map +1 -0
  555. package/dist/modules/crm_backend/screens/case-detail.d.ts +46 -0
  556. package/dist/modules/crm_backend/screens/case-detail.d.ts.map +1 -0
  557. package/dist/modules/crm_backend/screens/case-detail.js +506 -0
  558. package/dist/modules/crm_backend/screens/case-detail.js.map +1 -0
  559. package/dist/modules/crm_backend/screens/cases-list.d.ts +16 -0
  560. package/dist/modules/crm_backend/screens/cases-list.d.ts.map +1 -0
  561. package/dist/modules/crm_backend/screens/cases-list.js +86 -0
  562. package/dist/modules/crm_backend/screens/cases-list.js.map +1 -0
  563. package/dist/modules/crm_backend/screens/configuration.d.ts +28 -0
  564. package/dist/modules/crm_backend/screens/configuration.d.ts.map +1 -0
  565. package/dist/modules/crm_backend/screens/configuration.js +115 -0
  566. package/dist/modules/crm_backend/screens/configuration.js.map +1 -0
  567. package/dist/modules/crm_backend/screens/index.d.ts +14 -0
  568. package/dist/modules/crm_backend/screens/index.d.ts.map +1 -0
  569. package/dist/modules/crm_backend/screens/index.js +8 -0
  570. package/dist/modules/crm_backend/screens/index.js.map +1 -0
  571. package/dist/modules/crm_backend/screens/leaderboard.d.ts +12 -0
  572. package/dist/modules/crm_backend/screens/leaderboard.d.ts.map +1 -0
  573. package/dist/modules/crm_backend/screens/leaderboard.js +89 -0
  574. package/dist/modules/crm_backend/screens/leaderboard.js.map +1 -0
  575. package/dist/modules/crm_backend/screens/pipeline.d.ts +21 -0
  576. package/dist/modules/crm_backend/screens/pipeline.d.ts.map +1 -0
  577. package/dist/modules/crm_backend/screens/pipeline.js +22 -0
  578. package/dist/modules/crm_backend/screens/pipeline.js.map +1 -0
  579. package/dist/modules/crm_sale/index.d.ts.map +1 -1
  580. package/dist/modules/crm_sale/index.js +3 -4
  581. package/dist/modules/crm_sale/index.js.map +1 -1
  582. package/dist/modules/crm_sale/messages.d.ts +3 -1
  583. package/dist/modules/crm_sale/messages.d.ts.map +1 -1
  584. package/dist/modules/crm_sale/messages.js +4 -0
  585. package/dist/modules/crm_sale/messages.js.map +1 -1
  586. package/dist/modules/crm_sale/sale-functions.d.ts +8 -1
  587. package/dist/modules/crm_sale/sale-functions.d.ts.map +1 -1
  588. package/dist/modules/crm_sale/sale-functions.js +184 -55
  589. package/dist/modules/crm_sale/sale-functions.js.map +1 -1
  590. package/dist/modules/crm_staff_channel/channel-routes.d.ts +2 -0
  591. package/dist/modules/crm_staff_channel/channel-routes.d.ts.map +1 -0
  592. package/dist/modules/crm_staff_channel/channel-routes.js +788 -0
  593. package/dist/modules/crm_staff_channel/channel-routes.js.map +1 -0
  594. package/dist/modules/crm_staff_channel/index.d.ts +5 -0
  595. package/dist/modules/crm_staff_channel/index.d.ts.map +1 -0
  596. package/dist/modules/crm_staff_channel/index.js +30 -0
  597. package/dist/modules/crm_staff_channel/index.js.map +1 -0
  598. package/dist/modules/crm_website/functions.d.ts.map +1 -1
  599. package/dist/modules/crm_website/functions.js +89 -10
  600. package/dist/modules/crm_website/functions.js.map +1 -1
  601. package/dist/modules/crm_website/index.js +1 -2
  602. package/dist/modules/crm_website/index.js.map +1 -1
  603. package/dist/modules/crm_website/messages.d.ts +4 -1
  604. package/dist/modules/crm_website/messages.d.ts.map +1 -1
  605. package/dist/modules/crm_website/messages.js +6 -0
  606. package/dist/modules/crm_website/messages.js.map +1 -1
  607. package/dist/modules/crm_website/models.d.ts.map +1 -1
  608. package/dist/modules/crm_website/models.js +18 -0
  609. package/dist/modules/crm_website/models.js.map +1 -1
  610. package/dist/modules/crm_website/routes.d.ts.map +1 -1
  611. package/dist/modules/crm_website/routes.js +44 -12
  612. package/dist/modules/crm_website/routes.js.map +1 -1
  613. package/dist/modules/crm_website/screens.d.ts +7 -1
  614. package/dist/modules/crm_website/screens.d.ts.map +1 -1
  615. package/dist/modules/crm_website/screens.js +13 -8
  616. package/dist/modules/crm_website/screens.js.map +1 -1
  617. package/dist/modules/flow/functions.d.ts +3 -0
  618. package/dist/modules/flow/functions.d.ts.map +1 -0
  619. package/dist/modules/flow/functions.js +1876 -0
  620. package/dist/modules/flow/functions.js.map +1 -0
  621. package/dist/modules/flow/index.d.ts +12 -0
  622. package/dist/modules/flow/index.d.ts.map +1 -0
  623. package/dist/modules/flow/index.js +30 -0
  624. package/dist/modules/flow/index.js.map +1 -0
  625. package/dist/modules/flow/jobs.d.ts +3 -0
  626. package/dist/modules/flow/jobs.d.ts.map +1 -0
  627. package/dist/modules/flow/jobs.js +136 -0
  628. package/dist/modules/flow/jobs.js.map +1 -0
  629. package/dist/modules/flow/membership.d.ts +72 -0
  630. package/dist/modules/flow/membership.d.ts.map +1 -0
  631. package/dist/modules/flow/membership.js +176 -0
  632. package/dist/modules/flow/membership.js.map +1 -0
  633. package/dist/modules/flow/messages.d.ts +79 -0
  634. package/dist/modules/flow/messages.d.ts.map +1 -0
  635. package/dist/modules/flow/messages.js +152 -0
  636. package/dist/modules/flow/messages.js.map +1 -0
  637. package/dist/modules/flow/models.d.ts +3 -0
  638. package/dist/modules/flow/models.d.ts.map +1 -0
  639. package/dist/modules/flow/models.js +453 -0
  640. package/dist/modules/flow/models.js.map +1 -0
  641. package/dist/modules/flow/operations.d.ts +408 -0
  642. package/dist/modules/flow/operations.d.ts.map +1 -0
  643. package/dist/modules/flow/operations.js +1665 -0
  644. package/dist/modules/flow/operations.js.map +1 -0
  645. package/dist/modules/flow/pages.d.ts +146 -0
  646. package/dist/modules/flow/pages.d.ts.map +1 -0
  647. package/dist/modules/flow/pages.js +394 -0
  648. package/dist/modules/flow/pages.js.map +1 -0
  649. package/dist/modules/flow/projects.d.ts +41 -0
  650. package/dist/modules/flow/projects.d.ts.map +1 -0
  651. package/dist/modules/flow/projects.js +74 -0
  652. package/dist/modules/flow/projects.js.map +1 -0
  653. package/dist/modules/flow/search.d.ts +57 -0
  654. package/dist/modules/flow/search.d.ts.map +1 -0
  655. package/dist/modules/flow/search.js +110 -0
  656. package/dist/modules/flow/search.js.map +1 -0
  657. package/dist/modules/flow/types.d.ts +17 -0
  658. package/dist/modules/flow/types.d.ts.map +1 -0
  659. package/dist/modules/flow/types.js +13 -0
  660. package/dist/modules/flow/types.js.map +1 -0
  661. package/dist/modules/flow_backend/functions.d.ts +3 -0
  662. package/dist/modules/flow_backend/functions.d.ts.map +1 -0
  663. package/dist/modules/flow_backend/functions.js +162 -0
  664. package/dist/modules/flow_backend/functions.js.map +1 -0
  665. package/dist/modules/flow_backend/index.d.ts +3 -0
  666. package/dist/modules/flow_backend/index.d.ts.map +1 -0
  667. package/dist/modules/flow_backend/index.js +96 -0
  668. package/dist/modules/flow_backend/index.js.map +1 -0
  669. package/dist/modules/flow_backend/islands.d.ts +3 -0
  670. package/dist/modules/flow_backend/islands.d.ts.map +1 -0
  671. package/dist/modules/flow_backend/islands.js +31 -0
  672. package/dist/modules/flow_backend/islands.js.map +1 -0
  673. package/dist/modules/flow_backend/messages.d.ts +248 -0
  674. package/dist/modules/flow_backend/messages.d.ts.map +1 -0
  675. package/dist/modules/flow_backend/messages.js +470 -0
  676. package/dist/modules/flow_backend/messages.js.map +1 -0
  677. package/dist/modules/flow_backend/relation-control.d.ts +53 -0
  678. package/dist/modules/flow_backend/relation-control.d.ts.map +1 -0
  679. package/dist/modules/flow_backend/relation-control.js +106 -0
  680. package/dist/modules/flow_backend/relation-control.js.map +1 -0
  681. package/dist/modules/flow_backend/routes.d.ts +3 -0
  682. package/dist/modules/flow_backend/routes.d.ts.map +1 -0
  683. package/dist/modules/flow_backend/routes.js +2519 -0
  684. package/dist/modules/flow_backend/routes.js.map +1 -0
  685. package/dist/modules/flow_backend/screens/all-epics.d.ts +19 -0
  686. package/dist/modules/flow_backend/screens/all-epics.d.ts.map +1 -0
  687. package/dist/modules/flow_backend/screens/all-epics.js +59 -0
  688. package/dist/modules/flow_backend/screens/all-epics.js.map +1 -0
  689. package/dist/modules/flow_backend/screens/all-pages.d.ts +19 -0
  690. package/dist/modules/flow_backend/screens/all-pages.d.ts.map +1 -0
  691. package/dist/modules/flow_backend/screens/all-pages.js +65 -0
  692. package/dist/modules/flow_backend/screens/all-pages.js.map +1 -0
  693. package/dist/modules/flow_backend/screens/board.d.ts +5 -0
  694. package/dist/modules/flow_backend/screens/board.d.ts.map +1 -0
  695. package/dist/modules/flow_backend/screens/board.js +7 -0
  696. package/dist/modules/flow_backend/screens/board.js.map +1 -0
  697. package/dist/modules/flow_backend/screens/epic-detail.d.ts +22 -0
  698. package/dist/modules/flow_backend/screens/epic-detail.d.ts.map +1 -0
  699. package/dist/modules/flow_backend/screens/epic-detail.js +41 -0
  700. package/dist/modules/flow_backend/screens/epic-detail.js.map +1 -0
  701. package/dist/modules/flow_backend/screens/gantt.d.ts +21 -0
  702. package/dist/modules/flow_backend/screens/gantt.d.ts.map +1 -0
  703. package/dist/modules/flow_backend/screens/gantt.js +42 -0
  704. package/dist/modules/flow_backend/screens/gantt.js.map +1 -0
  705. package/dist/modules/flow_backend/screens/index.d.ts +29 -0
  706. package/dist/modules/flow_backend/screens/index.d.ts.map +1 -0
  707. package/dist/modules/flow_backend/screens/index.js +23 -0
  708. package/dist/modules/flow_backend/screens/index.js.map +1 -0
  709. package/dist/modules/flow_backend/screens/issue-detail.d.ts +38 -0
  710. package/dist/modules/flow_backend/screens/issue-detail.d.ts.map +1 -0
  711. package/dist/modules/flow_backend/screens/issue-detail.js +336 -0
  712. package/dist/modules/flow_backend/screens/issue-detail.js.map +1 -0
  713. package/dist/modules/flow_backend/screens/issues.d.ts +34 -0
  714. package/dist/modules/flow_backend/screens/issues.d.ts.map +1 -0
  715. package/dist/modules/flow_backend/screens/issues.js +118 -0
  716. package/dist/modules/flow_backend/screens/issues.js.map +1 -0
  717. package/dist/modules/flow_backend/screens/map.d.ts +13 -0
  718. package/dist/modules/flow_backend/screens/map.d.ts.map +1 -0
  719. package/dist/modules/flow_backend/screens/map.js +16 -0
  720. package/dist/modules/flow_backend/screens/map.js.map +1 -0
  721. package/dist/modules/flow_backend/screens/my-work.d.ts +42 -0
  722. package/dist/modules/flow_backend/screens/my-work.d.ts.map +1 -0
  723. package/dist/modules/flow_backend/screens/my-work.js +157 -0
  724. package/dist/modules/flow_backend/screens/my-work.js.map +1 -0
  725. package/dist/modules/flow_backend/screens/nav.d.ts +3 -0
  726. package/dist/modules/flow_backend/screens/nav.d.ts.map +1 -0
  727. package/dist/modules/flow_backend/screens/nav.js +79 -0
  728. package/dist/modules/flow_backend/screens/nav.js.map +1 -0
  729. package/dist/modules/flow_backend/screens/page-detail.d.ts +31 -0
  730. package/dist/modules/flow_backend/screens/page-detail.d.ts.map +1 -0
  731. package/dist/modules/flow_backend/screens/page-detail.js +113 -0
  732. package/dist/modules/flow_backend/screens/page-detail.js.map +1 -0
  733. package/dist/modules/flow_backend/screens/project-create.d.ts +26 -0
  734. package/dist/modules/flow_backend/screens/project-create.d.ts.map +1 -0
  735. package/dist/modules/flow_backend/screens/project-create.js +56 -0
  736. package/dist/modules/flow_backend/screens/project-create.js.map +1 -0
  737. package/dist/modules/flow_backend/screens/project-epics.d.ts +33 -0
  738. package/dist/modules/flow_backend/screens/project-epics.d.ts.map +1 -0
  739. package/dist/modules/flow_backend/screens/project-epics.js +90 -0
  740. package/dist/modules/flow_backend/screens/project-epics.js.map +1 -0
  741. package/dist/modules/flow_backend/screens/project-pages.d.ts +34 -0
  742. package/dist/modules/flow_backend/screens/project-pages.d.ts.map +1 -0
  743. package/dist/modules/flow_backend/screens/project-pages.js +66 -0
  744. package/dist/modules/flow_backend/screens/project-pages.js.map +1 -0
  745. package/dist/modules/flow_backend/screens/project-settings.d.ts +69 -0
  746. package/dist/modules/flow_backend/screens/project-settings.d.ts.map +1 -0
  747. package/dist/modules/flow_backend/screens/project-settings.js +248 -0
  748. package/dist/modules/flow_backend/screens/project-settings.js.map +1 -0
  749. package/dist/modules/flow_backend/screens/projects-list.d.ts +30 -0
  750. package/dist/modules/flow_backend/screens/projects-list.d.ts.map +1 -0
  751. package/dist/modules/flow_backend/screens/projects-list.js +121 -0
  752. package/dist/modules/flow_backend/screens/projects-list.js.map +1 -0
  753. package/dist/modules/flow_backend/screens/shared.d.ts +28 -0
  754. package/dist/modules/flow_backend/screens/shared.d.ts.map +1 -0
  755. package/dist/modules/flow_backend/screens/shared.js +46 -0
  756. package/dist/modules/flow_backend/screens/shared.js.map +1 -0
  757. package/dist/modules/flow_backend/screens/sprints.d.ts +33 -0
  758. package/dist/modules/flow_backend/screens/sprints.d.ts.map +1 -0
  759. package/dist/modules/flow_backend/screens/sprints.js +159 -0
  760. package/dist/modules/flow_backend/screens/sprints.js.map +1 -0
  761. package/dist/modules/flow_staff_channel/channel-routes.d.ts +2 -0
  762. package/dist/modules/flow_staff_channel/channel-routes.d.ts.map +1 -0
  763. package/dist/modules/flow_staff_channel/channel-routes.js +444 -0
  764. package/dist/modules/flow_staff_channel/channel-routes.js.map +1 -0
  765. package/dist/modules/flow_staff_channel/index.d.ts +5 -0
  766. package/dist/modules/flow_staff_channel/index.d.ts.map +1 -0
  767. package/dist/modules/flow_staff_channel/index.js +30 -0
  768. package/dist/modules/flow_staff_channel/index.js.map +1 -0
  769. package/dist/modules/hospitality_billing/functions.d.ts +18 -0
  770. package/dist/modules/hospitality_billing/functions.d.ts.map +1 -0
  771. package/dist/modules/hospitality_billing/functions.js +426 -0
  772. package/dist/modules/hospitality_billing/functions.js.map +1 -0
  773. package/dist/modules/hospitality_billing/index.d.ts +3 -0
  774. package/dist/modules/hospitality_billing/index.d.ts.map +1 -0
  775. package/dist/modules/hospitality_billing/index.js +25 -0
  776. package/dist/modules/hospitality_billing/index.js.map +1 -0
  777. package/dist/modules/hospitality_billing/jobs.d.ts +17 -0
  778. package/dist/modules/hospitality_billing/jobs.d.ts.map +1 -0
  779. package/dist/modules/hospitality_billing/jobs.js +83 -0
  780. package/dist/modules/hospitality_billing/jobs.js.map +1 -0
  781. package/dist/modules/hospitality_billing/menus.d.ts +9 -0
  782. package/dist/modules/hospitality_billing/menus.d.ts.map +1 -0
  783. package/dist/modules/hospitality_billing/menus.js +25 -0
  784. package/dist/modules/hospitality_billing/menus.js.map +1 -0
  785. package/dist/modules/hospitality_billing/messages.d.ts +3 -0
  786. package/dist/modules/hospitality_billing/messages.d.ts.map +1 -0
  787. package/dist/modules/hospitality_billing/messages.js +163 -0
  788. package/dist/modules/hospitality_billing/messages.js.map +1 -0
  789. package/dist/modules/hospitality_billing/models.d.ts +3 -0
  790. package/dist/modules/hospitality_billing/models.d.ts.map +1 -0
  791. package/dist/modules/hospitality_billing/models.js +65 -0
  792. package/dist/modules/hospitality_billing/models.js.map +1 -0
  793. package/dist/modules/hospitality_billing/routes.d.ts +3 -0
  794. package/dist/modules/hospitality_billing/routes.d.ts.map +1 -0
  795. package/dist/modules/hospitality_billing/routes.js +189 -0
  796. package/dist/modules/hospitality_billing/routes.js.map +1 -0
  797. package/dist/modules/hospitality_billing/screens/billing.d.ts +3 -0
  798. package/dist/modules/hospitality_billing/screens/billing.d.ts.map +1 -0
  799. package/dist/modules/hospitality_billing/screens/billing.js +20 -0
  800. package/dist/modules/hospitality_billing/screens/billing.js.map +1 -0
  801. package/dist/modules/hospitality_billing/screens/charge-rules.d.ts +12 -0
  802. package/dist/modules/hospitality_billing/screens/charge-rules.d.ts.map +1 -0
  803. package/dist/modules/hospitality_billing/screens/charge-rules.js +86 -0
  804. package/dist/modules/hospitality_billing/screens/charge-rules.js.map +1 -0
  805. package/dist/modules/hospitality_billing/screens/index.d.ts +4 -0
  806. package/dist/modules/hospitality_billing/screens/index.d.ts.map +1 -0
  807. package/dist/modules/hospitality_billing/screens/index.js +4 -0
  808. package/dist/modules/hospitality_billing/screens/index.js.map +1 -0
  809. package/dist/modules/hospitality_billing/screens/page-frame.d.ts +14 -0
  810. package/dist/modules/hospitality_billing/screens/page-frame.d.ts.map +1 -0
  811. package/dist/modules/hospitality_billing/screens/page-frame.js +6 -0
  812. package/dist/modules/hospitality_billing/screens/page-frame.js.map +1 -0
  813. package/dist/modules/hospitality_billing/screens/shared.d.ts +64 -0
  814. package/dist/modules/hospitality_billing/screens/shared.d.ts.map +1 -0
  815. package/dist/modules/hospitality_billing/screens/shared.js +117 -0
  816. package/dist/modules/hospitality_billing/screens/shared.js.map +1 -0
  817. package/dist/modules/hospitality_core/calendar.d.ts.map +1 -1
  818. package/dist/modules/hospitality_core/calendar.js +2 -1
  819. package/dist/modules/hospitality_core/calendar.js.map +1 -1
  820. package/dist/modules/hospitality_core/functions.d.ts.map +1 -1
  821. package/dist/modules/hospitality_core/functions.js +114 -14
  822. package/dist/modules/hospitality_core/functions.js.map +1 -1
  823. package/dist/modules/hospitality_core/index.d.ts +2 -2
  824. package/dist/modules/hospitality_core/index.d.ts.map +1 -1
  825. package/dist/modules/hospitality_core/index.js +3 -2
  826. package/dist/modules/hospitality_core/index.js.map +1 -1
  827. package/dist/modules/hospitality_core/inventory.d.ts +53 -4
  828. package/dist/modules/hospitality_core/inventory.d.ts.map +1 -1
  829. package/dist/modules/hospitality_core/inventory.js +121 -14
  830. package/dist/modules/hospitality_core/inventory.js.map +1 -1
  831. package/dist/modules/hospitality_core/menus.d.ts.map +1 -1
  832. package/dist/modules/hospitality_core/menus.js +31 -0
  833. package/dist/modules/hospitality_core/menus.js.map +1 -1
  834. package/dist/modules/hospitality_core/messages.d.ts.map +1 -1
  835. package/dist/modules/hospitality_core/messages.js +383 -183
  836. package/dist/modules/hospitality_core/messages.js.map +1 -1
  837. package/dist/modules/hospitality_core/models.d.ts +1 -1
  838. package/dist/modules/hospitality_core/models.d.ts.map +1 -1
  839. package/dist/modules/hospitality_core/models.js +47 -2
  840. package/dist/modules/hospitality_core/models.js.map +1 -1
  841. package/dist/modules/hospitality_core/night-audit.d.ts +1 -0
  842. package/dist/modules/hospitality_core/night-audit.d.ts.map +1 -1
  843. package/dist/modules/hospitality_core/night-audit.js +39 -1
  844. package/dist/modules/hospitality_core/night-audit.js.map +1 -1
  845. package/dist/modules/hospitality_core/online-booking.d.ts +5 -0
  846. package/dist/modules/hospitality_core/online-booking.d.ts.map +1 -0
  847. package/dist/modules/hospitality_core/online-booking.js +775 -0
  848. package/dist/modules/hospitality_core/online-booking.js.map +1 -0
  849. package/dist/modules/hospitality_core/operations.d.ts +21 -1
  850. package/dist/modules/hospitality_core/operations.d.ts.map +1 -1
  851. package/dist/modules/hospitality_core/operations.js +432 -67
  852. package/dist/modules/hospitality_core/operations.js.map +1 -1
  853. package/dist/modules/hospitality_core/routes.d.ts.map +1 -1
  854. package/dist/modules/hospitality_core/routes.js +503 -106
  855. package/dist/modules/hospitality_core/routes.js.map +1 -1
  856. package/dist/modules/hospitality_core/screens/amenities.d.ts +10 -0
  857. package/dist/modules/hospitality_core/screens/amenities.d.ts.map +1 -0
  858. package/dist/modules/hospitality_core/screens/amenities.js +65 -0
  859. package/dist/modules/hospitality_core/screens/amenities.js.map +1 -0
  860. package/dist/modules/hospitality_core/screens/building-detail.d.ts +3 -0
  861. package/dist/modules/hospitality_core/screens/building-detail.d.ts.map +1 -0
  862. package/dist/modules/hospitality_core/screens/building-detail.js +69 -0
  863. package/dist/modules/hospitality_core/screens/building-detail.js.map +1 -0
  864. package/dist/modules/hospitality_core/screens/cleaning-task-detail.d.ts +7 -0
  865. package/dist/modules/hospitality_core/screens/cleaning-task-detail.d.ts.map +1 -0
  866. package/dist/modules/hospitality_core/screens/cleaning-task-detail.js +109 -0
  867. package/dist/modules/hospitality_core/screens/cleaning-task-detail.js.map +1 -0
  868. package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts +20 -0
  869. package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts.map +1 -0
  870. package/dist/modules/hospitality_core/screens/cleaning-tasks.js +139 -0
  871. package/dist/modules/hospitality_core/screens/cleaning-tasks.js.map +1 -0
  872. package/dist/modules/hospitality_core/screens/content.d.ts +3 -0
  873. package/dist/modules/hospitality_core/screens/content.d.ts.map +1 -0
  874. package/dist/modules/hospitality_core/screens/content.js +114 -0
  875. package/dist/modules/hospitality_core/screens/content.js.map +1 -0
  876. package/dist/modules/hospitality_core/screens/floor-detail.d.ts +3 -0
  877. package/dist/modules/hospitality_core/screens/floor-detail.d.ts.map +1 -0
  878. package/dist/modules/hospitality_core/screens/floor-detail.js +74 -0
  879. package/dist/modules/hospitality_core/screens/floor-detail.js.map +1 -0
  880. package/dist/modules/hospitality_core/screens/folio-detail.d.ts +3 -0
  881. package/dist/modules/hospitality_core/screens/folio-detail.d.ts.map +1 -0
  882. package/dist/modules/hospitality_core/screens/folio-detail.js +142 -0
  883. package/dist/modules/hospitality_core/screens/folio-detail.js.map +1 -0
  884. package/dist/modules/hospitality_core/screens/folios.d.ts +3 -0
  885. package/dist/modules/hospitality_core/screens/folios.d.ts.map +1 -0
  886. package/dist/modules/hospitality_core/screens/folios.js +7 -0
  887. package/dist/modules/hospitality_core/screens/folios.js.map +1 -0
  888. package/dist/modules/hospitality_core/screens/front-desk.d.ts +35 -0
  889. package/dist/modules/hospitality_core/screens/front-desk.d.ts.map +1 -0
  890. package/dist/modules/hospitality_core/screens/front-desk.js +195 -0
  891. package/dist/modules/hospitality_core/screens/front-desk.js.map +1 -0
  892. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.d.ts +3 -0
  893. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.d.ts.map +1 -0
  894. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.js +121 -0
  895. package/dist/modules/hospitality_core/screens/housekeeping-room-detail.js.map +1 -0
  896. package/dist/modules/hospitality_core/screens/housekeeping-rooms.d.ts +9 -0
  897. package/dist/modules/hospitality_core/screens/housekeeping-rooms.d.ts.map +1 -0
  898. package/dist/modules/hospitality_core/screens/housekeeping-rooms.js +54 -0
  899. package/dist/modules/hospitality_core/screens/housekeeping-rooms.js.map +1 -0
  900. package/dist/modules/hospitality_core/screens/index.d.ts +33 -0
  901. package/dist/modules/hospitality_core/screens/index.d.ts.map +1 -0
  902. package/dist/modules/hospitality_core/screens/index.js +33 -0
  903. package/dist/modules/hospitality_core/screens/index.js.map +1 -0
  904. package/dist/modules/hospitality_core/screens/inventory.d.ts +8 -0
  905. package/dist/modules/hospitality_core/screens/inventory.d.ts.map +1 -0
  906. package/dist/modules/hospitality_core/screens/inventory.js +122 -0
  907. package/dist/modules/hospitality_core/screens/inventory.js.map +1 -0
  908. package/dist/modules/hospitality_core/screens/new-property.d.ts +3 -0
  909. package/dist/modules/hospitality_core/screens/new-property.d.ts.map +1 -0
  910. package/dist/modules/hospitality_core/screens/new-property.js +8 -0
  911. package/dist/modules/hospitality_core/screens/new-property.js.map +1 -0
  912. package/dist/modules/hospitality_core/screens/new-room-type.d.ts +3 -0
  913. package/dist/modules/hospitality_core/screens/new-room-type.d.ts.map +1 -0
  914. package/dist/modules/hospitality_core/screens/new-room-type.js +8 -0
  915. package/dist/modules/hospitality_core/screens/new-room-type.js.map +1 -0
  916. package/dist/modules/hospitality_core/screens/new-room.d.ts +3 -0
  917. package/dist/modules/hospitality_core/screens/new-room.d.ts.map +1 -0
  918. package/dist/modules/hospitality_core/screens/new-room.js +8 -0
  919. package/dist/modules/hospitality_core/screens/new-room.js.map +1 -0
  920. package/dist/modules/hospitality_core/screens/night-audit.d.ts +10 -0
  921. package/dist/modules/hospitality_core/screens/night-audit.d.ts.map +1 -0
  922. package/dist/modules/hospitality_core/screens/night-audit.js +67 -0
  923. package/dist/modules/hospitality_core/screens/night-audit.js.map +1 -0
  924. package/dist/modules/hospitality_core/screens/page-frame.d.ts +15 -0
  925. package/dist/modules/hospitality_core/screens/page-frame.d.ts.map +1 -0
  926. package/dist/modules/hospitality_core/screens/page-frame.js +10 -0
  927. package/dist/modules/hospitality_core/screens/page-frame.js.map +1 -0
  928. package/dist/modules/hospitality_core/screens/policies.d.ts +10 -0
  929. package/dist/modules/hospitality_core/screens/policies.d.ts.map +1 -0
  930. package/dist/modules/hospitality_core/screens/policies.js +72 -0
  931. package/dist/modules/hospitality_core/screens/policies.js.map +1 -0
  932. package/dist/modules/hospitality_core/screens/properties.d.ts +7 -0
  933. package/dist/modules/hospitality_core/screens/properties.d.ts.map +1 -0
  934. package/dist/modules/hospitality_core/screens/properties.js +45 -0
  935. package/dist/modules/hospitality_core/screens/properties.js.map +1 -0
  936. package/dist/modules/hospitality_core/screens/property-detail.d.ts +3 -0
  937. package/dist/modules/hospitality_core/screens/property-detail.d.ts.map +1 -0
  938. package/dist/modules/hospitality_core/screens/property-detail.js +92 -0
  939. package/dist/modules/hospitality_core/screens/property-detail.js.map +1 -0
  940. package/dist/modules/hospitality_core/screens/rate-plans.d.ts +10 -0
  941. package/dist/modules/hospitality_core/screens/rate-plans.d.ts.map +1 -0
  942. package/dist/modules/hospitality_core/screens/rate-plans.js +123 -0
  943. package/dist/modules/hospitality_core/screens/rate-plans.js.map +1 -0
  944. package/dist/modules/hospitality_core/screens/reservation-detail.d.ts +11 -0
  945. package/dist/modules/hospitality_core/screens/reservation-detail.d.ts.map +1 -0
  946. package/dist/modules/hospitality_core/screens/reservation-detail.js +237 -0
  947. package/dist/modules/hospitality_core/screens/reservation-detail.js.map +1 -0
  948. package/dist/modules/hospitality_core/screens/reservations.d.ts +17 -0
  949. package/dist/modules/hospitality_core/screens/reservations.d.ts.map +1 -0
  950. package/dist/modules/hospitality_core/screens/reservations.js +166 -0
  951. package/dist/modules/hospitality_core/screens/reservations.js.map +1 -0
  952. package/dist/modules/hospitality_core/screens/room-detail.d.ts +3 -0
  953. package/dist/modules/hospitality_core/screens/room-detail.d.ts.map +1 -0
  954. package/dist/modules/hospitality_core/screens/room-detail.js +75 -0
  955. package/dist/modules/hospitality_core/screens/room-detail.js.map +1 -0
  956. package/dist/modules/hospitality_core/screens/room-type-detail.d.ts +3 -0
  957. package/dist/modules/hospitality_core/screens/room-type-detail.d.ts.map +1 -0
  958. package/dist/modules/hospitality_core/screens/room-type-detail.js +91 -0
  959. package/dist/modules/hospitality_core/screens/room-type-detail.js.map +1 -0
  960. package/dist/modules/hospitality_core/screens/room-types.d.ts +3 -0
  961. package/dist/modules/hospitality_core/screens/room-types.d.ts.map +1 -0
  962. package/dist/modules/hospitality_core/screens/room-types.js +61 -0
  963. package/dist/modules/hospitality_core/screens/room-types.js.map +1 -0
  964. package/dist/modules/hospitality_core/screens/rooms.d.ts +10 -0
  965. package/dist/modules/hospitality_core/screens/rooms.d.ts.map +1 -0
  966. package/dist/modules/hospitality_core/screens/rooms.js +150 -0
  967. package/dist/modules/hospitality_core/screens/rooms.js.map +1 -0
  968. package/dist/modules/hospitality_core/screens/services.d.ts +18 -0
  969. package/dist/modules/hospitality_core/screens/services.d.ts.map +1 -0
  970. package/dist/modules/hospitality_core/screens/services.js +196 -0
  971. package/dist/modules/hospitality_core/screens/services.js.map +1 -0
  972. package/dist/modules/hospitality_core/screens/shared.d.ts +777 -0
  973. package/dist/modules/hospitality_core/screens/shared.d.ts.map +1 -0
  974. package/dist/modules/hospitality_core/screens/shared.js +1586 -0
  975. package/dist/modules/hospitality_core/screens/shared.js.map +1 -0
  976. package/dist/modules/hospitality_core/screens/stay-detail.d.ts +3 -0
  977. package/dist/modules/hospitality_core/screens/stay-detail.d.ts.map +1 -0
  978. package/dist/modules/hospitality_core/screens/stay-detail.js +233 -0
  979. package/dist/modules/hospitality_core/screens/stay-detail.js.map +1 -0
  980. package/dist/modules/hospitality_core/screens/stay-notices.d.ts +9 -0
  981. package/dist/modules/hospitality_core/screens/stay-notices.d.ts.map +1 -0
  982. package/dist/modules/hospitality_core/screens/stay-notices.js +87 -0
  983. package/dist/modules/hospitality_core/screens/stay-notices.js.map +1 -0
  984. package/dist/modules/hospitality_core/screens/stays.d.ts +3 -0
  985. package/dist/modules/hospitality_core/screens/stays.d.ts.map +1 -0
  986. package/dist/modules/hospitality_core/screens/stays.js +7 -0
  987. package/dist/modules/hospitality_core/screens/stays.js.map +1 -0
  988. package/dist/modules/hospitality_core/screens/tape-chart.d.ts +7 -0
  989. package/dist/modules/hospitality_core/screens/tape-chart.d.ts.map +1 -0
  990. package/dist/modules/hospitality_core/screens/tape-chart.js +99 -0
  991. package/dist/modules/hospitality_core/screens/tape-chart.js.map +1 -0
  992. package/dist/modules/hospitality_core/services.d.ts.map +1 -1
  993. package/dist/modules/hospitality_core/services.js +133 -30
  994. package/dist/modules/hospitality_core/services.js.map +1 -1
  995. package/dist/modules/hospitality_core/stay-notices.js +2 -2
  996. package/dist/modules/hospitality_core/stay-notices.js.map +1 -1
  997. package/dist/modules/hospitality_core/types.d.ts +26 -5
  998. package/dist/modules/hospitality_core/types.d.ts.map +1 -1
  999. package/dist/modules/hospitality_core/types.js +47 -5
  1000. package/dist/modules/hospitality_core/types.js.map +1 -1
  1001. package/dist/modules/hospitality_staff_channel/channel-routes.d.ts +2 -0
  1002. package/dist/modules/hospitality_staff_channel/channel-routes.d.ts.map +1 -0
  1003. package/dist/modules/hospitality_staff_channel/channel-routes.js +1227 -0
  1004. package/dist/modules/hospitality_staff_channel/channel-routes.js.map +1 -0
  1005. package/dist/modules/hospitality_staff_channel/index.d.ts +5 -0
  1006. package/dist/modules/hospitality_staff_channel/index.d.ts.map +1 -0
  1007. package/dist/modules/hospitality_staff_channel/index.js +34 -0
  1008. package/dist/modules/hospitality_staff_channel/index.js.map +1 -0
  1009. package/dist/modules/hr/functions.d.ts.map +1 -1
  1010. package/dist/modules/hr/functions.js +108 -44
  1011. package/dist/modules/hr/functions.js.map +1 -1
  1012. package/dist/modules/hr/index.d.ts.map +1 -1
  1013. package/dist/modules/hr/index.js +0 -1
  1014. package/dist/modules/hr/index.js.map +1 -1
  1015. package/dist/modules/hr_backend/index.d.ts +2 -1
  1016. package/dist/modules/hr_backend/index.d.ts.map +1 -1
  1017. package/dist/modules/hr_backend/index.js +39 -7
  1018. package/dist/modules/hr_backend/index.js.map +1 -1
  1019. package/dist/modules/hr_backend/routes.d.ts.map +1 -1
  1020. package/dist/modules/hr_backend/routes.js +279 -42
  1021. package/dist/modules/hr_backend/routes.js.map +1 -1
  1022. package/dist/modules/hr_backend/screens/employee-form.d.ts +28 -0
  1023. package/dist/modules/hr_backend/screens/employee-form.d.ts.map +1 -0
  1024. package/dist/modules/hr_backend/screens/employee-form.js +110 -0
  1025. package/dist/modules/hr_backend/screens/employee-form.js.map +1 -0
  1026. package/dist/modules/hr_backend/screens/employees-list.d.ts +22 -0
  1027. package/dist/modules/hr_backend/screens/employees-list.d.ts.map +1 -0
  1028. package/dist/modules/hr_backend/screens/employees-list.js +53 -0
  1029. package/dist/modules/hr_backend/screens/employees-list.js.map +1 -0
  1030. package/dist/modules/hr_backend/screens/index.d.ts +5 -0
  1031. package/dist/modules/hr_backend/screens/index.d.ts.map +1 -0
  1032. package/dist/modules/hr_backend/screens/index.js +5 -0
  1033. package/dist/modules/hr_backend/screens/index.js.map +1 -0
  1034. package/dist/modules/hr_backend/screens/leaves-list.d.ts +22 -0
  1035. package/dist/modules/hr_backend/screens/leaves-list.d.ts.map +1 -0
  1036. package/dist/modules/hr_backend/screens/leaves-list.js +78 -0
  1037. package/dist/modules/hr_backend/screens/leaves-list.js.map +1 -0
  1038. package/dist/modules/hr_backend/screens/roster.d.ts +19 -0
  1039. package/dist/modules/hr_backend/screens/roster.d.ts.map +1 -0
  1040. package/dist/modules/hr_backend/screens/roster.js +83 -0
  1041. package/dist/modules/hr_backend/screens/roster.js.map +1 -0
  1042. package/dist/modules/inventory_staff_channel/channel-routes.d.ts +2 -0
  1043. package/dist/modules/inventory_staff_channel/channel-routes.d.ts.map +1 -0
  1044. package/dist/modules/inventory_staff_channel/channel-routes.js +724 -0
  1045. package/dist/modules/inventory_staff_channel/channel-routes.js.map +1 -0
  1046. package/dist/modules/inventory_staff_channel/index.d.ts +5 -0
  1047. package/dist/modules/inventory_staff_channel/index.d.ts.map +1 -0
  1048. package/dist/modules/inventory_staff_channel/index.js +38 -0
  1049. package/dist/modules/inventory_staff_channel/index.js.map +1 -0
  1050. package/dist/modules/livedoc/documents.d.ts +48 -0
  1051. package/dist/modules/livedoc/documents.d.ts.map +1 -0
  1052. package/dist/modules/livedoc/documents.js +99 -0
  1053. package/dist/modules/livedoc/documents.js.map +1 -0
  1054. package/dist/modules/livedoc/functions.d.ts +3 -0
  1055. package/dist/modules/livedoc/functions.d.ts.map +1 -0
  1056. package/dist/modules/livedoc/functions.js +47 -0
  1057. package/dist/modules/livedoc/functions.js.map +1 -0
  1058. package/dist/modules/livedoc/index.d.ts +22 -0
  1059. package/dist/modules/livedoc/index.d.ts.map +1 -0
  1060. package/dist/modules/livedoc/index.js +37 -0
  1061. package/dist/modules/livedoc/index.js.map +1 -0
  1062. package/dist/modules/livedoc/islands.d.ts +3 -0
  1063. package/dist/modules/livedoc/islands.d.ts.map +1 -0
  1064. package/dist/modules/livedoc/islands.js +22 -0
  1065. package/dist/modules/livedoc/islands.js.map +1 -0
  1066. package/dist/modules/livedoc/routes.d.ts +11 -0
  1067. package/dist/modules/livedoc/routes.d.ts.map +1 -0
  1068. package/dist/modules/livedoc/routes.js +232 -0
  1069. package/dist/modules/livedoc/routes.js.map +1 -0
  1070. package/dist/modules/livedoc/sync.d.ts +124 -0
  1071. package/dist/modules/livedoc/sync.d.ts.map +1 -0
  1072. package/dist/modules/livedoc/sync.js +218 -0
  1073. package/dist/modules/livedoc/sync.js.map +1 -0
  1074. package/dist/modules/loyalty/admin-functions.d.ts.map +1 -1
  1075. package/dist/modules/loyalty/admin-functions.js +42 -6
  1076. package/dist/modules/loyalty/admin-functions.js.map +1 -1
  1077. package/dist/modules/loyalty/engine.d.ts +1 -0
  1078. package/dist/modules/loyalty/engine.d.ts.map +1 -1
  1079. package/dist/modules/loyalty/engine.js +88 -28
  1080. package/dist/modules/loyalty/engine.js.map +1 -1
  1081. package/dist/modules/loyalty/index.d.ts.map +1 -1
  1082. package/dist/modules/loyalty/index.js +10 -2
  1083. package/dist/modules/loyalty/index.js.map +1 -1
  1084. package/dist/modules/loyalty/ledger.d.ts.map +1 -1
  1085. package/dist/modules/loyalty/ledger.js +11 -0
  1086. package/dist/modules/loyalty/ledger.js.map +1 -1
  1087. package/dist/modules/loyalty/membership-functions.d.ts.map +1 -1
  1088. package/dist/modules/loyalty/membership-functions.js +23 -7
  1089. package/dist/modules/loyalty/membership-functions.js.map +1 -1
  1090. package/dist/modules/loyalty/messages.d.ts +8 -0
  1091. package/dist/modules/loyalty/messages.d.ts.map +1 -1
  1092. package/dist/modules/loyalty/messages.js +8 -0
  1093. package/dist/modules/loyalty/messages.js.map +1 -1
  1094. package/dist/modules/loyalty/models.d.ts.map +1 -1
  1095. package/dist/modules/loyalty/models.js +20 -0
  1096. package/dist/modules/loyalty/models.js.map +1 -1
  1097. package/dist/modules/loyalty/order-functions.d.ts +16 -1
  1098. package/dist/modules/loyalty/order-functions.d.ts.map +1 -1
  1099. package/dist/modules/loyalty/order-functions.js +513 -291
  1100. package/dist/modules/loyalty/order-functions.js.map +1 -1
  1101. package/dist/modules/loyalty/stats.d.ts +17 -0
  1102. package/dist/modules/loyalty/stats.d.ts.map +1 -0
  1103. package/dist/modules/loyalty/stats.js +178 -0
  1104. package/dist/modules/loyalty/stats.js.map +1 -0
  1105. package/dist/modules/loyalty/stored-value.d.ts +42 -0
  1106. package/dist/modules/loyalty/stored-value.d.ts.map +1 -0
  1107. package/dist/modules/loyalty/stored-value.js +368 -0
  1108. package/dist/modules/loyalty/stored-value.js.map +1 -0
  1109. package/dist/modules/loyalty/types.d.ts +6 -4
  1110. package/dist/modules/loyalty/types.d.ts.map +1 -1
  1111. package/dist/modules/loyalty/types.js +1 -1
  1112. package/dist/modules/loyalty/types.js.map +1 -1
  1113. package/dist/modules/loyalty_backend/index.js +443 -172
  1114. package/dist/modules/loyalty_backend/index.js.map +1 -1
  1115. package/dist/modules/loyalty_backend/messages.d.ts +58 -1
  1116. package/dist/modules/loyalty_backend/messages.d.ts.map +1 -1
  1117. package/dist/modules/loyalty_backend/messages.js +114 -0
  1118. package/dist/modules/loyalty_backend/messages.js.map +1 -1
  1119. package/dist/modules/loyalty_backend/screens/index.d.ts +90 -0
  1120. package/dist/modules/loyalty_backend/screens/index.d.ts.map +1 -0
  1121. package/dist/modules/loyalty_backend/screens/index.js +912 -0
  1122. package/dist/modules/loyalty_backend/screens/index.js.map +1 -0
  1123. package/dist/modules/loyalty_backend/screens/page-frame.d.ts +14 -0
  1124. package/dist/modules/loyalty_backend/screens/page-frame.d.ts.map +1 -0
  1125. package/dist/modules/loyalty_backend/screens/page-frame.js +13 -0
  1126. package/dist/modules/loyalty_backend/screens/page-frame.js.map +1 -0
  1127. package/dist/modules/loyalty_pos/channel.d.ts +2 -0
  1128. package/dist/modules/loyalty_pos/channel.d.ts.map +1 -0
  1129. package/dist/modules/loyalty_pos/channel.js +270 -0
  1130. package/dist/modules/loyalty_pos/channel.js.map +1 -0
  1131. package/dist/modules/loyalty_pos/functions.d.ts +11 -17
  1132. package/dist/modules/loyalty_pos/functions.d.ts.map +1 -1
  1133. package/dist/modules/loyalty_pos/functions.js +454 -94
  1134. package/dist/modules/loyalty_pos/functions.js.map +1 -1
  1135. package/dist/modules/loyalty_pos/index.js +6 -16
  1136. package/dist/modules/loyalty_pos/index.js.map +1 -1
  1137. package/dist/modules/loyalty_pos/jobs.d.ts +3 -0
  1138. package/dist/modules/loyalty_pos/jobs.d.ts.map +1 -0
  1139. package/dist/modules/loyalty_pos/jobs.js +30 -0
  1140. package/dist/modules/loyalty_pos/jobs.js.map +1 -0
  1141. package/dist/modules/loyalty_sale/functions.d.ts +2 -2
  1142. package/dist/modules/loyalty_sale/functions.d.ts.map +1 -1
  1143. package/dist/modules/loyalty_sale/functions.js +53 -34
  1144. package/dist/modules/loyalty_sale/functions.js.map +1 -1
  1145. package/dist/modules/loyalty_sale/index.js +0 -2
  1146. package/dist/modules/loyalty_sale/index.js.map +1 -1
  1147. package/dist/modules/mail/functions.d.ts.map +1 -1
  1148. package/dist/modules/mail/functions.js +48 -6
  1149. package/dist/modules/mail/functions.js.map +1 -1
  1150. package/dist/modules/mail/index.d.ts.map +1 -1
  1151. package/dist/modules/mail/index.js +0 -1
  1152. package/dist/modules/mail/index.js.map +1 -1
  1153. package/dist/modules/mail/operations.d.ts +19 -0
  1154. package/dist/modules/mail/operations.d.ts.map +1 -1
  1155. package/dist/modules/mail/operations.js +69 -0
  1156. package/dist/modules/mail/operations.js.map +1 -1
  1157. package/dist/modules/mail_backend/index.d.ts +1 -1
  1158. package/dist/modules/mail_backend/index.d.ts.map +1 -1
  1159. package/dist/modules/mail_backend/index.js +5 -14
  1160. package/dist/modules/mail_backend/index.js.map +1 -1
  1161. package/dist/modules/mail_backend/islands.js +2 -2
  1162. package/dist/modules/mail_backend/islands.js.map +1 -1
  1163. package/dist/modules/mail_backend/routes.d.ts.map +1 -1
  1164. package/dist/modules/mail_backend/routes.js +25 -20
  1165. package/dist/modules/mail_backend/routes.js.map +1 -1
  1166. package/dist/modules/mail_backend/screens/inbox-list.d.ts +9 -0
  1167. package/dist/modules/mail_backend/screens/inbox-list.d.ts.map +1 -0
  1168. package/dist/modules/mail_backend/screens/inbox-list.js +13 -0
  1169. package/dist/modules/mail_backend/screens/inbox-list.js.map +1 -0
  1170. package/dist/modules/mail_backend/screens/index.d.ts +3 -0
  1171. package/dist/modules/mail_backend/screens/index.d.ts.map +1 -0
  1172. package/dist/modules/mail_backend/screens/index.js +2 -0
  1173. package/dist/modules/mail_backend/screens/index.js.map +1 -0
  1174. package/dist/modules/mail_inbound/index.d.ts.map +1 -1
  1175. package/dist/modules/mail_inbound/index.js +0 -1
  1176. package/dist/modules/mail_inbound/index.js.map +1 -1
  1177. package/dist/modules/mail_inbound_backend/index.d.ts +1 -1
  1178. package/dist/modules/mail_inbound_backend/index.d.ts.map +1 -1
  1179. package/dist/modules/mail_inbound_backend/index.js +3 -12
  1180. package/dist/modules/mail_inbound_backend/index.js.map +1 -1
  1181. package/dist/modules/mail_inbound_backend/routes.d.ts.map +1 -1
  1182. package/dist/modules/mail_inbound_backend/routes.js +6 -21
  1183. package/dist/modules/mail_inbound_backend/routes.js.map +1 -1
  1184. package/dist/modules/mail_inbound_backend/screens/inbound-list.d.ts +8 -0
  1185. package/dist/modules/mail_inbound_backend/screens/inbound-list.d.ts.map +1 -0
  1186. package/dist/modules/mail_inbound_backend/screens/inbound-list.js +20 -0
  1187. package/dist/modules/mail_inbound_backend/screens/inbound-list.js.map +1 -0
  1188. package/dist/modules/mail_inbound_backend/screens/index.d.ts +3 -0
  1189. package/dist/modules/mail_inbound_backend/screens/index.d.ts.map +1 -0
  1190. package/dist/modules/mail_inbound_backend/screens/index.js +2 -0
  1191. package/dist/modules/mail_inbound_backend/screens/index.js.map +1 -0
  1192. package/dist/modules/mail_staff_channel/channel-routes.d.ts +2 -0
  1193. package/dist/modules/mail_staff_channel/channel-routes.d.ts.map +1 -0
  1194. package/dist/modules/mail_staff_channel/channel-routes.js +183 -0
  1195. package/dist/modules/mail_staff_channel/channel-routes.js.map +1 -0
  1196. package/dist/modules/mail_staff_channel/index.d.ts +5 -0
  1197. package/dist/modules/mail_staff_channel/index.d.ts.map +1 -0
  1198. package/dist/modules/mail_staff_channel/index.js +28 -0
  1199. package/dist/modules/mail_staff_channel/index.js.map +1 -0
  1200. package/dist/modules/mail_transport/index.d.ts.map +1 -1
  1201. package/dist/modules/mail_transport/index.js +0 -1
  1202. package/dist/modules/mail_transport/index.js.map +1 -1
  1203. package/dist/modules/mail_transport_backend/index.d.ts +1 -1
  1204. package/dist/modules/mail_transport_backend/index.d.ts.map +1 -1
  1205. package/dist/modules/mail_transport_backend/index.js +3 -12
  1206. package/dist/modules/mail_transport_backend/index.js.map +1 -1
  1207. package/dist/modules/mail_transport_backend/routes.d.ts.map +1 -1
  1208. package/dist/modules/mail_transport_backend/routes.js +23 -22
  1209. package/dist/modules/mail_transport_backend/routes.js.map +1 -1
  1210. package/dist/modules/mail_transport_backend/screens/index.d.ts +3 -0
  1211. package/dist/modules/mail_transport_backend/screens/index.d.ts.map +1 -0
  1212. package/dist/modules/mail_transport_backend/screens/index.js +2 -0
  1213. package/dist/modules/mail_transport_backend/screens/index.js.map +1 -0
  1214. package/dist/modules/mail_transport_backend/screens/outbox-list.d.ts +9 -0
  1215. package/dist/modules/mail_transport_backend/screens/outbox-list.d.ts.map +1 -0
  1216. package/dist/modules/mail_transport_backend/screens/outbox-list.js +29 -0
  1217. package/dist/modules/mail_transport_backend/screens/outbox-list.js.map +1 -0
  1218. package/dist/modules/manufacturing/functions.d.ts +3 -0
  1219. package/dist/modules/manufacturing/functions.d.ts.map +1 -0
  1220. package/dist/modules/manufacturing/functions.js +912 -0
  1221. package/dist/modules/manufacturing/functions.js.map +1 -0
  1222. package/dist/modules/manufacturing/index.d.ts +6 -0
  1223. package/dist/modules/manufacturing/index.d.ts.map +1 -0
  1224. package/dist/modules/manufacturing/index.js +42 -0
  1225. package/dist/modules/manufacturing/index.js.map +1 -0
  1226. package/dist/modules/manufacturing/models.d.ts +8 -0
  1227. package/dist/modules/manufacturing/models.d.ts.map +1 -0
  1228. package/dist/modules/manufacturing/models.js +145 -0
  1229. package/dist/modules/manufacturing/models.js.map +1 -0
  1230. package/dist/modules/manufacturing/relations.d.ts.map +1 -0
  1231. package/dist/modules/manufacturing/relations.js +37 -0
  1232. package/dist/modules/manufacturing/relations.js.map +1 -0
  1233. package/dist/modules/manufacturing/types.d.ts +7 -0
  1234. package/dist/modules/manufacturing/types.d.ts.map +1 -0
  1235. package/dist/modules/manufacturing/types.js +11 -0
  1236. package/dist/modules/manufacturing/types.js.map +1 -0
  1237. package/dist/modules/manufacturing_backend/index.d.ts +5 -0
  1238. package/dist/modules/manufacturing_backend/index.d.ts.map +1 -0
  1239. package/dist/modules/manufacturing_backend/index.js +146 -0
  1240. package/dist/modules/manufacturing_backend/index.js.map +1 -0
  1241. package/dist/modules/manufacturing_backend/routes.d.ts +3 -0
  1242. package/dist/modules/manufacturing_backend/routes.d.ts.map +1 -0
  1243. package/dist/modules/manufacturing_backend/routes.js +477 -0
  1244. package/dist/modules/manufacturing_backend/routes.js.map +1 -0
  1245. package/dist/modules/manufacturing_backend/screens/bom-create.d.ts +15 -0
  1246. package/dist/modules/manufacturing_backend/screens/bom-create.d.ts.map +1 -0
  1247. package/dist/modules/manufacturing_backend/screens/bom-create.js +39 -0
  1248. package/dist/modules/manufacturing_backend/screens/bom-create.js.map +1 -0
  1249. package/dist/modules/manufacturing_backend/screens/boms-list.d.ts +18 -0
  1250. package/dist/modules/manufacturing_backend/screens/boms-list.d.ts.map +1 -0
  1251. package/dist/modules/manufacturing_backend/screens/boms-list.js +36 -0
  1252. package/dist/modules/manufacturing_backend/screens/boms-list.js.map +1 -0
  1253. package/dist/modules/manufacturing_backend/screens/index.d.ts +8 -0
  1254. package/dist/modules/manufacturing_backend/screens/index.d.ts.map +1 -0
  1255. package/dist/modules/manufacturing_backend/screens/index.js +8 -0
  1256. package/dist/modules/manufacturing_backend/screens/index.js.map +1 -0
  1257. package/dist/modules/manufacturing_backend/screens/order-create.d.ts +13 -0
  1258. package/dist/modules/manufacturing_backend/screens/order-create.d.ts.map +1 -0
  1259. package/dist/modules/manufacturing_backend/screens/order-create.js +20 -0
  1260. package/dist/modules/manufacturing_backend/screens/order-create.js.map +1 -0
  1261. package/dist/modules/manufacturing_backend/screens/order-execution.d.ts +7 -0
  1262. package/dist/modules/manufacturing_backend/screens/order-execution.d.ts.map +1 -0
  1263. package/dist/modules/manufacturing_backend/screens/order-execution.js +129 -0
  1264. package/dist/modules/manufacturing_backend/screens/order-execution.js.map +1 -0
  1265. package/dist/modules/manufacturing_backend/screens/orders-list.d.ts +21 -0
  1266. package/dist/modules/manufacturing_backend/screens/orders-list.d.ts.map +1 -0
  1267. package/dist/modules/manufacturing_backend/screens/orders-list.js +49 -0
  1268. package/dist/modules/manufacturing_backend/screens/orders-list.js.map +1 -0
  1269. package/dist/modules/manufacturing_backend/screens/work-center-form.d.ts +24 -0
  1270. package/dist/modules/manufacturing_backend/screens/work-center-form.d.ts.map +1 -0
  1271. package/dist/modules/manufacturing_backend/screens/work-center-form.js +80 -0
  1272. package/dist/modules/manufacturing_backend/screens/work-center-form.js.map +1 -0
  1273. package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts +23 -0
  1274. package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts.map +1 -0
  1275. package/dist/modules/manufacturing_backend/screens/work-centers-list.js +61 -0
  1276. package/dist/modules/manufacturing_backend/screens/work-centers-list.js.map +1 -0
  1277. package/dist/modules/oauth/index.d.ts.map +1 -1
  1278. package/dist/modules/oauth/index.js +0 -1
  1279. package/dist/modules/oauth/index.js.map +1 -1
  1280. package/dist/modules/oauth/models.d.ts.map +1 -1
  1281. package/dist/modules/oauth/models.js +2 -1
  1282. package/dist/modules/oauth/models.js.map +1 -1
  1283. package/dist/modules/oauth_backend/index.d.ts +1 -1
  1284. package/dist/modules/oauth_backend/index.d.ts.map +1 -1
  1285. package/dist/modules/oauth_backend/index.js +3 -5
  1286. package/dist/modules/oauth_backend/index.js.map +1 -1
  1287. package/dist/modules/oauth_backend/messages.d.ts +4 -0
  1288. package/dist/modules/oauth_backend/messages.d.ts.map +1 -1
  1289. package/dist/modules/oauth_backend/messages.js +4 -0
  1290. package/dist/modules/oauth_backend/messages.js.map +1 -1
  1291. package/dist/modules/oauth_backend/routes.d.ts.map +1 -1
  1292. package/dist/modules/oauth_backend/routes.js +28 -30
  1293. package/dist/modules/oauth_backend/routes.js.map +1 -1
  1294. package/dist/modules/oauth_backend/screens/index.d.ts +66 -0
  1295. package/dist/modules/oauth_backend/screens/index.d.ts.map +1 -0
  1296. package/dist/modules/oauth_backend/screens/index.js +306 -0
  1297. package/dist/modules/oauth_backend/screens/index.js.map +1 -0
  1298. package/dist/modules/partner/functions.d.ts.map +1 -1
  1299. package/dist/modules/partner/functions.js +74 -6
  1300. package/dist/modules/partner/functions.js.map +1 -1
  1301. package/dist/modules/partner/index.d.ts.map +1 -1
  1302. package/dist/modules/partner/index.js +0 -1
  1303. package/dist/modules/partner/index.js.map +1 -1
  1304. package/dist/modules/partner/models.d.ts +4 -4
  1305. package/dist/modules/partner/models.d.ts.map +1 -1
  1306. package/dist/modules/partner/models.js +9 -7
  1307. package/dist/modules/partner/models.js.map +1 -1
  1308. package/dist/modules/partner/types.d.ts +2 -2
  1309. package/dist/modules/partner/types.js +2 -2
  1310. package/dist/modules/partner_backend/client/address-view.mjs +5 -5
  1311. package/dist/modules/partner_backend/client/address-view.mjs.map +1 -1
  1312. package/dist/modules/partner_backend/client/address.css +22 -10
  1313. package/dist/modules/partner_backend/client/partner.css +116 -0
  1314. package/dist/modules/partner_backend/index.d.ts +1 -1
  1315. package/dist/modules/partner_backend/index.d.ts.map +1 -1
  1316. package/dist/modules/partner_backend/index.js +34 -4
  1317. package/dist/modules/partner_backend/index.js.map +1 -1
  1318. package/dist/modules/partner_backend/menus.js +2 -2
  1319. package/dist/modules/partner_backend/menus.js.map +1 -1
  1320. package/dist/modules/partner_backend/routes.d.ts +3 -1
  1321. package/dist/modules/partner_backend/routes.d.ts.map +1 -1
  1322. package/dist/modules/partner_backend/routes.js +236 -91
  1323. package/dist/modules/partner_backend/routes.js.map +1 -1
  1324. package/dist/modules/partner_backend/screens/form.d.ts +21 -0
  1325. package/dist/modules/partner_backend/screens/form.d.ts.map +1 -0
  1326. package/dist/modules/partner_backend/screens/form.js +101 -0
  1327. package/dist/modules/partner_backend/screens/form.js.map +1 -0
  1328. package/dist/modules/partner_backend/screens/index.d.ts +5 -0
  1329. package/dist/modules/partner_backend/screens/index.d.ts.map +1 -0
  1330. package/dist/modules/partner_backend/screens/index.js +4 -0
  1331. package/dist/modules/partner_backend/screens/index.js.map +1 -0
  1332. package/dist/modules/partner_backend/screens/list.d.ts +6 -0
  1333. package/dist/modules/partner_backend/screens/list.d.ts.map +1 -0
  1334. package/dist/modules/partner_backend/screens/list.js +94 -0
  1335. package/dist/modules/partner_backend/screens/list.js.map +1 -0
  1336. package/dist/modules/partner_backend/screens/new.d.ts +5 -0
  1337. package/dist/modules/partner_backend/screens/new.d.ts.map +1 -0
  1338. package/dist/modules/partner_backend/screens/new.js +58 -0
  1339. package/dist/modules/partner_backend/screens/new.js.map +1 -0
  1340. package/dist/modules/partner_backend/screens/types.d.ts +44 -0
  1341. package/dist/modules/partner_backend/screens/types.d.ts.map +1 -0
  1342. package/dist/modules/partner_backend/screens/types.js +2 -0
  1343. package/dist/modules/partner_backend/screens/types.js.map +1 -0
  1344. package/dist/modules/partner_mail_backend/index.d.ts +5 -0
  1345. package/dist/modules/partner_mail_backend/index.d.ts.map +1 -0
  1346. package/dist/modules/partner_mail_backend/index.js +29 -0
  1347. package/dist/modules/partner_mail_backend/index.js.map +1 -0
  1348. package/dist/modules/pos/functions.d.ts +18 -2
  1349. package/dist/modules/pos/functions.d.ts.map +1 -1
  1350. package/dist/modules/pos/functions.js +3279 -345
  1351. package/dist/modules/pos/functions.js.map +1 -1
  1352. package/dist/modules/pos/index.d.ts +2 -1
  1353. package/dist/modules/pos/index.d.ts.map +1 -1
  1354. package/dist/modules/pos/index.js +5 -5
  1355. package/dist/modules/pos/index.js.map +1 -1
  1356. package/dist/modules/pos/models.d.ts.map +1 -1
  1357. package/dist/modules/pos/models.js +189 -1
  1358. package/dist/modules/pos/models.js.map +1 -1
  1359. package/dist/modules/pos/relations.d.ts.map +1 -1
  1360. package/dist/modules/pos/relations.js +11 -0
  1361. package/dist/modules/pos/relations.js.map +1 -1
  1362. package/dist/modules/pos_backend/index.js +182 -154
  1363. package/dist/modules/pos_backend/index.js.map +1 -1
  1364. package/dist/modules/pos_backend/screens.d.ts +1 -0
  1365. package/dist/modules/pos_backend/screens.d.ts.map +1 -1
  1366. package/dist/modules/pos_backend/screens.js +28 -38
  1367. package/dist/modules/pos_backend/screens.js.map +1 -1
  1368. package/dist/modules/pos_channel/catalog.d.ts +27 -0
  1369. package/dist/modules/pos_channel/catalog.d.ts.map +1 -0
  1370. package/dist/modules/pos_channel/catalog.js +310 -0
  1371. package/dist/modules/pos_channel/catalog.js.map +1 -0
  1372. package/dist/modules/pos_channel/index.d.ts +7 -0
  1373. package/dist/modules/pos_channel/index.d.ts.map +1 -0
  1374. package/dist/modules/pos_channel/index.js +61 -0
  1375. package/dist/modules/pos_channel/index.js.map +1 -0
  1376. package/dist/modules/pos_channel/offline.d.ts +66 -0
  1377. package/dist/modules/pos_channel/offline.d.ts.map +1 -0
  1378. package/dist/modules/pos_channel/offline.js +16 -0
  1379. package/dist/modules/pos_channel/offline.js.map +1 -0
  1380. package/dist/modules/pos_channel/operations.d.ts +422 -0
  1381. package/dist/modules/pos_channel/operations.d.ts.map +1 -0
  1382. package/dist/modules/pos_channel/operations.js +1781 -0
  1383. package/dist/modules/pos_channel/operations.js.map +1 -0
  1384. package/dist/modules/pos_channel/sync.d.ts +6 -0
  1385. package/dist/modules/pos_channel/sync.d.ts.map +1 -0
  1386. package/dist/modules/pos_channel/sync.js +1161 -0
  1387. package/dist/modules/pos_channel/sync.js.map +1 -0
  1388. package/dist/modules/pricing/index.d.ts.map +1 -1
  1389. package/dist/modules/pricing/index.js +3 -4
  1390. package/dist/modules/pricing/index.js.map +1 -1
  1391. package/dist/modules/pricing_backend/index.js +135 -78
  1392. package/dist/modules/pricing_backend/index.js.map +1 -1
  1393. package/dist/modules/pricing_backend/screens/index.d.ts +5 -0
  1394. package/dist/modules/pricing_backend/screens/index.d.ts.map +1 -0
  1395. package/dist/modules/pricing_backend/screens/index.js +4 -0
  1396. package/dist/modules/pricing_backend/screens/index.js.map +1 -0
  1397. package/dist/modules/pricing_backend/screens/pricelist-create.d.ts +10 -0
  1398. package/dist/modules/pricing_backend/screens/pricelist-create.d.ts.map +1 -0
  1399. package/dist/modules/pricing_backend/screens/pricelist-create.js +30 -0
  1400. package/dist/modules/pricing_backend/screens/pricelist-create.js.map +1 -0
  1401. package/dist/modules/pricing_backend/screens/pricelist-detail.d.ts +15 -0
  1402. package/dist/modules/pricing_backend/screens/pricelist-detail.d.ts.map +1 -0
  1403. package/dist/modules/pricing_backend/screens/pricelist-detail.js +164 -0
  1404. package/dist/modules/pricing_backend/screens/pricelist-detail.js.map +1 -0
  1405. package/dist/modules/pricing_backend/screens/pricelists-list.d.ts +11 -0
  1406. package/dist/modules/pricing_backend/screens/pricelists-list.d.ts.map +1 -0
  1407. package/dist/modules/pricing_backend/screens/pricelists-list.js +27 -0
  1408. package/dist/modules/pricing_backend/screens/pricelists-list.js.map +1 -0
  1409. package/dist/modules/pricing_backend/screens/shared.d.ts +21 -0
  1410. package/dist/modules/pricing_backend/screens/shared.d.ts.map +1 -0
  1411. package/dist/modules/pricing_backend/screens/shared.js +3 -0
  1412. package/dist/modules/pricing_backend/screens/shared.js.map +1 -0
  1413. package/dist/modules/product/functions.d.ts.map +1 -1
  1414. package/dist/modules/product/functions.js +679 -50
  1415. package/dist/modules/product/functions.js.map +1 -1
  1416. package/dist/modules/product/index.d.ts +2 -0
  1417. package/dist/modules/product/index.d.ts.map +1 -1
  1418. package/dist/modules/product/index.js +2 -2
  1419. package/dist/modules/product/index.js.map +1 -1
  1420. package/dist/modules/product/models.d.ts +1 -1
  1421. package/dist/modules/product/models.d.ts.map +1 -1
  1422. package/dist/modules/product/models.js +27 -4
  1423. package/dist/modules/product/models.js.map +1 -1
  1424. package/dist/modules/product/relations.d.ts.map +1 -1
  1425. package/dist/modules/product/relations.js +4 -0
  1426. package/dist/modules/product/relations.js.map +1 -1
  1427. package/dist/modules/product/sellable.d.ts +26 -0
  1428. package/dist/modules/product/sellable.d.ts.map +1 -0
  1429. package/dist/modules/product/sellable.js +56 -0
  1430. package/dist/modules/product/sellable.js.map +1 -0
  1431. package/dist/modules/product/types.d.ts +2 -2
  1432. package/dist/modules/product/views.d.ts.map +1 -1
  1433. package/dist/modules/product/views.js +5 -1
  1434. package/dist/modules/product/views.js.map +1 -1
  1435. package/dist/modules/product_activity_backend/index.d.ts.map +1 -1
  1436. package/dist/modules/product_activity_backend/index.js +2 -3
  1437. package/dist/modules/product_activity_backend/index.js.map +1 -1
  1438. package/dist/modules/product_backend/client/media-upload-view.d.mts.map +1 -1
  1439. package/dist/modules/product_backend/client/media-upload-view.mjs +1 -0
  1440. package/dist/modules/product_backend/client/media-upload-view.mjs.map +1 -1
  1441. package/dist/modules/product_backend/client/product.css +964 -0
  1442. package/dist/modules/product_backend/index.d.ts +5 -6
  1443. package/dist/modules/product_backend/index.d.ts.map +1 -1
  1444. package/dist/modules/product_backend/index.js +203 -14
  1445. package/dist/modules/product_backend/index.js.map +1 -1
  1446. package/dist/modules/product_backend/menus.js +2 -2
  1447. package/dist/modules/product_backend/menus.js.map +1 -1
  1448. package/dist/modules/product_backend/relation-control.d.ts +85 -0
  1449. package/dist/modules/product_backend/relation-control.d.ts.map +1 -0
  1450. package/dist/modules/product_backend/relation-control.js +129 -0
  1451. package/dist/modules/product_backend/relation-control.js.map +1 -0
  1452. package/dist/modules/product_backend/routes.d.ts.map +1 -1
  1453. package/dist/modules/product_backend/routes.js +502 -196
  1454. package/dist/modules/product_backend/routes.js.map +1 -1
  1455. package/dist/modules/product_backend/screens/attributes.d.ts +7 -0
  1456. package/dist/modules/product_backend/screens/attributes.d.ts.map +1 -0
  1457. package/dist/modules/product_backend/screens/attributes.js +66 -0
  1458. package/dist/modules/product_backend/screens/attributes.js.map +1 -0
  1459. package/dist/modules/product_backend/screens/create.d.ts +16 -0
  1460. package/dist/modules/product_backend/screens/create.d.ts.map +1 -0
  1461. package/dist/modules/product_backend/screens/create.js +86 -0
  1462. package/dist/modules/product_backend/screens/create.js.map +1 -0
  1463. package/dist/modules/product_backend/screens/detail.d.ts +87 -0
  1464. package/dist/modules/product_backend/screens/detail.d.ts.map +1 -0
  1465. package/dist/modules/product_backend/screens/detail.js +381 -0
  1466. package/dist/modules/product_backend/screens/detail.js.map +1 -0
  1467. package/dist/modules/product_backend/screens/favorite.d.ts +6 -0
  1468. package/dist/modules/product_backend/screens/favorite.d.ts.map +1 -0
  1469. package/dist/modules/product_backend/screens/favorite.js +43 -0
  1470. package/dist/modules/product_backend/screens/favorite.js.map +1 -0
  1471. package/dist/modules/product_backend/screens/index.d.ts +10 -0
  1472. package/dist/modules/product_backend/screens/index.d.ts.map +1 -0
  1473. package/dist/modules/product_backend/screens/index.js +7 -0
  1474. package/dist/modules/product_backend/screens/index.js.map +1 -0
  1475. package/dist/modules/product_backend/screens/list.d.ts +54 -0
  1476. package/dist/modules/product_backend/screens/list.d.ts.map +1 -0
  1477. package/dist/modules/product_backend/screens/list.js +124 -0
  1478. package/dist/modules/product_backend/screens/list.js.map +1 -0
  1479. package/dist/modules/product_backend/screens/variant.d.ts +9 -0
  1480. package/dist/modules/product_backend/screens/variant.d.ts.map +1 -0
  1481. package/dist/modules/product_backend/screens/variant.js +113 -0
  1482. package/dist/modules/product_backend/screens/variant.js.map +1 -0
  1483. package/dist/modules/product_mail_backend/index.d.ts.map +1 -1
  1484. package/dist/modules/product_mail_backend/index.js +2 -3
  1485. package/dist/modules/product_mail_backend/index.js.map +1 -1
  1486. package/dist/modules/product_media/functions.d.ts.map +1 -1
  1487. package/dist/modules/product_media/functions.js +59 -6
  1488. package/dist/modules/product_media/functions.js.map +1 -1
  1489. package/dist/modules/product_media/index.js +0 -1
  1490. package/dist/modules/product_media/index.js.map +1 -1
  1491. package/dist/modules/product_variant_activity_backend/index.d.ts.map +1 -1
  1492. package/dist/modules/product_variant_activity_backend/index.js +2 -3
  1493. package/dist/modules/product_variant_activity_backend/index.js.map +1 -1
  1494. package/dist/modules/product_variant_mail_backend/index.d.ts.map +1 -1
  1495. package/dist/modules/product_variant_mail_backend/index.js +2 -3
  1496. package/dist/modules/product_variant_mail_backend/index.js.map +1 -1
  1497. package/dist/modules/purchase/functions.d.ts.map +1 -1
  1498. package/dist/modules/purchase/functions.js +852 -225
  1499. package/dist/modules/purchase/functions.js.map +1 -1
  1500. package/dist/modules/purchase/index.d.ts.map +1 -1
  1501. package/dist/modules/purchase/index.js +30 -5
  1502. package/dist/modules/purchase/index.js.map +1 -1
  1503. package/dist/modules/purchase/models.d.ts.map +1 -1
  1504. package/dist/modules/purchase/models.js +1 -0
  1505. package/dist/modules/purchase/models.js.map +1 -1
  1506. package/dist/modules/purchase/reports.d.ts +4 -0
  1507. package/dist/modules/purchase/reports.d.ts.map +1 -0
  1508. package/dist/modules/purchase/reports.js +86 -0
  1509. package/dist/modules/purchase/reports.js.map +1 -0
  1510. package/dist/modules/purchase_backend/index.js +513 -112
  1511. package/dist/modules/purchase_backend/index.js.map +1 -1
  1512. package/dist/modules/purchase_backend/screens/index.d.ts +10 -0
  1513. package/dist/modules/purchase_backend/screens/index.d.ts.map +1 -0
  1514. package/dist/modules/purchase_backend/screens/index.js +10 -0
  1515. package/dist/modules/purchase_backend/screens/index.js.map +1 -0
  1516. package/dist/modules/purchase_backend/screens/order-detail.d.ts +31 -0
  1517. package/dist/modules/purchase_backend/screens/order-detail.d.ts.map +1 -0
  1518. package/dist/modules/purchase_backend/screens/order-detail.js +204 -0
  1519. package/dist/modules/purchase_backend/screens/order-detail.js.map +1 -0
  1520. package/dist/modules/purchase_backend/screens/order-list-shared.d.ts +7 -0
  1521. package/dist/modules/purchase_backend/screens/order-list-shared.d.ts.map +1 -0
  1522. package/dist/modules/purchase_backend/screens/order-list-shared.js +58 -0
  1523. package/dist/modules/purchase_backend/screens/order-list-shared.js.map +1 -0
  1524. package/dist/modules/purchase_backend/screens/overview.d.ts +19 -0
  1525. package/dist/modules/purchase_backend/screens/overview.d.ts.map +1 -0
  1526. package/dist/modules/purchase_backend/screens/overview.js +52 -0
  1527. package/dist/modules/purchase_backend/screens/overview.js.map +1 -0
  1528. package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts +14 -0
  1529. package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts.map +1 -0
  1530. package/dist/modules/purchase_backend/screens/purchase-orders-list.js +26 -0
  1531. package/dist/modules/purchase_backend/screens/purchase-orders-list.js.map +1 -0
  1532. package/dist/modules/purchase_backend/screens/rfq-create.d.ts +16 -0
  1533. package/dist/modules/purchase_backend/screens/rfq-create.d.ts.map +1 -0
  1534. package/dist/modules/purchase_backend/screens/rfq-create.js +24 -0
  1535. package/dist/modules/purchase_backend/screens/rfq-create.js.map +1 -0
  1536. package/dist/modules/purchase_backend/screens/rfqs-list.d.ts +18 -0
  1537. package/dist/modules/purchase_backend/screens/rfqs-list.d.ts.map +1 -0
  1538. package/dist/modules/purchase_backend/screens/rfqs-list.js +28 -0
  1539. package/dist/modules/purchase_backend/screens/rfqs-list.js.map +1 -0
  1540. package/dist/modules/purchase_backend/screens/shared.d.ts +18 -0
  1541. package/dist/modules/purchase_backend/screens/shared.d.ts.map +1 -0
  1542. package/dist/modules/purchase_backend/screens/shared.js +30 -0
  1543. package/dist/modules/purchase_backend/screens/shared.js.map +1 -0
  1544. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.d.ts +20 -0
  1545. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.d.ts.map +1 -0
  1546. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.js +25 -0
  1547. package/dist/modules/purchase_backend/screens/vendor-pricelist-create.js.map +1 -0
  1548. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts +33 -0
  1549. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts.map +1 -0
  1550. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js +73 -0
  1551. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js.map +1 -0
  1552. package/dist/modules/purchase_staff_channel/channel-routes.d.ts +2 -0
  1553. package/dist/modules/purchase_staff_channel/channel-routes.d.ts.map +1 -0
  1554. package/dist/modules/purchase_staff_channel/channel-routes.js +119 -0
  1555. package/dist/modules/purchase_staff_channel/channel-routes.js.map +1 -0
  1556. package/dist/modules/purchase_staff_channel/index.d.ts +8 -0
  1557. package/dist/modules/purchase_staff_channel/index.d.ts.map +1 -0
  1558. package/dist/modules/purchase_staff_channel/index.js +45 -0
  1559. package/dist/modules/purchase_staff_channel/index.js.map +1 -0
  1560. package/dist/modules/purchase_staff_channel/order-routes.d.ts +2 -0
  1561. package/dist/modules/purchase_staff_channel/order-routes.d.ts.map +1 -0
  1562. package/dist/modules/purchase_staff_channel/order-routes.js +754 -0
  1563. package/dist/modules/purchase_staff_channel/order-routes.js.map +1 -0
  1564. package/dist/modules/purchase_staff_channel/product-routes.d.ts +2 -0
  1565. package/dist/modules/purchase_staff_channel/product-routes.d.ts.map +1 -0
  1566. package/dist/modules/purchase_staff_channel/product-routes.js +183 -0
  1567. package/dist/modules/purchase_staff_channel/product-routes.js.map +1 -0
  1568. package/dist/modules/purchase_staff_channel/vendor-bill-routes.d.ts +2 -0
  1569. package/dist/modules/purchase_staff_channel/vendor-bill-routes.d.ts.map +1 -0
  1570. package/dist/modules/purchase_staff_channel/vendor-bill-routes.js +189 -0
  1571. package/dist/modules/purchase_staff_channel/vendor-bill-routes.js.map +1 -0
  1572. package/dist/modules/quality/functions.d.ts +3 -0
  1573. package/dist/modules/quality/functions.d.ts.map +1 -0
  1574. package/dist/modules/quality/functions.js +381 -0
  1575. package/dist/modules/quality/functions.js.map +1 -0
  1576. package/dist/modules/quality/index.d.ts +5 -0
  1577. package/dist/modules/quality/index.d.ts.map +1 -0
  1578. package/dist/modules/quality/index.js +19 -0
  1579. package/dist/modules/quality/index.js.map +1 -0
  1580. package/dist/modules/quality/models.d.ts +3 -0
  1581. package/dist/modules/quality/models.d.ts.map +1 -0
  1582. package/dist/modules/quality/models.js +91 -0
  1583. package/dist/modules/quality/models.js.map +1 -0
  1584. package/dist/modules/quality_staff_channel/channel-routes.d.ts +2 -0
  1585. package/dist/modules/quality_staff_channel/channel-routes.d.ts.map +1 -0
  1586. package/dist/modules/quality_staff_channel/channel-routes.js +495 -0
  1587. package/dist/modules/quality_staff_channel/channel-routes.js.map +1 -0
  1588. package/dist/modules/quality_staff_channel/index.d.ts +5 -0
  1589. package/dist/modules/quality_staff_channel/index.d.ts.map +1 -0
  1590. package/dist/modules/quality_staff_channel/index.js +30 -0
  1591. package/dist/modules/quality_staff_channel/index.js.map +1 -0
  1592. package/dist/modules/report/functions.d.ts +3 -0
  1593. package/dist/modules/report/functions.d.ts.map +1 -0
  1594. package/dist/modules/report/functions.js +197 -0
  1595. package/dist/modules/report/functions.js.map +1 -0
  1596. package/dist/modules/report/index.d.ts +3 -0
  1597. package/dist/modules/report/index.d.ts.map +1 -0
  1598. package/dist/modules/report/index.js +21 -0
  1599. package/dist/modules/report/index.js.map +1 -0
  1600. package/dist/modules/report/jobs.d.ts +3 -0
  1601. package/dist/modules/report/jobs.d.ts.map +1 -0
  1602. package/dist/modules/report/jobs.js +18 -0
  1603. package/dist/modules/report/jobs.js.map +1 -0
  1604. package/dist/modules/report/models.d.ts +3 -0
  1605. package/dist/modules/report/models.d.ts.map +1 -0
  1606. package/dist/modules/report/models.js +45 -0
  1607. package/dist/modules/report/models.js.map +1 -0
  1608. package/dist/modules/report/routes.d.ts +19 -0
  1609. package/dist/modules/report/routes.d.ts.map +1 -0
  1610. package/dist/modules/report/routes.js +138 -0
  1611. package/dist/modules/report/routes.js.map +1 -0
  1612. package/dist/modules/report_backend/index.d.ts +3 -0
  1613. package/dist/modules/report_backend/index.d.ts.map +1 -0
  1614. package/dist/modules/report_backend/index.js +67 -0
  1615. package/dist/modules/report_backend/index.js.map +1 -0
  1616. package/dist/modules/report_backend/routes.d.ts +10 -0
  1617. package/dist/modules/report_backend/routes.d.ts.map +1 -0
  1618. package/dist/modules/report_backend/routes.js +87 -0
  1619. package/dist/modules/report_backend/routes.js.map +1 -0
  1620. package/dist/modules/report_backend/screens/index.d.ts +13 -0
  1621. package/dist/modules/report_backend/screens/index.d.ts.map +1 -0
  1622. package/dist/modules/report_backend/screens/index.js +91 -0
  1623. package/dist/modules/report_backend/screens/index.js.map +1 -0
  1624. package/dist/modules/sale/functions.d.ts.map +1 -1
  1625. package/dist/modules/sale/functions.js +796 -238
  1626. package/dist/modules/sale/functions.js.map +1 -1
  1627. package/dist/modules/sale/index.d.ts.map +1 -1
  1628. package/dist/modules/sale/index.js +44 -5
  1629. package/dist/modules/sale/index.js.map +1 -1
  1630. package/dist/modules/sale/models.d.ts.map +1 -1
  1631. package/dist/modules/sale/models.js +47 -1
  1632. package/dist/modules/sale/models.js.map +1 -1
  1633. package/dist/modules/sale/relations.d.ts.map +1 -1
  1634. package/dist/modules/sale/relations.js +6 -0
  1635. package/dist/modules/sale/relations.js.map +1 -1
  1636. package/dist/modules/sale/reports.d.ts +4 -0
  1637. package/dist/modules/sale/reports.d.ts.map +1 -0
  1638. package/dist/modules/sale/reports.js +132 -0
  1639. package/dist/modules/sale/reports.js.map +1 -0
  1640. package/dist/modules/sale/scope.d.ts +31 -0
  1641. package/dist/modules/sale/scope.d.ts.map +1 -0
  1642. package/dist/modules/sale/scope.js +34 -0
  1643. package/dist/modules/sale/scope.js.map +1 -0
  1644. package/dist/modules/sale_activity_backend/index.d.ts.map +1 -1
  1645. package/dist/modules/sale_activity_backend/index.js +0 -1
  1646. package/dist/modules/sale_activity_backend/index.js.map +1 -1
  1647. package/dist/modules/sale_backend/index.js +338 -121
  1648. package/dist/modules/sale_backend/index.js.map +1 -1
  1649. package/dist/modules/sale_backend/screens/index.d.ts +9 -0
  1650. package/dist/modules/sale_backend/screens/index.d.ts.map +1 -0
  1651. package/dist/modules/sale_backend/screens/index.js +9 -0
  1652. package/dist/modules/sale_backend/screens/index.js.map +1 -0
  1653. package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts +14 -0
  1654. package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts.map +1 -0
  1655. package/dist/modules/sale_backend/screens/invoicing-policies-list.js +48 -0
  1656. package/dist/modules/sale_backend/screens/invoicing-policies-list.js.map +1 -0
  1657. package/dist/modules/sale_backend/screens/invoicing-policy-create.d.ts +14 -0
  1658. package/dist/modules/sale_backend/screens/invoicing-policy-create.d.ts.map +1 -0
  1659. package/dist/modules/sale_backend/screens/invoicing-policy-create.js +38 -0
  1660. package/dist/modules/sale_backend/screens/invoicing-policy-create.js.map +1 -0
  1661. package/dist/modules/sale_backend/screens/order-detail.d.ts +43 -0
  1662. package/dist/modules/sale_backend/screens/order-detail.d.ts.map +1 -0
  1663. package/dist/modules/sale_backend/screens/order-detail.js +226 -0
  1664. package/dist/modules/sale_backend/screens/order-detail.js.map +1 -0
  1665. package/dist/modules/sale_backend/screens/overview.d.ts +31 -0
  1666. package/dist/modules/sale_backend/screens/overview.d.ts.map +1 -0
  1667. package/dist/modules/sale_backend/screens/overview.js +73 -0
  1668. package/dist/modules/sale_backend/screens/overview.js.map +1 -0
  1669. package/dist/modules/sale_backend/screens/quotation-create.d.ts +13 -0
  1670. package/dist/modules/sale_backend/screens/quotation-create.d.ts.map +1 -0
  1671. package/dist/modules/sale_backend/screens/quotation-create.js +19 -0
  1672. package/dist/modules/sale_backend/screens/quotation-create.js.map +1 -0
  1673. package/dist/modules/sale_backend/screens/quotations-list.d.ts +25 -0
  1674. package/dist/modules/sale_backend/screens/quotations-list.d.ts.map +1 -0
  1675. package/dist/modules/sale_backend/screens/quotations-list.js +96 -0
  1676. package/dist/modules/sale_backend/screens/quotations-list.js.map +1 -0
  1677. package/dist/modules/sale_backend/screens/sales-orders-list.d.ts +25 -0
  1678. package/dist/modules/sale_backend/screens/sales-orders-list.d.ts.map +1 -0
  1679. package/dist/modules/sale_backend/screens/sales-orders-list.js +100 -0
  1680. package/dist/modules/sale_backend/screens/sales-orders-list.js.map +1 -0
  1681. package/dist/modules/sale_backend/screens/shared.d.ts +4 -0
  1682. package/dist/modules/sale_backend/screens/shared.d.ts.map +1 -0
  1683. package/dist/modules/sale_backend/screens/shared.js +4 -0
  1684. package/dist/modules/sale_backend/screens/shared.js.map +1 -0
  1685. package/dist/modules/sale_mail_backend/index.d.ts.map +1 -1
  1686. package/dist/modules/sale_mail_backend/index.js +0 -1
  1687. package/dist/modules/sale_mail_backend/index.js.map +1 -1
  1688. package/dist/modules/sale_staff_channel/channel-routes.d.ts +2 -0
  1689. package/dist/modules/sale_staff_channel/channel-routes.d.ts.map +1 -0
  1690. package/dist/modules/sale_staff_channel/channel-routes.js +296 -0
  1691. package/dist/modules/sale_staff_channel/channel-routes.js.map +1 -0
  1692. package/dist/modules/sale_staff_channel/index.d.ts +7 -0
  1693. package/dist/modules/sale_staff_channel/index.d.ts.map +1 -0
  1694. package/dist/modules/sale_staff_channel/index.js +44 -0
  1695. package/dist/modules/sale_staff_channel/index.js.map +1 -0
  1696. package/dist/modules/sale_staff_channel/order-routes.d.ts +2 -0
  1697. package/dist/modules/sale_staff_channel/order-routes.d.ts.map +1 -0
  1698. package/dist/modules/sale_staff_channel/order-routes.js +658 -0
  1699. package/dist/modules/sale_staff_channel/order-routes.js.map +1 -0
  1700. package/dist/modules/sale_staff_channel/product-routes.d.ts +2 -0
  1701. package/dist/modules/sale_staff_channel/product-routes.d.ts.map +1 -0
  1702. package/dist/modules/sale_staff_channel/product-routes.js +183 -0
  1703. package/dist/modules/sale_staff_channel/product-routes.js.map +1 -0
  1704. package/dist/modules/stock/functions.d.ts.map +1 -1
  1705. package/dist/modules/stock/functions.js +1239 -332
  1706. package/dist/modules/stock/functions.js.map +1 -1
  1707. package/dist/modules/stock/index.d.ts +2 -0
  1708. package/dist/modules/stock/index.d.ts.map +1 -1
  1709. package/dist/modules/stock/index.js +29 -6
  1710. package/dist/modules/stock/index.js.map +1 -1
  1711. package/dist/modules/stock/models.d.ts.map +1 -1
  1712. package/dist/modules/stock/models.js +1 -0
  1713. package/dist/modules/stock/models.js.map +1 -1
  1714. package/dist/modules/stock/reports.d.ts +4 -0
  1715. package/dist/modules/stock/reports.d.ts.map +1 -0
  1716. package/dist/modules/stock/reports.js +100 -0
  1717. package/dist/modules/stock/reports.js.map +1 -0
  1718. package/dist/modules/stock/routing.d.ts +1 -1
  1719. package/dist/modules/stock/routing.d.ts.map +1 -1
  1720. package/dist/modules/stock/routing.js +35 -30
  1721. package/dist/modules/stock/routing.js.map +1 -1
  1722. package/dist/modules/stock/scope.d.ts +23 -0
  1723. package/dist/modules/stock/scope.d.ts.map +1 -0
  1724. package/dist/modules/stock/scope.js +26 -0
  1725. package/dist/modules/stock/scope.js.map +1 -0
  1726. package/dist/modules/stock/units.d.ts +14 -0
  1727. package/dist/modules/stock/units.d.ts.map +1 -0
  1728. package/dist/modules/stock/units.js +50 -0
  1729. package/dist/modules/stock/units.js.map +1 -0
  1730. package/dist/modules/stock_activity_backend/index.d.ts.map +1 -1
  1731. package/dist/modules/stock_activity_backend/index.js +0 -1
  1732. package/dist/modules/stock_activity_backend/index.js.map +1 -1
  1733. package/dist/modules/stock_backend/client/editor-view.d.mts.map +1 -1
  1734. package/dist/modules/stock_backend/client/editor-view.mjs +12 -10
  1735. package/dist/modules/stock_backend/client/editor-view.mjs.map +1 -1
  1736. package/dist/modules/stock_backend/index.js +27 -20
  1737. package/dist/modules/stock_backend/index.js.map +1 -1
  1738. package/dist/modules/stock_backend/routes.d.ts.map +1 -1
  1739. package/dist/modules/stock_backend/routes.js +485 -232
  1740. package/dist/modules/stock_backend/routes.js.map +1 -1
  1741. package/dist/modules/stock_backend/screens/forecast.d.ts +28 -0
  1742. package/dist/modules/stock_backend/screens/forecast.d.ts.map +1 -0
  1743. package/dist/modules/stock_backend/screens/forecast.js +108 -0
  1744. package/dist/modules/stock_backend/screens/forecast.js.map +1 -0
  1745. package/dist/modules/stock_backend/screens/index.d.ts +22 -0
  1746. package/dist/modules/stock_backend/screens/index.d.ts.map +1 -0
  1747. package/dist/modules/stock_backend/screens/index.js +22 -0
  1748. package/dist/modules/stock_backend/screens/index.js.map +1 -0
  1749. package/dist/modules/stock_backend/screens/inventory.d.ts +27 -0
  1750. package/dist/modules/stock_backend/screens/inventory.d.ts.map +1 -0
  1751. package/dist/modules/stock_backend/screens/inventory.js +128 -0
  1752. package/dist/modules/stock_backend/screens/inventory.js.map +1 -0
  1753. package/dist/modules/stock_backend/screens/location-create.d.ts +15 -0
  1754. package/dist/modules/stock_backend/screens/location-create.d.ts.map +1 -0
  1755. package/dist/modules/stock_backend/screens/location-create.js +75 -0
  1756. package/dist/modules/stock_backend/screens/location-create.js.map +1 -0
  1757. package/dist/modules/stock_backend/screens/locations-list.d.ts +21 -0
  1758. package/dist/modules/stock_backend/screens/locations-list.d.ts.map +1 -0
  1759. package/dist/modules/stock_backend/screens/locations-list.js +62 -0
  1760. package/dist/modules/stock_backend/screens/locations-list.js.map +1 -0
  1761. package/dist/modules/stock_backend/screens/lot-create.d.ts +14 -0
  1762. package/dist/modules/stock_backend/screens/lot-create.d.ts.map +1 -0
  1763. package/dist/modules/stock_backend/screens/lot-create.js +60 -0
  1764. package/dist/modules/stock_backend/screens/lot-create.js.map +1 -0
  1765. package/dist/modules/stock_backend/screens/lot-detail.d.ts +30 -0
  1766. package/dist/modules/stock_backend/screens/lot-detail.d.ts.map +1 -0
  1767. package/dist/modules/stock_backend/screens/lot-detail.js +84 -0
  1768. package/dist/modules/stock_backend/screens/lot-detail.js.map +1 -0
  1769. package/dist/modules/stock_backend/screens/lots-list.d.ts +25 -0
  1770. package/dist/modules/stock_backend/screens/lots-list.d.ts.map +1 -0
  1771. package/dist/modules/stock_backend/screens/lots-list.js +54 -0
  1772. package/dist/modules/stock_backend/screens/lots-list.js.map +1 -0
  1773. package/dist/modules/stock_backend/screens/picking-type-create.d.ts +15 -0
  1774. package/dist/modules/stock_backend/screens/picking-type-create.d.ts.map +1 -0
  1775. package/dist/modules/stock_backend/screens/picking-type-create.js +89 -0
  1776. package/dist/modules/stock_backend/screens/picking-type-create.js.map +1 -0
  1777. package/dist/modules/stock_backend/screens/picking-types-list.d.ts +22 -0
  1778. package/dist/modules/stock_backend/screens/picking-types-list.d.ts.map +1 -0
  1779. package/dist/modules/stock_backend/screens/picking-types-list.js +80 -0
  1780. package/dist/modules/stock_backend/screens/picking-types-list.js.map +1 -0
  1781. package/dist/modules/stock_backend/screens/replenishment-create.d.ts +17 -0
  1782. package/dist/modules/stock_backend/screens/replenishment-create.d.ts.map +1 -0
  1783. package/dist/modules/stock_backend/screens/replenishment-create.js +74 -0
  1784. package/dist/modules/stock_backend/screens/replenishment-create.js.map +1 -0
  1785. package/dist/modules/stock_backend/screens/replenishment-list.d.ts +29 -0
  1786. package/dist/modules/stock_backend/screens/replenishment-list.d.ts.map +1 -0
  1787. package/dist/modules/stock_backend/screens/replenishment-list.js +84 -0
  1788. package/dist/modules/stock_backend/screens/replenishment-list.js.map +1 -0
  1789. package/dist/modules/stock_backend/screens/shared.d.ts +12 -0
  1790. package/dist/modules/stock_backend/screens/shared.d.ts.map +1 -0
  1791. package/dist/modules/stock_backend/screens/shared.js +29 -0
  1792. package/dist/modules/stock_backend/screens/shared.js.map +1 -0
  1793. package/dist/modules/stock_backend/screens/stock-route-create.d.ts +13 -0
  1794. package/dist/modules/stock_backend/screens/stock-route-create.d.ts.map +1 -0
  1795. package/dist/modules/stock_backend/screens/stock-route-create.js +52 -0
  1796. package/dist/modules/stock_backend/screens/stock-route-create.js.map +1 -0
  1797. package/dist/modules/stock_backend/screens/stock-route-detail.d.ts +30 -0
  1798. package/dist/modules/stock_backend/screens/stock-route-detail.d.ts.map +1 -0
  1799. package/dist/modules/stock_backend/screens/stock-route-detail.js +131 -0
  1800. package/dist/modules/stock_backend/screens/stock-route-detail.js.map +1 -0
  1801. package/dist/modules/stock_backend/screens/stock-routes-list.d.ts +22 -0
  1802. package/dist/modules/stock_backend/screens/stock-routes-list.d.ts.map +1 -0
  1803. package/dist/modules/stock_backend/screens/stock-routes-list.js +51 -0
  1804. package/dist/modules/stock_backend/screens/stock-routes-list.js.map +1 -0
  1805. package/dist/modules/stock_backend/screens/stock.d.ts +7 -0
  1806. package/dist/modules/stock_backend/screens/stock.d.ts.map +1 -0
  1807. package/dist/modules/stock_backend/screens/stock.js +13 -0
  1808. package/dist/modules/stock_backend/screens/stock.js.map +1 -0
  1809. package/dist/modules/stock_backend/screens/transfer-create.d.ts +13 -0
  1810. package/dist/modules/stock_backend/screens/transfer-create.d.ts.map +1 -0
  1811. package/dist/modules/stock_backend/screens/transfer-create.js +38 -0
  1812. package/dist/modules/stock_backend/screens/transfer-create.js.map +1 -0
  1813. package/dist/modules/stock_backend/screens/transfer-detail.d.ts +27 -0
  1814. package/dist/modules/stock_backend/screens/transfer-detail.d.ts.map +1 -0
  1815. package/dist/modules/stock_backend/screens/transfer-detail.js +91 -0
  1816. package/dist/modules/stock_backend/screens/transfer-detail.js.map +1 -0
  1817. package/dist/modules/stock_backend/screens/transfers-list.d.ts +25 -0
  1818. package/dist/modules/stock_backend/screens/transfers-list.d.ts.map +1 -0
  1819. package/dist/modules/stock_backend/screens/transfers-list.js +81 -0
  1820. package/dist/modules/stock_backend/screens/transfers-list.js.map +1 -0
  1821. package/dist/modules/stock_backend/screens/warehouse-create.d.ts +13 -0
  1822. package/dist/modules/stock_backend/screens/warehouse-create.d.ts.map +1 -0
  1823. package/dist/modules/stock_backend/screens/warehouse-create.js +79 -0
  1824. package/dist/modules/stock_backend/screens/warehouse-create.js.map +1 -0
  1825. package/dist/modules/stock_backend/screens/warehouses-list.d.ts +21 -0
  1826. package/dist/modules/stock_backend/screens/warehouses-list.d.ts.map +1 -0
  1827. package/dist/modules/stock_backend/screens/warehouses-list.js +60 -0
  1828. package/dist/modules/stock_backend/screens/warehouses-list.js.map +1 -0
  1829. package/dist/modules/stock_lot_activity_backend/index.d.ts.map +1 -1
  1830. package/dist/modules/stock_lot_activity_backend/index.js +0 -1
  1831. package/dist/modules/stock_lot_activity_backend/index.js.map +1 -1
  1832. package/dist/modules/stock_lot_mail_backend/index.d.ts.map +1 -1
  1833. package/dist/modules/stock_lot_mail_backend/index.js +0 -1
  1834. package/dist/modules/stock_lot_mail_backend/index.js.map +1 -1
  1835. package/dist/modules/stock_mail_backend/index.d.ts.map +1 -1
  1836. package/dist/modules/stock_mail_backend/index.js +0 -1
  1837. package/dist/modules/stock_mail_backend/index.js.map +1 -1
  1838. package/dist/modules/stock_mail_inbound/index.d.ts.map +1 -1
  1839. package/dist/modules/stock_mail_inbound/index.js +0 -2
  1840. package/dist/modules/stock_mail_inbound/index.js.map +1 -1
  1841. package/dist/modules/stock_staff_channel/channel-routes.d.ts +656 -0
  1842. package/dist/modules/stock_staff_channel/channel-routes.d.ts.map +1 -0
  1843. package/dist/modules/stock_staff_channel/channel-routes.js +445 -0
  1844. package/dist/modules/stock_staff_channel/channel-routes.js.map +1 -0
  1845. package/dist/modules/stock_staff_channel/functions.d.ts +3 -0
  1846. package/dist/modules/stock_staff_channel/functions.d.ts.map +1 -0
  1847. package/dist/modules/stock_staff_channel/functions.js +954 -0
  1848. package/dist/modules/stock_staff_channel/functions.js.map +1 -0
  1849. package/dist/modules/stock_staff_channel/index.d.ts +8 -0
  1850. package/dist/modules/stock_staff_channel/index.d.ts.map +1 -0
  1851. package/dist/modules/stock_staff_channel/index.js +37 -0
  1852. package/dist/modules/stock_staff_channel/index.js.map +1 -0
  1853. package/dist/modules/stock_staff_channel/models.d.ts +4 -0
  1854. package/dist/modules/stock_staff_channel/models.d.ts.map +1 -0
  1855. package/dist/modules/stock_staff_channel/models.js +119 -0
  1856. package/dist/modules/stock_staff_channel/models.js.map +1 -0
  1857. package/dist/modules/stock_staff_channel/operation-routes.d.ts +2 -0
  1858. package/dist/modules/stock_staff_channel/operation-routes.d.ts.map +1 -0
  1859. package/dist/modules/stock_staff_channel/operation-routes.js +1269 -0
  1860. package/dist/modules/stock_staff_channel/operation-routes.js.map +1 -0
  1861. package/dist/modules/storage/functions.d.ts.map +1 -1
  1862. package/dist/modules/storage/functions.js +18 -5
  1863. package/dist/modules/storage/functions.js.map +1 -1
  1864. package/dist/modules/storage/index.js +0 -1
  1865. package/dist/modules/storage/index.js.map +1 -1
  1866. package/dist/modules/storage/jobs.d.ts +21 -1
  1867. package/dist/modules/storage/jobs.d.ts.map +1 -1
  1868. package/dist/modules/storage/jobs.js +142 -2
  1869. package/dist/modules/storage/jobs.js.map +1 -1
  1870. package/dist/modules/storage/models.d.ts.map +1 -1
  1871. package/dist/modules/storage/models.js +2 -0
  1872. package/dist/modules/storage/models.js.map +1 -1
  1873. package/dist/modules/storage/policy.d.ts +5 -0
  1874. package/dist/modules/storage/policy.d.ts.map +1 -0
  1875. package/dist/modules/storage/policy.js +13 -0
  1876. package/dist/modules/storage/policy.js.map +1 -0
  1877. package/dist/modules/storage/routes.d.ts +1 -0
  1878. package/dist/modules/storage/routes.d.ts.map +1 -1
  1879. package/dist/modules/storage/routes.js +19 -15
  1880. package/dist/modules/storage/routes.js.map +1 -1
  1881. package/dist/modules/uom/convert.d.ts +1 -1
  1882. package/dist/modules/uom/convert.js +2 -2
  1883. package/dist/modules/uom/convert.js.map +1 -1
  1884. package/dist/modules/uom/functions.d.ts.map +1 -1
  1885. package/dist/modules/uom/functions.js +39 -4
  1886. package/dist/modules/uom/functions.js.map +1 -1
  1887. package/dist/modules/uom/index.d.ts.map +1 -1
  1888. package/dist/modules/uom/index.js +1 -2
  1889. package/dist/modules/uom/index.js.map +1 -1
  1890. package/dist/modules/uom/messages.js +2 -2
  1891. package/dist/modules/uom/messages.js.map +1 -1
  1892. package/dist/modules/uom/models.d.ts +1 -1
  1893. package/dist/modules/uom/models.d.ts.map +1 -1
  1894. package/dist/modules/uom/models.js +1 -1
  1895. package/dist/modules/uom/models.js.map +1 -1
  1896. package/dist/modules/user/authorization.d.ts +80 -0
  1897. package/dist/modules/user/authorization.d.ts.map +1 -0
  1898. package/dist/modules/user/authorization.js +1039 -0
  1899. package/dist/modules/user/authorization.js.map +1 -0
  1900. package/dist/modules/user/functions.d.ts.map +1 -1
  1901. package/dist/modules/user/functions.js +188 -32
  1902. package/dist/modules/user/functions.js.map +1 -1
  1903. package/dist/modules/user/index.d.ts +4 -1
  1904. package/dist/modules/user/index.d.ts.map +1 -1
  1905. package/dist/modules/user/index.js +2 -3
  1906. package/dist/modules/user/index.js.map +1 -1
  1907. package/dist/modules/user/login.d.ts +1 -27
  1908. package/dist/modules/user/login.d.ts.map +1 -1
  1909. package/dist/modules/user/login.js +5 -45
  1910. package/dist/modules/user/login.js.map +1 -1
  1911. package/dist/modules/user/messages.d.ts +6 -0
  1912. package/dist/modules/user/messages.d.ts.map +1 -1
  1913. package/dist/modules/user/messages.js +6 -0
  1914. package/dist/modules/user/messages.js.map +1 -1
  1915. package/dist/modules/user/models.d.ts +1 -1
  1916. package/dist/modules/user/models.d.ts.map +1 -1
  1917. package/dist/modules/user/models.js +73 -9
  1918. package/dist/modules/user/models.js.map +1 -1
  1919. package/dist/modules/user/relations.d.ts.map +1 -1
  1920. package/dist/modules/user/relations.js +6 -0
  1921. package/dist/modules/user/relations.js.map +1 -1
  1922. package/dist/modules/user/roles.d.ts +11 -1
  1923. package/dist/modules/user/roles.d.ts.map +1 -1
  1924. package/dist/modules/user/roles.js +402 -117
  1925. package/dist/modules/user/roles.js.map +1 -1
  1926. package/dist/modules/user/routes.js +1 -1
  1927. package/dist/modules/user/routes.js.map +1 -1
  1928. package/dist/modules/user_backend/index.d.ts +1 -1
  1929. package/dist/modules/user_backend/index.d.ts.map +1 -1
  1930. package/dist/modules/user_backend/index.js +1 -3
  1931. package/dist/modules/user_backend/index.js.map +1 -1
  1932. package/dist/modules/user_backend/messages.d.ts +60 -0
  1933. package/dist/modules/user_backend/messages.d.ts.map +1 -1
  1934. package/dist/modules/user_backend/messages.js +60 -0
  1935. package/dist/modules/user_backend/messages.js.map +1 -1
  1936. package/dist/modules/user_backend/routes.d.ts.map +1 -1
  1937. package/dist/modules/user_backend/routes.js +352 -69
  1938. package/dist/modules/user_backend/routes.js.map +1 -1
  1939. package/dist/modules/user_backend/screens/index.d.ts +11 -0
  1940. package/dist/modules/user_backend/screens/index.d.ts.map +1 -0
  1941. package/dist/modules/user_backend/screens/index.js +8 -0
  1942. package/dist/modules/user_backend/screens/index.js.map +1 -0
  1943. package/dist/modules/user_backend/screens/presets-form.d.ts +16 -0
  1944. package/dist/modules/user_backend/screens/presets-form.d.ts.map +1 -0
  1945. package/dist/modules/user_backend/screens/presets-form.js +37 -0
  1946. package/dist/modules/user_backend/screens/presets-form.js.map +1 -0
  1947. package/dist/modules/user_backend/screens/profile-form.d.ts +14 -0
  1948. package/dist/modules/user_backend/screens/profile-form.d.ts.map +1 -0
  1949. package/dist/modules/user_backend/screens/profile-form.js +37 -0
  1950. package/dist/modules/user_backend/screens/profile-form.js.map +1 -0
  1951. package/dist/modules/user_backend/screens/role-form.d.ts +21 -0
  1952. package/dist/modules/user_backend/screens/role-form.d.ts.map +1 -0
  1953. package/dist/modules/user_backend/screens/role-form.js +93 -0
  1954. package/dist/modules/user_backend/screens/role-form.js.map +1 -0
  1955. package/dist/modules/user_backend/screens/roles-list.d.ts +15 -0
  1956. package/dist/modules/user_backend/screens/roles-list.d.ts.map +1 -0
  1957. package/dist/modules/user_backend/screens/roles-list.js +48 -0
  1958. package/dist/modules/user_backend/screens/roles-list.js.map +1 -0
  1959. package/dist/modules/user_backend/screens/sessions.d.ts +5 -0
  1960. package/dist/modules/user_backend/screens/sessions.d.ts.map +1 -0
  1961. package/dist/modules/user_backend/screens/sessions.js +35 -0
  1962. package/dist/modules/user_backend/screens/sessions.js.map +1 -0
  1963. package/dist/modules/user_backend/screens/types.d.ts +68 -0
  1964. package/dist/modules/user_backend/screens/types.d.ts.map +1 -0
  1965. package/dist/modules/user_backend/screens/types.js +2 -0
  1966. package/dist/modules/user_backend/screens/types.js.map +1 -0
  1967. package/dist/modules/user_backend/screens/user-form.d.ts +55 -0
  1968. package/dist/modules/user_backend/screens/user-form.d.ts.map +1 -0
  1969. package/dist/modules/user_backend/screens/user-form.js +174 -0
  1970. package/dist/modules/user_backend/screens/user-form.js.map +1 -0
  1971. package/dist/modules/user_backend/screens/users-list.d.ts +17 -0
  1972. package/dist/modules/user_backend/screens/users-list.d.ts.map +1 -0
  1973. package/dist/modules/user_backend/screens/users-list.js +56 -0
  1974. package/dist/modules/user_backend/screens/users-list.js.map +1 -0
  1975. package/dist/modules/website/cms.d.ts +18 -1
  1976. package/dist/modules/website/cms.d.ts.map +1 -1
  1977. package/dist/modules/website/cms.js +373 -38
  1978. package/dist/modules/website/cms.js.map +1 -1
  1979. package/dist/modules/website/customer.d.ts.map +1 -1
  1980. package/dist/modules/website/customer.js +249 -1
  1981. package/dist/modules/website/customer.js.map +1 -1
  1982. package/dist/modules/website/index.d.ts.map +1 -1
  1983. package/dist/modules/website/index.js +26 -4
  1984. package/dist/modules/website/index.js.map +1 -1
  1985. package/dist/modules/website/models.d.ts.map +1 -1
  1986. package/dist/modules/website/models.js +101 -0
  1987. package/dist/modules/website/models.js.map +1 -1
  1988. package/dist/modules/website/paths.d.ts +31 -0
  1989. package/dist/modules/website/paths.d.ts.map +1 -0
  1990. package/dist/modules/website/paths.js +48 -0
  1991. package/dist/modules/website/paths.js.map +1 -0
  1992. package/dist/modules/website/publication.d.ts +3 -0
  1993. package/dist/modules/website/publication.d.ts.map +1 -0
  1994. package/dist/modules/website/publication.js +366 -0
  1995. package/dist/modules/website/publication.js.map +1 -0
  1996. package/dist/modules/website/renderable.d.ts +32 -0
  1997. package/dist/modules/website/renderable.d.ts.map +1 -0
  1998. package/dist/modules/website/renderable.js +59 -0
  1999. package/dist/modules/website/renderable.js.map +1 -0
  2000. package/dist/modules/website/sections.d.ts.map +1 -1
  2001. package/dist/modules/website/sections.js +13 -0
  2002. package/dist/modules/website/sections.js.map +1 -1
  2003. package/dist/modules/website_backend/csv.d.ts +23 -0
  2004. package/dist/modules/website_backend/csv.d.ts.map +1 -0
  2005. package/dist/modules/website_backend/csv.js +31 -0
  2006. package/dist/modules/website_backend/csv.js.map +1 -0
  2007. package/dist/modules/website_backend/index.js +260 -2
  2008. package/dist/modules/website_backend/index.js.map +1 -1
  2009. package/dist/modules/website_backend/menus.d.ts.map +1 -1
  2010. package/dist/modules/website_backend/menus.js +28 -6
  2011. package/dist/modules/website_backend/menus.js.map +1 -1
  2012. package/dist/modules/website_backend/routes.d.ts.map +1 -1
  2013. package/dist/modules/website_backend/routes.js +684 -126
  2014. package/dist/modules/website_backend/routes.js.map +1 -1
  2015. package/dist/modules/website_backend/screens/index.d.ts +333 -0
  2016. package/dist/modules/website_backend/screens/index.d.ts.map +1 -0
  2017. package/dist/modules/website_backend/screens/index.js +1332 -0
  2018. package/dist/modules/website_backend/screens/index.js.map +1 -0
  2019. package/dist/modules/website_backend/screens/page-frame.d.ts +14 -0
  2020. package/dist/modules/website_backend/screens/page-frame.d.ts.map +1 -0
  2021. package/dist/modules/website_backend/screens/page-frame.js +13 -0
  2022. package/dist/modules/website_backend/screens/page-frame.js.map +1 -0
  2023. package/dist/modules/website_form/audit.d.ts +27 -0
  2024. package/dist/modules/website_form/audit.d.ts.map +1 -0
  2025. package/dist/modules/website_form/audit.js +30 -0
  2026. package/dist/modules/website_form/audit.js.map +1 -0
  2027. package/dist/modules/website_form/functions.d.ts.map +1 -1
  2028. package/dist/modules/website_form/functions.js +416 -12
  2029. package/dist/modules/website_form/functions.js.map +1 -1
  2030. package/dist/modules/website_form/index.js +24 -2
  2031. package/dist/modules/website_form/index.js.map +1 -1
  2032. package/dist/modules/website_form/jobs.d.ts +11 -0
  2033. package/dist/modules/website_form/jobs.d.ts.map +1 -0
  2034. package/dist/modules/website_form/jobs.js +80 -0
  2035. package/dist/modules/website_form/jobs.js.map +1 -0
  2036. package/dist/modules/website_form/models.d.ts.map +1 -1
  2037. package/dist/modules/website_form/models.js +89 -0
  2038. package/dist/modules/website_form/models.js.map +1 -1
  2039. package/dist/modules/website_form/purge.d.ts +22 -0
  2040. package/dist/modules/website_form/purge.d.ts.map +1 -0
  2041. package/dist/modules/website_form/purge.js +59 -0
  2042. package/dist/modules/website_form/purge.js.map +1 -0
  2043. package/dist/modules/website_form/retention.d.ts +70 -0
  2044. package/dist/modules/website_form/retention.d.ts.map +1 -0
  2045. package/dist/modules/website_form/retention.js +145 -0
  2046. package/dist/modules/website_form/retention.js.map +1 -0
  2047. package/dist/modules/website_form/routes.d.ts.map +1 -1
  2048. package/dist/modules/website_form/routes.js +37 -3
  2049. package/dist/modules/website_form/routes.js.map +1 -1
  2050. package/dist/modules/website_form_mail/index.d.ts +36 -0
  2051. package/dist/modules/website_form_mail/index.d.ts.map +1 -0
  2052. package/dist/modules/website_form_mail/index.js +137 -0
  2053. package/dist/modules/website_form_mail/index.js.map +1 -0
  2054. package/dist/modules/website_hospitality/channel-routes.d.ts +2 -0
  2055. package/dist/modules/website_hospitality/channel-routes.d.ts.map +1 -0
  2056. package/dist/modules/website_hospitality/channel-routes.js +355 -0
  2057. package/dist/modules/website_hospitality/channel-routes.js.map +1 -0
  2058. package/dist/modules/website_hospitality/functions.d.ts.map +1 -1
  2059. package/dist/modules/website_hospitality/functions.js +27 -2
  2060. package/dist/modules/website_hospitality/functions.js.map +1 -1
  2061. package/dist/modules/website_hospitality/index.js +4 -3
  2062. package/dist/modules/website_hospitality/index.js.map +1 -1
  2063. package/dist/modules/website_hospitality/models.d.ts.map +1 -1
  2064. package/dist/modules/website_hospitality/models.js +2 -0
  2065. package/dist/modules/website_hospitality/models.js.map +1 -1
  2066. package/dist/modules/website_menu/functions.d.ts.map +1 -1
  2067. package/dist/modules/website_menu/functions.js +184 -9
  2068. package/dist/modules/website_menu/functions.js.map +1 -1
  2069. package/dist/modules/website_menu/index.js +6 -1
  2070. package/dist/modules/website_menu/index.js.map +1 -1
  2071. package/dist/modules/website_retail/channel-routes.d.ts +2 -0
  2072. package/dist/modules/website_retail/channel-routes.d.ts.map +1 -0
  2073. package/dist/modules/website_retail/channel-routes.js +305 -0
  2074. package/dist/modules/website_retail/channel-routes.js.map +1 -0
  2075. package/dist/modules/website_retail/functions.d.ts +14 -1
  2076. package/dist/modules/website_retail/functions.d.ts.map +1 -1
  2077. package/dist/modules/website_retail/functions.js +6 -6
  2078. package/dist/modules/website_retail/functions.js.map +1 -1
  2079. package/dist/modules/website_retail/index.js +24 -3
  2080. package/dist/modules/website_retail/index.js.map +1 -1
  2081. package/dist/modules/website_retail/models.d.ts.map +1 -1
  2082. package/dist/modules/website_retail/models.js +30 -0
  2083. package/dist/modules/website_retail/models.js.map +1 -1
  2084. package/dist/modules/website_retail/online.d.ts +3 -0
  2085. package/dist/modules/website_retail/online.d.ts.map +1 -0
  2086. package/dist/modules/website_retail/online.js +710 -0
  2087. package/dist/modules/website_retail/online.js.map +1 -0
  2088. package/dist/modules/website_search/client/search.d.mts +16 -2
  2089. package/dist/modules/website_search/client/search.d.mts.map +1 -1
  2090. package/dist/modules/website_search/client/search.mjs +112 -6
  2091. package/dist/modules/website_search/client/search.mjs.map +1 -1
  2092. package/dist/modules/website_search/functions.d.ts +3 -0
  2093. package/dist/modules/website_search/functions.d.ts.map +1 -0
  2094. package/dist/modules/website_search/functions.js +239 -0
  2095. package/dist/modules/website_search/functions.js.map +1 -0
  2096. package/dist/modules/website_search/index.js +4 -1
  2097. package/dist/modules/website_search/index.js.map +1 -1
  2098. package/dist/modules/website_search/islands.d.ts +6 -0
  2099. package/dist/modules/website_search/islands.d.ts.map +1 -1
  2100. package/dist/modules/website_search/islands.js +8 -2
  2101. package/dist/modules/website_search/islands.js.map +1 -1
  2102. package/dist/modules/website_search/models.d.ts +15 -0
  2103. package/dist/modules/website_search/models.d.ts.map +1 -0
  2104. package/dist/modules/website_search/models.js +58 -0
  2105. package/dist/modules/website_search/models.js.map +1 -0
  2106. package/dist/modules/website_seo/functions.d.ts +3 -0
  2107. package/dist/modules/website_seo/functions.d.ts.map +1 -0
  2108. package/dist/modules/website_seo/functions.js +164 -0
  2109. package/dist/modules/website_seo/functions.js.map +1 -0
  2110. package/dist/modules/website_seo/index.js +15 -5
  2111. package/dist/modules/website_seo/index.js.map +1 -1
  2112. package/dist/modules/website_seo/projection.d.ts +52 -0
  2113. package/dist/modules/website_seo/projection.d.ts.map +1 -0
  2114. package/dist/modules/website_seo/projection.js +129 -0
  2115. package/dist/modules/website_seo/projection.js.map +1 -0
  2116. package/dist/modules/website_seo/routes.d.ts +3 -0
  2117. package/dist/modules/website_seo/routes.d.ts.map +1 -0
  2118. package/dist/modules/website_seo/routes.js +56 -0
  2119. package/dist/modules/website_seo/routes.js.map +1 -0
  2120. package/dist/permission-catalogue.d.ts +5 -0
  2121. package/dist/permission-catalogue.d.ts.map +1 -0
  2122. package/dist/permission-catalogue.js +1505 -0
  2123. package/dist/permission-catalogue.js.map +1 -0
  2124. package/dist/scaffold/index.d.ts +2 -0
  2125. package/dist/scaffold/index.d.ts.map +1 -0
  2126. package/dist/scaffold/index.js +31 -0
  2127. package/dist/scaffold/index.js.map +1 -0
  2128. package/dist/scaffold/templates/README.md.tmpl +17 -0
  2129. package/dist/scaffold/templates/gitignore.tmpl +2 -0
  2130. package/dist/scaffold/templates/ket.workspace.mjs.tmpl +1 -0
  2131. package/dist/scaffold/templates/package.json.tmpl +15 -0
  2132. package/dist/themes/hospitality/templates/website.columns.ktl +4 -0
  2133. package/dist/themes/paper/templates/website.columns.ktl +4 -0
  2134. package/dist/ui/actions.d.ts +4 -0
  2135. package/dist/ui/actions.d.ts.map +1 -1
  2136. package/dist/ui/actions.js +1 -1
  2137. package/dist/ui/actions.js.map +1 -1
  2138. package/dist/ui/activity.d.ts +1 -1
  2139. package/dist/ui/activity.d.ts.map +1 -1
  2140. package/dist/ui/activity.js +3 -5
  2141. package/dist/ui/activity.js.map +1 -1
  2142. package/dist/ui/attachments.js +1 -1
  2143. package/dist/ui/attachments.js.map +1 -1
  2144. package/dist/ui/auth.d.ts +36 -0
  2145. package/dist/ui/auth.d.ts.map +1 -1
  2146. package/dist/ui/auth.js +55 -0
  2147. package/dist/ui/auth.js.map +1 -1
  2148. package/dist/ui/board-page.d.ts +6 -0
  2149. package/dist/ui/board-page.d.ts.map +1 -0
  2150. package/dist/ui/board-page.js +4 -0
  2151. package/dist/ui/board-page.js.map +1 -0
  2152. package/dist/ui/charts.d.ts +83 -0
  2153. package/dist/ui/charts.d.ts.map +1 -0
  2154. package/dist/ui/charts.js +105 -0
  2155. package/dist/ui/charts.js.map +1 -0
  2156. package/dist/ui/chrome.d.ts +37 -2
  2157. package/dist/ui/chrome.d.ts.map +1 -1
  2158. package/dist/ui/chrome.js +39 -5
  2159. package/dist/ui/chrome.js.map +1 -1
  2160. package/dist/ui/client/activity-view.mjs +7 -7
  2161. package/dist/ui/client/activity-view.mjs.map +1 -1
  2162. package/dist/ui/client/activity.css +6 -34
  2163. package/dist/ui/client/calendar-view.d.mts.map +1 -1
  2164. package/dist/ui/client/calendar-view.mjs +7 -6
  2165. package/dist/ui/client/calendar-view.mjs.map +1 -1
  2166. package/dist/ui/client/calendar.css +4 -14
  2167. package/dist/ui/client/chart-view.d.ts +51 -0
  2168. package/dist/ui/client/chart-view.d.ts.map +1 -0
  2169. package/dist/ui/client/chart-view.js +192 -0
  2170. package/dist/ui/client/chart-view.js.map +1 -0
  2171. package/dist/ui/client/flow-app.css +387 -0
  2172. package/dist/ui/client/flow-board-view.d.mts +8 -0
  2173. package/dist/ui/client/flow-board-view.d.mts.map +1 -0
  2174. package/dist/ui/client/flow-board-view.mjs +161 -0
  2175. package/dist/ui/client/flow-board-view.mjs.map +1 -0
  2176. package/dist/ui/client/flow-board.d.mts +3 -0
  2177. package/dist/ui/client/flow-board.d.mts.map +1 -0
  2178. package/dist/ui/client/flow-board.mjs +7 -0
  2179. package/dist/ui/client/flow-board.mjs.map +1 -0
  2180. package/dist/ui/client/flow-map-view.d.mts +2 -0
  2181. package/dist/ui/client/flow-map-view.d.mts.map +1 -0
  2182. package/dist/ui/client/flow-map-view.mjs +235 -0
  2183. package/dist/ui/client/flow-map-view.mjs.map +1 -0
  2184. package/dist/ui/client/flow-map.d.mts +3 -0
  2185. package/dist/ui/client/flow-map.d.mts.map +1 -0
  2186. package/dist/ui/client/flow-map.mjs +7 -0
  2187. package/dist/ui/client/flow-map.mjs.map +1 -0
  2188. package/dist/ui/client/live-doc-blocks.d.ts +19 -0
  2189. package/dist/ui/client/live-doc-blocks.d.ts.map +1 -0
  2190. package/dist/ui/client/live-doc-blocks.js +23 -0
  2191. package/dist/ui/client/live-doc-blocks.js.map +1 -0
  2192. package/dist/ui/client/live-doc-markdown.d.ts +18 -0
  2193. package/dist/ui/client/live-doc-markdown.d.ts.map +1 -0
  2194. package/dist/ui/client/live-doc-markdown.js +175 -0
  2195. package/dist/ui/client/live-doc-markdown.js.map +1 -0
  2196. package/dist/ui/client/live-doc-shell.d.ts +101 -0
  2197. package/dist/ui/client/live-doc-shell.d.ts.map +1 -0
  2198. package/dist/ui/client/live-doc-shell.js +251 -0
  2199. package/dist/ui/client/live-doc-shell.js.map +1 -0
  2200. package/dist/ui/client/live-doc-view.d.ts +33 -0
  2201. package/dist/ui/client/live-doc-view.d.ts.map +1 -0
  2202. package/dist/ui/client/live-doc-view.js +1237 -0
  2203. package/dist/ui/client/live-doc-view.js.map +1 -0
  2204. package/dist/ui/client/live-doc.css +243 -0
  2205. package/dist/ui/client/live-doc.d.mts +12 -0
  2206. package/dist/ui/client/live-doc.d.mts.map +1 -0
  2207. package/dist/ui/client/live-doc.mjs +11 -0
  2208. package/dist/ui/client/live-doc.mjs.map +7 -0
  2209. package/dist/ui/client/mail-bundle.d.mts +9 -0
  2210. package/dist/ui/client/mail-bundle.d.mts.map +1 -0
  2211. package/dist/ui/client/mail-bundle.mjs +50 -0
  2212. package/dist/ui/client/mail-bundle.mjs.map +7 -0
  2213. package/dist/ui/client/mail-entry.d.mts +11 -0
  2214. package/dist/ui/client/mail-entry.d.mts.map +1 -0
  2215. package/dist/ui/client/mail-entry.mjs +9 -0
  2216. package/dist/ui/client/mail-entry.mjs.map +1 -0
  2217. package/dist/ui/client/mail-view.d.mts.map +1 -1
  2218. package/dist/ui/client/mail-view.mjs +5 -3
  2219. package/dist/ui/client/mail-view.mjs.map +1 -1
  2220. package/dist/ui/client/mail.css +3 -3
  2221. package/dist/ui/client/relation-select-view.d.ts +77 -0
  2222. package/dist/ui/client/relation-select-view.d.ts.map +1 -0
  2223. package/dist/ui/client/relation-select-view.js +216 -0
  2224. package/dist/ui/client/relation-select-view.js.map +1 -0
  2225. package/dist/ui/client/table-selection-view.d.ts +4 -0
  2226. package/dist/ui/client/table-selection-view.d.ts.map +1 -0
  2227. package/dist/ui/client/table-selection-view.js +283 -0
  2228. package/dist/ui/client/table-selection-view.js.map +1 -0
  2229. package/dist/ui/dashboard-page.d.ts +6 -0
  2230. package/dist/ui/dashboard-page.d.ts.map +1 -0
  2231. package/dist/ui/dashboard-page.js +4 -0
  2232. package/dist/ui/dashboard-page.js.map +1 -0
  2233. package/dist/ui/data.d.ts +51 -1
  2234. package/dist/ui/data.d.ts.map +1 -1
  2235. package/dist/ui/data.js +87 -1
  2236. package/dist/ui/data.js.map +1 -1
  2237. package/dist/ui/date-picker.d.ts.map +1 -1
  2238. package/dist/ui/date-picker.js +2 -2
  2239. package/dist/ui/date-picker.js.map +1 -1
  2240. package/dist/ui/form-page.d.ts +6 -0
  2241. package/dist/ui/form-page.d.ts.map +1 -0
  2242. package/dist/ui/form-page.js +5 -0
  2243. package/dist/ui/form-page.js.map +1 -0
  2244. package/dist/ui/form.d.ts +4 -1
  2245. package/dist/ui/form.d.ts.map +1 -1
  2246. package/dist/ui/form.js +7 -5
  2247. package/dist/ui/form.js.map +1 -1
  2248. package/dist/ui/format.d.ts +13 -2
  2249. package/dist/ui/format.d.ts.map +1 -1
  2250. package/dist/ui/format.js +28 -7
  2251. package/dist/ui/format.js.map +1 -1
  2252. package/dist/ui/gantt.d.ts +52 -0
  2253. package/dist/ui/gantt.d.ts.map +1 -0
  2254. package/dist/ui/gantt.js +92 -0
  2255. package/dist/ui/gantt.js.map +1 -0
  2256. package/dist/ui/hooks.d.ts.map +1 -1
  2257. package/dist/ui/hooks.js +14 -0
  2258. package/dist/ui/hooks.js.map +1 -1
  2259. package/dist/ui/icons.d.ts.map +1 -1
  2260. package/dist/ui/icons.js +6 -1
  2261. package/dist/ui/icons.js.map +1 -1
  2262. package/dist/ui/index.d.ts +95 -14
  2263. package/dist/ui/index.d.ts.map +1 -1
  2264. package/dist/ui/index.js +78 -13
  2265. package/dist/ui/index.js.map +1 -1
  2266. package/dist/ui/layout.d.ts +43 -38
  2267. package/dist/ui/layout.d.ts.map +1 -1
  2268. package/dist/ui/layout.js +29 -37
  2269. package/dist/ui/layout.js.map +1 -1
  2270. package/dist/ui/list-page.d.ts +19 -0
  2271. package/dist/ui/list-page.d.ts.map +1 -0
  2272. package/dist/ui/list-page.js +21 -0
  2273. package/dist/ui/list-page.js.map +1 -0
  2274. package/dist/ui/media.d.ts.map +1 -1
  2275. package/dist/ui/media.js +1 -1
  2276. package/dist/ui/media.js.map +1 -1
  2277. package/dist/ui/modal.d.ts +26 -1
  2278. package/dist/ui/modal.d.ts.map +1 -1
  2279. package/dist/ui/modal.js +18 -2
  2280. package/dist/ui/modal.js.map +1 -1
  2281. package/dist/ui/nav.d.ts +21 -1
  2282. package/dist/ui/nav.d.ts.map +1 -1
  2283. package/dist/ui/nav.js +43 -8
  2284. package/dist/ui/nav.js.map +1 -1
  2285. package/dist/ui/navigation.d.ts +36 -2
  2286. package/dist/ui/navigation.d.ts.map +1 -1
  2287. package/dist/ui/navigation.js +60 -5
  2288. package/dist/ui/navigation.js.map +1 -1
  2289. package/dist/ui/partner.d.ts +18 -0
  2290. package/dist/ui/partner.d.ts.map +1 -0
  2291. package/dist/ui/partner.js +11 -0
  2292. package/dist/ui/partner.js.map +1 -0
  2293. package/dist/ui/primitives.d.ts +28 -10
  2294. package/dist/ui/primitives.d.ts.map +1 -1
  2295. package/dist/ui/primitives.js +21 -7
  2296. package/dist/ui/primitives.js.map +1 -1
  2297. package/dist/ui/product-media.d.ts +47 -0
  2298. package/dist/ui/product-media.d.ts.map +1 -0
  2299. package/dist/ui/product-media.js +67 -0
  2300. package/dist/ui/product-media.js.map +1 -0
  2301. package/dist/ui/product-variants.d.ts +68 -0
  2302. package/dist/ui/product-variants.d.ts.map +1 -0
  2303. package/dist/ui/product-variants.js +81 -0
  2304. package/dist/ui/product-variants.js.map +1 -0
  2305. package/dist/ui/record-detail.d.ts +70 -0
  2306. package/dist/ui/record-detail.d.ts.map +1 -0
  2307. package/dist/ui/record-detail.js +35 -0
  2308. package/dist/ui/record-detail.js.map +1 -0
  2309. package/dist/ui/record-page.d.ts +16 -0
  2310. package/dist/ui/record-page.d.ts.map +1 -0
  2311. package/dist/ui/record-page.js +13 -0
  2312. package/dist/ui/record-page.js.map +1 -0
  2313. package/dist/ui/record.d.ts +15 -3
  2314. package/dist/ui/record.d.ts.map +1 -1
  2315. package/dist/ui/record.js +6 -5
  2316. package/dist/ui/record.js.map +1 -1
  2317. package/dist/ui/surfaces.d.ts +30 -2
  2318. package/dist/ui/surfaces.d.ts.map +1 -1
  2319. package/dist/ui/surfaces.js +39 -2
  2320. package/dist/ui/surfaces.js.map +1 -1
  2321. package/dist/ui/table.d.ts +25 -2
  2322. package/dist/ui/table.d.ts.map +1 -1
  2323. package/dist/ui/table.js +10 -6
  2324. package/dist/ui/table.js.map +1 -1
  2325. package/dist/ui/timeframe.d.ts +39 -0
  2326. package/dist/ui/timeframe.d.ts.map +1 -0
  2327. package/dist/ui/timeframe.js +36 -0
  2328. package/dist/ui/timeframe.js.map +1 -0
  2329. package/dist/ui/workspace-page.d.ts +16 -0
  2330. package/dist/ui/workspace-page.d.ts.map +1 -0
  2331. package/dist/ui/workspace-page.js +15 -0
  2332. package/dist/ui/workspace-page.js.map +1 -0
  2333. package/package.json +16 -3
  2334. package/dist/modules/account/tt99.d.ts +0 -30
  2335. package/dist/modules/account/tt99.d.ts.map +0 -1
  2336. package/dist/modules/account/tt99.js +0 -1661
  2337. package/dist/modules/account/tt99.js.map +0 -1
  2338. package/dist/modules/account_backend/accounting-overview-screen.d.ts +0 -18
  2339. package/dist/modules/account_backend/accounting-overview-screen.d.ts.map +0 -1
  2340. package/dist/modules/account_backend/accounting-overview-screen.js +0 -104
  2341. package/dist/modules/account_backend/accounting-overview-screen.js.map +0 -1
  2342. package/dist/modules/account_backend/accounts-screen.d.ts +0 -13
  2343. package/dist/modules/account_backend/accounts-screen.d.ts.map +0 -1
  2344. package/dist/modules/account_backend/accounts-screen.js +0 -49
  2345. package/dist/modules/account_backend/accounts-screen.js.map +0 -1
  2346. package/dist/modules/account_backend/customer-invoices-screen.d.ts +0 -14
  2347. package/dist/modules/account_backend/customer-invoices-screen.d.ts.map +0 -1
  2348. package/dist/modules/account_backend/customer-invoices-screen.js +0 -63
  2349. package/dist/modules/account_backend/customer-invoices-screen.js.map +0 -1
  2350. package/dist/modules/account_backend/general-ledger-screen.d.ts +0 -13
  2351. package/dist/modules/account_backend/general-ledger-screen.d.ts.map +0 -1
  2352. package/dist/modules/account_backend/general-ledger-screen.js +0 -56
  2353. package/dist/modules/account_backend/general-ledger-screen.js.map +0 -1
  2354. package/dist/modules/account_backend/journal-entries-screen.d.ts +0 -14
  2355. package/dist/modules/account_backend/journal-entries-screen.d.ts.map +0 -1
  2356. package/dist/modules/account_backend/journal-entries-screen.js +0 -45
  2357. package/dist/modules/account_backend/journal-entries-screen.js.map +0 -1
  2358. package/dist/modules/account_backend/journals-screen.d.ts +0 -14
  2359. package/dist/modules/account_backend/journals-screen.d.ts.map +0 -1
  2360. package/dist/modules/account_backend/journals-screen.js +0 -53
  2361. package/dist/modules/account_backend/journals-screen.js.map +0 -1
  2362. package/dist/modules/account_backend/move-detail-screen.d.ts +0 -10
  2363. package/dist/modules/account_backend/move-detail-screen.d.ts.map +0 -1
  2364. package/dist/modules/account_backend/move-detail-screen.js +0 -100
  2365. package/dist/modules/account_backend/move-detail-screen.js.map +0 -1
  2366. package/dist/modules/account_backend/partner-ledger-screen.d.ts +0 -14
  2367. package/dist/modules/account_backend/partner-ledger-screen.d.ts.map +0 -1
  2368. package/dist/modules/account_backend/partner-ledger-screen.js +0 -69
  2369. package/dist/modules/account_backend/partner-ledger-screen.js.map +0 -1
  2370. package/dist/modules/account_backend/payment-terms-screen.d.ts +0 -14
  2371. package/dist/modules/account_backend/payment-terms-screen.d.ts.map +0 -1
  2372. package/dist/modules/account_backend/payment-terms-screen.js +0 -40
  2373. package/dist/modules/account_backend/payment-terms-screen.js.map +0 -1
  2374. package/dist/modules/account_backend/payments-screen.d.ts +0 -14
  2375. package/dist/modules/account_backend/payments-screen.d.ts.map +0 -1
  2376. package/dist/modules/account_backend/payments-screen.js +0 -54
  2377. package/dist/modules/account_backend/payments-screen.js.map +0 -1
  2378. package/dist/modules/account_backend/screens.d.ts +0 -7
  2379. package/dist/modules/account_backend/screens.d.ts.map +0 -1
  2380. package/dist/modules/account_backend/screens.js +0 -7
  2381. package/dist/modules/account_backend/screens.js.map +0 -1
  2382. package/dist/modules/account_backend/taxes-screen.d.ts +0 -15
  2383. package/dist/modules/account_backend/taxes-screen.d.ts.map +0 -1
  2384. package/dist/modules/account_backend/taxes-screen.js +0 -73
  2385. package/dist/modules/account_backend/taxes-screen.js.map +0 -1
  2386. package/dist/modules/account_backend/trial-balance-screen.d.ts +0 -13
  2387. package/dist/modules/account_backend/trial-balance-screen.d.ts.map +0 -1
  2388. package/dist/modules/account_backend/trial-balance-screen.js +0 -62
  2389. package/dist/modules/account_backend/trial-balance-screen.js.map +0 -1
  2390. package/dist/modules/account_backend/vendor-bills-screen.d.ts +0 -14
  2391. package/dist/modules/account_backend/vendor-bills-screen.d.ts.map +0 -1
  2392. package/dist/modules/account_backend/vendor-bills-screen.js +0 -59
  2393. package/dist/modules/account_backend/vendor-bills-screen.js.map +0 -1
  2394. package/dist/modules/account_partner_backend/screens.d.ts +0 -16
  2395. package/dist/modules/account_partner_backend/screens.d.ts.map +0 -1
  2396. package/dist/modules/account_partner_backend/screens.js +0 -26
  2397. package/dist/modules/account_partner_backend/screens.js.map +0 -1
  2398. package/dist/modules/activity_backend/screens.d.ts +0 -5
  2399. package/dist/modules/activity_backend/screens.d.ts.map +0 -1
  2400. package/dist/modules/activity_backend/screens.js +0 -52
  2401. package/dist/modules/activity_backend/screens.js.map +0 -1
  2402. package/dist/modules/address_backend/screens.d.ts +0 -31
  2403. package/dist/modules/address_backend/screens.d.ts.map +0 -1
  2404. package/dist/modules/address_backend/screens.js +0 -147
  2405. package/dist/modules/address_backend/screens.js.map +0 -1
  2406. package/dist/modules/backend/design/admin.css +0 -4229
  2407. package/dist/modules/backend/design/client/relation-select-view.d.mts +0 -5
  2408. package/dist/modules/backend/design/client/relation-select-view.d.mts.map +0 -1
  2409. package/dist/modules/backend/design/client/relation-select-view.mjs +0 -335
  2410. package/dist/modules/backend/design/client/relation-select-view.mjs.map +0 -1
  2411. package/dist/modules/calendar_backend/screens.d.ts +0 -5
  2412. package/dist/modules/calendar_backend/screens.d.ts.map +0 -1
  2413. package/dist/modules/calendar_backend/screens.js +0 -4
  2414. package/dist/modules/calendar_backend/screens.js.map +0 -1
  2415. package/dist/modules/company_backend/screens.d.ts +0 -62
  2416. package/dist/modules/company_backend/screens.d.ts.map +0 -1
  2417. package/dist/modules/company_backend/screens.js +0 -268
  2418. package/dist/modules/company_backend/screens.js.map +0 -1
  2419. package/dist/modules/crm_backend/list-search.d.ts +0 -21
  2420. package/dist/modules/crm_backend/list-search.d.ts.map +0 -1
  2421. package/dist/modules/crm_backend/list-search.js +0 -220
  2422. package/dist/modules/crm_backend/list-search.js.map +0 -1
  2423. package/dist/modules/crm_backend/screens.d.ts +0 -32
  2424. package/dist/modules/crm_backend/screens.d.ts.map +0 -1
  2425. package/dist/modules/crm_backend/screens.js +0 -405
  2426. package/dist/modules/crm_backend/screens.js.map +0 -1
  2427. package/dist/modules/hospitality_core/screens.d.ts +0 -773
  2428. package/dist/modules/hospitality_core/screens.d.ts.map +0 -1
  2429. package/dist/modules/hospitality_core/screens.js +0 -4152
  2430. package/dist/modules/hospitality_core/screens.js.map +0 -1
  2431. package/dist/modules/hr_backend/screens.d.ts +0 -9
  2432. package/dist/modules/hr_backend/screens.d.ts.map +0 -1
  2433. package/dist/modules/hr_backend/screens.js +0 -144
  2434. package/dist/modules/hr_backend/screens.js.map +0 -1
  2435. package/dist/modules/loyalty_backend/screens.d.ts +0 -33
  2436. package/dist/modules/loyalty_backend/screens.d.ts.map +0 -1
  2437. package/dist/modules/loyalty_backend/screens.js +0 -562
  2438. package/dist/modules/loyalty_backend/screens.js.map +0 -1
  2439. package/dist/modules/mail_backend/screens.d.ts +0 -5
  2440. package/dist/modules/mail_backend/screens.d.ts.map +0 -1
  2441. package/dist/modules/mail_backend/screens.js +0 -11
  2442. package/dist/modules/mail_backend/screens.js.map +0 -1
  2443. package/dist/modules/mail_inbound_backend/screens.d.ts +0 -5
  2444. package/dist/modules/mail_inbound_backend/screens.d.ts.map +0 -1
  2445. package/dist/modules/mail_inbound_backend/screens.js +0 -25
  2446. package/dist/modules/mail_inbound_backend/screens.js.map +0 -1
  2447. package/dist/modules/mail_transport_backend/screens.d.ts +0 -5
  2448. package/dist/modules/mail_transport_backend/screens.d.ts.map +0 -1
  2449. package/dist/modules/mail_transport_backend/screens.js +0 -35
  2450. package/dist/modules/mail_transport_backend/screens.js.map +0 -1
  2451. package/dist/modules/oauth_backend/screens.d.ts +0 -66
  2452. package/dist/modules/oauth_backend/screens.d.ts.map +0 -1
  2453. package/dist/modules/oauth_backend/screens.js +0 -323
  2454. package/dist/modules/oauth_backend/screens.js.map +0 -1
  2455. package/dist/modules/odoo_collaboration_import/functions.d.ts.map +0 -1
  2456. package/dist/modules/odoo_collaboration_import/functions.js +0 -128
  2457. package/dist/modules/odoo_collaboration_import/functions.js.map +0 -1
  2458. package/dist/modules/odoo_collaboration_import/index.d.ts +0 -6
  2459. package/dist/modules/odoo_collaboration_import/index.d.ts.map +0 -1
  2460. package/dist/modules/odoo_collaboration_import/index.js +0 -31
  2461. package/dist/modules/odoo_collaboration_import/index.js.map +0 -1
  2462. package/dist/modules/odoo_collaboration_import/models.d.ts.map +0 -1
  2463. package/dist/modules/odoo_collaboration_import/models.js +0 -76
  2464. package/dist/modules/odoo_collaboration_import/models.js.map +0 -1
  2465. package/dist/modules/odoo_collaboration_import/operations.d.ts +0 -14
  2466. package/dist/modules/odoo_collaboration_import/operations.d.ts.map +0 -1
  2467. package/dist/modules/odoo_collaboration_import/operations.js +0 -1139
  2468. package/dist/modules/odoo_collaboration_import/operations.js.map +0 -1
  2469. package/dist/modules/odoo_collaboration_import/relations.d.ts.map +0 -1
  2470. package/dist/modules/odoo_collaboration_import/relations.js +0 -19
  2471. package/dist/modules/odoo_collaboration_import/relations.js.map +0 -1
  2472. package/dist/modules/odoo_collaboration_import/types.d.ts +0 -58
  2473. package/dist/modules/odoo_collaboration_import/types.d.ts.map +0 -1
  2474. package/dist/modules/odoo_collaboration_import/types.js.map +0 -1
  2475. package/dist/modules/partner_backend/screens.d.ts +0 -53
  2476. package/dist/modules/partner_backend/screens.d.ts.map +0 -1
  2477. package/dist/modules/partner_backend/screens.js +0 -169
  2478. package/dist/modules/partner_backend/screens.js.map +0 -1
  2479. package/dist/modules/pricing_backend/screens.d.ts +0 -13
  2480. package/dist/modules/pricing_backend/screens.d.ts.map +0 -1
  2481. package/dist/modules/pricing_backend/screens.js +0 -182
  2482. package/dist/modules/pricing_backend/screens.js.map +0 -1
  2483. package/dist/modules/product_backend/attributes-screen.d.ts +0 -7
  2484. package/dist/modules/product_backend/attributes-screen.d.ts.map +0 -1
  2485. package/dist/modules/product_backend/attributes-screen.js +0 -76
  2486. package/dist/modules/product_backend/attributes-screen.js.map +0 -1
  2487. package/dist/modules/product_backend/create-screen.d.ts +0 -12
  2488. package/dist/modules/product_backend/create-screen.d.ts.map +0 -1
  2489. package/dist/modules/product_backend/create-screen.js +0 -83
  2490. package/dist/modules/product_backend/create-screen.js.map +0 -1
  2491. package/dist/modules/product_backend/screens.d.ts +0 -68
  2492. package/dist/modules/product_backend/screens.d.ts.map +0 -1
  2493. package/dist/modules/product_backend/screens.js +0 -388
  2494. package/dist/modules/product_backend/screens.js.map +0 -1
  2495. package/dist/modules/purchase_backend/screens.d.ts +0 -29
  2496. package/dist/modules/purchase_backend/screens.d.ts.map +0 -1
  2497. package/dist/modules/purchase_backend/screens.js +0 -324
  2498. package/dist/modules/purchase_backend/screens.js.map +0 -1
  2499. package/dist/modules/sale_backend/invoicing-policies-screen.d.ts +0 -14
  2500. package/dist/modules/sale_backend/invoicing-policies-screen.d.ts.map +0 -1
  2501. package/dist/modules/sale_backend/invoicing-policies-screen.js +0 -36
  2502. package/dist/modules/sale_backend/invoicing-policies-screen.js.map +0 -1
  2503. package/dist/modules/sale_backend/order-detail-screen.d.ts +0 -18
  2504. package/dist/modules/sale_backend/order-detail-screen.d.ts.map +0 -1
  2505. package/dist/modules/sale_backend/order-detail-screen.js +0 -217
  2506. package/dist/modules/sale_backend/order-detail-screen.js.map +0 -1
  2507. package/dist/modules/sale_backend/quotations-screen.d.ts +0 -15
  2508. package/dist/modules/sale_backend/quotations-screen.d.ts.map +0 -1
  2509. package/dist/modules/sale_backend/quotations-screen.js +0 -64
  2510. package/dist/modules/sale_backend/quotations-screen.js.map +0 -1
  2511. package/dist/modules/sale_backend/sales-orders-screen.d.ts +0 -12
  2512. package/dist/modules/sale_backend/sales-orders-screen.d.ts.map +0 -1
  2513. package/dist/modules/sale_backend/sales-orders-screen.js +0 -65
  2514. package/dist/modules/sale_backend/sales-orders-screen.js.map +0 -1
  2515. package/dist/modules/sale_backend/screens.d.ts +0 -23
  2516. package/dist/modules/sale_backend/screens.d.ts.map +0 -1
  2517. package/dist/modules/sale_backend/screens.js +0 -275
  2518. package/dist/modules/sale_backend/screens.js.map +0 -1
  2519. package/dist/modules/stock_backend/forecast-screen.d.ts +0 -28
  2520. package/dist/modules/stock_backend/forecast-screen.d.ts.map +0 -1
  2521. package/dist/modules/stock_backend/forecast-screen.js +0 -108
  2522. package/dist/modules/stock_backend/forecast-screen.js.map +0 -1
  2523. package/dist/modules/stock_backend/inventory-screen.d.ts +0 -27
  2524. package/dist/modules/stock_backend/inventory-screen.d.ts.map +0 -1
  2525. package/dist/modules/stock_backend/inventory-screen.js +0 -141
  2526. package/dist/modules/stock_backend/inventory-screen.js.map +0 -1
  2527. package/dist/modules/stock_backend/locations-screen.d.ts +0 -18
  2528. package/dist/modules/stock_backend/locations-screen.d.ts.map +0 -1
  2529. package/dist/modules/stock_backend/locations-screen.js +0 -92
  2530. package/dist/modules/stock_backend/locations-screen.js.map +0 -1
  2531. package/dist/modules/stock_backend/lot-screen.d.ts +0 -30
  2532. package/dist/modules/stock_backend/lot-screen.d.ts.map +0 -1
  2533. package/dist/modules/stock_backend/lot-screen.js +0 -86
  2534. package/dist/modules/stock_backend/lot-screen.js.map +0 -1
  2535. package/dist/modules/stock_backend/lots-screen.d.ts +0 -21
  2536. package/dist/modules/stock_backend/lots-screen.d.ts.map +0 -1
  2537. package/dist/modules/stock_backend/lots-screen.js +0 -79
  2538. package/dist/modules/stock_backend/lots-screen.js.map +0 -1
  2539. package/dist/modules/stock_backend/picking-types-screen.d.ts +0 -21
  2540. package/dist/modules/stock_backend/picking-types-screen.d.ts.map +0 -1
  2541. package/dist/modules/stock_backend/picking-types-screen.js +0 -110
  2542. package/dist/modules/stock_backend/picking-types-screen.js.map +0 -1
  2543. package/dist/modules/stock_backend/replenishment-screen.d.ts +0 -29
  2544. package/dist/modules/stock_backend/replenishment-screen.d.ts.map +0 -1
  2545. package/dist/modules/stock_backend/replenishment-screen.js +0 -131
  2546. package/dist/modules/stock_backend/replenishment-screen.js.map +0 -1
  2547. package/dist/modules/stock_backend/screens.d.ts +0 -14
  2548. package/dist/modules/stock_backend/screens.d.ts.map +0 -1
  2549. package/dist/modules/stock_backend/screens.js +0 -40
  2550. package/dist/modules/stock_backend/screens.js.map +0 -1
  2551. package/dist/modules/stock_backend/stock-route-screen.d.ts +0 -30
  2552. package/dist/modules/stock_backend/stock-route-screen.d.ts.map +0 -1
  2553. package/dist/modules/stock_backend/stock-route-screen.js +0 -129
  2554. package/dist/modules/stock_backend/stock-route-screen.js.map +0 -1
  2555. package/dist/modules/stock_backend/stock-routes-screen.d.ts +0 -17
  2556. package/dist/modules/stock_backend/stock-routes-screen.d.ts.map +0 -1
  2557. package/dist/modules/stock_backend/stock-routes-screen.js +0 -60
  2558. package/dist/modules/stock_backend/stock-routes-screen.js.map +0 -1
  2559. package/dist/modules/stock_backend/transfer-screen.d.ts +0 -26
  2560. package/dist/modules/stock_backend/transfer-screen.d.ts.map +0 -1
  2561. package/dist/modules/stock_backend/transfer-screen.js +0 -95
  2562. package/dist/modules/stock_backend/transfer-screen.js.map +0 -1
  2563. package/dist/modules/stock_backend/transfers-screen.d.ts +0 -21
  2564. package/dist/modules/stock_backend/transfers-screen.d.ts.map +0 -1
  2565. package/dist/modules/stock_backend/transfers-screen.js +0 -88
  2566. package/dist/modules/stock_backend/transfers-screen.js.map +0 -1
  2567. package/dist/modules/stock_backend/warehouses-screen.d.ts +0 -17
  2568. package/dist/modules/stock_backend/warehouses-screen.d.ts.map +0 -1
  2569. package/dist/modules/stock_backend/warehouses-screen.js +0 -96
  2570. package/dist/modules/stock_backend/warehouses-screen.js.map +0 -1
  2571. package/dist/modules/user_backend/screens.d.ts +0 -70
  2572. package/dist/modules/user_backend/screens.d.ts.map +0 -1
  2573. package/dist/modules/user_backend/screens.js +0 -308
  2574. package/dist/modules/user_backend/screens.js.map +0 -1
  2575. package/dist/modules/website/customer-routes.d.ts +0 -3
  2576. package/dist/modules/website/customer-routes.d.ts.map +0 -1
  2577. package/dist/modules/website/customer-routes.js +0 -322
  2578. package/dist/modules/website/customer-routes.js.map +0 -1
  2579. package/dist/modules/website_backend/screens.d.ts +0 -114
  2580. package/dist/modules/website_backend/screens.d.ts.map +0 -1
  2581. package/dist/modules/website_backend/screens.js +0 -625
  2582. package/dist/modules/website_backend/screens.js.map +0 -1
  2583. package/dist/ui/client/mail.d.mts +0 -11
  2584. package/dist/ui/client/mail.d.mts.map +0 -1
  2585. package/dist/ui/client/mail.mjs +0 -10
  2586. package/dist/ui/client/mail.mjs.map +0 -1
  2587. /package/dist/modules/{odoo_collaboration_import → account_staff_channel}/functions.d.ts +0 -0
  2588. /package/dist/modules/{odoo_collaboration_import → account_staff_channel}/models.d.ts +0 -0
  2589. /package/dist/modules/{odoo_collaboration_import → address_backend/screens}/types.js +0 -0
  2590. /package/dist/modules/{odoo_collaboration_import → manufacturing}/relations.d.ts +0 -0
@@ -1,5 +1,8 @@
1
- import { asc, defineFn, eq, from } from '@ketvietlab/ketjs';
1
+ import { and, asc, defineFn, deleteFrom, eq, from, ilike, inArray, or } from '@ketvietlab/ketjs';
2
+ import { accountingFilterDateText, accountingDateText, assertAccountingTimezone, DEFAULT_ACCOUNTING_TIMEZONE, fiscalYearKey, moveAccountingDate, } from './date.js';
3
+ import { canonicalDecimalText, compareDecimals, decimalSign, discountedLineMinor, divisionTaxMinor, includedDivisionBaseMinor, includedPercentBaseMinor, minorText, MONEY_POLICY_VERSION, moneyMinor, multiplyToMinor, percentOfMinor, scaleOf, sumMoneyMinor, } from './money.js';
2
4
  import { ACCOUNT_SETUP_EFFECTS, ensureCompanyAccounting } from './setup.js';
5
+ import { claimPostingPeriod } from './period.js';
3
6
  export const ACCOUNT_TYPES = [
4
7
  'asset_receivable',
5
8
  'asset_cash',
@@ -32,19 +35,26 @@ export const MOVE_TYPES = [
32
35
  'in_receipt',
33
36
  ];
34
37
  export const MOVE_STATES = ['draft', 'posted', 'cancel'];
35
- export const PAYMENT_STATES = [
36
- 'not_paid',
37
- 'in_payment',
38
- 'paid',
39
- 'partial',
40
- 'reversed',
41
- 'blocked',
42
- 'invoicing_legacy',
43
- ];
38
+ /**
39
+ * The four a document can actually be in.
40
+ *
41
+ * Three more were carried over from the ERP this vocabulary came from, and
42
+ * nothing in this ledger ever wrote them — so a filter offering them returned an
43
+ * empty list however the books were kept. Same reason `group` left
44
+ * TAX_AMOUNT_TYPES: a choice that cannot be reached only wastes the reader's
45
+ * time.
46
+ */
47
+ export const PAYMENT_STATES = ['not_paid', 'paid', 'partial', 'reversed'];
44
48
  export const TAX_USES = ['sale', 'purchase', 'none'];
45
- export const TAX_AMOUNT_TYPES = ['group', 'fixed', 'percent', 'division'];
49
+ /**
50
+ * Group taxes are deliberately absent: a line takes a list of taxes and applies
51
+ * them in sequence, which is what a group would have expressed anyway. Offering
52
+ * `group` as a saveable amount type only produced taxes that threw on first use.
53
+ */
54
+ export const TAX_AMOUNT_TYPES = ['fixed', 'percent', 'division'];
46
55
  export const PAYMENT_TYPES = ['outbound', 'inbound'];
47
56
  export const PARTNER_TYPES = ['customer', 'supplier'];
57
+ export const PAYMENT_SETTLEMENT_KINDS = ['liquidity', 'stored_value'];
48
58
  export const PAYMENT_TERM_VALUES = ['percent', 'fixed'];
49
59
  export const PAYMENT_TERM_DELAY_TYPES = [
50
60
  'days_after',
@@ -52,22 +62,556 @@ export const PAYMENT_TERM_DELAY_TYPES = [
52
62
  'days_after_end_of_next_month',
53
63
  'days_end_of_month_on_the',
54
64
  ];
55
- const invalid = (field, message) => ({ ok: false, errors: [{ field, message }] });
65
+ /**
66
+ * Every way this module can say no, in one place.
67
+ *
68
+ * A refusal travels as a code, because the words belong to whoever is reading:
69
+ * a backend screen translates it, and a ledger read in Vietnamese must not grow
70
+ * English prose. The sentence here is the same reason for an API client or a log
71
+ * that has no translator, and `{name}` placeholders are filled from `params`.
72
+ */
73
+ const REFUSALS = {
74
+ moveMissing: 'journal entry does not exist',
75
+ moveDraftOnly: 'only a draft entry can be posted',
76
+ movePostedOnly: 'only a posted entry can be reversed',
77
+ moveNotCancellable: 'a posted entry is corrected with account.reverseMove, not cancelled',
78
+ moveConcurrent: 'the invoice changed concurrently; review it and retry',
79
+ moveIdReused: 'a different journal entry already uses this id',
80
+ moveTypeUnsupported: 'unsupported move type',
81
+ linesTooFew: 'a journal entry needs at least two lines',
82
+ lineSideBoth: 'each line must have a non-negative debit or credit, never both',
83
+ lineAmountRequired: 'each journal item needs a non-zero debit or credit',
84
+ lineBalanceInvalid: 'journal item balance must equal debit minus credit',
85
+ lineResidualInvalid: 'journal item residual is inconsistent with its account and balance',
86
+ entryUnbalanced: 'entry is not balanced: debit {debit}, credit {credit}',
87
+ moveTotalInvalid: 'document totals do not match its open-item counterparts',
88
+ reversalNoLines: 'the entry has no journal items to reverse',
89
+ reversalIdReused: 'a different reversal already uses this id',
90
+ moveAlreadyReversed: 'the entry already has a different reversal',
91
+ lineDraftOnly: 'lines can only be added to a draft entry',
92
+ lineIdTaken: 'a different journal item already uses this id',
93
+ moneyExactString: 'money values must be canonical decimal strings without exponent notation',
94
+ accountingDateInvalid: 'accounting and document dates must be valid civil dates',
95
+ moveCurrencyMismatch: 'journal entry currency must match the active company ledger',
96
+ periodLocked: 'the {scope} books are locked through {through}',
97
+ periodConcurrent: 'the accounting period policy changed; review and retry',
98
+ accountMissing: 'account does not exist',
99
+ accountInactive: 'inactive accounts cannot receive new journal items',
100
+ accountTypeUnsupported: 'unsupported account type',
101
+ accountCodeFormat: 'account code may contain only letters, numbers, and dots',
102
+ offBalanceReconcile: 'off-balance accounts cannot be reconciled',
103
+ defaultAccountMissing: 'default account does not exist',
104
+ journalMissing: 'journal does not exist',
105
+ journalInactive: 'inactive journals cannot post new entries',
106
+ journalTypeUnsupported: 'unsupported journal type',
107
+ journalCodeFormat: 'journal code must be alphanumeric',
108
+ journalMustBeSale: 'a customer document requires a sale journal',
109
+ journalMustBePurchase: 'a vendor document requires a purchase journal',
110
+ journalLiquidityMissing: 'payment journal needs a default liquidity account',
111
+ journalNotLiquidity: 'payments require a bank or cash journal',
112
+ journalNotStoredValue: 'stored value settlements require a general journal',
113
+ journalStoredValueAccount: 'stored value settlements require a liability default account',
114
+ taxMissing: 'tax does not exist',
115
+ taxUseUnsupported: 'unsupported tax use',
116
+ taxComputationUnsupported: 'unsupported tax computation',
117
+ taxScopeUnsupported: 'tax scope must be service or consu',
118
+ taxAccountMissing: 'tax account does not exist',
119
+ taxDirectionMismatch: 'tax "{name}" does not match the invoice direction',
120
+ taxPostingAccountMissing: 'tax "{name}" needs a valid posting account',
121
+ taxMixedPriceInclude: 'a line cannot mix price-included and price-excluded taxes',
122
+ taxManyPriceInclude: 'a line supports at most one price-included tax',
123
+ taxDivisionFull: 'a division tax of 100% or more has no finite base',
124
+ productMissing: 'product template does not exist',
125
+ taxFixedExceedsLine: 'a price-included fixed tax cannot be larger than the line it is inside',
126
+ taxQuantityPositive: 'line quantity must be positive',
127
+ taxPriceInvalid: 'unit price and discount are invalid',
128
+ partnerMissing: 'partner does not exist',
129
+ paymentTermMissing: 'payment term does not exist',
130
+ termValueUnsupported: 'value must be percent or fixed',
131
+ termDelayUnsupported: 'unsupported delay type',
132
+ termPercentRange: 'percentage must be between 0 and 100',
133
+ invoiceTypeRequired: 'createInvoice requires an invoice, refund, or receipt type',
134
+ invoiceIdReused: 'a different invoice already uses this id',
135
+ invoiceAccountsMissing: 'invoice accounts do not exist',
136
+ invoiceLinesAndSingle: 'give either lines or a single description, not both',
137
+ invoiceLinesEmpty: 'an invoice needs at least one line',
138
+ invoiceLineRequired: 'every invoice line needs a description',
139
+ lineAccountUndecided: 'no revenue or expense account was given, and neither the product category nor the company has a default',
140
+ counterpartAccountUndecided: 'no receivable or payable account was given, and neither the partner nor the company has a default',
141
+ categoryMissing: 'the product category does not exist',
142
+ defaultAccountType: 'that account type cannot serve as this default',
143
+ counterpartMustBeReceivable: 'the counterpart account must be a receivable account',
144
+ counterpartMustBePayable: 'the counterpart account must be a payable account',
145
+ paymentTypeUnsupported: 'payment type must be inbound or outbound',
146
+ paymentIdReused: 'a different payment already uses this id',
147
+ partnerTypeUnsupported: 'partner type must be customer or supplier',
148
+ paymentSettlementKindUnsupported: 'settlement kind must be liquidity or stored value',
149
+ storedValueOperationUnsupported: 'stored value balance operation must be issue or expire',
150
+ storedValueCounterpart: 'stored value issue needs an asset counterpart and expiry needs income',
151
+ amountPositive: 'payment amount must be positive',
152
+ destinationMissing: 'destination account does not exist',
153
+ destinationMustBeReceivable: 'a customer payment must settle a receivable account',
154
+ destinationMustBePayable: 'a supplier payment must settle a payable account',
155
+ openItemMissing: 'open item does not exist',
156
+ openItemAccountMismatch: 'open item uses another destination account',
157
+ openItemDirection: 'open item has the wrong debit or credit direction',
158
+ amountExceedsOpenItem: 'payment amount exceeds the selected open item',
159
+ invoicePaymentType: 'only a customer invoice can collect a payment',
160
+ invoicePaymentState: 'only a posted customer invoice can collect a payment',
161
+ invoicePaymentResidual: 'the customer invoice has no amount left to collect',
162
+ invoicePaymentAccounts: 'one mobile payment cannot settle several receivable accounts',
163
+ reconcileAmountPositive: 'reconciliation amount must be positive',
164
+ reconcileSides: 'reconciliation needs one debit and one credit line',
165
+ reconcileAccountMismatch: 'reconciled lines must use the same account',
166
+ reconcilePostedOnly: 'only posted journal items can be reconciled',
167
+ reconcileNotAllowed: 'this account does not allow reconciliation',
168
+ reconcileAmountExceeds: 'amount exceeds a residual balance',
169
+ reconcileConcurrent: 'residual balance changed concurrently; retry reconciliation',
170
+ };
171
+ const fill = (sentence, params) => params ? sentence.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? `{${name}}`)) : sentence;
172
+ const invalid = (field, code, params) => ({
173
+ ok: false,
174
+ errors: [{ field, code: `account.error.${code}`, message: fill(REFUSALS[code], params), params }],
175
+ });
176
+ /** A refusal raised from inside a helper or a transaction, carrying its code out. */
177
+ class Refusal extends Error {
178
+ code;
179
+ params;
180
+ constructor(code, params) {
181
+ super(fill(REFUSALS[code], params));
182
+ this.code = code;
183
+ this.params = params;
184
+ }
185
+ }
186
+ /** Turn whatever a guarded block threw into a refusal the caller can act on. */
187
+ const refused = (field, error) => error instanceof Refusal
188
+ ? invalid(field, error.code, error.params)
189
+ : { ok: false, errors: [{ field, message: error.message }] };
56
190
  const n = (value) => Number(value ?? 0);
57
- const money = (value) => Math.round((value + Number.EPSILON) * 100) / 100;
58
- const decimal = (value) => String(money(value));
191
+ /** Exact numeric identity without routing ledger values through JavaScript Number. */
192
+ const decimalIdentity = (value) => {
193
+ let source = String(value).trim().replace(/^\+/, '');
194
+ const exponent = /^(-?)(\d+)(?:\.(\d+))?e([+-]?\d+)$/i.exec(source);
195
+ if (exponent) {
196
+ const sign = exponent[1] ?? '';
197
+ const whole = exponent[2] ?? '0';
198
+ const fraction = exponent[3] ?? '';
199
+ const digits = whole + fraction;
200
+ const shift = Number(exponent[4]);
201
+ if (Number.isSafeInteger(shift) && Math.abs(shift) <= 4096) {
202
+ const point = whole.length + shift;
203
+ source =
204
+ point <= 0
205
+ ? `${sign}0.${'0'.repeat(-point)}${digits}`
206
+ : point >= digits.length
207
+ ? `${sign}${digits}${'0'.repeat(point - digits.length)}`
208
+ : `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;
209
+ }
210
+ }
211
+ const parsed = /^(-?)(?:(\d+)(?:\.(\d*))?|\.(\d+))$/.exec(source);
212
+ if (!parsed)
213
+ return source;
214
+ const negative = parsed[1] === '-';
215
+ const whole = (parsed[2] ?? '0').replace(/^0+(?=\d)/, '');
216
+ const fraction = (parsed[3] ?? parsed[4] ?? '').replace(/0+$/, '');
217
+ if (!/[1-9]/.test(`${whole}${fraction}`))
218
+ return '0';
219
+ return `${negative ? '-' : ''}${whole}${fraction ? `.${fraction}` : ''}`;
220
+ };
221
+ const DECIMAL_CREATE_FIELDS = new Set([
222
+ 'quantity',
223
+ 'priceUnit',
224
+ 'discount',
225
+ 'debit',
226
+ 'credit',
227
+ 'balance',
228
+ 'amountUntaxed',
229
+ 'amountTax',
230
+ 'amountTotal',
231
+ 'amountResidual',
232
+ ]);
233
+ /** Compare the values a command owns without being confused by adapter scalar types. */
234
+ const sameStored = (field, held, wanted) => {
235
+ if (held == null || wanted == null)
236
+ return (held ?? null) === (wanted ?? null);
237
+ if (DECIMAL_CREATE_FIELDS.has(field))
238
+ return decimalIdentity(held) === decimalIdentity(wanted);
239
+ return String(held) === String(wanted);
240
+ };
241
+ /**
242
+ * Idempotency means equal normalized financial semantics, not byte-identical JSON:
243
+ * immutable fields and line structure must match, while mutable posting state does not.
244
+ */
245
+ const rowMatches = (held, wanted, fields) => fields.every((field) => sameStored(field, held[field], wanted[field]));
246
+ /** Datetimes have one persisted spelling on both SQLite and PostgreSQL. */
247
+ const instantText = (value) => {
248
+ const at = value instanceof Date ? value : new Date(String(value));
249
+ return Number.isNaN(at.getTime()) ? String(value) : at.toISOString();
250
+ };
251
+ const MOVE_CREATE_FIELDS = [
252
+ 'journalId',
253
+ 'moveType',
254
+ 'ref',
255
+ 'partnerId',
256
+ 'invoiceDate',
257
+ 'invoiceDateDue',
258
+ 'paymentTermId',
259
+ 'currency',
260
+ 'moneyPolicyVersion',
261
+ ];
262
+ const MOVE_LINE_CREATE_FIELDS = [
263
+ 'moveId',
264
+ 'name',
265
+ 'accountId',
266
+ 'partnerId',
267
+ 'productId',
268
+ 'productUomId',
269
+ 'quantity',
270
+ 'priceUnit',
271
+ 'discount',
272
+ 'taxId',
273
+ 'debit',
274
+ 'credit',
275
+ 'balance',
276
+ 'dateMaturity',
277
+ 'displayType',
278
+ 'sequence',
279
+ ];
280
+ const claimMoveRevision = async (ctx, move, expectedRevision) => {
281
+ const revision = n(move.revision);
282
+ if (expectedRevision !== undefined && revision !== n(expectedRevision))
283
+ return false;
284
+ const changed = await ctx.db.compareAndSet('account.Move', { id: move.id }, { revision: move.revision ?? null }, { revision: revision + 1 });
285
+ return 'dryRun' in changed || changed.matched;
286
+ };
59
287
  const today = () => new Date().toISOString();
60
- async function companyCurrency(ctx) {
288
+ const wildcard = (value) => String(value ?? '').replace(/[\\%_]/g, '\\$&');
289
+ export async function ledgerOf(ctx) {
61
290
  if (!ctx.scope.company)
62
291
  throw new Error('accounting requires an active company');
63
292
  const company = (await ctx.db.select('company.Company', { id: ctx.scope.company }))[0];
64
293
  if (!company)
65
294
  throw new Error(`company ${ctx.scope.company} does not exist`);
66
- return String(company.currency);
295
+ const currency = String(company.currency);
296
+ const timezone = assertAccountingTimezone(company.accountingTimezone ?? DEFAULT_ACCOUNTING_TIMEZONE);
297
+ return { currency, scale: scaleOf(currency), timezone };
67
298
  }
68
299
  async function accountOf(ctx, id) {
69
300
  return (await ctx.db.select('account.Account', { id }))[0] ?? null;
70
301
  }
302
+ export class DraftMoveBoundaryError extends Error {
303
+ field;
304
+ constructor(field, message) {
305
+ super(message);
306
+ this.field = field;
307
+ }
308
+ }
309
+ const boundaryError = (field, message) => {
310
+ throw new DraftMoveBoundaryError(field, message);
311
+ };
312
+ /**
313
+ * The sole transaction-level boundary for a complete draft journal entry.
314
+ *
315
+ * Sale, Purchase and POS build their domain document inside a transaction, then
316
+ * hand the complete move here. The boundary re-derives every monetary invariant
317
+ * before any ledger row is accepted. Callers must pass their transaction context;
318
+ * this helper deliberately does not open a nested transaction.
319
+ */
320
+ export async function insertDraftMove(ctx, input) {
321
+ const { currency, scale, timezone } = await ledgerOf(ctx);
322
+ const moveId = String(input.move.id ?? '');
323
+ if (!moveId)
324
+ boundaryError('move.id', 'a draft move id is required');
325
+ if (input.move.state !== 'draft')
326
+ boundaryError('move.state', 'the shared boundary only accepts draft moves');
327
+ if (String(input.move.currency) !== currency)
328
+ boundaryError('move.currency', 'the move currency must match the active company ledger');
329
+ const journal = (await ctx.db.select('account.Journal', { id: input.move.journalId }))[0];
330
+ if (!journal)
331
+ boundaryError('move.journalId', 'the journal does not exist in the active company');
332
+ if (journal.active === false)
333
+ boundaryError('move.journalId', 'an inactive journal cannot receive a new draft move');
334
+ if (input.lines.length < 2)
335
+ boundaryError('lines', 'a draft move needs at least two lines');
336
+ const ids = new Set();
337
+ const normalizedLines = [];
338
+ let debitTotal = 0n;
339
+ let creditTotal = 0n;
340
+ let residualTotal = 0n;
341
+ const accountCache = new Map();
342
+ for (const given of input.lines) {
343
+ const id = String(given.id ?? '');
344
+ if (!id || ids.has(id))
345
+ boundaryError('lines.id', 'journal item ids must be present and unique');
346
+ ids.add(id);
347
+ if (String(given.moveId) !== moveId)
348
+ boundaryError('lines.moveId', 'every journal item must belong to the draft move');
349
+ const accountId = String(given.accountId ?? '');
350
+ let account = accountCache.get(accountId);
351
+ if (!account) {
352
+ const loaded = await accountOf(ctx, accountId);
353
+ if (!loaded)
354
+ throw new DraftMoveBoundaryError('lines.accountId', 'a journal item account is outside the active company');
355
+ account = loaded;
356
+ accountCache.set(accountId, loaded);
357
+ }
358
+ if (account.active === false)
359
+ boundaryError('lines.accountId', 'an inactive account cannot receive a new journal item');
360
+ const { debit, credit, balance, residual, quantity, priceUnit, discount } = (() => {
361
+ try {
362
+ return {
363
+ debit: moneyMinor(given.debit ?? '0', scale),
364
+ credit: moneyMinor(given.credit ?? '0', scale),
365
+ balance: moneyMinor(given.balance ?? '0', scale),
366
+ residual: moneyMinor(given.amountResidual ?? '0', scale),
367
+ quantity: canonicalDecimalText(given.quantity ?? '1'),
368
+ priceUnit: canonicalDecimalText(given.priceUnit ?? '0'),
369
+ discount: canonicalDecimalText(given.discount ?? '0'),
370
+ };
371
+ }
372
+ catch {
373
+ throw new DraftMoveBoundaryError('lines.amount', 'journal item decimals must be canonical exact strings');
374
+ }
375
+ })();
376
+ if (debit < 0n || credit < 0n || (debit > 0n && credit > 0n))
377
+ boundaryError('lines.side', 'a journal item must use one non-negative side');
378
+ if (debit === 0n && credit === 0n)
379
+ boundaryError('lines.side', 'a journal item needs a non-zero debit or credit');
380
+ if (balance !== debit - credit)
381
+ boundaryError('lines.balance', 'journal item balance must equal debit minus credit');
382
+ const magnitude = balance < 0n ? -balance : balance;
383
+ if (residual < 0n || residual > magnitude)
384
+ boundaryError('lines.amountResidual', 'journal item residual must be within its balance');
385
+ if (account.reconcile === true) {
386
+ if (given.reconciled === true ? residual !== 0n : residual !== magnitude)
387
+ boundaryError('lines.amountResidual', 'a reconcilable draft line must carry its full residual');
388
+ }
389
+ else if (residual !== 0n)
390
+ boundaryError('lines.amountResidual', 'a non-reconcilable account cannot carry a residual');
391
+ if (given.reconciled === true)
392
+ boundaryError('lines.reconciled', 'a draft journal item cannot already be reconciled');
393
+ debitTotal += debit;
394
+ creditTotal += credit;
395
+ residualTotal += residual;
396
+ normalizedLines.push({
397
+ ...given,
398
+ quantity,
399
+ priceUnit,
400
+ discount,
401
+ debit: minorText(debit, scale),
402
+ credit: minorText(credit, scale),
403
+ balance: minorText(balance, scale),
404
+ reconciled: false,
405
+ amountResidual: minorText(residual, scale),
406
+ });
407
+ }
408
+ if (debitTotal !== creditTotal)
409
+ boundaryError('lines', 'the draft move must balance exactly at company-currency scale');
410
+ let { untaxed, tax, total } = (() => {
411
+ try {
412
+ return {
413
+ untaxed: moneyMinor(input.move.amountUntaxed ?? '0', scale),
414
+ tax: moneyMinor(input.move.amountTax ?? '0', scale),
415
+ total: moneyMinor(input.move.amountTotal ?? '0', scale),
416
+ };
417
+ }
418
+ catch {
419
+ throw new DraftMoveBoundaryError('move.amountTotal', 'move totals must be canonical exact strings');
420
+ }
421
+ })();
422
+ if (String(input.move.moveType) === 'entry') {
423
+ // A journal entry's displayed total is its balanced turnover. Contra lines
424
+ // can make the source transaction's net amount smaller than this gross
425
+ // debit/credit total, so an entry does not carry invoice subtotal semantics.
426
+ untaxed = debitTotal;
427
+ tax = 0n;
428
+ total = debitTotal;
429
+ }
430
+ else {
431
+ if (untaxed + tax !== total)
432
+ boundaryError('move.amountTotal', 'untaxed plus tax must equal the document total');
433
+ if (total !== residualTotal)
434
+ boundaryError('move.amountTotal', 'the document total must equal its open-item counterparts');
435
+ }
436
+ const move = {
437
+ ...input.move,
438
+ currency,
439
+ accountingDate: accountingDateText(input.move.accountingDate ?? input.move.date, timezone),
440
+ documentDate: accountingDateText(input.move.documentDate ?? input.move.invoiceDate ?? input.move.accountingDate ?? input.move.date, timezone),
441
+ amountUntaxed: minorText(untaxed, scale),
442
+ amountTax: minorText(tax, scale),
443
+ amountTotal: minorText(total, scale),
444
+ postedAt: null,
445
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
446
+ revision: 0,
447
+ };
448
+ const inserted = await ctx.db.insertIfAbsent('account.Move', move);
449
+ if (!('dryRun' in inserted) && !inserted.inserted) {
450
+ const existing = (await ctx.db.select('account.Move', { id: moveId }))[0];
451
+ const storedLines = await ctx.db.select('account.MoveLine', { moveId });
452
+ const sameMove = Boolean(existing &&
453
+ rowMatches(existing, move, Object.keys(move).filter((field) => field !== 'companyId' && field !== 'revision')));
454
+ const byId = new Map(storedLines.map((row) => [String(row.id), row]));
455
+ const sameLines = storedLines.length === normalizedLines.length &&
456
+ normalizedLines.every((line) => {
457
+ const held = byId.get(String(line.id));
458
+ return Boolean(held &&
459
+ rowMatches(held, line, Object.keys(line).filter((field) => field !== 'companyId')));
460
+ });
461
+ if (!sameMove || !sameLines)
462
+ boundaryError('move.id', 'the draft move id is already used by different financial content');
463
+ return { id: moveId, existing: true };
464
+ }
465
+ for (const line of normalizedLines) {
466
+ const result = await ctx.db.insertIfAbsent('account.MoveLine', line);
467
+ if (!('dryRun' in result) && !result.inserted)
468
+ boundaryError('lines.id', 'a journal item id is already used outside this draft move');
469
+ }
470
+ return { id: moveId, existing: false };
471
+ }
472
+ /** Reads a company's fallback accounts, whether or not a row has been written yet. */
473
+ async function defaultsOf(ctx) {
474
+ return (await ctx.db.select('account.Defaults'))[0] ?? {};
475
+ }
476
+ /**
477
+ * The category a variant belongs to, through its template.
478
+ *
479
+ * An invoice line names a variant, the catalogue hangs the category off the
480
+ * template, and the accounts hang off the category — so reaching one from the
481
+ * other is two hops, not a join this query layer offers.
482
+ */
483
+ async function categoryOfProduct(ctx, productId) {
484
+ if (!productId)
485
+ return null;
486
+ const variant = (await ctx.db.select('product.Product', { id: productId }))[0];
487
+ if (!variant)
488
+ return null;
489
+ const template = (await ctx.db.select('product.Template', { id: variant.templateId }))[0];
490
+ return template?.categoryId ?? null;
491
+ }
492
+ export const ACCOUNT_RESOLUTION_EFFECTS = [
493
+ 'read:account.Account',
494
+ 'read:account.Defaults',
495
+ 'read:account.CategoryAccount',
496
+ 'read:product.Product',
497
+ 'read:product.Template',
498
+ 'read:partner.CompanyTerms',
499
+ ];
500
+ /**
501
+ * Decide which accounts a document posts to.
502
+ *
503
+ * Most: an explicit choice wins, then the narrowest configured default, then the
504
+ * company's. Asking the person writing an invoice to name a revenue account out
505
+ * of 216 is asking them to re-answer a question the chart already answers the
506
+ * same way every time — and to get it wrong occasionally.
507
+ *
508
+ * The partner's control accounts are read from `partner.CompanyTerms`, whose
509
+ * account fields the optional `account_partner` module adds. When it is not
510
+ * installed the fields are simply absent and resolution falls through to the
511
+ * company default, which is why this reads them rather than depending on it.
512
+ */
513
+ async function resolveAccounts(ctx, args, explicit = {}) {
514
+ const customer = ['out_invoice', 'out_refund', 'out_receipt'].includes(args.moveType);
515
+ const defaults = await defaultsOf(ctx);
516
+ let lineAccountId = explicit.lineAccountId ?? null;
517
+ let lineAccountFrom = lineAccountId ? 'explicit' : null;
518
+ if (!lineAccountId) {
519
+ const categoryId = await categoryOfProduct(ctx, args.productId);
520
+ const mapped = categoryId
521
+ ? ((await ctx.db.select('account.CategoryAccount', { categoryId }))[0] ?? null)
522
+ : null;
523
+ const fromCategory = customer ? mapped?.incomeAccountId : mapped?.expenseAccountId;
524
+ if (fromCategory) {
525
+ lineAccountId = fromCategory;
526
+ lineAccountFrom = 'category';
527
+ }
528
+ else {
529
+ lineAccountId = (customer ? defaults.incomeAccountId : defaults.expenseAccountId) ?? null;
530
+ lineAccountFrom = lineAccountId ? 'company' : null;
531
+ }
532
+ }
533
+ let counterpartAccountId = explicit.counterpartAccountId ?? null;
534
+ let counterpartAccountFrom = counterpartAccountId
535
+ ? 'explicit'
536
+ : null;
537
+ if (!counterpartAccountId) {
538
+ const terms = args.partnerId
539
+ ? ((await ctx.db.select('partner.CompanyTerms', { partnerId: args.partnerId }))[0] ?? null)
540
+ : null;
541
+ const fromPartner = customer ? terms?.receivableAccountId : terms?.payableAccountId;
542
+ if (fromPartner) {
543
+ counterpartAccountId = fromPartner;
544
+ counterpartAccountFrom = 'partner';
545
+ }
546
+ else {
547
+ counterpartAccountId = (customer ? defaults.receivableAccountId : defaults.payableAccountId) ?? null;
548
+ counterpartAccountFrom = counterpartAccountId ? 'company' : null;
549
+ }
550
+ }
551
+ return { lineAccountId, lineAccountFrom, counterpartAccountId, counterpartAccountFrom };
552
+ }
553
+ /**
554
+ * Paging is opt-in, never implicit. A screen asks for a page; an export or a
555
+ * report asks for everything and gets it, rather than a silently truncated list
556
+ * that reads as complete.
557
+ */
558
+ const paginate = (q, limit, offset) => {
559
+ const size = Math.trunc(n(limit));
560
+ const start = Math.trunc(n(offset));
561
+ const limited = size > 0 ? q.limit(size) : q;
562
+ return start > 0 ? limited.offset(start) : limited;
563
+ };
564
+ const slice = (rows, limit, offset) => {
565
+ const size = Math.trunc(n(limit));
566
+ const start = Math.max(0, Math.trunc(n(offset)));
567
+ return size > 0 ? rows.slice(start, start + size) : rows.slice(start);
568
+ };
569
+ const moveTypeList = (value) => Array.isArray(value) ? value.map(String).filter((type) => MOVE_TYPES.includes(type)) : [];
570
+ const paymentStateList = (value) => Array.isArray(value) ? value.map(String).filter((state) => PAYMENT_STATES.includes(state)) : [];
571
+ /** The ids of every posted move inside an optional inclusive civil-date window. */
572
+ export async function postedMoves(ctx, dateFrom, dateTo) {
573
+ const { currency, timezone } = await ledgerOf(ctx);
574
+ const fromDate = accountingFilterDateText(dateFrom);
575
+ const toDate = accountingFilterDateText(dateTo);
576
+ const M = ctx.table('account.Move');
577
+ const moves = await ctx.db.all(from(M).where(eq(M.state, 'posted')));
578
+ const selected = [];
579
+ for (const held of moves) {
580
+ if (String(held.currency) !== currency)
581
+ throw new Refusal('moveCurrencyMismatch');
582
+ const accountingDate = moveAccountingDate(held, timezone);
583
+ if (fromDate && accountingDate < fromDate)
584
+ continue;
585
+ if (toDate && accountingDate > toDate)
586
+ continue;
587
+ selected.push([String(held.id), { ...held, accountingDate }]);
588
+ }
589
+ return new Map(selected);
590
+ }
591
+ /**
592
+ * Journal items belonging to the given moves. The ids go into the query so the
593
+ * database does the narrowing; chunking keeps a long reporting window from
594
+ * building a parameter list no driver will accept.
595
+ */
596
+ export async function linesOfMoves(ctx, moveIds, accountId) {
597
+ if (!moveIds.length)
598
+ return [];
599
+ const L = ctx.table('account.MoveLine');
600
+ const rows = [];
601
+ for (let at = 0; at < moveIds.length; at += 400) {
602
+ const chunk = moveIds.slice(at, at + 400);
603
+ rows.push(...(await ctx.db.all(from(L).where(and(inArray(L.moveId, chunk), ...(accountId ? [eq(L.accountId, accountId)] : []))))));
604
+ }
605
+ return rows;
606
+ }
607
+ /**
608
+ * Every account of the active company, by id. Callers that classify a whole page
609
+ * of journal items need this once instead of a lookup per line — a chart of
610
+ * accounts is bounded by a company's configured chart while a ledger is not.
611
+ */
612
+ export async function accountsById(ctx) {
613
+ return new Map((await ctx.db.select('account.Account')).map((row) => [String(row.id), row]));
614
+ }
71
615
  async function dueDate(ctx, paymentTermId, date) {
72
616
  if (!paymentTermId)
73
617
  return date.toISOString();
@@ -95,39 +639,178 @@ async function dueDate(ctx, paymentTermId, date) {
95
639
  }
96
640
  return latest.toISOString();
97
641
  }
98
- function taxAmounts(tax, quantity, priceUnit, discount) {
99
- const gross = money(quantity * priceUnit * (1 - discount / 100));
100
- if (!tax)
101
- return { untaxed: gross, tax: 0, total: gross };
102
- if (tax.amountType === 'group')
103
- throw new Error('group taxes are outside the supported Odoo 19 subset');
104
- const rate = n(tax.amount) / 100;
105
- let untaxed = gross;
106
- let taxAmount = 0;
107
- if (tax.amountType === 'fixed') {
108
- taxAmount = money(n(tax.amount) * quantity);
109
- if (tax.priceInclude)
110
- untaxed = money(gross - taxAmount);
642
+ const taxOrder = (a, b) => n(a.sequence) - n(b.sequence) || String(a.id).localeCompare(String(b.id));
643
+ /**
644
+ * Apply a line's taxes in sequence.
645
+ *
646
+ * A tax marked `includeBaseAmount` adds its own amount to the base every later
647
+ * tax is computed on this is how import duty compounds into import VAT, which
648
+ * is the case for a chart installed by a localization or configured by an operator.
649
+ */
650
+ function taxAmounts(taxes, quantity, priceUnit, discount, scale) {
651
+ const gross = discountedLineMinor(quantity, priceUnit, discount, scale);
652
+ if (!taxes.length) {
653
+ const amount = minorText(gross, scale);
654
+ return { untaxed: amount, tax: minorText(0n, scale), total: amount, shares: [] };
111
655
  }
112
- else if (tax.amountType === 'percent') {
113
- if (tax.priceInclude) {
114
- untaxed = money(gross / (1 + rate));
115
- taxAmount = money(gross - untaxed);
656
+ const ordered = [...taxes].sort(taxOrder);
657
+ const included = ordered.filter((tax) => tax.priceInclude === true);
658
+ if (included.length && included.length !== ordered.length)
659
+ throw new Refusal('taxMixedPriceInclude');
660
+ if (included.length > 1)
661
+ throw new Refusal('taxManyPriceInclude');
662
+ const share = (tax, base) => {
663
+ if (tax.amountType === 'fixed')
664
+ return multiplyToMinor([tax.amount, quantity], scale);
665
+ if (tax.amountType === 'percent')
666
+ return percentOfMinor(base, tax.amount);
667
+ if (tax.amountType === 'division') {
668
+ if (compareDecimals(tax.amount, '100') >= 0)
669
+ throw new Refusal('taxDivisionFull');
670
+ return divisionTaxMinor(base, tax.amount);
116
671
  }
117
- else
118
- taxAmount = money(gross * rate);
119
- }
120
- else if (tax.amountType === 'division') {
121
- if (tax.priceInclude) {
122
- untaxed = money(gross * (1 - rate));
123
- taxAmount = money(gross - untaxed);
672
+ throw new Refusal('taxComputationUnsupported');
673
+ };
674
+ if (included.length === 1) {
675
+ const tax = ordered[0];
676
+ let untaxed = gross;
677
+ if (tax.amountType === 'fixed') {
678
+ untaxed = gross - share(tax, gross);
679
+ // A fixed tax said to be inside the price cannot be more than the price.
680
+ // Left alone it makes the base negative, which posts a credit to revenue
681
+ // as a debit and reverses the sign of the sale in the ledger.
682
+ if (untaxed < 0n)
683
+ throw new Refusal('taxFixedExceedsLine');
684
+ }
685
+ else if (tax.amountType === 'percent')
686
+ untaxed = includedPercentBaseMinor(gross, tax.amount);
687
+ else if (tax.amountType === 'division') {
688
+ if (compareDecimals(tax.amount, '100') >= 0)
689
+ throw new Refusal('taxDivisionFull');
690
+ untaxed = includedDivisionBaseMinor(gross, tax.amount);
124
691
  }
125
692
  else
126
- taxAmount = money(gross / (1 - rate) - gross);
693
+ throw new Refusal('taxComputationUnsupported');
694
+ const amount = gross - untaxed;
695
+ return {
696
+ untaxed: minorText(untaxed, scale),
697
+ tax: minorText(amount, scale),
698
+ total: minorText(untaxed + amount, scale),
699
+ shares: [
700
+ {
701
+ taxId: tax.id,
702
+ name: String(tax.name),
703
+ accountId: tax.accountId ?? null,
704
+ amount: minorText(amount, scale),
705
+ },
706
+ ],
707
+ };
708
+ }
709
+ const shares = [];
710
+ let base = gross;
711
+ let total = 0n;
712
+ for (const tax of ordered) {
713
+ const amount = share(tax, base);
714
+ shares.push({
715
+ taxId: tax.id,
716
+ name: String(tax.name),
717
+ accountId: tax.accountId ?? null,
718
+ amount: minorText(amount, scale),
719
+ });
720
+ total += amount;
721
+ if (tax.includeBaseAmount === true)
722
+ base += amount;
723
+ }
724
+ return {
725
+ untaxed: minorText(gross, scale),
726
+ tax: minorText(total, scale),
727
+ total: minorText(gross + total, scale),
728
+ shares,
729
+ };
730
+ }
731
+ /** Canonical product line calculation shared by Sales, POS and invoices. */
732
+ export async function quoteTaxLineForPosting(ctx, input) {
733
+ let quantity;
734
+ let priceUnit;
735
+ let discount;
736
+ try {
737
+ quantity = canonicalDecimalText(input.quantity);
738
+ priceUnit = canonicalDecimalText(input.priceUnit);
739
+ discount = canonicalDecimalText(input.discount ?? '0');
740
+ if (decimalSign(quantity) <= 0)
741
+ return invalid('quantity', 'taxQuantityPositive');
742
+ if ((!input.allowNegativePrice && decimalSign(priceUnit) < 0) ||
743
+ decimalSign(discount) < 0 ||
744
+ compareDecimals(discount, '100') > 0)
745
+ return invalid('priceUnit', 'taxPriceInvalid');
127
746
  }
128
- return { untaxed, tax: taxAmount, total: money(untaxed + taxAmount) };
747
+ catch {
748
+ return invalid('priceUnit', 'taxPriceInvalid');
749
+ }
750
+ let wanted;
751
+ if (Array.isArray(input.taxIds))
752
+ wanted = [...new Set(input.taxIds.map(String))];
753
+ else if (input.productId) {
754
+ const product = (await ctx.db.select('product.Product', { id: input.productId }))[0];
755
+ if (!product)
756
+ return invalid('productId', 'productMissing');
757
+ const mapping = (await ctx.db.select('account.ProductTax', { templateId: product.templateId }))[0];
758
+ wanted = mapping?.taxId ? [String(mapping.taxId)] : [];
759
+ }
760
+ else
761
+ wanted = [];
762
+ const taxes = [];
763
+ for (const id of wanted) {
764
+ const tax = (await ctx.db.select('account.Tax', { id }))[0];
765
+ if (!tax || tax.active === false)
766
+ return invalid('taxIds', 'taxMissing');
767
+ if (![input.taxUse ?? 'sale', 'none'].includes(String(tax.typeTaxUse)))
768
+ return invalid('taxIds', 'taxDirectionMismatch', { name: tax.name });
769
+ taxes.push(tax);
770
+ }
771
+ const { currency, scale } = await ledgerOf(ctx);
772
+ try {
773
+ const amounts = taxAmounts(taxes, quantity, priceUnit, discount, scale);
774
+ const shares = new Map(amounts.shares.map((share) => [String(share.taxId), share]));
775
+ return {
776
+ ok: true,
777
+ currency,
778
+ scale,
779
+ quantity,
780
+ priceUnit,
781
+ discount,
782
+ amountUntaxed: amounts.untaxed,
783
+ amountTax: amounts.tax,
784
+ amountTotal: amounts.total,
785
+ taxIds: taxes.sort(taxOrder).map((tax) => String(tax.id)),
786
+ taxes: taxes.sort(taxOrder).map((tax) => ({
787
+ id: String(tax.id),
788
+ name: String(tax.name),
789
+ amountType: String(tax.amountType),
790
+ amount: String(tax.amount),
791
+ priceInclude: tax.priceInclude === true,
792
+ includeBaseAmount: tax.includeBaseAmount === true,
793
+ sequence: n(tax.sequence),
794
+ share: shares.get(String(tax.id))?.amount ?? minorText(0n, scale),
795
+ })),
796
+ shares: amounts.shares,
797
+ };
798
+ }
799
+ catch (error) {
800
+ return refused('taxIds', error);
801
+ }
802
+ }
803
+ /** Public calculation evidence intentionally excludes ledger account routing. */
804
+ export async function quoteTaxLine(ctx, input) {
805
+ const quote = await quoteTaxLineForPosting(ctx, input);
806
+ if (quote.ok !== true)
807
+ return quote;
808
+ return {
809
+ ...quote,
810
+ shares: quote.shares.map(({ accountId: _accountId, ...share }) => share),
811
+ };
129
812
  }
130
- async function nextMoveName(ctx, journal, date) {
813
+ async function nextMoveName(ctx, journal, accountingDate) {
131
814
  for (let attempt = 0; attempt < 32; attempt += 1) {
132
815
  const current = (await ctx.db.select('account.Journal', { id: journal.id }))[0];
133
816
  if (!current)
@@ -135,59 +818,266 @@ async function nextMoveName(ctx, journal, date) {
135
818
  const previous = n(current.sequenceNumber);
136
819
  const changed = await ctx.db.compareAndSet('account.Journal', { id: journal.id }, { sequenceNumber: current.sequenceNumber }, { sequenceNumber: previous + 1 });
137
820
  if ('dryRun' in changed || changed.matched)
138
- return `${String(journal.code).toUpperCase()}/${date.getUTCFullYear()}/${String(previous + 1).padStart(5, '0')}`;
821
+ return `${String(journal.code).toUpperCase()}/${fiscalYearKey(accountingDate)}/${String(previous + 1).padStart(5, '0')}`;
139
822
  }
140
823
  throw new Error('journal sequence did not settle after concurrent updates');
141
824
  }
142
- async function post(ctx, id) {
825
+ export async function postMoveById(ctx, id, expectedRevision) {
143
826
  const move = (await ctx.db.select('account.Move', { id }))[0];
144
827
  if (!move)
145
- return invalid('id', 'journal entry does not exist');
146
- if (move.state === 'posted')
828
+ return invalid('id', 'moveMissing');
829
+ if (move.state === 'posted') {
830
+ await ctx.db.insertIfAbsent('account.AuditEvent', {
831
+ id: `move:${String(move.id)}:posted`,
832
+ subjectType: 'move',
833
+ subjectId: String(move.id),
834
+ action: 'posted',
835
+ actorId: ctx.actor ?? null,
836
+ accountingDate: move.accountingDate,
837
+ reason: null,
838
+ relatedId: null,
839
+ details: { journalId: move.journalId, name: move.name, moneyPolicyVersion: move.moneyPolicyVersion },
840
+ createdAt: move.postedAt ?? today(),
841
+ });
147
842
  return { ok: true, id: move.id, name: move.name };
843
+ }
148
844
  if (move.state !== 'draft')
149
- return invalid('state', 'only a draft entry can be posted');
845
+ return invalid('state', 'moveDraftOnly');
846
+ const { currency, scale, timezone } = await ledgerOf(ctx);
847
+ if (String(move.currency) !== currency)
848
+ return invalid('currency', 'moveCurrencyMismatch');
849
+ const journal = (await ctx.db.select('account.Journal', { id: move.journalId }))[0];
850
+ if (!journal)
851
+ return invalid('journalId', 'journalMissing');
852
+ if (journal.active === false)
853
+ return invalid('journalId', 'journalInactive');
150
854
  const lines = await ctx.db.select('account.MoveLine', { moveId: id });
151
855
  if (lines.length < 2)
152
- return invalid('lines', 'a journal entry needs at least two lines');
153
- let debit = 0;
154
- let credit = 0;
856
+ return invalid('lines', 'linesTooFew');
857
+ let debit = 0n;
858
+ let credit = 0n;
859
+ let residualTotal = 0n;
860
+ const accounts = new Map();
155
861
  for (const line of lines) {
156
- if (n(line.debit) < 0 || n(line.credit) < 0 || (n(line.debit) > 0 && n(line.credit) > 0))
157
- return invalid('lines', 'each line must have a non-negative debit or credit, never both');
158
- debit = money(debit + n(line.debit));
159
- credit = money(credit + n(line.credit));
862
+ let lineDebit;
863
+ let lineCredit;
864
+ let balance;
865
+ let residual;
866
+ try {
867
+ lineDebit = moneyMinor(line.debit, scale);
868
+ lineCredit = moneyMinor(line.credit, scale);
869
+ balance = moneyMinor(line.balance, scale);
870
+ residual = moneyMinor(line.amountResidual, scale);
871
+ }
872
+ catch {
873
+ return invalid('lines', 'moneyExactString');
874
+ }
875
+ if (lineDebit < 0n || lineCredit < 0n || (lineDebit > 0n && lineCredit > 0n))
876
+ return invalid('lines', 'lineSideBoth');
877
+ if (lineDebit === 0n && lineCredit === 0n)
878
+ return invalid('lines', 'lineAmountRequired');
879
+ if (balance !== lineDebit - lineCredit)
880
+ return invalid('lines', 'lineBalanceInvalid');
881
+ const accountId = String(line.accountId);
882
+ let account = accounts.get(accountId);
883
+ if (!account) {
884
+ account = (await accountOf(ctx, accountId)) ?? undefined;
885
+ if (!account)
886
+ return invalid('lines.accountId', 'accountMissing');
887
+ accounts.set(accountId, account);
888
+ }
889
+ if (account.active === false)
890
+ return invalid('lines.accountId', 'accountInactive');
891
+ const magnitude = balance < 0n ? -balance : balance;
892
+ if (line.reconciled === true ||
893
+ residual < 0n ||
894
+ residual > magnitude ||
895
+ (account.reconcile === true ? residual !== magnitude : residual !== 0n))
896
+ return invalid('lines.amountResidual', 'lineResidualInvalid');
897
+ debit += lineDebit;
898
+ credit += lineCredit;
899
+ residualTotal += residual;
900
+ }
901
+ if (debit !== credit)
902
+ return invalid('lines', 'entryUnbalanced', {
903
+ debit: minorText(debit, scale),
904
+ credit: minorText(credit, scale),
905
+ });
906
+ if (move.moveType !== 'entry') {
907
+ let untaxed;
908
+ let tax;
909
+ let total;
910
+ try {
911
+ untaxed = moneyMinor(move.amountUntaxed, scale);
912
+ tax = moneyMinor(move.amountTax, scale);
913
+ total = moneyMinor(move.amountTotal, scale);
914
+ }
915
+ catch {
916
+ return invalid('amountTotal', 'moneyExactString');
917
+ }
918
+ if (untaxed + tax !== total || total !== residualTotal)
919
+ return invalid('amountTotal', 'moveTotalInvalid');
160
920
  }
161
- if (Math.abs(debit - credit) > 0.000001)
162
- return invalid('lines', `entry is not balanced: debit ${debit}, credit ${credit}`);
163
- const journal = (await ctx.db.select('account.Journal', { id: move.journalId }))[0];
164
- if (!journal)
165
- return invalid('journalId', 'journal does not exist');
166
921
  const postedAt = today();
167
- const assigned = await ctx.tx(async (tx) => {
168
- const name = await nextMoveName(tx, journal, new Date(String(move.date)));
169
- await tx.db.update('account.Move', { id }, { name, state: 'posted', postedAt });
170
- return name;
171
- });
922
+ // An invoice already carries the totals its own line builder computed. A manual
923
+ // entry has none, and a ledger that shows every entry as 0 is not a ledger.
924
+ const totals = move.moveType === 'entry'
925
+ ? {
926
+ amountUntaxed: minorText(debit, scale),
927
+ amountTax: minorText(0n, scale),
928
+ amountTotal: minorText(debit, scale),
929
+ }
930
+ : {};
931
+ let assigned;
932
+ try {
933
+ assigned = await ctx.tx(async (tx) => {
934
+ const current = (await tx.db.select('account.Move', { id }))[0];
935
+ if (!current)
936
+ throw new Refusal('moveMissing');
937
+ if (current.state === 'posted')
938
+ return String(current.name);
939
+ if (current.state !== 'draft')
940
+ throw new Refusal('moveDraftOnly');
941
+ // The validated line snapshot belongs to the revision read above. Claim that
942
+ // exact revision even when the caller did not supply a token: if a line was
943
+ // added after validation, posting must retry and validate the new set.
944
+ const validatedRevision = expectedRevision ?? move.revision ?? null;
945
+ if (!(await claimMoveRevision(tx, current, validatedRevision)))
946
+ throw new Refusal('moveConcurrent');
947
+ let accountingDate;
948
+ let documentDate;
949
+ try {
950
+ accountingDate = accountingDateText(current.accountingDate ?? current.date, timezone);
951
+ documentDate = accountingDateText(current.documentDate ?? current.invoiceDate ?? current.accountingDate ?? current.date, timezone);
952
+ }
953
+ catch {
954
+ throw new Refusal('accountingDateInvalid');
955
+ }
956
+ let locked;
957
+ try {
958
+ locked = await claimPostingPeriod(tx, {
959
+ accountingDate,
960
+ moveType: current.moveType,
961
+ journalType: journal.type,
962
+ hasTax: lines.some((line) => line.taxId != null),
963
+ });
964
+ }
965
+ catch {
966
+ throw new Refusal('periodConcurrent');
967
+ }
968
+ if (locked)
969
+ throw new Refusal('periodLocked', locked);
970
+ const name = await nextMoveName(tx, journal, accountingDate);
971
+ await tx.db.update('account.Move', { id }, {
972
+ name,
973
+ state: 'posted',
974
+ accountingDate,
975
+ documentDate,
976
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
977
+ postedAt,
978
+ ...totals,
979
+ });
980
+ await tx.db.insertIfAbsent('account.AuditEvent', {
981
+ id: `move:${String(id)}:posted`,
982
+ subjectType: 'move',
983
+ subjectId: String(id),
984
+ action: 'posted',
985
+ actorId: tx.actor ?? null,
986
+ accountingDate,
987
+ reason: null,
988
+ relatedId: null,
989
+ details: { journalId: journal.id, name, moneyPolicyVersion: MONEY_POLICY_VERSION },
990
+ createdAt: postedAt,
991
+ });
992
+ return name;
993
+ });
994
+ }
995
+ catch (error) {
996
+ // Two replicas may both validate the same draft and one may lose the CAS only
997
+ // because the other already posted it. That retry has reached its requested
998
+ // state and is therefore an idempotent success, not a conflict.
999
+ if (error instanceof Refusal && error.code === 'moveConcurrent') {
1000
+ const settled = (await ctx.db.select('account.Move', { id }))[0];
1001
+ if (settled?.state === 'posted')
1002
+ return { ok: true, id: settled.id, name: settled.name };
1003
+ }
1004
+ return refused(error instanceof Refusal && error.code === 'accountingDateInvalid'
1005
+ ? 'accountingDate'
1006
+ : error instanceof Refusal && error.code === 'periodLocked'
1007
+ ? 'accountingDate'
1008
+ : 'expectedRevision', error);
1009
+ }
172
1010
  return { ok: true, id: move.id, name: assigned };
173
1011
  }
174
- async function updatePaymentState(ctx, moveId) {
1012
+ const OPEN_ITEM_TYPES = ['asset_receivable', 'liability_payable'];
1013
+ async function updatePaymentState(ctx, moveId, accounts) {
175
1014
  const move = (await ctx.db.select('account.Move', { id: moveId }))[0];
176
1015
  if (!move || move.moveType === 'entry')
177
1016
  return;
178
- const lines = await ctx.db.select('account.MoveLine', { moveId });
179
- const candidates = [];
180
- for (const line of lines) {
181
- const account = await accountOf(ctx, line.accountId);
182
- if (account?.accountType === 'asset_receivable' || account?.accountType === 'liability_payable')
183
- candidates.push(line);
184
- }
185
- const original = candidates.reduce((sum, line) => sum + Math.abs(n(line.balance)), 0);
186
- const residual = candidates.reduce((sum, line) => sum + Math.abs(n(line.amountResidual)), 0);
187
- const paymentState = residual < 0.000001 ? 'paid' : residual < original ? 'partial' : 'not_paid';
1017
+ // A reversal settles the document; it must not be relabelled by the residual math.
1018
+ if (move.paymentState === 'reversed')
1019
+ return;
1020
+ const byId = accounts ?? (await accountsById(ctx));
1021
+ const candidates = (await ctx.db.select('account.MoveLine', { moveId })).filter((line) => OPEN_ITEM_TYPES.includes(String(byId.get(String(line.accountId))?.accountType)));
1022
+ const scale = scaleOf(move.currency);
1023
+ const original = candidates.reduce((sum, line) => {
1024
+ const amount = moneyMinor(line.balance, scale);
1025
+ return sum + (amount < 0n ? -amount : amount);
1026
+ }, 0n);
1027
+ const residual = candidates.reduce((sum, line) => {
1028
+ const amount = moneyMinor(line.amountResidual, scale);
1029
+ return sum + (amount < 0n ? -amount : amount);
1030
+ }, 0n);
1031
+ const paymentState = residual === 0n ? 'paid' : residual < original ? 'partial' : 'not_paid';
188
1032
  await ctx.db.update('account.Move', { id: moveId }, { paymentState });
189
1033
  }
1034
+ /**
1035
+ * The slice of a list a picker actually needs.
1036
+ *
1037
+ * A relation picker sends `search` on every keystroke and `limit` to keep the
1038
+ * response small; `validateInput` rejects inputs a function does not declare, so
1039
+ * a list without them cannot back a picker at all. `product` and `uom` carry the
1040
+ * same helper for the same reason.
1041
+ */
1042
+ const narrow = (rows, args, fields) => {
1043
+ const needle = String(args.search ?? '')
1044
+ .trim()
1045
+ .toLocaleLowerCase();
1046
+ const matched = needle
1047
+ ? rows.filter((row) => fields.some((field) => String(row[field] ?? '')
1048
+ .toLocaleLowerCase()
1049
+ .includes(needle)))
1050
+ : rows;
1051
+ const limit = Number(args.limit);
1052
+ return Number.isInteger(limit) && limit > 0 ? matched.slice(0, limit) : matched;
1053
+ };
190
1054
  export const functions = {
1055
+ quoteLine: defineFn({
1056
+ input: {
1057
+ productId: 'id?',
1058
+ taxIds: 'json?',
1059
+ quantity: 'decimal',
1060
+ priceUnit: 'decimal',
1061
+ discount: 'decimal?',
1062
+ },
1063
+ output: {
1064
+ ok: 'bool',
1065
+ currency: 'text?',
1066
+ scale: 'int?',
1067
+ quantity: 'decimal?',
1068
+ priceUnit: 'decimal?',
1069
+ discount: 'decimal?',
1070
+ amountUntaxed: 'decimal?',
1071
+ amountTax: 'decimal?',
1072
+ amountTotal: 'decimal?',
1073
+ taxIds: 'json?',
1074
+ taxes: 'json?',
1075
+ errors: 'json?',
1076
+ },
1077
+ effects: ['read:company.Company', 'read:product.Product', 'read:account.ProductTax', 'read:account.Tax'],
1078
+ agent: true,
1079
+ handler: (ctx, args) => quoteTaxLine(ctx, args),
1080
+ }),
191
1081
  initializeCompany: defineFn({
192
1082
  input: {},
193
1083
  output: {
@@ -209,15 +1099,41 @@ export const functions = {
209
1099
  agent: true,
210
1100
  handler: async (ctx) => (await ctx.db.select('account.Setup'))[0] ?? null,
211
1101
  }),
1102
+ /**
1103
+ * The chart of accounts, narrowed the way a picker asks for it.
1104
+ *
1105
+ * `search` and `limit` are what a relation picker sends on every keystroke, and
1106
+ * an unknown input is a hard error — so a chart of two hundred accounts is only
1107
+ * reachable through a search dialog once they are part of the signature.
1108
+ * `accountTypes` moves a restriction the forms were applying after the fact
1109
+ * into the query, so the dialog offers nothing the field would reject.
1110
+ */
212
1111
  listAccounts: defineFn({
213
- input: { includeArchived: 'bool?' },
1112
+ input: { includeArchived: 'bool?', accountTypes: 'json?', search: 'text?', limit: 'int?' },
214
1113
  effects: ['read:account.Account', ...ACCOUNT_SETUP_EFFECTS],
215
1114
  agent: true,
216
1115
  handler: async (ctx, args) => {
217
1116
  await ensureCompanyAccounting(ctx);
218
1117
  const A = ctx.table('account.Account');
219
1118
  const q = from(A).orderBy(asc(A.code));
220
- return ctx.db.all(args.includeArchived ? q : q.where(eq(A.active, true)));
1119
+ const rows = await ctx.db.all(args.includeArchived ? q : q.where(eq(A.active, true)));
1120
+ const types = Array.isArray(args.accountTypes) ? args.accountTypes.map(String) : [];
1121
+ const wanted = types.length
1122
+ ? rows.filter((row) => types.some((type) =>
1123
+ // A prefix so a field can ask for every income account without
1124
+ // naming income_other alongside income.
1125
+ type.endsWith('*')
1126
+ ? String(row.accountType).startsWith(type.slice(0, -1))
1127
+ : String(row.accountType) === type))
1128
+ : rows;
1129
+ const needle = String(args.search ?? '')
1130
+ .trim()
1131
+ .toLocaleLowerCase();
1132
+ const matched = needle
1133
+ ? wanted.filter((row) => `${String(row.code)} ${String(row.name)}`.toLocaleLowerCase().includes(needle))
1134
+ : wanted;
1135
+ const limit = Number(args.limit);
1136
+ return Number.isInteger(limit) && limit > 0 ? matched.slice(0, limit) : matched;
221
1137
  },
222
1138
  }),
223
1139
  saveAccount: defineFn({
@@ -228,13 +1144,13 @@ export const functions = {
228
1144
  agent: true,
229
1145
  handler: async (ctx, args) => {
230
1146
  if (!ACCOUNT_TYPES.includes(args.accountType))
231
- return invalid('accountType', 'unsupported Odoo 19 account type');
1147
+ return invalid('accountType', 'accountTypeUnsupported');
232
1148
  if (!/^[A-Za-z0-9.]+$/.test(String(args.code)))
233
- return invalid('code', 'account code may contain only letters, numbers, and dots');
1149
+ return invalid('code', 'accountCodeFormat');
234
1150
  const forced = ['asset_receivable', 'liability_payable'].includes(String(args.accountType));
235
1151
  const reconcile = forced || args.reconcile === true;
236
1152
  if (args.accountType === 'off_balance' && reconcile)
237
- return invalid('reconcile', 'off-balance accounts cannot be reconciled');
1153
+ return invalid('reconcile', 'offBalanceReconcile');
238
1154
  const existing = (await ctx.db.select('account.Account', { id: args.id }))[0];
239
1155
  const values = { ...args, reconcile, active: args.active ?? true };
240
1156
  const cs = ctx
@@ -248,12 +1164,15 @@ export const functions = {
248
1164
  },
249
1165
  }),
250
1166
  listJournals: defineFn({
251
- input: { type: 'text?' },
1167
+ input: { type: 'text?', includeArchived: 'bool?' },
252
1168
  effects: ['read:account.Journal', ...ACCOUNT_SETUP_EFFECTS],
253
1169
  agent: true,
254
1170
  handler: async (ctx, args) => {
255
1171
  await ensureCompanyAccounting(ctx);
256
- return ctx.db.select('account.Journal', args.type ? { type: args.type, active: true } : { active: true });
1172
+ return ctx.db.select('account.Journal', {
1173
+ ...(args.type ? { type: args.type } : {}),
1174
+ ...(args.includeArchived ? {} : { active: true }),
1175
+ });
257
1176
  },
258
1177
  }),
259
1178
  saveJournal: defineFn({
@@ -264,11 +1183,11 @@ export const functions = {
264
1183
  agent: true,
265
1184
  handler: async (ctx, args) => {
266
1185
  if (!JOURNAL_TYPES.includes(args.type))
267
- return invalid('type', 'unsupported Odoo 19 journal type');
1186
+ return invalid('type', 'journalTypeUnsupported');
268
1187
  if (!/^[A-Za-z0-9]+$/.test(String(args.code)))
269
- return invalid('code', 'journal code must be alphanumeric');
1188
+ return invalid('code', 'journalCodeFormat');
270
1189
  if (args.defaultAccountId && !(await accountOf(ctx, args.defaultAccountId)))
271
- return invalid('defaultAccountId', 'default account does not exist');
1190
+ return invalid('defaultAccountId', 'defaultAccountMissing');
272
1191
  const existing = (await ctx.db.select('account.Journal', { id: args.id }))[0];
273
1192
  const values = {
274
1193
  ...args,
@@ -287,12 +1206,63 @@ export const functions = {
287
1206
  },
288
1207
  }),
289
1208
  listTaxes: defineFn({
290
- input: { typeTaxUse: 'text?' },
1209
+ input: { typeTaxUse: 'text?', includeArchived: 'bool?', search: 'text?', limit: 'int?' },
291
1210
  effects: ['read:account.Tax', ...ACCOUNT_SETUP_EFFECTS],
292
1211
  agent: true,
293
1212
  handler: async (ctx, args) => {
294
1213
  await ensureCompanyAccounting(ctx);
295
- return ctx.db.select('account.Tax', args.typeTaxUse ? { typeTaxUse: args.typeTaxUse, active: true } : { active: true });
1214
+ const rows = await ctx.db.select('account.Tax', {
1215
+ ...(args.typeTaxUse ? { typeTaxUse: args.typeTaxUse } : {}),
1216
+ ...(args.includeArchived ? {} : { active: true }),
1217
+ });
1218
+ return narrow(rows.sort(taxOrder), args, ['name']);
1219
+ },
1220
+ }),
1221
+ getProductTax: defineFn({
1222
+ input: { templateId: 'id' },
1223
+ output: { id: 'id', templateId: 'id', taxId: 'id' },
1224
+ effects: ['read:account.ProductTax'],
1225
+ agent: true,
1226
+ handler: async (ctx, args) => (await ctx.db.select('account.ProductTax', { templateId: args.templateId }))[0] ?? null,
1227
+ }),
1228
+ setProductTax: defineFn({
1229
+ input: { templateId: 'id', taxId: 'id?' },
1230
+ output: { ok: 'bool', id: 'id?', errors: 'json?' },
1231
+ effects: [
1232
+ 'read:product.Template',
1233
+ 'read:account.Tax',
1234
+ 'read:account.ProductTax',
1235
+ 'write:account.ProductTax',
1236
+ ],
1237
+ idempotent: true,
1238
+ agent: true,
1239
+ handler: async (ctx, args) => {
1240
+ if (!(await ctx.db.select('product.Template', { id: args.templateId }))[0])
1241
+ return invalid('templateId', 'productMissing');
1242
+ const held = (await ctx.db.select('account.ProductTax', { templateId: args.templateId }))[0];
1243
+ if (!args.taxId) {
1244
+ if (held) {
1245
+ const ProductTax = ctx.table('account.ProductTax');
1246
+ await ctx.db.del(deleteFrom(ProductTax).where(eq(ProductTax.id, held.id)));
1247
+ }
1248
+ return { ok: true };
1249
+ }
1250
+ const tax = (await ctx.db.select('account.Tax', { id: args.taxId }))[0];
1251
+ if (!tax)
1252
+ return invalid('taxId', 'taxMissing');
1253
+ if (!['sale', 'none'].includes(String(tax.typeTaxUse)))
1254
+ return invalid('taxId', 'taxDirectionMismatch', { name: tax.name });
1255
+ if (held) {
1256
+ await ctx.db.update('account.ProductTax', { id: held.id }, { taxId: args.taxId });
1257
+ return { ok: true, id: held.id };
1258
+ }
1259
+ const id = `product-tax:${String(ctx.scope.company ?? '')}:${String(args.templateId)}`;
1260
+ await ctx.db.insert('account.ProductTax', {
1261
+ id,
1262
+ templateId: args.templateId,
1263
+ taxId: args.taxId,
1264
+ });
1265
+ return { ok: true, id };
296
1266
  },
297
1267
  }),
298
1268
  saveTax: defineFn({
@@ -301,7 +1271,6 @@ export const functions = {
301
1271
  name: 'text',
302
1272
  description: 'text?',
303
1273
  typeTaxUse: 'text',
304
- taxScope: 'text?',
305
1274
  amountType: 'text',
306
1275
  amount: 'decimal',
307
1276
  priceInclude: 'bool?',
@@ -316,16 +1285,24 @@ export const functions = {
316
1285
  agent: true,
317
1286
  handler: async (ctx, args) => {
318
1287
  if (!TAX_USES.includes(args.typeTaxUse))
319
- return invalid('typeTaxUse', 'unsupported Odoo 19 tax use');
1288
+ return invalid('typeTaxUse', 'taxUseUnsupported');
320
1289
  if (!TAX_AMOUNT_TYPES.includes(args.amountType))
321
- return invalid('amountType', 'unsupported Odoo 19 tax computation');
1290
+ return invalid('amountType', 'taxComputationUnsupported');
322
1291
  if (args.taxScope && !['service', 'consu'].includes(String(args.taxScope)))
323
- return invalid('taxScope', 'tax scope must be service or consu');
1292
+ return invalid('taxScope', 'taxScopeUnsupported');
324
1293
  if (args.accountId && !(await accountOf(ctx, args.accountId)))
325
- return invalid('accountId', 'tax account does not exist');
1294
+ return invalid('accountId', 'taxAccountMissing');
1295
+ let amount;
1296
+ try {
1297
+ amount = canonicalDecimalText(args.amount);
1298
+ }
1299
+ catch {
1300
+ return invalid('amount', 'moneyExactString');
1301
+ }
326
1302
  const existing = (await ctx.db.select('account.Tax', { id: args.id }))[0];
327
1303
  const values = {
328
1304
  ...args,
1305
+ amount,
329
1306
  priceInclude: args.priceInclude === true,
330
1307
  includeBaseAmount: args.includeBaseAmount === true,
331
1308
  sequence: args.sequence ?? 10,
@@ -338,7 +1315,6 @@ export const functions = {
338
1315
  'name',
339
1316
  'description',
340
1317
  'typeTaxUse',
341
- 'taxScope',
342
1318
  'amountType',
343
1319
  'amount',
344
1320
  'priceInclude',
@@ -354,14 +1330,152 @@ export const functions = {
354
1330
  return { ok: true, id: args.id };
355
1331
  },
356
1332
  }),
357
- listPaymentTerms: defineFn({
1333
+ getDefaults: defineFn({
358
1334
  input: {},
359
- effects: ['read:account.PaymentTerm', 'read:account.PaymentTermLine', ...ACCOUNT_SETUP_EFFECTS],
1335
+ output: {
1336
+ id: 'id?',
1337
+ incomeAccountId: 'id?',
1338
+ expenseAccountId: 'id?',
1339
+ receivableAccountId: 'id?',
1340
+ payableAccountId: 'id?',
1341
+ },
1342
+ effects: ['read:account.Defaults', ...ACCOUNT_SETUP_EFFECTS],
1343
+ agent: true,
1344
+ handler: async (ctx) => {
1345
+ await ensureCompanyAccounting(ctx);
1346
+ return (await ctx.db.select('account.Defaults'))[0] ?? {};
1347
+ },
1348
+ }),
1349
+ saveDefaults: defineFn({
1350
+ input: {
1351
+ incomeAccountId: 'id?',
1352
+ expenseAccountId: 'id?',
1353
+ receivableAccountId: 'id?',
1354
+ payableAccountId: 'id?',
1355
+ },
1356
+ output: { ok: 'bool', id: 'id?', errors: 'json?' },
1357
+ effects: ['read:account.Account', 'read:account.Defaults', 'write:account.Defaults'],
1358
+ idempotent: true,
1359
+ agent: true,
1360
+ handler: async (ctx, args) => {
1361
+ // Each default has a type the ledger will insist on later; refusing here
1362
+ // means the invoice that would have used it never fails in the first place.
1363
+ for (const [field, wanted] of [
1364
+ ['incomeAccountId', ['income', 'income_other']],
1365
+ ['expenseAccountId', ['expense', 'expense_other', 'expense_depreciation', 'expense_direct_cost']],
1366
+ ['receivableAccountId', ['asset_receivable']],
1367
+ ['payableAccountId', ['liability_payable']],
1368
+ ]) {
1369
+ const id = args[field];
1370
+ if (!id)
1371
+ continue;
1372
+ const account = await accountOf(ctx, id);
1373
+ if (!account)
1374
+ return invalid(field, 'accountMissing');
1375
+ if (!wanted.includes(String(account.accountType)))
1376
+ return invalid(field, field === 'receivableAccountId'
1377
+ ? 'counterpartMustBeReceivable'
1378
+ : field === 'payableAccountId'
1379
+ ? 'counterpartMustBePayable'
1380
+ : 'defaultAccountType');
1381
+ }
1382
+ const held = (await ctx.db.select('account.Defaults'))[0];
1383
+ const values = {
1384
+ incomeAccountId: args.incomeAccountId ?? null,
1385
+ expenseAccountId: args.expenseAccountId ?? null,
1386
+ receivableAccountId: args.receivableAccountId ?? null,
1387
+ payableAccountId: args.payableAccountId ?? null,
1388
+ };
1389
+ if (held) {
1390
+ await ctx.db.update('account.Defaults', { id: held.id }, values);
1391
+ return { ok: true, id: held.id };
1392
+ }
1393
+ const id = `account-defaults:${String(ctx.scope.company ?? '')}`;
1394
+ await ctx.db.insert('account.Defaults', { id, ...values });
1395
+ return { ok: true, id };
1396
+ },
1397
+ }),
1398
+ listCategoryAccounts: defineFn({
1399
+ input: {},
1400
+ effects: ['read:account.CategoryAccount', 'read:product.Category'],
360
1401
  agent: true,
361
1402
  handler: async (ctx) => {
1403
+ const categories = new Map((await ctx.db.select('product.Category')).map((row) => [String(row.id), row]));
1404
+ return (await ctx.db.select('account.CategoryAccount')).map((row) => ({
1405
+ ...row,
1406
+ categoryName: categories.get(String(row.categoryId))?.name ?? null,
1407
+ }));
1408
+ },
1409
+ }),
1410
+ saveCategoryAccount: defineFn({
1411
+ input: { categoryId: 'id', incomeAccountId: 'id?', expenseAccountId: 'id?' },
1412
+ output: { ok: 'bool', id: 'id?', errors: 'json?' },
1413
+ effects: [
1414
+ 'read:account.Account',
1415
+ 'read:account.CategoryAccount',
1416
+ 'read:product.Category',
1417
+ 'write:account.CategoryAccount',
1418
+ ],
1419
+ idempotent: true,
1420
+ agent: true,
1421
+ handler: async (ctx, args) => {
1422
+ if (!(await ctx.db.select('product.Category', { id: args.categoryId }))[0])
1423
+ return invalid('categoryId', 'categoryMissing');
1424
+ for (const [field, wanted] of [
1425
+ ['incomeAccountId', ['income', 'income_other']],
1426
+ ['expenseAccountId', ['expense', 'expense_other', 'expense_depreciation', 'expense_direct_cost']],
1427
+ ]) {
1428
+ const id = args[field];
1429
+ if (!id)
1430
+ continue;
1431
+ const account = await accountOf(ctx, id);
1432
+ if (!account)
1433
+ return invalid(field, 'accountMissing');
1434
+ if (!wanted.includes(String(account.accountType)))
1435
+ return invalid(field, 'defaultAccountType');
1436
+ }
1437
+ const values = {
1438
+ incomeAccountId: args.incomeAccountId ?? null,
1439
+ expenseAccountId: args.expenseAccountId ?? null,
1440
+ };
1441
+ const held = (await ctx.db.select('account.CategoryAccount', { categoryId: args.categoryId }))[0];
1442
+ if (held) {
1443
+ await ctx.db.update('account.CategoryAccount', { id: held.id }, values);
1444
+ return { ok: true, id: held.id };
1445
+ }
1446
+ // One row per company and category, so the id can be derived rather than
1447
+ // generated: a second save corrects the first instead of racing it.
1448
+ const id = `category-account:${String(ctx.scope.company ?? '')}:${String(args.categoryId)}`;
1449
+ await ctx.db.insert('account.CategoryAccount', { id, categoryId: args.categoryId, ...values });
1450
+ return { ok: true, id };
1451
+ },
1452
+ }),
1453
+ /** What a document would post to, and what decided it. The forms use this to explain themselves. */
1454
+ previewAccounts: defineFn({
1455
+ input: { moveType: 'text', partnerId: 'id?', productId: 'id?' },
1456
+ output: {
1457
+ lineAccountId: 'id?',
1458
+ lineAccountFrom: 'text?',
1459
+ counterpartAccountId: 'id?',
1460
+ counterpartAccountFrom: 'text?',
1461
+ },
1462
+ effects: [...ACCOUNT_RESOLUTION_EFFECTS],
1463
+ agent: true,
1464
+ handler: (ctx, args) => resolveAccounts(ctx, {
1465
+ moveType: String(args.moveType),
1466
+ partnerId: args.partnerId,
1467
+ productId: args.productId,
1468
+ }),
1469
+ }),
1470
+ listPaymentTerms: defineFn({
1471
+ input: { includeArchived: 'bool?' },
1472
+ effects: ['read:account.PaymentTerm', 'read:account.PaymentTermLine', ...ACCOUNT_SETUP_EFFECTS],
1473
+ agent: true,
1474
+ handler: async (ctx, args) => {
362
1475
  await ensureCompanyAccounting(ctx);
363
1476
  const T = ctx.table('account.PaymentTerm');
364
- return ctx.db.all(from(T).where(eq(T.active, true)).orderBy(asc(T.name)).preload('lines'));
1477
+ const q = from(T).orderBy(asc(T.name)).preload('lines');
1478
+ return ctx.db.all(args.includeArchived ? q : q.where(eq(T.active, true)));
365
1479
  },
366
1480
  }),
367
1481
  savePaymentTerm: defineFn({
@@ -400,15 +1514,23 @@ export const functions = {
400
1514
  agent: true,
401
1515
  handler: async (ctx, args) => {
402
1516
  if (!(await ctx.db.select('account.PaymentTerm', { id: args.paymentId }))[0])
403
- return invalid('paymentId', 'payment term does not exist');
1517
+ return invalid('paymentId', 'paymentTermMissing');
404
1518
  if (!PAYMENT_TERM_VALUES.includes(args.value))
405
- return invalid('value', 'value must be percent or fixed');
1519
+ return invalid('value', 'termValueUnsupported');
406
1520
  if (!PAYMENT_TERM_DELAY_TYPES.includes(args.delayType))
407
- return invalid('delayType', 'unsupported Odoo 19 delay type');
408
- if (args.value === 'percent' && (n(args.valueAmount) < 0 || n(args.valueAmount) > 100))
409
- return invalid('valueAmount', 'percentage must be between 0 and 100');
1521
+ return invalid('delayType', 'termDelayUnsupported');
1522
+ let valueAmount;
1523
+ try {
1524
+ valueAmount = canonicalDecimalText(args.valueAmount);
1525
+ }
1526
+ catch {
1527
+ return invalid('valueAmount', 'moneyExactString');
1528
+ }
1529
+ if (args.value === 'percent' &&
1530
+ (decimalSign(valueAmount) < 0 || compareDecimals(valueAmount, '100') > 0))
1531
+ return invalid('valueAmount', 'termPercentRange');
410
1532
  const existing = (await ctx.db.select('account.PaymentTermLine', { id: args.id }))[0];
411
- const values = { ...args, sequence: args.sequence ?? 10 };
1533
+ const values = { ...args, valueAmount, sequence: args.sequence ?? 10 };
412
1534
  const cs = ctx
413
1535
  .change('account.PaymentTermLine', values, existing ?? null)
414
1536
  .cast(['id', 'paymentId', 'value', 'valueAmount', 'delayType', 'nbDays', 'daysNextMonth', 'sequence'])
@@ -420,35 +1542,125 @@ export const functions = {
420
1542
  },
421
1543
  }),
422
1544
  listMoves: defineFn({
423
- input: { moveType: 'text?', state: 'text?', partnerId: 'id?' },
1545
+ input: {
1546
+ moveType: 'text?',
1547
+ moveTypes: 'json?',
1548
+ state: 'text?',
1549
+ paymentState: 'text?',
1550
+ paymentStates: 'json?',
1551
+ partnerId: 'id?',
1552
+ search: 'text?',
1553
+ dateFrom: 'date?',
1554
+ dateTo: 'date?',
1555
+ order: 'text?',
1556
+ limit: 'int?',
1557
+ offset: 'int?',
1558
+ },
1559
+ effects: ['read:account.Move', 'read:company.Company'],
1560
+ agent: true,
1561
+ handler: async (ctx, args) => {
1562
+ const M = ctx.table('account.Move');
1563
+ const where = [
1564
+ ...(args.moveType ? [eq(M.moveType, args.moveType)] : []),
1565
+ ...(moveTypeList(args.moveTypes).length ? [inArray(M.moveType, moveTypeList(args.moveTypes))] : []),
1566
+ ...(args.state ? [eq(M.state, args.state)] : []),
1567
+ ...(args.paymentState ? [eq(M.paymentState, args.paymentState)] : []),
1568
+ ...(paymentStateList(args.paymentStates).length
1569
+ ? [inArray(M.paymentState, paymentStateList(args.paymentStates))]
1570
+ : []),
1571
+ ...(args.partnerId ? [eq(M.partnerId, args.partnerId)] : []),
1572
+ ...(args.search
1573
+ ? [
1574
+ or(ilike(M.name, `%${wildcard(args.search)}%`, true), ilike(M.ref, `%${wildcard(args.search)}%`, true)),
1575
+ ]
1576
+ : []),
1577
+ ];
1578
+ const { timezone } = await ledgerOf(ctx);
1579
+ const dateFrom = accountingFilterDateText(args.dateFrom);
1580
+ const dateTo = accountingFilterDateText(args.dateTo);
1581
+ const loaded = (await ctx.db.all(where.length ? from(M).where(and(...where)) : from(M)));
1582
+ const rows = loaded
1583
+ .map((move) => ({ ...move, accountingDate: moveAccountingDate(move, timezone) }))
1584
+ .filter((move) => (!dateFrom || String(move.accountingDate) >= dateFrom) &&
1585
+ (!dateTo || String(move.accountingDate) <= dateTo))
1586
+ .sort((left, right) => {
1587
+ const held = String(left.accountingDate).localeCompare(String(right.accountingDate)) ||
1588
+ String(left.id).localeCompare(String(right.id));
1589
+ return args.order === 'desc' ? -held : held;
1590
+ });
1591
+ return slice(rows, args.limit, args.offset);
1592
+ },
1593
+ }),
1594
+ countMoves: defineFn({
1595
+ input: {
1596
+ moveType: 'text?',
1597
+ moveTypes: 'json?',
1598
+ state: 'text?',
1599
+ paymentState: 'text?',
1600
+ partnerId: 'id?',
1601
+ },
1602
+ output: { count: 'int' },
424
1603
  effects: ['read:account.Move'],
425
1604
  agent: true,
426
- handler: (ctx, args) => ctx.db.select('account.Move', {
427
- ...(args.moveType ? { moveType: args.moveType } : {}),
428
- ...(args.state ? { state: args.state } : {}),
429
- ...(args.partnerId ? { partnerId: args.partnerId } : {}),
430
- }),
1605
+ handler: async (ctx, args) => {
1606
+ const M = ctx.table('account.Move');
1607
+ const where = [
1608
+ ...(args.moveType ? [eq(M.moveType, args.moveType)] : []),
1609
+ ...(moveTypeList(args.moveTypes).length ? [inArray(M.moveType, moveTypeList(args.moveTypes))] : []),
1610
+ ...(args.state ? [eq(M.state, args.state)] : []),
1611
+ ...(args.paymentState ? [eq(M.paymentState, args.paymentState)] : []),
1612
+ ...(args.partnerId ? [eq(M.partnerId, args.partnerId)] : []),
1613
+ ];
1614
+ return { count: await ctx.db.count(where.length ? from(M).where(and(...where)) : from(M)) };
1615
+ },
431
1616
  }),
432
- listOpenItems: defineFn({
433
- input: { partnerId: 'id?', accountId: 'id?' },
434
- effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine'],
1617
+ listMoveResiduals: defineFn({
1618
+ input: { moveIds: 'json' },
1619
+ effects: ['read:account.MoveLine', 'read:company.Company'],
435
1620
  agent: true,
436
1621
  handler: async (ctx, args) => {
437
- const posted = new Map((await ctx.db.select('account.Move', { state: 'posted' })).map((move) => [String(move.id), move]));
438
- const rows = [];
439
- for (const line of await ctx.db.select('account.MoveLine', {
440
- ...(args.partnerId ? { partnerId: args.partnerId } : {}),
441
- ...(args.accountId ? { accountId: args.accountId } : {}),
442
- })) {
443
- const move = posted.get(String(line.moveId));
444
- if (!move || line.reconciled || n(line.amountResidual) <= 0)
445
- continue;
446
- const account = await accountOf(ctx, line.accountId);
447
- if (!account?.reconcile)
448
- continue;
449
- rows.push({ ...line, move });
1622
+ const { scale } = await ledgerOf(ctx);
1623
+ const ids = Array.isArray(args.moveIds) ? [...new Set(args.moveIds.map(String).filter(Boolean))] : [];
1624
+ const totals = new Map(ids.map((id) => [id, 0n]));
1625
+ const L = ctx.table('account.MoveLine');
1626
+ for (let at = 0; at < ids.length; at += 400) {
1627
+ const chunk = ids.slice(at, at + 400);
1628
+ for (const line of await ctx.db.all(from(L).where(inArray(L.moveId, chunk)))) {
1629
+ const residual = moneyMinor(line.amountResidual, scale);
1630
+ if (residual > 0n)
1631
+ totals.set(String(line.moveId), (totals.get(String(line.moveId)) ?? 0n) + residual);
1632
+ }
450
1633
  }
451
- return rows.sort((a, b) => String(a.move.date).localeCompare(String(b.move.date)));
1634
+ return ids.map((moveId) => ({
1635
+ moveId,
1636
+ amountResidual: minorText(totals.get(moveId) ?? 0n, scale),
1637
+ }));
1638
+ },
1639
+ }),
1640
+ listOpenItems: defineFn({
1641
+ input: { partnerId: 'id?', accountId: 'id?', limit: 'int?', offset: 'int?' },
1642
+ effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine', 'read:company.Company'],
1643
+ agent: true,
1644
+ handler: async (ctx, args) => {
1645
+ const { scale, timezone } = await ledgerOf(ctx);
1646
+ const byId = await accountsById(ctx);
1647
+ const reconcilable = [...byId.values()].filter((row) => row.reconcile === true).map((row) => row.id);
1648
+ if (!reconcilable.length)
1649
+ return [];
1650
+ const posted = new Map((await ctx.db.select('account.Move', { state: 'posted' })).map((move) => [
1651
+ String(move.id),
1652
+ { ...move, accountingDate: moveAccountingDate(move, timezone) },
1653
+ ]));
1654
+ if (!posted.size)
1655
+ return [];
1656
+ const L = ctx.table('account.MoveLine');
1657
+ const lines = await ctx.db.all(from(L).where(and(eq(L.reconciled, false), inArray(L.accountId, args.accountId ? [args.accountId] : reconcilable), ...(args.partnerId ? [eq(L.partnerId, args.partnerId)] : []))));
1658
+ const rows = lines
1659
+ .filter((line) => posted.has(String(line.moveId)) && moneyMinor(line.amountResidual, scale) > 0n)
1660
+ .map((line) => ({ ...line, move: posted.get(String(line.moveId)) }))
1661
+ .sort((a, b) => String(a.move.accountingDate).localeCompare(String(b.move.accountingDate)) ||
1662
+ String(a.id).localeCompare(String(b.id)));
1663
+ return slice(rows, args.limit, args.offset);
452
1664
  },
453
1665
  }),
454
1666
  getMove: defineFn({
@@ -466,6 +1678,8 @@ export const functions = {
466
1678
  journalId: 'id',
467
1679
  moveType: 'text?',
468
1680
  date: 'datetime?',
1681
+ accountingDate: 'date?',
1682
+ documentDate: 'date?',
469
1683
  ref: 'text?',
470
1684
  partnerId: 'id?',
471
1685
  invoiceDate: 'datetime?',
@@ -476,7 +1690,9 @@ export const functions = {
476
1690
  effects: [
477
1691
  'read:account.Journal',
478
1692
  'read:account.Move',
1693
+ 'read:account.PaymentTerm',
479
1694
  'read:account.PaymentTermLine',
1695
+ 'read:partner.Partner',
480
1696
  'read:company.Company',
481
1697
  'write:account.Move',
482
1698
  ],
@@ -485,36 +1701,64 @@ export const functions = {
485
1701
  handler: async (ctx, args) => {
486
1702
  const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
487
1703
  if (!journal)
488
- return invalid('journalId', 'journal does not exist');
1704
+ return invalid('journalId', 'journalMissing');
489
1705
  const moveType = String(args.moveType ?? 'entry');
490
1706
  if (!MOVE_TYPES.includes(moveType))
491
- return invalid('moveType', 'unsupported Odoo 19 move type');
492
- const existing = (await ctx.db.select('account.Move', { id: args.id }))[0];
493
- if (existing)
494
- return { ok: true, id: args.id };
495
- const date = String(args.date ?? today());
496
- await ctx.db.insert('account.Move', {
1707
+ return invalid('moveType', 'moveTypeUnsupported');
1708
+ if (args.partnerId && !(await ctx.db.select('partner.Partner', { id: args.partnerId }))[0])
1709
+ return invalid('partnerId', 'partnerMissing');
1710
+ if (args.paymentTermId && !(await ctx.db.select('account.PaymentTerm', { id: args.paymentTermId }))[0])
1711
+ return invalid('paymentTermId', 'paymentTermMissing');
1712
+ const { currency, scale, timezone } = await ledgerOf(ctx);
1713
+ const date = instantText(args.date ?? today());
1714
+ const invoiceDate = args.invoiceDate == null ? null : instantText(args.invoiceDate);
1715
+ const accountingDate = accountingDateText(args.accountingDate ?? date, timezone);
1716
+ const documentDate = accountingDateText(args.documentDate ?? invoiceDate ?? args.accountingDate ?? date, timezone);
1717
+ const invoiceDateDue = args.invoiceDateDue != null
1718
+ ? instantText(args.invoiceDateDue)
1719
+ : invoiceDate
1720
+ ? await dueDate(ctx, args.paymentTermId, new Date(invoiceDate))
1721
+ : null;
1722
+ const row = {
497
1723
  id: args.id,
498
1724
  name: String(args.id),
499
1725
  ref: args.ref ?? null,
500
1726
  date,
1727
+ accountingDate,
1728
+ documentDate,
501
1729
  moveType,
502
1730
  state: 'draft',
503
1731
  journalId: args.journalId,
504
1732
  partnerId: args.partnerId ?? null,
505
- invoiceDate: args.invoiceDate ?? null,
506
- invoiceDateDue: args.invoiceDateDue ??
507
- (args.invoiceDate
508
- ? await dueDate(ctx, args.paymentTermId, new Date(String(args.invoiceDate)))
509
- : null),
1733
+ invoiceDate,
1734
+ invoiceDateDue,
510
1735
  paymentTermId: args.paymentTermId ?? null,
511
1736
  paymentState: moveType === 'entry' ? 'paid' : 'not_paid',
512
- currency: await companyCurrency(ctx),
513
- amountUntaxed: '0',
514
- amountTax: '0',
515
- amountTotal: '0',
1737
+ currency,
1738
+ amountUntaxed: minorText(0n, scale),
1739
+ amountTax: minorText(0n, scale),
1740
+ amountTotal: minorText(0n, scale),
1741
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
516
1742
  postedAt: null,
517
- });
1743
+ revision: 0,
1744
+ };
1745
+ const inserted = await ctx.db.insertIfAbsent('account.Move', row);
1746
+ if ('dryRun' in inserted || inserted.inserted)
1747
+ return { ok: true, id: args.id };
1748
+ const existing = (await ctx.db.select('account.Move', { id: args.id }))[0];
1749
+ const fields = [
1750
+ ...MOVE_CREATE_FIELDS,
1751
+ ...(args.date == null ? [] : ['date']),
1752
+ ...(args.accountingDate == null && args.date == null ? [] : ['accountingDate']),
1753
+ ...(args.documentDate == null &&
1754
+ args.invoiceDate == null &&
1755
+ args.accountingDate == null &&
1756
+ args.date == null
1757
+ ? []
1758
+ : ['documentDate']),
1759
+ ];
1760
+ if (!existing || !rowMatches(existing, row, fields))
1761
+ return invalid('id', 'moveIdReused');
518
1762
  return { ok: true, id: args.id };
519
1763
  },
520
1764
  }),
@@ -536,22 +1780,47 @@ export const functions = {
536
1780
  dateMaturity: 'datetime?',
537
1781
  displayType: 'text?',
538
1782
  sequence: 'int?',
1783
+ expectedRevision: 'int?',
539
1784
  },
540
- output: { ok: 'bool', id: 'id?', errors: 'json?' },
541
- effects: ['read:account.Move', 'read:account.Account', 'write:account.MoveLine'],
1785
+ output: { ok: 'bool', id: 'id?', existing: 'bool?', errors: 'json?' },
1786
+ effects: [
1787
+ 'read:account.Move',
1788
+ 'read:account.MoveLine',
1789
+ 'read:account.Account',
1790
+ 'read:account.Tax',
1791
+ 'write:account.Move',
1792
+ 'write:account.MoveLine',
1793
+ ],
542
1794
  idempotent: true,
543
1795
  agent: true,
544
1796
  handler: async (ctx, args) => {
545
1797
  const move = (await ctx.db.select('account.Move', { id: args.moveId }))[0];
546
- if (move?.state !== 'draft')
547
- return invalid('moveId', 'lines can only be added to a draft entry');
1798
+ if (!move)
1799
+ return invalid('moveId', 'lineDraftOnly');
548
1800
  const account = await accountOf(ctx, args.accountId);
549
1801
  if (!account)
550
- return invalid('accountId', 'account does not exist');
551
- const debit = money(n(args.debit)), credit = money(n(args.credit));
552
- if (debit < 0 || credit < 0 || (debit > 0 && credit > 0))
553
- return invalid('debit', 'a line may have debit or credit, never both');
554
- const inserted = await ctx.db.insertIfAbsent('account.MoveLine', {
1802
+ return invalid('accountId', 'accountMissing');
1803
+ if (args.taxId && !(await ctx.db.select('account.Tax', { id: args.taxId }))[0])
1804
+ return invalid('taxId', 'taxMissing');
1805
+ const scale = scaleOf(move.currency);
1806
+ let debit;
1807
+ let credit;
1808
+ let quantity;
1809
+ let priceUnit;
1810
+ let discount;
1811
+ try {
1812
+ debit = moneyMinor(args.debit ?? '0', scale);
1813
+ credit = moneyMinor(args.credit ?? '0', scale);
1814
+ quantity = canonicalDecimalText(args.quantity ?? '1');
1815
+ priceUnit = canonicalDecimalText(args.priceUnit ?? '0');
1816
+ discount = canonicalDecimalText(args.discount ?? '0');
1817
+ }
1818
+ catch {
1819
+ return invalid('debit', 'moneyExactString');
1820
+ }
1821
+ if (debit < 0n || credit < 0n || (debit > 0n && credit > 0n))
1822
+ return invalid('debit', 'lineSideBoth');
1823
+ const row = {
555
1824
  id: args.id,
556
1825
  moveId: args.moveId,
557
1826
  name: args.name,
@@ -559,22 +1828,80 @@ export const functions = {
559
1828
  partnerId: args.partnerId ?? move.partnerId ?? null,
560
1829
  productId: args.productId ?? null,
561
1830
  productUomId: args.productUomId ?? null,
562
- quantity: args.quantity ?? '1',
563
- priceUnit: args.priceUnit ?? '0',
564
- discount: args.discount ?? '0',
1831
+ quantity,
1832
+ priceUnit,
1833
+ discount,
565
1834
  taxId: args.taxId ?? null,
566
- debit: decimal(debit),
567
- credit: decimal(credit),
568
- balance: decimal(debit - credit),
569
- dateMaturity: args.dateMaturity ?? null,
1835
+ debit: minorText(debit, scale),
1836
+ credit: minorText(credit, scale),
1837
+ balance: minorText(debit - credit, scale),
1838
+ dateMaturity: args.dateMaturity == null ? null : instantText(args.dateMaturity),
570
1839
  displayType: args.displayType ?? null,
571
1840
  reconciled: false,
572
- amountResidual: account.reconcile ? decimal(Math.abs(debit - credit)) : '0',
1841
+ amountResidual: account.reconcile
1842
+ ? minorText(debit >= credit ? debit - credit : credit - debit, scale)
1843
+ : minorText(0n, scale),
573
1844
  sequence: args.sequence ?? 10,
574
- });
575
- return { ok: true, id: args.id, existing: !('dryRun' in inserted) && !inserted.inserted };
1845
+ };
1846
+ const sameLine = (held) => Boolean(held && rowMatches(held, row, MOVE_LINE_CREATE_FIELDS));
1847
+ try {
1848
+ return await ctx.tx(async (tx) => {
1849
+ const current = (await tx.db.select('account.Move', { id: args.moveId }))[0];
1850
+ if (!current)
1851
+ throw new Refusal('lineDraftOnly');
1852
+ // A retry remains successful after the move was posted. Only a genuinely
1853
+ // new line is subject to the draft-state gate.
1854
+ const existing = (await tx.db.select('account.MoveLine', { id: args.id }))[0];
1855
+ if (existing) {
1856
+ if (!sameLine(existing))
1857
+ throw new Refusal('lineIdTaken');
1858
+ return { ok: true, id: args.id, existing: true };
1859
+ }
1860
+ if (current.state !== 'draft')
1861
+ throw new Refusal('lineDraftOnly');
1862
+ if (!(await claimMoveRevision(tx, current, args.expectedRevision)))
1863
+ throw new Refusal('moveConcurrent');
1864
+ const inserted = await tx.db.insertIfAbsent('account.MoveLine', row);
1865
+ if ('dryRun' in inserted || inserted.inserted)
1866
+ return { ok: true, id: args.id, existing: false };
1867
+ const held = (await tx.db.select('account.MoveLine', { id: args.id }))[0];
1868
+ if (!sameLine(held))
1869
+ throw new Refusal('lineIdTaken');
1870
+ return { ok: true, id: args.id, existing: true };
1871
+ });
1872
+ }
1873
+ catch (error) {
1874
+ if (error instanceof Refusal && error.code === 'moveConcurrent') {
1875
+ const held = (await ctx.db.select('account.MoveLine', { id: args.id }))[0];
1876
+ if (sameLine(held))
1877
+ return { ok: true, id: args.id, existing: true };
1878
+ const settled = (await ctx.db.select('account.Move', { id: args.moveId }))[0];
1879
+ if (settled?.state !== 'draft')
1880
+ return invalid('moveId', 'lineDraftOnly');
1881
+ }
1882
+ const field = error instanceof Refusal && error.code === 'lineIdTaken'
1883
+ ? 'id'
1884
+ : error instanceof Refusal && error.code === 'lineDraftOnly'
1885
+ ? 'moveId'
1886
+ : 'expectedRevision';
1887
+ return refused(field, error);
1888
+ }
576
1889
  },
577
1890
  }),
1891
+ /**
1892
+ * An invoice, in one call, with one line or many.
1893
+ *
1894
+ * A document with several lines cannot be assembled out of `createMove` and
1895
+ * `addMoveLine`: those write exactly what they are given, and the tax a line
1896
+ * carries has to become a posting of its own, computed in the order taxes
1897
+ * compound. Leaving that to callers means every caller re-derives VAT, and
1898
+ * they will not all round it the same way.
1899
+ *
1900
+ * So `lines` is the general form and the flat `description`/`quantity`/
1901
+ * `priceUnit` arguments are the one-line shorthand. A single-line document
1902
+ * built either way lands on the same rows with the same ids, which is what
1903
+ * lets an existing caller keep its `${id}:base` and `${id}:tax` identifiers.
1904
+ */
578
1905
  createInvoice: defineFn({
579
1906
  input: {
580
1907
  id: 'id',
@@ -582,27 +1909,42 @@ export const functions = {
582
1909
  moveType: 'text',
583
1910
  partnerId: 'id',
584
1911
  invoiceDate: 'datetime?',
1912
+ accountingDate: 'date?',
1913
+ documentDate: 'date?',
585
1914
  paymentTermId: 'id?',
586
1915
  ref: 'text?',
587
- description: 'text',
1916
+ /**
1917
+ * The lines of the document, when there is more than one.
1918
+ *
1919
+ * `{ description, quantity, priceUnit, productId?, productUomId?,
1920
+ * discount?, taxId?, taxIds?, lineAccountId?, taxAccountId? }` — the same
1921
+ * fields as the shorthand below, per line. Give this or the shorthand,
1922
+ * never both.
1923
+ */
1924
+ lines: 'json?',
1925
+ description: 'text?',
588
1926
  productId: 'id?',
589
1927
  productUomId: 'id?',
590
- quantity: 'decimal',
591
- priceUnit: 'decimal',
1928
+ quantity: 'decimal?',
1929
+ priceUnit: 'decimal?',
592
1930
  discount: 'decimal?',
593
- lineAccountId: 'id',
594
- counterpartAccountId: 'id',
1931
+ // Optional: left out, they come from the product's category, the partner,
1932
+ // and the company's defaults, in that order.
1933
+ lineAccountId: 'id?',
1934
+ counterpartAccountId: 'id?',
595
1935
  taxId: 'id?',
1936
+ taxIds: 'json?',
596
1937
  taxAccountId: 'id?',
597
1938
  },
598
1939
  output: { ok: 'bool', id: 'id?', amountTotal: 'decimal?', errors: 'json?' },
599
1940
  effects: [
600
1941
  'read:account.Journal',
601
- 'read:account.Account',
602
1942
  'read:account.Tax',
603
1943
  'read:account.Move',
1944
+ 'read:account.MoveLine',
604
1945
  'read:account.PaymentTermLine',
605
1946
  'read:company.Company',
1947
+ ...ACCOUNT_RESOLUTION_EFFECTS,
606
1948
  'write:account.Move',
607
1949
  'write:account.MoveLine',
608
1950
  ],
@@ -610,60 +1952,141 @@ export const functions = {
610
1952
  agent: true,
611
1953
  handler: async (ctx, args) => {
612
1954
  if (!['out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'].includes(String(args.moveType)))
613
- return invalid('moveType', 'createInvoice requires an invoice, refund, or receipt type');
1955
+ return invalid('moveType', 'invoiceTypeRequired');
614
1956
  const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
615
1957
  if (!journal)
616
- return invalid('journalId', 'journal does not exist');
1958
+ return invalid('journalId', 'journalMissing');
617
1959
  const customerDocument = ['out_invoice', 'out_refund', 'out_receipt'].includes(String(args.moveType));
618
- const expectedJournal = customerDocument ? 'sale' : 'purchase';
619
- if (journal.type !== expectedJournal)
620
- return invalid('journalId', `${String(args.moveType)} requires a ${expectedJournal} journal`);
621
- const lineAccount = await accountOf(ctx, args.lineAccountId), counterpart = await accountOf(ctx, args.counterpartAccountId);
622
- if (!lineAccount || !counterpart)
623
- return invalid('accountId', 'invoice accounts do not exist');
624
- const expectedCounterpart = customerDocument ? 'asset_receivable' : 'liability_payable';
625
- if (counterpart.accountType !== expectedCounterpart)
626
- return invalid('counterpartAccountId', `counterpart account must be ${expectedCounterpart}`);
627
- const tax = args.taxId ? ((await ctx.db.select('account.Tax', { id: args.taxId }))[0] ?? null) : null;
628
- if (tax && ![customerDocument ? 'sale' : 'purchase', 'none'].includes(String(tax.typeTaxUse)))
629
- return invalid('taxId', 'tax use does not match the invoice direction');
630
- let amounts;
631
- try {
632
- amounts = taxAmounts(tax, n(args.quantity), n(args.priceUnit), n(args.discount));
633
- }
634
- catch (error) {
635
- return invalid('taxId', error.message);
1960
+ if (journal.type !== (customerDocument ? 'sale' : 'purchase'))
1961
+ return invalid('journalId', customerDocument ? 'journalMustBeSale' : 'journalMustBePurchase');
1962
+ // One shape or the other. Accepting both would leave the shorthand's line
1963
+ // either silently dropped or silently appended, and neither is obvious
1964
+ // from the call site.
1965
+ const many = args.lines !== undefined && args.lines !== null;
1966
+ if (many && args.description !== undefined)
1967
+ return invalid('lines', 'invoiceLinesAndSingle');
1968
+ const given = many ? (Array.isArray(args.lines) ? args.lines : []) : [args];
1969
+ if (many && !given.length)
1970
+ return invalid('lines', 'invoiceLinesEmpty');
1971
+ if (!many && (args.description === undefined || args.description === null))
1972
+ return invalid('description', 'invoiceLineRequired');
1973
+ const { currency, scale, timezone } = await ledgerOf(ctx);
1974
+ const priced = [];
1975
+ // Tax shares are accumulated across the whole document: two lines at the
1976
+ // same rate post one tax line, as a paper invoice shows one VAT figure per
1977
+ // rate rather than one per row.
1978
+ const shares = new Map();
1979
+ for (const [at, entry] of given.entries()) {
1980
+ const spec = (entry ?? {});
1981
+ const where = many ? `lines.${at}` : 'description';
1982
+ if (spec.description === undefined || spec.description === null)
1983
+ return invalid(where, 'invoiceLineRequired');
1984
+ const resolved = await resolveAccounts(ctx, { moveType: String(args.moveType), partnerId: args.partnerId, productId: spec.productId }, { lineAccountId: spec.lineAccountId });
1985
+ if (!resolved.lineAccountId)
1986
+ return invalid(many ? where : 'lineAccountId', 'lineAccountUndecided');
1987
+ if (!(await accountOf(ctx, resolved.lineAccountId)))
1988
+ return invalid(many ? where : 'lineAccountId', 'invoiceAccountsMissing');
1989
+ // `taxId` stays accepted so existing callers keep working; `taxIds` is how a
1990
+ // line carries the sequence of taxes that compound into one another.
1991
+ const wanted = [
1992
+ ...(Array.isArray(spec.taxIds) ? spec.taxIds.map(String) : []),
1993
+ ...(spec.taxId ? [String(spec.taxId)] : []),
1994
+ ].filter((id, index, all) => all.indexOf(id) === index);
1995
+ const taxes = [];
1996
+ for (const id of wanted) {
1997
+ const tax = (await ctx.db.select('account.Tax', { id }))[0];
1998
+ if (!tax)
1999
+ return invalid(many ? where : 'taxIds', 'taxMissing');
2000
+ if (![customerDocument ? 'sale' : 'purchase', 'none'].includes(String(tax.typeTaxUse)))
2001
+ return invalid(many ? where : 'taxIds', 'taxDirectionMismatch', { name: tax.name });
2002
+ taxes.push(tax);
2003
+ }
2004
+ let amounts;
2005
+ try {
2006
+ const quantity = canonicalDecimalText(spec.quantity ?? '1');
2007
+ const priceUnit = canonicalDecimalText(spec.priceUnit ?? '0');
2008
+ const discount = canonicalDecimalText(spec.discount ?? '0');
2009
+ if (decimalSign(quantity) <= 0 ||
2010
+ decimalSign(priceUnit) < 0 ||
2011
+ decimalSign(discount) < 0 ||
2012
+ compareDecimals(discount, '100') > 0)
2013
+ return invalid(where, 'taxPriceInvalid');
2014
+ amounts = taxAmounts(taxes, quantity, priceUnit, discount, scale);
2015
+ spec.quantity = quantity;
2016
+ spec.priceUnit = priceUnit;
2017
+ spec.discount = discount;
2018
+ }
2019
+ catch (error) {
2020
+ return refused(many ? where : 'taxIds', error);
2021
+ }
2022
+ // Each tax posts to its own account. A single override stays meaningful only
2023
+ // while there is one tax to override.
2024
+ for (const held of amounts.shares) {
2025
+ if (moneyMinor(held.amount, scale) === 0n)
2026
+ continue;
2027
+ const accountId = (amounts.shares.length === 1 ? spec.taxAccountId : null) ?? held.accountId;
2028
+ if (!accountId || !(await accountOf(ctx, accountId)))
2029
+ return invalid(many ? where : 'taxAccountId', 'taxPostingAccountMissing', { name: held.name });
2030
+ const key = `${String(held.taxId)}:${String(accountId)}`;
2031
+ const running = shares.get(key);
2032
+ if (running)
2033
+ running.amount = minorText(moneyMinor(running.amount, scale) + moneyMinor(held.amount, scale), scale);
2034
+ else
2035
+ shares.set(key, { ...held, accountId });
2036
+ }
2037
+ priced.push({
2038
+ spec,
2039
+ accountId: resolved.lineAccountId,
2040
+ amounts,
2041
+ firstTaxId: taxes[0]?.id ?? null,
2042
+ });
636
2043
  }
637
- const taxAccountId = args.taxAccountId ?? tax?.accountId;
638
- if (amounts.tax && (!taxAccountId || !(await accountOf(ctx, taxAccountId))))
639
- return invalid('taxAccountId', 'a valid tax account is required when tax is non-zero');
640
- const existing = (await ctx.db.select('account.Move', { id: args.id }))[0];
641
- if (existing)
642
- return { ok: true, id: args.id, amountTotal: existing.amountTotal };
643
- const invoiceDate = String(args.invoiceDate ?? today());
644
- const currency = await companyCurrency(ctx);
2044
+ // After the lines, so a document with nothing to post still reports the
2045
+ // revenue account it could not decide before the receivable one.
2046
+ const resolvedCounterpart = await resolveAccounts(ctx, { moveType: String(args.moveType), partnerId: args.partnerId }, { counterpartAccountId: args.counterpartAccountId });
2047
+ if (!resolvedCounterpart.counterpartAccountId)
2048
+ return invalid('counterpartAccountId', 'counterpartAccountUndecided');
2049
+ const counterpart = await accountOf(ctx, resolvedCounterpart.counterpartAccountId);
2050
+ if (!counterpart)
2051
+ return invalid('counterpartAccountId', 'invoiceAccountsMissing');
2052
+ if (counterpart.accountType !== (customerDocument ? 'asset_receivable' : 'liability_payable'))
2053
+ return invalid('counterpartAccountId', customerDocument ? 'counterpartMustBeReceivable' : 'counterpartMustBePayable');
2054
+ const untaxed = sumMoneyMinor(priced.map((line) => line.amounts.untaxed), scale);
2055
+ const tax = sumMoneyMinor([...shares.values()].map((held) => held.amount), scale);
2056
+ const total = untaxed + tax;
2057
+ const posting = [...shares.values()];
2058
+ const invoiceDate = instantText(args.invoiceDate ?? today());
2059
+ const accountingDate = accountingDateText(args.accountingDate ?? invoiceDate, timezone);
2060
+ const documentDate = accountingDateText(args.documentDate ?? invoiceDate, timezone);
2061
+ const due = await dueDate(ctx, args.paymentTermId, new Date(invoiceDate));
645
2062
  const mainDebit = ['in_invoice', 'in_receipt', 'out_refund'].includes(String(args.moveType));
646
- await ctx.tx(async (tx) => {
647
- await tx.db.insert('account.Move', {
648
- id: args.id,
649
- name: String(args.id),
650
- ref: args.ref ?? null,
651
- date: invoiceDate,
652
- moveType: args.moveType,
653
- state: 'draft',
654
- journalId: args.journalId,
655
- partnerId: args.partnerId,
656
- invoiceDate,
657
- invoiceDateDue: await dueDate(tx, args.paymentTermId, new Date(invoiceDate)),
658
- paymentTermId: args.paymentTermId ?? null,
659
- paymentState: 'not_paid',
660
- currency,
661
- amountUntaxed: decimal(amounts.untaxed),
662
- amountTax: decimal(amounts.tax),
663
- amountTotal: decimal(amounts.total),
664
- postedAt: null,
665
- });
666
- const line = async (id, accountId, amount, debitSide, name, reconcilable, extra = {}) => tx.db.insert('account.MoveLine', {
2063
+ const moveRow = {
2064
+ id: args.id,
2065
+ name: String(args.id),
2066
+ ref: args.ref ?? null,
2067
+ date: invoiceDate,
2068
+ accountingDate,
2069
+ documentDate,
2070
+ moveType: args.moveType,
2071
+ state: 'draft',
2072
+ journalId: args.journalId,
2073
+ partnerId: args.partnerId,
2074
+ invoiceDate,
2075
+ invoiceDateDue: due,
2076
+ paymentTermId: args.paymentTermId ?? null,
2077
+ paymentState: 'not_paid',
2078
+ currency,
2079
+ amountUntaxed: minorText(untaxed, scale),
2080
+ amountTax: minorText(tax, scale),
2081
+ amountTotal: minorText(total, scale),
2082
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
2083
+ postedAt: null,
2084
+ revision: 0,
2085
+ };
2086
+ const lineRows = [];
2087
+ const line = (id, accountId, amount, debitSide, name, reconcilable, extra = {}) => {
2088
+ const minor = typeof amount === 'bigint' ? amount : moneyMinor(amount, scale);
2089
+ lineRows.push({
667
2090
  id,
668
2091
  moveId: args.id,
669
2092
  name,
@@ -672,50 +2095,105 @@ export const functions = {
672
2095
  productId: null,
673
2096
  productUomId: null,
674
2097
  quantity: '1',
675
- priceUnit: decimal(amount),
2098
+ priceUnit: minorText(minor, scale),
676
2099
  discount: '0',
677
2100
  taxId: null,
678
- debit: debitSide ? decimal(amount) : '0',
679
- credit: debitSide ? '0' : decimal(amount),
680
- balance: decimal(debitSide ? amount : -amount),
2101
+ debit: debitSide ? minorText(minor, scale) : minorText(0n, scale),
2102
+ credit: debitSide ? minorText(0n, scale) : minorText(minor, scale),
2103
+ balance: minorText(debitSide ? minor : -minor, scale),
681
2104
  dateMaturity: null,
682
2105
  displayType: null,
683
2106
  reconciled: false,
684
- amountResidual: reconcilable ? decimal(amount) : '0',
2107
+ amountResidual: minorText(reconcilable ? minor : 0n, scale),
685
2108
  sequence: 10,
686
2109
  ...extra,
687
2110
  });
688
- await line(`${String(args.id)}:base`, args.lineAccountId, amounts.untaxed, mainDebit, String(args.description), false, {
689
- productId: args.productId ?? null,
690
- productUomId: args.productUomId ?? null,
691
- quantity: String(args.quantity),
692
- priceUnit: String(args.priceUnit),
693
- discount: String(args.discount ?? 0),
694
- taxId: args.taxId ?? null,
2111
+ };
2112
+ for (const [at, held] of priced.entries())
2113
+ line(
2114
+ // The first line keeps the historical id, so a single-line document
2115
+ // written through either shape lands on exactly the same row.
2116
+ at === 0 ? `${String(args.id)}:base` : `${String(args.id)}:base:${at}`, held.accountId, held.amounts.untaxed, mainDebit, String(held.spec.description), false, {
2117
+ productId: held.spec.productId ?? null,
2118
+ productUomId: held.spec.productUomId ?? null,
2119
+ quantity: held.spec.quantity,
2120
+ priceUnit: held.spec.priceUnit,
2121
+ discount: held.spec.discount,
2122
+ taxId: held.firstTaxId,
2123
+ sequence: 10 + at,
695
2124
  });
696
- if (amounts.tax)
697
- await line(`${String(args.id)}:tax`, taxAccountId, amounts.tax, mainDebit, String(tax?.name ?? 'Tax'), false, { sequence: 20 });
698
- await line(`${String(args.id)}:counterpart`, args.counterpartAccountId, amounts.total, !mainDebit, String(args.ref ?? args.description), true, { dateMaturity: await dueDate(tx, args.paymentTermId, new Date(invoiceDate)), sequence: 30 });
699
- });
700
- return { ok: true, id: args.id, amountTotal: decimal(amounts.total) };
2125
+ for (const [at, held] of posting.entries())
2126
+ line(
2127
+ // The first tax line keeps the historical id so an existing document
2128
+ // reprocessed by id lands on the same rows.
2129
+ at === 0 ? `${String(args.id)}:tax` : `${String(args.id)}:tax:${String(held.taxId)}`, held.accountId, held.amount, mainDebit, held.name, false, { taxId: held.taxId, sequence: 10 + priced.length + at });
2130
+ line(`${String(args.id)}:counterpart`, resolvedCounterpart.counterpartAccountId, total, !mainDebit, String(args.ref ?? priced[0]?.spec.description ?? args.id), true, { dateMaturity: due, sequence: 10 + priced.length + posting.length });
2131
+ try {
2132
+ const amountTotal = await ctx.tx(async (tx) => {
2133
+ const inserted = await tx.db.insertIfAbsent('account.Move', moveRow);
2134
+ if (!('dryRun' in inserted) && !inserted.inserted) {
2135
+ const existing = (await tx.db.select('account.Move', { id: args.id }))[0];
2136
+ const moveFields = [
2137
+ 'journalId',
2138
+ 'moveType',
2139
+ 'ref',
2140
+ 'partnerId',
2141
+ 'paymentTermId',
2142
+ 'currency',
2143
+ 'amountUntaxed',
2144
+ 'amountTax',
2145
+ 'amountTotal',
2146
+ 'moneyPolicyVersion',
2147
+ ...(args.invoiceDate == null ? [] : ['date', 'invoiceDate', 'invoiceDateDue']),
2148
+ ...(args.accountingDate == null && args.invoiceDate == null ? [] : ['accountingDate']),
2149
+ ...(args.documentDate == null && args.invoiceDate == null ? [] : ['documentDate']),
2150
+ ];
2151
+ const storedLines = await tx.db.select('account.MoveLine', { moveId: args.id });
2152
+ const lineFields = args.invoiceDate == null
2153
+ ? MOVE_LINE_CREATE_FIELDS.filter((field) => field !== 'dateMaturity')
2154
+ : MOVE_LINE_CREATE_FIELDS;
2155
+ const byLineId = new Map(storedLines.map((held) => [String(held.id), held]));
2156
+ const sameLines = storedLines.length === lineRows.length &&
2157
+ lineRows.every((wanted) => {
2158
+ const held = byLineId.get(String(wanted.id));
2159
+ return Boolean(held && rowMatches(held, wanted, lineFields));
2160
+ });
2161
+ if (!existing || !rowMatches(existing, moveRow, moveFields) || !sameLines)
2162
+ throw new Refusal('invoiceIdReused');
2163
+ return String(existing.amountTotal);
2164
+ }
2165
+ for (const row of lineRows)
2166
+ await tx.db.insert('account.MoveLine', row);
2167
+ return minorText(total, scale);
2168
+ });
2169
+ return { ok: true, id: args.id, amountTotal };
2170
+ }
2171
+ catch (error) {
2172
+ return refused('id', error);
2173
+ }
701
2174
  },
702
2175
  }),
703
2176
  postMove: defineFn({
704
- input: { id: 'id' },
2177
+ input: { id: 'id', expectedRevision: 'int?' },
705
2178
  output: { ok: 'bool', id: 'id?', name: 'text?', errors: 'json?' },
706
2179
  effects: [
707
2180
  'read:account.Move',
708
2181
  'read:account.MoveLine',
709
2182
  'read:account.Journal',
2183
+ 'read:account.Account',
2184
+ 'read:account.PeriodPolicy',
2185
+ 'read:company.Company',
710
2186
  'write:account.Journal',
711
2187
  'write:account.Move',
2188
+ 'write:account.PeriodPolicy',
2189
+ 'write:account.AuditEvent',
712
2190
  ],
713
2191
  idempotent: true,
714
2192
  agent: true,
715
- handler: (ctx, args) => post(ctx, args.id),
2193
+ handler: (ctx, args) => postMoveById(ctx, args.id, args.expectedRevision),
716
2194
  }),
717
2195
  cancelMove: defineFn({
718
- input: { id: 'id' },
2196
+ input: { id: 'id', expectedRevision: 'int?' },
719
2197
  output: { ok: 'bool', id: 'id?', errors: 'json?' },
720
2198
  effects: ['read:account.Move', 'write:account.Move'],
721
2199
  idempotent: true,
@@ -723,18 +2201,438 @@ export const functions = {
723
2201
  handler: async (ctx, args) => {
724
2202
  const move = (await ctx.db.select('account.Move', { id: args.id }))[0];
725
2203
  if (!move)
726
- return invalid('id', 'journal entry does not exist');
2204
+ return invalid('id', 'moveMissing');
2205
+ if (move.state === 'cancel')
2206
+ return { ok: true, id: args.id };
727
2207
  if (move.state === 'posted')
728
- return invalid('state', 'posted entries must be reversed; direct cancellation is unsupported');
729
- await ctx.db.update('account.Move', { id: args.id }, { state: 'cancel' });
730
- return { ok: true, id: args.id };
2208
+ return invalid('state', 'moveNotCancellable');
2209
+ try {
2210
+ await ctx.tx(async (tx) => {
2211
+ const current = (await tx.db.select('account.Move', { id: args.id }))[0];
2212
+ if (!current)
2213
+ throw new Refusal('moveMissing');
2214
+ if (current.state === 'cancel')
2215
+ return;
2216
+ if (current.state === 'posted')
2217
+ throw new Refusal('moveNotCancellable');
2218
+ if (!(await claimMoveRevision(tx, current, args.expectedRevision)))
2219
+ throw new Refusal('moveConcurrent');
2220
+ await tx.db.update('account.Move', { id: args.id }, { state: 'cancel' });
2221
+ });
2222
+ return { ok: true, id: args.id };
2223
+ }
2224
+ catch (error) {
2225
+ return refused('expectedRevision', error);
2226
+ }
2227
+ },
2228
+ }),
2229
+ /**
2230
+ * Post the mirror image of an entry that is already in the books.
2231
+ *
2232
+ * A posted entry is never edited or deleted — the correction is a second entry
2233
+ * whose debits and credits are the first one's, swapped. Where the original
2234
+ * opened an item on a reconcilable account, the reversal closes it against the
2235
+ * original, so the document stops showing up as owed.
2236
+ */
2237
+ reverseMove: defineFn({
2238
+ input: {
2239
+ id: 'id',
2240
+ reversalId: 'id',
2241
+ date: 'datetime?',
2242
+ accountingDate: 'date?',
2243
+ documentDate: 'date?',
2244
+ ref: 'text?',
2245
+ reason: 'text?',
2246
+ journalId: 'id?',
2247
+ },
2248
+ output: { ok: 'bool', id: 'id?', reversalId: 'id?', name: 'text?', errors: 'json?' },
2249
+ effects: [
2250
+ 'read:account.Move',
2251
+ 'read:account.MoveLine',
2252
+ 'read:account.Account',
2253
+ 'read:account.Journal',
2254
+ 'read:account.PartialReconcile',
2255
+ 'read:account.Payment',
2256
+ 'read:account.PeriodPolicy',
2257
+ 'read:company.Company',
2258
+ 'write:account.Journal',
2259
+ 'write:account.Move',
2260
+ 'write:account.MoveLine',
2261
+ 'write:account.PartialReconcile',
2262
+ 'write:account.Payment',
2263
+ 'write:account.PeriodPolicy',
2264
+ 'write:account.AuditEvent',
2265
+ ],
2266
+ idempotent: true,
2267
+ agent: true,
2268
+ handler: async (ctx, args) => {
2269
+ const move = (await ctx.db.select('account.Move', { id: args.id }))[0];
2270
+ if (!move)
2271
+ return invalid('id', 'moveMissing');
2272
+ if (move.state !== 'posted')
2273
+ return invalid('state', 'movePostedOnly');
2274
+ const reversalId = String(args.reversalId);
2275
+ if (move.reversedById && String(move.reversedById) !== reversalId)
2276
+ return invalid('reversalId', 'moveAlreadyReversed');
2277
+ const already = (await ctx.db.select('account.Move', { id: args.reversalId }))[0];
2278
+ const lines = (await ctx.db.select('account.MoveLine', { moveId: args.id })).sort((a, b) => n(a.sequence) - n(b.sequence) || String(a.id).localeCompare(String(b.id)));
2279
+ if (!lines.length)
2280
+ return invalid('lines', 'reversalNoLines');
2281
+ const journalId = args.journalId ?? already?.journalId ?? move.journalId;
2282
+ if (!(await ctx.db.select('account.Journal', { id: journalId }))[0])
2283
+ return invalid('journalId', 'journalMissing');
2284
+ const { currency, scale, timezone } = await ledgerOf(ctx);
2285
+ if (String(move.currency) !== currency)
2286
+ return invalid('currency', 'moveCurrencyMismatch');
2287
+ const byId = await accountsById(ctx);
2288
+ let date = instantText(args.date ?? already?.date ?? today());
2289
+ let accountingDate;
2290
+ let documentDate;
2291
+ try {
2292
+ accountingDate = accountingDateText(args.accountingDate ?? already?.accountingDate ?? date, timezone);
2293
+ documentDate = accountingDateText(args.documentDate ?? already?.documentDate ?? accountingDate, timezone);
2294
+ }
2295
+ catch {
2296
+ return invalid('accountingDate', 'accountingDateInvalid');
2297
+ }
2298
+ const reversalRow = {
2299
+ id: reversalId,
2300
+ name: reversalId,
2301
+ // The reference is the document being corrected, not a sentence about it:
2302
+ // this module has no translator, and a ledger read in Vietnamese must not
2303
+ // grow English prose.
2304
+ ref: args.ref ?? already?.ref ?? move.name,
2305
+ date,
2306
+ accountingDate,
2307
+ documentDate,
2308
+ moveType: 'entry',
2309
+ state: 'draft',
2310
+ journalId,
2311
+ partnerId: move.partnerId ?? null,
2312
+ invoiceDate: null,
2313
+ invoiceDateDue: null,
2314
+ paymentTermId: null,
2315
+ paymentState: 'paid',
2316
+ currency: move.currency,
2317
+ amountUntaxed: move.amountUntaxed,
2318
+ amountTax: move.amountTax,
2319
+ amountTotal: move.amountTotal,
2320
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
2321
+ postedAt: null,
2322
+ reversalOfId: move.id,
2323
+ reversedById: null,
2324
+ reversalStatus: 'creating',
2325
+ revision: 0,
2326
+ };
2327
+ const mirrorRows = lines.map((line) => {
2328
+ const debit = moneyMinor(line.credit, scale);
2329
+ const credit = moneyMinor(line.debit, scale);
2330
+ const reconcilable = byId.get(String(line.accountId))?.reconcile === true;
2331
+ return {
2332
+ id: `${reversalId}:${String(line.id)}`,
2333
+ moveId: reversalId,
2334
+ name: line.name,
2335
+ accountId: line.accountId,
2336
+ partnerId: line.partnerId ?? null,
2337
+ productId: line.productId ?? null,
2338
+ productUomId: line.productUomId ?? null,
2339
+ quantity: line.quantity,
2340
+ priceUnit: line.priceUnit,
2341
+ discount: line.discount,
2342
+ taxId: line.taxId ?? null,
2343
+ debit: minorText(debit, scale),
2344
+ credit: minorText(credit, scale),
2345
+ balance: minorText(debit - credit, scale),
2346
+ dateMaturity: null,
2347
+ displayType: line.displayType ?? null,
2348
+ reconciled: false,
2349
+ amountResidual: minorText(reconcilable ? (debit >= credit ? debit - credit : credit - debit) : 0n, scale),
2350
+ sequence: line.sequence,
2351
+ };
2352
+ });
2353
+ try {
2354
+ const settled = await ctx.tx(async (tx) => {
2355
+ const source = (await tx.db.select('account.Move', { id: args.id }))[0];
2356
+ if (!source)
2357
+ throw new Refusal('moveMissing');
2358
+ if (source.state !== 'posted')
2359
+ throw new Refusal('movePostedOnly');
2360
+ if (source.reversedById && String(source.reversedById) !== reversalId)
2361
+ throw new Refusal('moveAlreadyReversed');
2362
+ if (!source.reversedById) {
2363
+ const claimed = await tx.db.compareAndSet('account.Move', { id: args.id }, { reversedById: source.reversedById ?? null }, { reversedById: reversalId });
2364
+ if (!('dryRun' in claimed) && !claimed.matched) {
2365
+ const current = (await tx.db.select('account.Move', { id: args.id }))[0];
2366
+ if (String(current?.reversedById ?? '') !== reversalId)
2367
+ throw new Refusal('moveAlreadyReversed');
2368
+ }
2369
+ }
2370
+ const inserted = await tx.db.insertIfAbsent('account.Move', reversalRow);
2371
+ if (!('dryRun' in inserted) && !inserted.inserted) {
2372
+ const existing = (await tx.db.select('account.Move', { id: reversalId }))[0];
2373
+ const moveFields = [
2374
+ 'ref',
2375
+ 'moveType',
2376
+ 'journalId',
2377
+ 'partnerId',
2378
+ 'invoiceDate',
2379
+ 'paymentTermId',
2380
+ 'currency',
2381
+ 'moneyPolicyVersion',
2382
+ 'reversalOfId',
2383
+ ...(args.date == null ? [] : ['date']),
2384
+ ...(args.accountingDate == null ? [] : ['accountingDate']),
2385
+ ...(args.documentDate == null ? [] : ['documentDate']),
2386
+ ];
2387
+ const storedLines = await tx.db.select('account.MoveLine', { moveId: reversalId });
2388
+ const byLineId = new Map(storedLines.map((held) => [String(held.id), held]));
2389
+ const sameLines = storedLines.length === mirrorRows.length &&
2390
+ mirrorRows.every((wanted) => {
2391
+ const held = byLineId.get(String(wanted.id));
2392
+ return Boolean(held && rowMatches(held, wanted, MOVE_LINE_CREATE_FIELDS));
2393
+ });
2394
+ if (!existing ||
2395
+ !['draft', 'posted'].includes(String(existing.state)) ||
2396
+ !rowMatches(existing, reversalRow, moveFields) ||
2397
+ !sameLines)
2398
+ throw new Refusal('reversalIdReused');
2399
+ return existing;
2400
+ }
2401
+ for (const row of mirrorRows)
2402
+ await tx.db.insert('account.MoveLine', row);
2403
+ return reversalRow;
2404
+ });
2405
+ date = String(settled.date);
2406
+ }
2407
+ catch (error) {
2408
+ return refused('reversalId', error);
2409
+ }
2410
+ const posted = await postMoveById(ctx, reversalId);
2411
+ if (posted.ok !== true)
2412
+ return posted;
2413
+ const postedReversal = (await ctx.db.select('account.Move', { id: reversalId }))[0];
2414
+ if (postedReversal?.reversalStatus === 'creating' || !postedReversal?.reversalStatus)
2415
+ await ctx.db.update('account.Move', { id: reversalId }, { reversalStatus: 'posted' });
2416
+ if (postedReversal?.reversalStatus !== 'completed')
2417
+ await ctx.db.update('account.Move', { id: reversalId }, { reversalStatus: 'reconciling' });
2418
+ // Close what the original left open, as far as each side still allows.
2419
+ for (const line of lines) {
2420
+ if (byId.get(String(line.accountId))?.reconcile !== true)
2421
+ continue;
2422
+ const mirror = (await ctx.db.select('account.MoveLine', { id: `${reversalId}:${String(line.id)}` }))[0];
2423
+ const fresh = (await ctx.db.select('account.MoveLine', { id: line.id }))[0];
2424
+ if (!mirror || !fresh)
2425
+ continue;
2426
+ const freshResidual = moneyMinor(fresh.amountResidual, scale);
2427
+ const mirrorResidual = moneyMinor(mirror.amountResidual, scale);
2428
+ const amount = freshResidual < mirrorResidual ? freshResidual : mirrorResidual;
2429
+ if (amount <= 0n)
2430
+ continue;
2431
+ const debitFirst = moneyMinor(fresh.balance, scale) > 0n;
2432
+ const result = await functions.reconcile.handler(ctx, {
2433
+ id: `${reversalId}:reconcile:${String(line.id)}`,
2434
+ debitMoveId: debitFirst ? fresh.id : mirror.id,
2435
+ creditMoveId: debitFirst ? mirror.id : fresh.id,
2436
+ amount: minorText(amount, scale),
2437
+ date,
2438
+ });
2439
+ if (result.ok !== true)
2440
+ return result;
2441
+ }
2442
+ try {
2443
+ await ctx.tx(async (tx) => {
2444
+ const source = (await tx.db.select('account.Move', { id: args.id }))[0];
2445
+ const reversal = (await tx.db.select('account.Move', { id: reversalId }))[0];
2446
+ if (!source || String(source.reversedById ?? '') !== reversalId)
2447
+ throw new Refusal('moveAlreadyReversed');
2448
+ if (!reversal || String(reversal.reversalOfId ?? '') !== String(source.id))
2449
+ throw new Refusal('reversalIdReused');
2450
+ if (source.moveType !== 'entry')
2451
+ await tx.db.update('account.Move', { id: args.id }, { paymentState: 'reversed' });
2452
+ // A payment's own move is an `entry`, so the line above never reaches it
2453
+ // and the payment kept reading `paid` after the money had been reversed
2454
+ // out of the books — the ledger and the payments list disagreeing about
2455
+ // whether a customer had paid.
2456
+ for (const payment of await tx.db.select('account.Payment', { moveId: args.id }))
2457
+ await tx.db.update('account.Payment', { id: payment.id }, { state: 'reversed' });
2458
+ await tx.db.update('account.Move', { id: reversalId }, { reversalStatus: 'completed' });
2459
+ await tx.db.insertIfAbsent('account.AuditEvent', {
2460
+ id: `move:${String(args.id)}:reversed:${reversalId}`,
2461
+ subjectType: 'move',
2462
+ subjectId: String(args.id),
2463
+ action: 'reversed',
2464
+ actorId: tx.actor ?? null,
2465
+ accountingDate: reversal.accountingDate,
2466
+ reason: args.reason ?? args.ref ?? source.name,
2467
+ relatedId: reversalId,
2468
+ details: { originalId: source.id, reversalId, replacementId: null },
2469
+ createdAt: today(),
2470
+ });
2471
+ });
2472
+ }
2473
+ catch (error) {
2474
+ return refused('reversalId', error);
2475
+ }
2476
+ return { ok: true, id: args.id, reversalId, name: posted.name };
731
2477
  },
732
2478
  }),
733
2479
  listPayments: defineFn({
734
- input: {},
2480
+ input: { partnerId: 'id?', state: 'text?', limit: 'int?', offset: 'int?' },
735
2481
  effects: ['read:account.Payment'],
736
2482
  agent: true,
737
- handler: (ctx) => ctx.db.select('account.Payment'),
2483
+ handler: (ctx, args) => {
2484
+ const P = ctx.table('account.Payment');
2485
+ const where = [
2486
+ ...(args.partnerId ? [eq(P.partnerId, args.partnerId)] : []),
2487
+ ...(args.state ? [eq(P.state, args.state)] : []),
2488
+ ];
2489
+ const q = (where.length ? from(P).where(and(...where)) : from(P)).orderBy(asc(P.accountingDate), asc(P.date), asc(P.id));
2490
+ return ctx.db.all(paginate(q, args.limit, args.offset));
2491
+ },
2492
+ }),
2493
+ /**
2494
+ * Post the two ledger events that change stored-value liability without a sale.
2495
+ *
2496
+ * Issuing value increases the liability against an asset/clearing account;
2497
+ * expiry releases it to income. Redemption and customer refund are settlements
2498
+ * of a receivable and therefore use `registerPayment` with `stored_value`.
2499
+ */
2500
+ postStoredValueBalance: defineFn({
2501
+ input: {
2502
+ id: 'id',
2503
+ operation: 'text',
2504
+ journalId: 'id',
2505
+ liabilityAccountId: 'id',
2506
+ counterpartAccountId: 'id',
2507
+ amount: 'decimal',
2508
+ partnerId: 'id?',
2509
+ date: 'datetime?',
2510
+ accountingDate: 'date?',
2511
+ documentDate: 'date?',
2512
+ reference: 'text?',
2513
+ },
2514
+ output: { ok: 'bool', id: 'id?', moveId: 'id?', operation: 'text?', amount: 'decimal?', errors: 'json?' },
2515
+ effects: [
2516
+ 'read:account.Journal',
2517
+ 'read:account.Account',
2518
+ 'read:account.Move',
2519
+ 'read:account.MoveLine',
2520
+ 'read:account.PeriodPolicy',
2521
+ 'read:company.Company',
2522
+ 'read:partner.Partner',
2523
+ 'write:account.Journal',
2524
+ 'write:account.Move',
2525
+ 'write:account.MoveLine',
2526
+ 'write:account.PeriodPolicy',
2527
+ 'write:account.AuditEvent',
2528
+ ],
2529
+ idempotent: true,
2530
+ agent: true,
2531
+ handler: async (ctx, args) => {
2532
+ const operation = String(args.operation);
2533
+ if (!['issue', 'expire'].includes(operation))
2534
+ return invalid('operation', 'storedValueOperationUnsupported');
2535
+ const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
2536
+ if (!journal || String(journal.type) !== 'general')
2537
+ return invalid('journalId', 'journalNotStoredValue');
2538
+ const [liability, counterpart] = await Promise.all([
2539
+ accountOf(ctx, args.liabilityAccountId),
2540
+ accountOf(ctx, args.counterpartAccountId),
2541
+ ]);
2542
+ if (!liability || !String(liability.accountType).startsWith('liability'))
2543
+ return invalid('liabilityAccountId', 'journalStoredValueAccount');
2544
+ const counterpartType = String(counterpart?.accountType ?? '');
2545
+ if (!counterpart ||
2546
+ (operation === 'issue' && !counterpartType.startsWith('asset')) ||
2547
+ (operation === 'expire' && !counterpartType.startsWith('income')))
2548
+ return invalid('counterpartAccountId', 'storedValueCounterpart');
2549
+ if (args.partnerId && !(await ctx.db.select('partner.Partner', { id: args.partnerId }))[0])
2550
+ return invalid('partnerId', 'partnerMissing');
2551
+ const existing = (await ctx.db.select('account.Move', { id: args.id }))[0];
2552
+ const { currency, scale, timezone } = await ledgerOf(ctx);
2553
+ let amount;
2554
+ try {
2555
+ amount = moneyMinor(args.amount, scale);
2556
+ }
2557
+ catch {
2558
+ return invalid('amount', 'moneyExactString');
2559
+ }
2560
+ if (amount <= 0n)
2561
+ return invalid('amount', 'amountPositive');
2562
+ const amountText = minorText(amount, scale);
2563
+ const zero = minorText(0n, scale);
2564
+ const date = instantText(args.date ?? existing?.date ?? today());
2565
+ let accountingDate;
2566
+ let documentDate;
2567
+ try {
2568
+ accountingDate = accountingDateText(args.accountingDate ?? existing?.accountingDate ?? date, timezone);
2569
+ documentDate = accountingDateText(args.documentDate ?? existing?.documentDate ?? accountingDate, timezone);
2570
+ }
2571
+ catch {
2572
+ return invalid('accountingDate', 'accountingDateInvalid');
2573
+ }
2574
+ const increasing = operation === 'issue';
2575
+ const line = (id, account, debitSide, sequence) => ({
2576
+ id,
2577
+ moveId: args.id,
2578
+ name: `account.stored_value.${operation}`,
2579
+ accountId: account.id,
2580
+ partnerId: args.partnerId ?? null,
2581
+ productId: null,
2582
+ productUomId: null,
2583
+ quantity: '1',
2584
+ priceUnit: amountText,
2585
+ discount: '0',
2586
+ taxId: null,
2587
+ debit: debitSide ? amountText : zero,
2588
+ credit: debitSide ? zero : amountText,
2589
+ balance: debitSide ? amountText : minorText(-amount, scale),
2590
+ dateMaturity: null,
2591
+ displayType: null,
2592
+ reconciled: false,
2593
+ amountResidual: account.reconcile === true ? amountText : zero,
2594
+ sequence,
2595
+ });
2596
+ try {
2597
+ await ctx.tx(async (tx) => {
2598
+ await insertDraftMove(tx, {
2599
+ move: {
2600
+ id: args.id,
2601
+ name: String(args.id),
2602
+ ref: args.reference ?? null,
2603
+ date,
2604
+ accountingDate,
2605
+ documentDate,
2606
+ moveType: 'entry',
2607
+ state: 'draft',
2608
+ journalId: args.journalId,
2609
+ partnerId: args.partnerId ?? null,
2610
+ invoiceDate: null,
2611
+ invoiceDateDue: null,
2612
+ paymentTermId: null,
2613
+ paymentState: 'paid',
2614
+ currency,
2615
+ amountUntaxed: amountText,
2616
+ amountTax: zero,
2617
+ amountTotal: amountText,
2618
+ postedAt: null,
2619
+ revision: 0,
2620
+ },
2621
+ lines: [
2622
+ line(`${String(args.id)}:counterpart`, counterpart, increasing, 10),
2623
+ line(`${String(args.id)}:liability`, liability, !increasing, 20),
2624
+ ],
2625
+ });
2626
+ });
2627
+ }
2628
+ catch (error) {
2629
+ return refused('id', error);
2630
+ }
2631
+ const posted = await postMoveById(ctx, args.id);
2632
+ if (posted.ok !== true)
2633
+ return posted;
2634
+ return { ok: true, id: args.id, moveId: args.id, operation, amount: amountText };
2635
+ },
738
2636
  }),
739
2637
  registerPayment: defineFn({
740
2638
  input: {
@@ -747,9 +2645,14 @@ export const functions = {
747
2645
  destinationAccountId: 'id',
748
2646
  amount: 'decimal',
749
2647
  date: 'datetime?',
2648
+ accountingDate: 'date?',
2649
+ documentDate: 'date?',
750
2650
  memo: 'text?',
751
2651
  paymentReference: 'text?',
2652
+ settlementKind: 'text?',
752
2653
  reconcileLineId: 'id?',
2654
+ invoiceId: 'id?',
2655
+ expectedRevision: 'int?',
753
2656
  },
754
2657
  output: { ok: 'bool', id: 'id?', moveId: 'id?', errors: 'json?' },
755
2658
  effects: [
@@ -759,53 +2662,112 @@ export const functions = {
759
2662
  'read:account.Move',
760
2663
  'read:account.MoveLine',
761
2664
  'read:account.PartialReconcile',
2665
+ 'read:account.PeriodPolicy',
762
2666
  'read:company.Company',
763
2667
  'write:account.Payment',
764
2668
  'write:account.Journal',
765
2669
  'write:account.Move',
766
2670
  'write:account.MoveLine',
767
2671
  'write:account.PartialReconcile',
2672
+ 'write:account.PeriodPolicy',
2673
+ 'write:account.AuditEvent',
768
2674
  ],
769
2675
  idempotent: true,
770
2676
  agent: true,
771
2677
  handler: async (ctx, args) => {
772
2678
  if (!PAYMENT_TYPES.includes(args.paymentType))
773
- return invalid('paymentType', 'payment type must be inbound or outbound');
2679
+ return invalid('paymentType', 'paymentTypeUnsupported');
774
2680
  if (!PARTNER_TYPES.includes(args.partnerType))
775
- return invalid('partnerType', 'partner type must be customer or supplier');
776
- if (!(n(args.amount) > 0))
777
- return invalid('amount', 'payment amount must be positive');
2681
+ return invalid('partnerType', 'partnerTypeUnsupported');
2682
+ const settlementKind = String(args.settlementKind ?? 'liquidity');
2683
+ if (!PAYMENT_SETTLEMENT_KINDS.includes(settlementKind))
2684
+ return invalid('settlementKind', 'paymentSettlementKindUnsupported');
2685
+ const { currency, scale, timezone } = await ledgerOf(ctx);
2686
+ let amount;
2687
+ try {
2688
+ amount = moneyMinor(args.amount, scale);
2689
+ }
2690
+ catch {
2691
+ return invalid('amount', 'moneyExactString');
2692
+ }
2693
+ if (amount <= 0n)
2694
+ return invalid('amount', 'amountPositive');
778
2695
  const journal = (await ctx.db.select('account.Journal', { id: args.journalId }))[0];
779
2696
  if (!journal?.defaultAccountId)
780
- return invalid('journalId', 'payment journal needs a default liquidity account');
781
- if (!['bank', 'cash'].includes(String(journal.type)))
782
- return invalid('journalId', 'payments require a bank or cash journal');
2697
+ return invalid('journalId', 'journalLiquidityMissing');
2698
+ const settlementAccount = await accountOf(ctx, journal.defaultAccountId);
2699
+ if (settlementKind === 'liquidity') {
2700
+ if (!['bank', 'cash'].includes(String(journal.type)))
2701
+ return invalid('journalId', 'journalNotLiquidity');
2702
+ }
2703
+ else {
2704
+ if (String(journal.type) !== 'general')
2705
+ return invalid('journalId', 'journalNotStoredValue');
2706
+ if (!String(settlementAccount?.accountType ?? '').startsWith('liability'))
2707
+ return invalid('journalId', 'journalStoredValueAccount');
2708
+ }
783
2709
  const destination = await accountOf(ctx, args.destinationAccountId);
784
2710
  if (!destination)
785
- return invalid('destinationAccountId', 'destination account does not exist');
786
- const expectedDestination = args.partnerType === 'customer' ? 'asset_receivable' : 'liability_payable';
787
- if (destination.accountType !== expectedDestination)
788
- return invalid('destinationAccountId', `destination account must be ${expectedDestination}`);
2711
+ return invalid('destinationAccountId', 'destinationMissing');
2712
+ const forCustomer = args.partnerType === 'customer';
2713
+ if (destination.accountType !== (forCustomer ? 'asset_receivable' : 'liability_payable'))
2714
+ return invalid('destinationAccountId', forCustomer ? 'destinationMustBeReceivable' : 'destinationMustBePayable');
789
2715
  const existing = (await ctx.db.select('account.Payment', { id: args.id }))[0];
2716
+ const date = instantText(args.date ?? existing?.date ?? today());
2717
+ let accountingDate;
2718
+ let documentDate;
2719
+ try {
2720
+ accountingDate = accountingDateText(args.accountingDate ?? existing?.accountingDate ?? date, timezone);
2721
+ documentDate = accountingDateText(args.documentDate ?? existing?.documentDate ?? accountingDate, timezone);
2722
+ }
2723
+ catch {
2724
+ return invalid('accountingDate', 'accountingDateInvalid');
2725
+ }
2726
+ if (existing &&
2727
+ (moneyMinor(existing.amount, scale) !== amount ||
2728
+ String(existing.name) !== String(args.name) ||
2729
+ String(existing.paymentType) !== String(args.paymentType) ||
2730
+ String(existing.partnerType) !== String(args.partnerType) ||
2731
+ String(existing.partnerId ?? '') !== String(args.partnerId ?? '') ||
2732
+ String(existing.journalId) !== String(args.journalId) ||
2733
+ String(existing.destinationAccountId) !== String(args.destinationAccountId) ||
2734
+ String(existing.reconcileLineId ?? '') !== String(args.reconcileLineId ?? '') ||
2735
+ String(existing.invoiceId ?? '') !== String(args.invoiceId ?? '') ||
2736
+ instantText(existing.date) !== date ||
2737
+ moveAccountingDate(existing, timezone) !== accountingDate ||
2738
+ String(existing.documentDate ?? accountingDate) !== documentDate ||
2739
+ String(existing.memo ?? '') !== String(args.memo ?? '') ||
2740
+ String(existing.paymentReference ?? '') !== String(args.paymentReference ?? '') ||
2741
+ String(existing.settlementKind ?? 'liquidity') !== settlementKind ||
2742
+ String(existing.currency) !== currency))
2743
+ return invalid('id', 'paymentIdReused');
2744
+ if (existing?.state === 'reversed')
2745
+ return { ok: true, id: args.id, moveId: existing.moveId };
790
2746
  if (existing &&
791
2747
  args.reconcileLineId &&
792
2748
  (await ctx.db.select('account.PartialReconcile', {
793
2749
  id: `${String(args.id)}:reconcile:${String(args.reconcileLineId)}`,
794
- }))[0])
2750
+ }))[0]) {
2751
+ const posted = await postMoveById(ctx, existing.moveId);
2752
+ if (posted.ok !== true)
2753
+ return posted;
2754
+ if (existing.state !== 'paid')
2755
+ await ctx.db.update('account.Payment', { id: args.id }, { state: 'paid' });
795
2756
  return { ok: true, id: args.id, moveId: existing.moveId };
2757
+ }
796
2758
  let reconcileTarget = null;
797
2759
  if (args.reconcileLineId) {
798
2760
  reconcileTarget = (await ctx.db.select('account.MoveLine', { id: args.reconcileLineId }))[0] ?? null;
799
2761
  if (!reconcileTarget)
800
- return invalid('reconcileLineId', 'open item does not exist');
2762
+ return invalid('reconcileLineId', 'openItemMissing');
801
2763
  if (reconcileTarget.accountId !== args.destinationAccountId)
802
- return invalid('reconcileLineId', 'open item uses another destination account');
2764
+ return invalid('reconcileLineId', 'openItemAccountMismatch');
803
2765
  const expectedDebit = args.paymentType === 'inbound';
804
- if ((expectedDebit && n(reconcileTarget.balance) <= 0) ||
805
- (!expectedDebit && n(reconcileTarget.balance) >= 0))
806
- return invalid('reconcileLineId', 'open item has the wrong debit or credit direction');
807
- if (n(args.amount) - n(reconcileTarget.amountResidual) > 0.000001)
808
- return invalid('amount', 'payment amount exceeds the selected open item');
2766
+ const targetBalance = moneyMinor(reconcileTarget.balance, scale);
2767
+ if ((expectedDebit && targetBalance <= 0n) || (!expectedDebit && targetBalance >= 0n))
2768
+ return invalid('reconcileLineId', 'openItemDirection');
2769
+ if (amount > moneyMinor(reconcileTarget.amountResidual, scale))
2770
+ return invalid('amount', 'amountExceedsOpenItem');
809
2771
  }
810
2772
  const reconcilePayment = async (paymentMoveId) => {
811
2773
  if (!reconcileTarget)
@@ -815,77 +2777,144 @@ export const functions = {
815
2777
  id: `${String(args.id)}:reconcile:${String(reconcileTarget.id)}`,
816
2778
  debitMoveId: args.paymentType === 'inbound' ? reconcileTarget.id : counterpartId,
817
2779
  creditMoveId: args.paymentType === 'inbound' ? counterpartId : reconcileTarget.id,
818
- amount: args.amount,
819
- date: args.date ?? today(),
2780
+ amount: minorText(amount, scale),
2781
+ date,
820
2782
  });
821
2783
  return result.ok === true ? null : result;
822
2784
  };
823
2785
  if (existing) {
2786
+ // A retry of the same call is a success. A different payment under an id
2787
+ // that is already taken is not: the stored move is left as it was, and
2788
+ // reconciling it for a newly supplied amount would settle an open item
2789
+ // against money the ledger never recorded.
2790
+ const posted = await postMoveById(ctx, existing.moveId);
2791
+ if (posted.ok !== true)
2792
+ return posted;
2793
+ if (existing.state !== 'paid')
2794
+ await ctx.db.update('account.Payment', { id: args.id }, { state: 'paid' });
824
2795
  const failed = await reconcilePayment(String(existing.moveId));
825
2796
  return failed ?? { ok: true, id: args.id, moveId: existing.moveId };
826
2797
  }
827
- const moveId = `${String(args.id)}:move`, date = String(args.date ?? today()), currency = await companyCurrency(ctx), inbound = args.paymentType === 'inbound';
828
- await ctx.tx(async (tx) => {
829
- await tx.db.insert('account.Move', {
830
- id: moveId,
831
- name: moveId,
832
- ref: args.paymentReference ?? args.memo ?? null,
833
- date,
834
- moveType: 'entry',
835
- state: 'draft',
836
- journalId: args.journalId,
837
- partnerId: args.partnerId ?? null,
838
- invoiceDate: null,
839
- invoiceDateDue: null,
840
- paymentTermId: null,
841
- paymentState: 'paid',
842
- currency,
843
- amountUntaxed: '0',
844
- amountTax: '0',
845
- amountTotal: String(args.amount),
846
- postedAt: null,
847
- });
848
- const add = (id, accountId, debitSide, reconcilable) => tx.db.insert('account.MoveLine', {
849
- id,
850
- moveId,
851
- name: args.memo ?? args.name,
852
- accountId,
853
- partnerId: args.partnerId ?? null,
854
- productId: null,
855
- productUomId: null,
856
- quantity: '1',
857
- priceUnit: String(args.amount),
858
- discount: '0',
859
- taxId: null,
860
- debit: debitSide ? String(args.amount) : '0',
861
- credit: debitSide ? '0' : String(args.amount),
862
- balance: decimal(debitSide ? n(args.amount) : -n(args.amount)),
863
- dateMaturity: null,
864
- displayType: null,
865
- reconciled: false,
866
- amountResidual: reconcilable ? String(args.amount) : '0',
867
- sequence: debitSide ? 10 : 20,
868
- });
869
- await add(`${moveId}:liquidity`, journal.defaultAccountId, inbound, false);
870
- await add(`${moveId}:counterpart`, args.destinationAccountId, !inbound, true);
871
- await tx.db.insert('account.Payment', {
872
- id: args.id,
873
- name: args.name,
874
- paymentType: args.paymentType,
875
- partnerType: args.partnerType,
876
- partnerId: args.partnerId ?? null,
877
- journalId: args.journalId,
878
- destinationAccountId: args.destinationAccountId,
879
- amount: args.amount,
880
- date,
881
- memo: args.memo ?? null,
882
- paymentReference: args.paymentReference ?? null,
883
- state: 'in_process',
884
- currency,
885
- moveId,
2798
+ const moveId = `${String(args.id)}:move`, inbound = args.paymentType === 'inbound';
2799
+ try {
2800
+ await ctx.tx(async (tx) => {
2801
+ if (args.invoiceId) {
2802
+ const invoice = (await tx.db.select('account.Move', { id: args.invoiceId }))[0];
2803
+ if (!invoice)
2804
+ throw new Refusal('moveMissing');
2805
+ if (!(await claimMoveRevision(tx, invoice, args.expectedRevision)))
2806
+ throw new Refusal('moveConcurrent');
2807
+ }
2808
+ const paymentMove = {
2809
+ id: moveId,
2810
+ name: moveId,
2811
+ ref: args.paymentReference ?? args.memo ?? null,
2812
+ date,
2813
+ accountingDate,
2814
+ documentDate,
2815
+ moveType: 'entry',
2816
+ state: 'draft',
2817
+ journalId: args.journalId,
2818
+ partnerId: args.partnerId ?? null,
2819
+ invoiceDate: null,
2820
+ invoiceDateDue: null,
2821
+ paymentTermId: null,
2822
+ paymentState: 'paid',
2823
+ currency,
2824
+ amountUntaxed: minorText(amount, scale),
2825
+ amountTax: minorText(0n, scale),
2826
+ amountTotal: minorText(amount, scale),
2827
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
2828
+ postedAt: null,
2829
+ revision: 0,
2830
+ };
2831
+ const line = (id, accountId, debitSide, reconcilable) => ({
2832
+ id,
2833
+ moveId,
2834
+ name: args.memo ?? args.name,
2835
+ accountId,
2836
+ partnerId: args.partnerId ?? null,
2837
+ productId: null,
2838
+ productUomId: null,
2839
+ quantity: '1',
2840
+ priceUnit: minorText(amount, scale),
2841
+ discount: '0',
2842
+ taxId: null,
2843
+ debit: minorText(debitSide ? amount : 0n, scale),
2844
+ credit: minorText(debitSide ? 0n : amount, scale),
2845
+ balance: minorText(debitSide ? amount : -amount, scale),
2846
+ dateMaturity: null,
2847
+ displayType: null,
2848
+ reconciled: false,
2849
+ amountResidual: minorText(reconcilable ? amount : 0n, scale),
2850
+ sequence: debitSide ? 10 : 20,
2851
+ });
2852
+ await insertDraftMove(tx, {
2853
+ move: paymentMove,
2854
+ lines: [
2855
+ line(`${moveId}:liquidity`, journal.defaultAccountId, inbound, false),
2856
+ line(`${moveId}:counterpart`, args.destinationAccountId, !inbound, true),
2857
+ ],
2858
+ });
2859
+ const paymentRow = {
2860
+ id: args.id,
2861
+ name: args.name,
2862
+ paymentType: args.paymentType,
2863
+ partnerType: args.partnerType,
2864
+ partnerId: args.partnerId ?? null,
2865
+ journalId: args.journalId,
2866
+ destinationAccountId: args.destinationAccountId,
2867
+ amount: minorText(amount, scale),
2868
+ date,
2869
+ accountingDate,
2870
+ documentDate,
2871
+ memo: args.memo ?? null,
2872
+ paymentReference: args.paymentReference ?? null,
2873
+ settlementKind,
2874
+ state: 'in_process',
2875
+ currency,
2876
+ moneyPolicyVersion: MONEY_POLICY_VERSION,
2877
+ moveId,
2878
+ reconcileLineId: args.reconcileLineId ?? null,
2879
+ invoiceId: args.invoiceId ?? null,
2880
+ };
2881
+ const inserted = await tx.db.insertIfAbsent('account.Payment', paymentRow);
2882
+ if (!('dryRun' in inserted) && !inserted.inserted) {
2883
+ const held = (await tx.db.select('account.Payment', { id: args.id }))[0];
2884
+ if (!held ||
2885
+ !rowMatches(held, paymentRow, [
2886
+ 'name',
2887
+ 'paymentType',
2888
+ 'partnerType',
2889
+ 'partnerId',
2890
+ 'journalId',
2891
+ 'destinationAccountId',
2892
+ 'amount',
2893
+ 'date',
2894
+ 'accountingDate',
2895
+ 'documentDate',
2896
+ 'memo',
2897
+ 'paymentReference',
2898
+ 'settlementKind',
2899
+ 'currency',
2900
+ 'moneyPolicyVersion',
2901
+ 'moveId',
2902
+ 'reconcileLineId',
2903
+ 'invoiceId',
2904
+ ]))
2905
+ throw new Refusal('paymentIdReused');
2906
+ }
886
2907
  });
887
- });
888
- const posted = await post(ctx, moveId);
2908
+ }
2909
+ catch (error) {
2910
+ if (error instanceof Refusal && error.code === 'moveConcurrent') {
2911
+ const settled = (await ctx.db.select('account.Payment', { id: args.id }))[0];
2912
+ if (settled)
2913
+ return (await functions.registerPayment.handler(ctx, args));
2914
+ }
2915
+ return refused('expectedRevision', error);
2916
+ }
2917
+ const posted = await postMoveById(ctx, moveId);
889
2918
  if (posted.ok !== true)
890
2919
  return posted;
891
2920
  await ctx.db.update('account.Payment', { id: args.id }, { state: 'paid' });
@@ -895,14 +2924,135 @@ export const functions = {
895
2924
  return { ok: true, id: args.id, moveId };
896
2925
  },
897
2926
  }),
2927
+ /**
2928
+ * Collect the complete residual of one posted customer invoice.
2929
+ *
2930
+ * A payment can settle several due-date lines. The lower-level payment
2931
+ * primitive intentionally accepts one open item, so this aggregate creates a
2932
+ * single deterministic payment and reconciles its counterpart across every
2933
+ * receivable line. Retries resume unfinished reconciliations from the same
2934
+ * payment id; the invoice revision is claimed in the transaction that first
2935
+ * creates that payment, preventing two collectors from recording the same
2936
+ * money concurrently.
2937
+ */
2938
+ registerInvoicePayment: defineFn({
2939
+ input: {
2940
+ id: 'id',
2941
+ invoiceId: 'id',
2942
+ journalId: 'id',
2943
+ expectedRevision: 'int?',
2944
+ date: 'datetime?',
2945
+ accountingDate: 'date?',
2946
+ documentDate: 'date?',
2947
+ },
2948
+ output: { ok: 'bool', id: 'id?', moveId: 'id?', amount: 'decimal?', errors: 'json?' },
2949
+ effects: [
2950
+ 'read:account.Payment',
2951
+ 'read:account.Journal',
2952
+ 'read:account.Account',
2953
+ 'read:account.Move',
2954
+ 'read:account.MoveLine',
2955
+ 'read:account.PartialReconcile',
2956
+ 'read:account.PeriodPolicy',
2957
+ 'read:company.Company',
2958
+ 'write:account.Payment',
2959
+ 'write:account.Journal',
2960
+ 'write:account.Move',
2961
+ 'write:account.MoveLine',
2962
+ 'write:account.PartialReconcile',
2963
+ 'write:account.PeriodPolicy',
2964
+ 'write:account.AuditEvent',
2965
+ ],
2966
+ idempotent: true,
2967
+ agent: true,
2968
+ handler: async (ctx, args) => {
2969
+ const invoice = (await ctx.db.select('account.Move', { id: args.invoiceId }))[0];
2970
+ if (!invoice)
2971
+ return invalid('invoiceId', 'moveMissing');
2972
+ if (invoice.moveType !== 'out_invoice')
2973
+ return invalid('invoiceId', 'invoicePaymentType');
2974
+ if (invoice.state !== 'posted')
2975
+ return invalid('state', 'invoicePaymentState');
2976
+ const existing = (await ctx.db.select('account.Payment', { id: args.id }))[0];
2977
+ if (existing && String(existing.invoiceId ?? '') !== String(args.invoiceId))
2978
+ return invalid('id', 'paymentIdReused');
2979
+ const { scale } = await ledgerOf(ctx);
2980
+ const accounts = await accountsById(ctx);
2981
+ const receivables = (await ctx.db.select('account.MoveLine', { moveId: args.invoiceId }))
2982
+ .filter((line) => accounts.get(String(line.accountId))?.accountType === 'asset_receivable' &&
2983
+ moneyMinor(line.amountResidual, scale) > 0n)
2984
+ .sort((left, right) => String(left.id).localeCompare(String(right.id)));
2985
+ if (!receivables.length) {
2986
+ if (existing)
2987
+ return { ok: true, id: args.id, moveId: existing.moveId, amount: String(existing.amount) };
2988
+ return invalid('invoiceId', 'invoicePaymentResidual');
2989
+ }
2990
+ const destinationIds = [...new Set(receivables.map((line) => String(line.accountId)))];
2991
+ if (destinationIds.length !== 1)
2992
+ return invalid('invoiceId', 'invoicePaymentAccounts');
2993
+ const amount = existing
2994
+ ? moneyMinor(existing.amount, scale)
2995
+ : sumMoneyMinor(receivables.map((line) => line.amountResidual), scale);
2996
+ const registered = (await functions.registerPayment.handler(ctx, {
2997
+ id: args.id,
2998
+ name: `Payment ${String(invoice.name)}`,
2999
+ paymentType: 'inbound',
3000
+ partnerType: 'customer',
3001
+ partnerId: invoice.partnerId,
3002
+ journalId: args.journalId,
3003
+ destinationAccountId: destinationIds[0],
3004
+ amount: minorText(amount, scale),
3005
+ date: args.date ?? today(),
3006
+ ...(args.accountingDate ? { accountingDate: args.accountingDate } : {}),
3007
+ ...(args.documentDate ? { documentDate: args.documentDate } : {}),
3008
+ memo: String(invoice.name),
3009
+ paymentReference: String(invoice.name),
3010
+ invoiceId: args.invoiceId,
3011
+ expectedRevision: args.expectedRevision,
3012
+ }));
3013
+ if (registered.ok !== true)
3014
+ return registered;
3015
+ const counterpartId = `${String(registered.moveId)}:counterpart`;
3016
+ for (const line of receivables) {
3017
+ const current = (await ctx.db.select('account.MoveLine', { id: line.id }))[0];
3018
+ const residual = moneyMinor(current?.amountResidual ?? '0', scale);
3019
+ if (residual <= 0n)
3020
+ continue;
3021
+ const reconciled = (await functions.reconcile.handler(ctx, {
3022
+ id: `${String(args.id)}:invoice:${String(line.id)}`,
3023
+ debitMoveId: line.id,
3024
+ creditMoveId: counterpartId,
3025
+ amount: minorText(residual, scale),
3026
+ date: args.date ?? today(),
3027
+ }));
3028
+ if (reconciled.ok !== true)
3029
+ return reconciled;
3030
+ }
3031
+ return {
3032
+ ok: true,
3033
+ id: args.id,
3034
+ moveId: registered.moveId,
3035
+ amount: minorText(amount, scale),
3036
+ };
3037
+ },
3038
+ }),
898
3039
  reconcile: defineFn({
899
- input: { id: 'id', debitMoveId: 'id', creditMoveId: 'id', amount: 'decimal', date: 'datetime?' },
3040
+ input: {
3041
+ id: 'id',
3042
+ debitMoveId: 'id',
3043
+ creditMoveId: 'id',
3044
+ amount: 'decimal',
3045
+ date: 'datetime?',
3046
+ actorId: 'text?',
3047
+ reason: 'text?',
3048
+ },
900
3049
  output: { ok: 'bool', id: 'id?', errors: 'json?' },
901
3050
  effects: [
902
3051
  'read:account.Move',
903
3052
  'read:account.MoveLine',
904
3053
  'read:account.Account',
905
3054
  'read:account.PartialReconcile',
3055
+ 'read:company.Company',
906
3056
  'write:account.Move',
907
3057
  'write:account.MoveLine',
908
3058
  'write:account.PartialReconcile',
@@ -910,9 +3060,16 @@ export const functions = {
910
3060
  idempotent: true,
911
3061
  agent: true,
912
3062
  handler: async (ctx, args) => {
913
- const amount = money(n(args.amount));
914
- if (!(amount > 0))
915
- return invalid('amount', 'reconciliation amount must be positive');
3063
+ const { scale } = await ledgerOf(ctx);
3064
+ let amount;
3065
+ try {
3066
+ amount = moneyMinor(args.amount, scale);
3067
+ }
3068
+ catch {
3069
+ return invalid('amount', 'moneyExactString');
3070
+ }
3071
+ if (amount <= 0n)
3072
+ return invalid('amount', 'reconcileAmountPositive');
916
3073
  if ((await ctx.db.select('account.PartialReconcile', { id: args.id }))[0])
917
3074
  return { ok: true, id: args.id };
918
3075
  let moveIds = null;
@@ -920,118 +3077,142 @@ export const functions = {
920
3077
  moveIds = await ctx.tx(async (tx) => {
921
3078
  const debit = (await tx.db.select('account.MoveLine', { id: args.debitMoveId }))[0];
922
3079
  const credit = (await tx.db.select('account.MoveLine', { id: args.creditMoveId }))[0];
923
- if (!debit || !credit || n(debit.balance) <= 0 || n(credit.balance) >= 0)
924
- throw new Error('reconciliation needs one debit and one credit line');
3080
+ if (!debit ||
3081
+ !credit ||
3082
+ moneyMinor(debit.balance, scale) <= 0n ||
3083
+ moneyMinor(credit.balance, scale) >= 0n)
3084
+ throw new Refusal('reconcileSides');
925
3085
  if (debit.accountId !== credit.accountId)
926
- throw new Error('reconciled lines must use the same account');
3086
+ throw new Refusal('reconcileAccountMismatch');
927
3087
  const [debitMove, creditMove] = await Promise.all([
928
3088
  tx.db.select('account.Move', { id: debit.moveId }),
929
3089
  tx.db.select('account.Move', { id: credit.moveId }),
930
3090
  ]);
931
3091
  if (debitMove[0]?.state !== 'posted' || creditMove[0]?.state !== 'posted')
932
- throw new Error('only posted journal items can be reconciled');
3092
+ throw new Refusal('reconcilePostedOnly');
933
3093
  const account = await accountOf(tx, debit.accountId);
934
3094
  if (!account?.reconcile)
935
- throw new Error('account does not allow reconciliation');
936
- if (amount - n(debit.amountResidual) > 0.000001 || amount - n(credit.amountResidual) > 0.000001)
937
- throw new Error('amount exceeds a residual balance');
3095
+ throw new Refusal('reconcileNotAllowed');
3096
+ const debitHeld = moneyMinor(debit.amountResidual, scale);
3097
+ const creditHeld = moneyMinor(credit.amountResidual, scale);
3098
+ if (amount > debitHeld || amount > creditHeld)
3099
+ throw new Refusal('reconcileAmountExceeds');
938
3100
  const held = await tx.db.insertIfAbsent('account.PartialReconcile', {
939
3101
  id: args.id,
940
3102
  debitMoveId: args.debitMoveId,
941
3103
  creditMoveId: args.creditMoveId,
942
- amount: decimal(amount),
3104
+ amount: minorText(amount, scale),
943
3105
  date: args.date ?? today(),
3106
+ state: 'active',
3107
+ actorId: args.actorId ?? null,
3108
+ reason: args.reason ?? null,
3109
+ reversedAt: null,
3110
+ reversedBy: null,
3111
+ reversalReason: null,
944
3112
  });
945
3113
  if (!('dryRun' in held) && !held.inserted)
946
3114
  return [debit.moveId, credit.moveId];
947
- const debitResidual = money(n(debit.amountResidual) - amount);
948
- const creditResidual = money(n(credit.amountResidual) - amount);
949
- const debitWrite = await tx.db.compareAndSet('account.MoveLine', { id: debit.id }, { amountResidual: debit.amountResidual }, { amountResidual: decimal(debitResidual), reconciled: debitResidual === 0 });
950
- const creditWrite = await tx.db.compareAndSet('account.MoveLine', { id: credit.id }, { amountResidual: credit.amountResidual }, { amountResidual: decimal(creditResidual), reconciled: creditResidual === 0 });
3115
+ const debitResidual = debitHeld - amount;
3116
+ const creditResidual = creditHeld - amount;
3117
+ const debitWrite = await tx.db.compareAndSet('account.MoveLine', { id: debit.id }, { amountResidual: debit.amountResidual }, { amountResidual: minorText(debitResidual, scale), reconciled: debitResidual === 0n });
3118
+ const creditWrite = await tx.db.compareAndSet('account.MoveLine', { id: credit.id }, { amountResidual: credit.amountResidual }, { amountResidual: minorText(creditResidual, scale), reconciled: creditResidual === 0n });
951
3119
  if ((!('dryRun' in debitWrite) && !debitWrite.matched) ||
952
3120
  (!('dryRun' in creditWrite) && !creditWrite.matched))
953
- throw new Error('residual balance changed concurrently; retry reconciliation');
3121
+ throw new Refusal('reconcileConcurrent');
954
3122
  return [debit.moveId, credit.moveId];
955
3123
  });
956
3124
  }
957
3125
  catch (error) {
958
- return invalid('lines', error.message);
3126
+ return refused('lines', error);
959
3127
  }
960
3128
  if (moveIds) {
961
- await updatePaymentState(ctx, moveIds[0]);
962
- await updatePaymentState(ctx, moveIds[1]);
3129
+ const accounts = await accountsById(ctx);
3130
+ await updatePaymentState(ctx, moveIds[0], accounts);
3131
+ await updatePaymentState(ctx, moveIds[1], accounts);
963
3132
  }
964
3133
  return { ok: true, id: args.id };
965
3134
  },
966
3135
  }),
967
3136
  trialBalance: defineFn({
968
- input: { dateFrom: 'datetime?', dateTo: 'datetime?' },
969
- effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine'],
3137
+ input: { dateFrom: 'date?', dateTo: 'date?' },
3138
+ effects: ['read:account.Account', 'read:account.Move', 'read:account.MoveLine', 'read:company.Company'],
970
3139
  agent: true,
971
3140
  handler: async (ctx, args) => {
972
- const accounts = await ctx.db.select('account.Account'), moves = new Map((await ctx.db.select('account.Move', { state: 'posted' })).map((move) => [String(move.id), move]));
3141
+ const { scale } = await ledgerOf(ctx);
3142
+ const accounts = await ctx.db.select('account.Account');
3143
+ // The date window belongs to the move, so it narrows the move query and the
3144
+ // journal items are then fetched for those moves alone.
3145
+ const moves = await postedMoves(ctx, args.dateFrom, args.dateTo);
973
3146
  const result = new Map();
974
- for (const line of await ctx.db.select('account.MoveLine')) {
975
- const move = moves.get(String(line.moveId));
976
- if (!move)
977
- continue;
978
- const at = new Date(String(move.date)).getTime(), from = args.dateFrom ? new Date(String(args.dateFrom)).getTime() : -Infinity, to = args.dateTo ? new Date(String(args.dateTo)).getTime() : Infinity;
979
- if (at < from || at > to)
980
- continue;
981
- const held = result.get(String(line.accountId)) ?? { debit: 0, credit: 0 };
982
- held.debit = money(held.debit + n(line.debit));
983
- held.credit = money(held.credit + n(line.credit));
3147
+ for (const line of await linesOfMoves(ctx, [...moves.keys()])) {
3148
+ const held = result.get(String(line.accountId)) ?? { debit: 0n, credit: 0n };
3149
+ held.debit += moneyMinor(line.debit, scale);
3150
+ held.credit += moneyMinor(line.credit, scale);
984
3151
  result.set(String(line.accountId), held);
985
3152
  }
986
3153
  return accounts
987
3154
  .map((account) => {
988
- const held = result.get(String(account.id)) ?? { debit: 0, credit: 0 };
3155
+ const held = result.get(String(account.id)) ?? { debit: 0n, credit: 0n };
989
3156
  return {
990
3157
  accountId: account.id,
991
3158
  code: account.code,
992
3159
  name: account.name,
993
- debit: decimal(held.debit),
994
- credit: decimal(held.credit),
995
- balance: decimal(held.debit - held.credit),
3160
+ debit: minorText(held.debit, scale),
3161
+ credit: minorText(held.credit, scale),
3162
+ balance: minorText(held.debit - held.credit, scale),
996
3163
  };
997
3164
  })
998
- .filter((row) => n(row.debit) || n(row.credit));
3165
+ .filter((row) => moneyMinor(row.debit, scale) !== 0n || moneyMinor(row.credit, scale) !== 0n);
999
3166
  },
1000
3167
  }),
1001
3168
  generalLedger: defineFn({
1002
- input: { accountId: 'id?', dateFrom: 'datetime?', dateTo: 'datetime?' },
1003
- effects: ['read:account.Move', 'read:account.MoveLine'],
3169
+ input: {
3170
+ accountId: 'id?',
3171
+ dateFrom: 'date?',
3172
+ dateTo: 'date?',
3173
+ limit: 'int?',
3174
+ offset: 'int?',
3175
+ },
3176
+ effects: ['read:account.Move', 'read:account.MoveLine', 'read:company.Company'],
1004
3177
  agent: true,
1005
3178
  handler: async (ctx, args) => {
1006
- const moves = new Map((await ctx.db.select('account.Move', { state: 'posted' })).map((move) => [String(move.id), move]));
1007
- const rows = [];
1008
- for (const line of await ctx.db.select('account.MoveLine', args.accountId ? { accountId: args.accountId } : {})) {
1009
- const move = moves.get(String(line.moveId));
1010
- if (!move)
1011
- continue;
1012
- const at = new Date(String(move.date)).getTime();
1013
- if (at < (args.dateFrom ? new Date(String(args.dateFrom)).getTime() : -Infinity))
1014
- continue;
1015
- if (at > (args.dateTo ? new Date(String(args.dateTo)).getTime() : Infinity))
1016
- continue;
1017
- rows.push({ ...line, move });
1018
- }
1019
- return rows.sort((a, b) => String(a.move.date).localeCompare(String(b.move.date)) || n(a.sequence) - n(b.sequence));
3179
+ const moves = await postedMoves(ctx, args.dateFrom, args.dateTo);
3180
+ const rows = (await linesOfMoves(ctx, [...moves.keys()], args.accountId))
3181
+ .map((line) => ({ ...line, move: moves.get(String(line.moveId)) }))
3182
+ .sort((a, b) => String(a.move.accountingDate).localeCompare(String(b.move.accountingDate)) ||
3183
+ String(a.moveId).localeCompare(String(b.moveId)) ||
3184
+ n(a.sequence) - n(b.sequence));
3185
+ return slice(rows, args.limit, args.offset);
1020
3186
  },
1021
3187
  }),
1022
3188
  partnerStatement: defineFn({
1023
- input: { partnerId: 'id' },
1024
- effects: ['read:account.Move', 'read:account.MoveLine', 'read:account.Account'],
3189
+ input: {
3190
+ partnerId: 'id',
3191
+ dateFrom: 'date?',
3192
+ dateTo: 'date?',
3193
+ limit: 'int?',
3194
+ offset: 'int?',
3195
+ },
3196
+ effects: ['read:account.Move', 'read:account.MoveLine', 'read:account.Account', 'read:company.Company'],
1025
3197
  agent: true,
1026
3198
  handler: async (ctx, args) => {
1027
- const moves = new Map((await ctx.db.select('account.Move', { state: 'posted', partnerId: args.partnerId })).map((move) => [String(move.id), move])), rows = [];
1028
- for (const line of await ctx.db.select('account.MoveLine', { partnerId: args.partnerId })) {
1029
- const account = await accountOf(ctx, line.accountId);
1030
- if (moves.has(String(line.moveId)) &&
1031
- ['asset_receivable', 'liability_payable'].includes(String(account?.accountType)))
1032
- rows.push({ ...line, move: moves.get(String(line.moveId)) });
1033
- }
1034
- return rows;
3199
+ const byId = await accountsById(ctx);
3200
+ const control = [...byId.values()]
3201
+ .filter((row) => OPEN_ITEM_TYPES.includes(String(row.accountType)))
3202
+ .map((row) => row.id);
3203
+ if (!control.length)
3204
+ return [];
3205
+ const moves = new Map([...(await postedMoves(ctx, args.dateFrom, args.dateTo))].filter(([, move]) => String(move.partnerId) === String(args.partnerId)));
3206
+ if (!moves.size)
3207
+ return [];
3208
+ const L = ctx.table('account.MoveLine');
3209
+ const lines = await ctx.db.all(from(L).where(and(eq(L.partnerId, args.partnerId), inArray(L.accountId, control))));
3210
+ const rows = lines
3211
+ .filter((line) => moves.has(String(line.moveId)))
3212
+ .map((line) => ({ ...line, move: moves.get(String(line.moveId)) }))
3213
+ .sort((a, b) => String(a.move.accountingDate).localeCompare(String(b.move.accountingDate)) ||
3214
+ String(a.id).localeCompare(String(b.id)));
3215
+ return slice(rows, args.limit, args.offset);
1035
3216
  },
1036
3217
  }),
1037
3218
  };