shutro-erp 0.3.5 → 0.3.6

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 (384) hide show
  1. package/dist/account_asset/.kosh/bindings.d.ts +22 -0
  2. package/dist/account_asset/.kosh/bindings.js +15 -0
  3. package/dist/account_asset/.kosh/schema.d.ts +1755 -0
  4. package/dist/account_asset/board.d.ts +61 -0
  5. package/dist/account_asset/board.js +86 -0
  6. package/dist/account_asset/books.d.ts +42 -0
  7. package/dist/account_asset/books.js +398 -0
  8. package/dist/account_asset/demo.d.ts +7 -0
  9. package/dist/account_asset/demo.js +72 -0
  10. package/dist/account_asset/index.d.ts +9 -0
  11. package/dist/account_asset/index.js +335 -0
  12. package/dist/account_asset/module.d.ts +7622 -0
  13. package/dist/account_asset/module.js +230 -0
  14. package/dist/account_budget/.kosh/bindings.d.ts +22 -0
  15. package/dist/account_budget/.kosh/bindings.js +15 -0
  16. package/dist/account_budget/.kosh/schema.d.ts +1767 -0
  17. package/dist/account_budget/budget.d.ts +5 -0
  18. package/dist/account_budget/budget.js +142 -0
  19. package/dist/account_budget/demo.d.ts +6 -0
  20. package/dist/account_budget/demo.js +30 -0
  21. package/dist/account_budget/index.d.ts +4 -0
  22. package/dist/account_budget/index.js +223 -0
  23. package/dist/account_budget/module.d.ts +13863 -0
  24. package/dist/account_budget/module.js +167 -0
  25. package/dist/account_portal/.kosh/bindings.js +1 -1
  26. package/dist/account_portal/.kosh/schema.d.ts +123 -4
  27. package/dist/account_portal/module.d.ts +146 -0
  28. package/dist/accounting/.kosh/bindings.js +1 -1
  29. package/dist/accounting/.kosh/schema.d.ts +123 -4
  30. package/dist/accounting/index.d.ts +1 -1
  31. package/dist/accounting/index.js +131 -3
  32. package/dist/accounting/module.d.ts +296 -0
  33. package/dist/accounting/module.js +32 -1
  34. package/dist/approvals/.kosh/bindings.d.ts +22 -0
  35. package/dist/approvals/.kosh/bindings.js +15 -0
  36. package/dist/approvals/.kosh/schema.d.ts +611 -0
  37. package/dist/approvals/index.d.ts +18 -0
  38. package/dist/approvals/index.js +302 -0
  39. package/dist/approvals/mails.d.ts +25 -0
  40. package/dist/approvals/mails.js +82 -0
  41. package/dist/approvals/module.d.ts +1 -0
  42. package/dist/approvals/module.js +12 -0
  43. package/dist/approvals/web/History.d.ts +4 -0
  44. package/dist/approvals/web/History.js +13 -0
  45. package/dist/approvals/web/Inbox.d.ts +9 -0
  46. package/dist/approvals/web/Inbox.js +114 -0
  47. package/dist/approvals/web/Mine.d.ts +7 -0
  48. package/dist/approvals/web/Mine.js +27 -0
  49. package/dist/approvals/web/index.d.ts +13 -0
  50. package/dist/approvals/web/index.js +22 -0
  51. package/dist/approvals/web/messages.d.ts +2 -0
  52. package/dist/approvals/web/messages.js +119 -0
  53. package/dist/approvals/web/shared.d.ts +59 -0
  54. package/dist/approvals/web/shared.js +46 -0
  55. package/dist/attendance/.kosh/bindings.d.ts +22 -0
  56. package/dist/attendance/.kosh/bindings.js +15 -0
  57. package/dist/attendance/.kosh/schema.d.ts +1048 -0
  58. package/dist/attendance/days.d.ts +96 -0
  59. package/dist/attendance/days.js +430 -0
  60. package/dist/attendance/demo.d.ts +7 -0
  61. package/dist/attendance/demo.js +58 -0
  62. package/dist/attendance/index.d.ts +4 -0
  63. package/dist/attendance/index.js +513 -0
  64. package/dist/attendance/module.d.ts +3969 -0
  65. package/dist/attendance/module.js +412 -0
  66. package/dist/attendance/routes.d.ts +16 -0
  67. package/dist/attendance/routes.js +266 -0
  68. package/dist/attendance/web/Check.d.ts +8 -0
  69. package/dist/attendance/web/Check.js +40 -0
  70. package/dist/attendance/web/Kiosk.d.ts +8 -0
  71. package/dist/attendance/web/Kiosk.js +62 -0
  72. package/dist/attendance/web/PinButton.d.ts +7 -0
  73. package/dist/attendance/web/PinButton.js +29 -0
  74. package/dist/attendance/web/index.d.ts +13 -0
  75. package/dist/attendance/web/index.js +22 -0
  76. package/dist/attendance/web/messages.d.ts +2 -0
  77. package/dist/attendance/web/messages.js +61 -0
  78. package/dist/cli/init.js +32 -0
  79. package/dist/cli/templates.d.ts +1 -1
  80. package/dist/cli/templates.js +89 -0
  81. package/dist/contacts/module.js +13 -2
  82. package/dist/crm/.kosh/bindings.js +1 -1
  83. package/dist/crm/.kosh/schema.d.ts +2 -1
  84. package/dist/crm/module.d.ts +2 -0
  85. package/dist/crm/module.js +2 -1
  86. package/dist/documents/.kosh/bindings.d.ts +22 -0
  87. package/dist/documents/.kosh/bindings.js +15 -0
  88. package/dist/documents/.kosh/schema.d.ts +862 -0
  89. package/dist/documents/demo.d.ts +6 -0
  90. package/dist/documents/demo.js +22 -0
  91. package/dist/documents/documents.d.ts +98 -0
  92. package/dist/documents/documents.js +318 -0
  93. package/dist/documents/index.d.ts +30 -0
  94. package/dist/documents/index.js +442 -0
  95. package/dist/documents/module.d.ts +2781 -0
  96. package/dist/documents/module.js +214 -0
  97. package/dist/documents/web/Versions.d.ts +7 -0
  98. package/dist/documents/web/Versions.js +45 -0
  99. package/dist/documents/web/index.d.ts +11 -0
  100. package/dist/documents/web/index.js +16 -0
  101. package/dist/documents/web/messages.d.ts +2 -0
  102. package/dist/documents/web/messages.js +21 -0
  103. package/dist/event_account/.kosh/bindings.js +1 -1
  104. package/dist/event_account/.kosh/schema.d.ts +123 -4
  105. package/dist/event_account/module.d.ts +146 -0
  106. package/dist/expense/.kosh/bindings.d.ts +22 -0
  107. package/dist/expense/.kosh/bindings.js +15 -0
  108. package/dist/expense/.kosh/schema.d.ts +1299 -0
  109. package/dist/expense/demo.d.ts +7 -0
  110. package/dist/expense/demo.js +69 -0
  111. package/dist/expense/index.d.ts +3 -0
  112. package/dist/expense/index.js +495 -0
  113. package/dist/expense/module.d.ts +4747 -0
  114. package/dist/expense/module.js +647 -0
  115. package/dist/expense_account/.kosh/bindings.d.ts +22 -0
  116. package/dist/expense_account/.kosh/bindings.js +15 -0
  117. package/dist/expense_account/.kosh/schema.d.ts +1936 -0
  118. package/dist/expense_account/index.d.ts +3 -0
  119. package/dist/expense_account/index.js +74 -0
  120. package/dist/expense_account/module.d.ts +9153 -0
  121. package/dist/expense_account/module.js +318 -0
  122. package/dist/helpdesk/.kosh/bindings.d.ts +22 -0
  123. package/dist/helpdesk/.kosh/bindings.js +15 -0
  124. package/dist/helpdesk/.kosh/schema.d.ts +885 -0
  125. package/dist/helpdesk/demo.d.ts +7 -0
  126. package/dist/helpdesk/demo.js +65 -0
  127. package/dist/helpdesk/hours.d.ts +17 -0
  128. package/dist/helpdesk/hours.js +94 -0
  129. package/dist/helpdesk/index.d.ts +10 -0
  130. package/dist/helpdesk/index.js +461 -0
  131. package/dist/helpdesk/module.d.ts +2940 -0
  132. package/dist/helpdesk/module.js +326 -0
  133. package/dist/helpdesk/routes.d.ts +12 -0
  134. package/dist/helpdesk/routes.js +132 -0
  135. package/dist/helpdesk/sla.d.ts +37 -0
  136. package/dist/helpdesk/sla.js +226 -0
  137. package/dist/hr/index.d.ts +1 -1
  138. package/dist/hr/index.js +1 -1
  139. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  140. package/dist/l10n_bd/.kosh/schema.d.ts +123 -4
  141. package/dist/l10n_bd/module.d.ts +146 -0
  142. package/dist/l10n_bd_payroll/.kosh/bindings.d.ts +22 -0
  143. package/dist/l10n_bd_payroll/.kosh/bindings.js +15 -0
  144. package/dist/l10n_bd_payroll/.kosh/schema.d.ts +2312 -0
  145. package/dist/l10n_bd_payroll/data.d.ts +47 -0
  146. package/dist/l10n_bd_payroll/data.js +347 -0
  147. package/dist/l10n_bd_payroll/index.d.ts +4 -0
  148. package/dist/l10n_bd_payroll/index.js +24 -0
  149. package/dist/l10n_bd_payroll/module.d.ts +12932 -0
  150. package/dist/l10n_bd_payroll/module.js +86 -0
  151. package/dist/l10n_in/.kosh/bindings.js +1 -1
  152. package/dist/l10n_in/.kosh/schema.d.ts +123 -4
  153. package/dist/l10n_in/module.d.ts +147 -0
  154. package/dist/mail/inbound/handle.js +6 -1
  155. package/dist/maintenance_stock/.kosh/bindings.js +1 -1
  156. package/dist/maintenance_stock/.kosh/schema.d.ts +77 -2
  157. package/dist/maintenance_stock/module.d.ts +788 -66
  158. package/dist/modules-sdk/index.d.ts +1 -1
  159. package/dist/modules-sdk/manifest.d.ts +39 -2
  160. package/dist/mrp/.kosh/bindings.js +1 -1
  161. package/dist/mrp/.kosh/schema.d.ts +77 -2
  162. package/dist/mrp/index.d.ts +1 -1
  163. package/dist/mrp/index.js +2 -1
  164. package/dist/mrp/module.d.ts +781 -54
  165. package/dist/mrp/module.js +64 -2
  166. package/dist/mrp_account/.kosh/bindings.js +1 -1
  167. package/dist/mrp_account/.kosh/schema.d.ts +198 -5
  168. package/dist/mrp_account/module.d.ts +4852 -2541
  169. package/dist/payment/.kosh/bindings.js +1 -1
  170. package/dist/payment/.kosh/schema.d.ts +125 -5
  171. package/dist/payment/index.d.ts +41 -0
  172. package/dist/payment/index.js +131 -74
  173. package/dist/payment/module.d.ts +210 -6
  174. package/dist/payment/module.js +19 -3
  175. package/dist/payment/settle.js +10 -1
  176. package/dist/payroll/.kosh/bindings.d.ts +22 -0
  177. package/dist/payroll/.kosh/bindings.js +15 -0
  178. package/dist/payroll/.kosh/schema.d.ts +1390 -0
  179. package/dist/payroll/compute.d.ts +35 -0
  180. package/dist/payroll/compute.js +398 -0
  181. package/dist/payroll/demo.d.ts +55 -0
  182. package/dist/payroll/demo.js +121 -0
  183. package/dist/payroll/formula.d.ts +62 -0
  184. package/dist/payroll/formula.js +320 -0
  185. package/dist/payroll/index.d.ts +230 -0
  186. package/dist/payroll/index.js +713 -0
  187. package/dist/payroll/module.d.ts +9390 -0
  188. package/dist/payroll/module.js +606 -0
  189. package/dist/payroll/routes.d.ts +10 -0
  190. package/dist/payroll/routes.js +112 -0
  191. package/dist/payroll_account/.kosh/bindings.d.ts +22 -0
  192. package/dist/payroll_account/.kosh/bindings.js +15 -0
  193. package/dist/payroll_account/.kosh/schema.d.ts +2308 -0
  194. package/dist/payroll_account/index.d.ts +3 -0
  195. package/dist/payroll_account/index.js +40 -0
  196. package/dist/payroll_account/module.d.ts +12396 -0
  197. package/dist/payroll_account/module.js +256 -0
  198. package/dist/permissions/approvals.d.ts +131 -9
  199. package/dist/permissions/approvals.js +662 -57
  200. package/dist/permissions/index.d.ts +1 -1
  201. package/dist/permissions/index.js +2 -2
  202. package/dist/permissions/models.js +191 -12
  203. package/dist/permissions/routes.d.ts +6 -1
  204. package/dist/permissions/routes.js +37 -4
  205. package/dist/permissions/web/ApprovalPanel.d.ts +5 -4
  206. package/dist/permissions/web/ApprovalPanel.js +39 -13
  207. package/dist/permissions/web/index.d.ts +6 -4
  208. package/dist/permissions/web/index.js +13 -4
  209. package/dist/permissions/web/messages.d.ts +2 -0
  210. package/dist/permissions/web/messages.js +43 -0
  211. package/dist/portal/index.js +1 -1
  212. package/dist/pos/.kosh/bindings.js +1 -1
  213. package/dist/pos/.kosh/schema.d.ts +123 -4
  214. package/dist/pos/index.js +4 -0
  215. package/dist/pos/module.d.ts +147 -0
  216. package/dist/pos_stock/.kosh/bindings.js +1 -1
  217. package/dist/pos_stock/.kosh/schema.d.ts +198 -5
  218. package/dist/pos_stock/module.d.ts +914 -46
  219. package/dist/product/.kosh/bindings.js +1 -1
  220. package/dist/product/.kosh/schema.d.ts +2 -1
  221. package/dist/product/index.js +13 -0
  222. package/dist/product/module.d.ts +2 -0
  223. package/dist/product/module.js +2 -1
  224. package/dist/project/.kosh/bindings.js +1 -1
  225. package/dist/project/.kosh/schema.d.ts +672 -1
  226. package/dist/project/index.d.ts +3 -1
  227. package/dist/project/index.js +901 -14
  228. package/dist/project/module.d.ts +9892 -390
  229. package/dist/project/module.js +1530 -13
  230. package/dist/project/routes.d.ts +44 -0
  231. package/dist/project/routes.js +314 -0
  232. package/dist/project/schedule.d.ts +72 -0
  233. package/dist/project/schedule.js +192 -0
  234. package/dist/project/web/Refresh.d.ts +8 -0
  235. package/dist/project/web/Refresh.js +29 -0
  236. package/dist/project/web/Schedule.d.ts +9 -0
  237. package/dist/project/web/Schedule.js +93 -0
  238. package/dist/project/web/Structure.d.ts +8 -0
  239. package/dist/project/web/Structure.js +86 -0
  240. package/dist/project/web/Workload.d.ts +8 -0
  241. package/dist/project/web/Workload.js +43 -0
  242. package/dist/project/web/index.d.ts +14 -0
  243. package/dist/project/web/index.js +25 -0
  244. package/dist/project/web/messages.d.ts +2 -0
  245. package/dist/project/web/messages.js +85 -0
  246. package/dist/project_account/.kosh/bindings.d.ts +22 -0
  247. package/dist/project_account/.kosh/bindings.js +15 -0
  248. package/dist/project_account/.kosh/schema.d.ts +2241 -0
  249. package/dist/project_account/index.d.ts +3 -0
  250. package/dist/project_account/index.js +27 -0
  251. package/dist/project_account/module.d.ts +11539 -0
  252. package/dist/project_account/module.js +76 -0
  253. package/dist/project_portal/.kosh/bindings.js +1 -1
  254. package/dist/project_portal/.kosh/schema.d.ts +672 -1
  255. package/dist/project_portal/module.d.ts +4798 -129
  256. package/dist/project_purchase/.kosh/bindings.d.ts +22 -0
  257. package/dist/project_purchase/.kosh/bindings.js +15 -0
  258. package/dist/project_purchase/.kosh/schema.d.ts +2320 -0
  259. package/dist/project_purchase/index.d.ts +9 -0
  260. package/dist/project_purchase/index.js +22 -0
  261. package/dist/project_purchase/module.d.ts +25147 -0
  262. package/dist/project_purchase/module.js +56 -0
  263. package/dist/purchase/.kosh/bindings.js +1 -1
  264. package/dist/purchase/.kosh/schema.d.ts +97 -4
  265. package/dist/purchase/module.d.ts +13 -2
  266. package/dist/purchase/module.js +10 -1
  267. package/dist/purchase_account/.kosh/bindings.js +1 -1
  268. package/dist/purchase_account/.kosh/schema.d.ts +126 -6
  269. package/dist/purchase_account/index.js +1 -0
  270. package/dist/purchase_account/module.d.ts +176 -1
  271. package/dist/purchase_account/module.js +13 -2
  272. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  273. package/dist/purchase_portal/.kosh/schema.d.ts +97 -4
  274. package/dist/purchase_portal/module.d.ts +6 -1
  275. package/dist/purchase_stock/.kosh/bindings.js +1 -1
  276. package/dist/purchase_stock/.kosh/schema.d.ts +174 -5
  277. package/dist/purchase_stock/index.d.ts +1 -1
  278. package/dist/purchase_stock/index.js +9 -2
  279. package/dist/purchase_stock/module.d.ts +840 -68
  280. package/dist/purchase_stock/module.js +242 -6
  281. package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
  282. package/dist/purchase_stock_account/.kosh/schema.d.ts +203 -7
  283. package/dist/purchase_stock_account/module.d.ts +8163 -5514
  284. package/dist/purchase_stock_account/module.js +11 -5
  285. package/dist/recruitment/.kosh/bindings.js +1 -1
  286. package/dist/recruitment/.kosh/schema.d.ts +2 -1
  287. package/dist/recruitment/module.d.ts +2 -0
  288. package/dist/recruitment/module.js +2 -1
  289. package/dist/sale_account/.kosh/bindings.js +1 -1
  290. package/dist/sale_account/.kosh/schema.d.ts +123 -4
  291. package/dist/sale_account/module.d.ts +147 -0
  292. package/dist/sale_portal/.kosh/bindings.js +1 -1
  293. package/dist/sale_portal/.kosh/schema.d.ts +2 -1
  294. package/dist/sale_portal/module.d.ts +1 -0
  295. package/dist/sale_project/.kosh/bindings.js +1 -1
  296. package/dist/sale_project/.kosh/schema.d.ts +673 -1
  297. package/dist/sale_project/module.d.ts +4800 -129
  298. package/dist/sale_project/module.js +17 -1
  299. package/dist/sale_stock/.kosh/bindings.js +1 -1
  300. package/dist/sale_stock/.kosh/schema.d.ts +77 -2
  301. package/dist/sale_stock/module.d.ts +789 -66
  302. package/dist/sales/.kosh/bindings.js +1 -1
  303. package/dist/sales/.kosh/schema.d.ts +2 -1
  304. package/dist/sales/index.js +4 -0
  305. package/dist/sales/module.d.ts +1 -0
  306. package/dist/sign/.kosh/bindings.d.ts +22 -0
  307. package/dist/sign/.kosh/bindings.js +15 -0
  308. package/dist/sign/.kosh/schema.d.ts +990 -0
  309. package/dist/sign/index.d.ts +14 -0
  310. package/dist/sign/index.js +350 -0
  311. package/dist/sign/module.d.ts +4478 -0
  312. package/dist/sign/module.js +158 -0
  313. package/dist/sign/sign.d.ts +82 -0
  314. package/dist/sign/sign.js +474 -0
  315. package/dist/stock/.kosh/bindings.js +1 -1
  316. package/dist/stock/.kosh/schema.d.ts +77 -2
  317. package/dist/stock/demo.d.ts +2 -1
  318. package/dist/stock/demo.js +28 -1
  319. package/dist/stock/index.d.ts +2 -1
  320. package/dist/stock/index.js +233 -4
  321. package/dist/stock/module.d.ts +2363 -837
  322. package/dist/stock/module.js +569 -14
  323. package/dist/stock/replenish.d.ts +38 -0
  324. package/dist/stock/replenish.js +176 -0
  325. package/dist/stock/web/Replenishment.d.ts +8 -0
  326. package/dist/stock/web/Replenishment.js +84 -0
  327. package/dist/stock/web/index.d.ts +4 -2
  328. package/dist/stock/web/index.js +6 -2
  329. package/dist/stock/web/messages.js +52 -0
  330. package/dist/stock_account/.kosh/bindings.js +1 -1
  331. package/dist/stock_account/.kosh/schema.d.ts +198 -5
  332. package/dist/stock_account/index.js +10 -0
  333. package/dist/stock_account/module.d.ts +969 -101
  334. package/dist/trade_finance/index.js +2 -0
  335. package/dist/trade_finance/module.js +2 -0
  336. package/dist/trade_finance_account/.kosh/bindings.js +1 -1
  337. package/dist/trade_finance_account/.kosh/schema.d.ts +123 -4
  338. package/dist/trade_finance_account/index.js +1 -0
  339. package/dist/trade_finance_account/module.d.ts +146 -0
  340. package/dist/trade_finance_account/module.js +1 -0
  341. package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
  342. package/dist/trade_finance_purchase/.kosh/schema.d.ts +97 -4
  343. package/dist/trade_finance_purchase/module.d.ts +6 -1
  344. package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
  345. package/dist/trade_finance_sale/.kosh/schema.d.ts +2 -1
  346. package/dist/trade_finance_sale/module.d.ts +1 -0
  347. package/dist/ui/app.js +24 -12
  348. package/dist/ui/components/AppIcon.js +8 -1
  349. package/dist/ui/i18n/messages.d.ts +4 -0
  350. package/dist/ui/i18n/messages.js +8 -0
  351. package/dist/ui/views/FormView.js +4 -2
  352. package/dist/ui/views/KanbanView.js +9 -1
  353. package/dist/ui/views/ListView.js +4 -2
  354. package/dist/ui/views/widgets.js +7 -1
  355. package/dist/website/index.js +1 -0
  356. package/dist/website/module.js +1 -0
  357. package/dist/website_crm/.kosh/bindings.js +1 -1
  358. package/dist/website_crm/.kosh/schema.d.ts +2 -1
  359. package/dist/website_crm/module.d.ts +1 -0
  360. package/dist/website_sale/.kosh/bindings.d.ts +22 -0
  361. package/dist/website_sale/.kosh/bindings.js +15 -0
  362. package/dist/website_sale/.kosh/schema.d.ts +2284 -0
  363. package/dist/website_sale/couriers.d.ts +50 -0
  364. package/dist/website_sale/couriers.js +59 -0
  365. package/dist/website_sale/demo.d.ts +7 -0
  366. package/dist/website_sale/demo.js +90 -0
  367. package/dist/website_sale/growth.d.ts +31 -0
  368. package/dist/website_sale/growth.js +163 -0
  369. package/dist/website_sale/index.d.ts +49 -0
  370. package/dist/website_sale/index.js +538 -0
  371. package/dist/website_sale/module.d.ts +22027 -0
  372. package/dist/website_sale/module.js +397 -0
  373. package/dist/website_sale/shipments.d.ts +16 -0
  374. package/dist/website_sale/shipments.js +113 -0
  375. package/dist/website_sale/shop.d.ts +81 -0
  376. package/dist/website_sale/shop.js +649 -0
  377. package/dist/website_sale_stock/.kosh/bindings.d.ts +22 -0
  378. package/dist/website_sale_stock/.kosh/bindings.js +15 -0
  379. package/dist/website_sale_stock/.kosh/schema.d.ts +2681 -0
  380. package/dist/website_sale_stock/index.d.ts +9 -0
  381. package/dist/website_sale_stock/index.js +20 -0
  382. package/dist/website_sale_stock/module.d.ts +24998 -0
  383. package/dist/website_sale_stock/module.js +28 -0
  384. package/package.json +83 -2
@@ -0,0 +1,5 @@
1
+ import type { Env } from './.kosh/bindings.js';
2
+ /** Refreshes the actual and committed amounts of the approved budgets' lines (those of `budgets`, or all). */
3
+ export declare function refreshBudgets(env: Env, budgets?: readonly number[]): Promise<number>;
4
+ /** The submitted orders against the approved budget lines of their dates: refused beyond a block, marked beyond a warn. */
5
+ export declare function checkOrders(env: Env, ids: readonly number[]): Promise<void>;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Budgets against the books (RFC 0024 §2.5): each approved line's **actual** — the posted journal lines of the
3
+ * budget's period on its account (every expense account when none) and cost centre (every one when none), debit
4
+ * less credit — and **committed** — the untaxed lines of confirmed purchase orders of the period with its cost centre
5
+ * that are not billed yet (lines without an account, or on the purchases journal's account). A purchase order
6
+ * submitted is checked against the lines it touches: beyond a **block** line it is refused with the shortfall; beyond
7
+ * a **warn** line it is marked `overBudget`, which brings an Accounting manager's approval.
8
+ */
9
+ import { orm } from '../server/orm.js';
10
+ const ZERO = orm.toDecimal(0);
11
+ const EXPENSES = ['expense', 'expense_direct_cost', 'expense_depreciation'];
12
+ /** A date-only value as `YYYY-MM-DD` (PostgreSQL dates read as local midnights). */
13
+ function isoDate(v) {
14
+ if (!(v instanceof Date))
15
+ return String(v ?? '').slice(0, 10);
16
+ const pad = (n) => String(n).padStart(2, '0');
17
+ return `${v.getFullYear()}-${pad(v.getMonth() + 1)}-${pad(v.getDate())}`;
18
+ }
19
+ /** Whether purchase orders commit against a line: no account, or the company's purchases account. */
20
+ async function commitsOn(env, line) {
21
+ if (line.account === null)
22
+ return true;
23
+ const [journal] = await (await env
24
+ .model('account.journal')
25
+ .search({ where: { company: line.company, type: 'purchase' }, limit: 1 })).load({});
26
+ return journal?.defaultAccount?.id === line.account;
27
+ }
28
+ async function actualOf(env, line) {
29
+ const found = await env.model('account.move.line').search({
30
+ where: {
31
+ posted: true,
32
+ 'move.company': line.company,
33
+ date: { gte: line.from, lte: line.to },
34
+ ...(line.account === null
35
+ ? { accountType: { in: EXPENSES } }
36
+ : { account: line.account }),
37
+ ...(line.analytic === null ? {} : { analytic: line.analytic }),
38
+ },
39
+ });
40
+ return [...(await found.load(['debit', 'credit']))].reduce((s, l) => s.plus(l.debit.amount).minus(l.credit.amount), ZERO);
41
+ }
42
+ /** Untaxed amounts of purchase order lines of the line's scope; `orders` limits it (confirmed, not billed, by default). */
43
+ async function purchasesOf(env, line, orders) {
44
+ if (!(await commitsOn(env, line)))
45
+ return ZERO;
46
+ const where = orders === undefined
47
+ ? {
48
+ 'order.state': { in: ['purchase', 'done'] },
49
+ 'order.billState': { ne: 'billed' },
50
+ 'order.company': line.company,
51
+ 'order.dateOrder': { gte: line.from, lte: line.to },
52
+ }
53
+ : { order: { in: orders } };
54
+ const found = await env.model('purchase.order.line').search({
55
+ where: { ...where, ...(line.analytic === null ? {} : { analytic: line.analytic }) },
56
+ });
57
+ return [...(await found.load(['subtotal']))].reduce((s, l) => s.plus(l.subtotal?.amount ?? ZERO), ZERO);
58
+ }
59
+ /** Refreshes the actual and committed amounts of the approved budgets' lines (those of `budgets`, or all). */
60
+ export async function refreshBudgets(env, budgets) {
61
+ const found = await env.model('account.budget').search({
62
+ where: {
63
+ state: 'approved',
64
+ ...(budgets === undefined ? {} : { id: { in: budgets } }),
65
+ },
66
+ });
67
+ let count = 0;
68
+ for (const b of await found.load({ lines: true, company: true })) {
69
+ for (const l of b.lines) {
70
+ const scope = {
71
+ from: isoDate(b.dateFrom),
72
+ to: isoDate(b.dateTo),
73
+ analytic: l.analytic?.id ?? null,
74
+ account: l.account?.id ?? null,
75
+ company: b.company.id,
76
+ };
77
+ await env
78
+ .model('account.budget.line')
79
+ .browse([l.id])
80
+ .write({
81
+ actual: (await actualOf(env, scope)).toString(),
82
+ committed: (await purchasesOf(env, scope)).toString(),
83
+ });
84
+ count += 1;
85
+ }
86
+ }
87
+ await env.flush();
88
+ return count;
89
+ }
90
+ /** The submitted orders against the approved budget lines of their dates: refused beyond a block, marked beyond a warn. */
91
+ export async function checkOrders(env, ids) {
92
+ for (const o of await env
93
+ .model('purchase.order')
94
+ .browse(ids)
95
+ .load({ company: true })) {
96
+ const date = isoDate(o.dateOrder);
97
+ const budgets = await (await env.model('account.budget').search({
98
+ where: {
99
+ state: 'approved',
100
+ company: o.company.id,
101
+ dateFrom: { lte: date },
102
+ dateTo: { gte: date },
103
+ },
104
+ })).load({ lines: true });
105
+ const notes = [];
106
+ let over = false;
107
+ for (const b of budgets)
108
+ for (const l of b.lines) {
109
+ if (l.control === 'none')
110
+ continue;
111
+ const scope = {
112
+ from: isoDate(b.dateFrom),
113
+ to: isoDate(b.dateTo),
114
+ analytic: l.analytic?.id ?? null,
115
+ account: l.account?.id ?? null,
116
+ company: o.company.id,
117
+ };
118
+ const thisOrder = await purchasesOf(env, scope, [o.id]);
119
+ if (thisOrder.isZero())
120
+ continue;
121
+ const left = l.planned
122
+ .minus(await actualOf(env, scope))
123
+ .minus(await purchasesOf(env, scope));
124
+ const short = thisOrder.minus(left);
125
+ if (short.lte(0))
126
+ continue;
127
+ const what = `${b.name} › ${l.name}: ${left.toFixed(2)} left, this order ${thisOrder.toFixed(2)} (${short.toFixed(2)} beyond)`;
128
+ if (l.control === 'block')
129
+ throw new orm.ValidationError('purchase.order', ['lines'], `Beyond the budget — ${what}.`, 'Lower the order, choose another cost centre, or ask an Accounting manager to raise the budget.');
130
+ over = true;
131
+ notes.push(what);
132
+ }
133
+ await env
134
+ .model('purchase.order')
135
+ .browse([o.id])
136
+ .write({
137
+ overBudget: over,
138
+ budgetNote: notes.length === 0 ? null : notes.join('\n'),
139
+ });
140
+ }
141
+ await env.flush();
142
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Budgets' demo data (RFC 0008 §5.8): two cost centres and this year's budget — the operations team's purchases (a
3
+ * warning beyond them), office expenses (report only) — approved, with its figures from the books.
4
+ */
5
+ import type { DemoContext } from '../modules-sdk/index.js';
6
+ export declare function budgetDemo(ctx: DemoContext): Promise<string>;
@@ -0,0 +1,30 @@
1
+ const DINA = { login: 'dina', name: 'Dina Rahman', groups: ['account.manager'] };
2
+ export async function budgetDemo(ctx) {
3
+ return ctx.as(DINA, async (raw) => {
4
+ const env = raw;
5
+ const office = (await env.model('account.account').search({ where: { code: '6300' }, limit: 1 })).ids[0];
6
+ if (office === undefined)
7
+ return 'Budgets: no chart of accounts, nothing made.';
8
+ const centre = async (code, name) => (await env.model('account.analytic').search({ where: { code }, limit: 1 })).ids[0] ??
9
+ (await env.model('account.analytic').create([{ code, name }])).ids[0];
10
+ const ops = await centre('OPS', 'Operations');
11
+ await centre('SALES', 'Sales team');
12
+ const year = ctx.date(0).slice(0, 4);
13
+ const made = await env.model('account.budget').create([
14
+ {
15
+ name: `Budget ${year}`,
16
+ dateFrom: `${year}-01-01`,
17
+ dateTo: `${year}-12-31`,
18
+ lines: {
19
+ create: [
20
+ { name: 'Operations purchases', analytic: ops, planned: '1500000', control: 'warn' },
21
+ { name: 'Office expenses', account: office, planned: '300000', control: 'none' },
22
+ ],
23
+ },
24
+ },
25
+ ]);
26
+ await env.flush();
27
+ await env.model('account.budget').browse(made.ids).approve();
28
+ return `Budgets: the ${year} budget with two lines, approved.`;
29
+ });
30
+ }
@@ -0,0 +1,4 @@
1
+ import { defineModule } from '../modules-sdk/index.js';
2
+ export { checkOrders, refreshBudgets } from './budget.js';
3
+ export { accountBudgetShutro, Budget, BudgetLine, PurchaseBudget } from './module.js';
4
+ export declare const accountBudget: ReturnType<typeof defineModule>;
@@ -0,0 +1,223 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * `shutro-erp/account_budget` (RFC 0024 §2.5): **Budgets** in Accounting. A budget for a period with lines by cost centre
4
+ * and / or account; each line's actual (posted) and committed amount (confirmed purchase orders not billed), what is
5
+ * left and how much is used; and a control on purchase orders — beyond a **warn** line an order needs an Accounting
6
+ * manager's approval as well, beyond a **block** line it is refused with the shortfall.
7
+ *
8
+ * - `POST /api/v1/budgets/refresh` `{ budgets? }`: the actual and committed amounts, now (daily on the server)
9
+ */
10
+ import { accounting } from '../accounting/index.js';
11
+ import { defineModule } from '../modules-sdk/index.js';
12
+ import { purchaseAccount } from '../purchase_account/index.js';
13
+ import { HttpProblem } from '../server/index.js';
14
+ import { action, field, form, list, pivot, search } from '../views/index.js';
15
+ import { refreshBudgets } from './budget.js';
16
+ import { budgetDemo } from './demo.js';
17
+ import { accountBudgetShutro, Budget, BudgetLine } from './module.js';
18
+ export { checkOrders, refreshBudgets } from './budget.js';
19
+ export { accountBudgetShutro, Budget, BudgetLine, PurchaseBudget } from './module.js';
20
+ function registerBudgetRoutes(context) {
21
+ const { app } = context;
22
+ app.post('/api/v1/budgets/refresh', async (request) => {
23
+ const given = request.body?.['budgets'];
24
+ const budgets = Array.isArray(given) ? given.map(Number) : undefined;
25
+ return request.env(async (raw) => {
26
+ const env = raw;
27
+ if (!env.administrator && !env.groups.has('account.user'))
28
+ throw new HttpProblem(403, 'access', 'Accountants', 'This needs the Accountant role.');
29
+ return env.asSuperuser({ reason: 'budget figures' }, async (su) => ({
30
+ lines: await refreshBudgets(su, budgets),
31
+ }));
32
+ }, { write: true });
33
+ });
34
+ if (process.env['KOSH_SCHEDULES'] === 'off')
35
+ return;
36
+ const run = async () => {
37
+ try {
38
+ const companies = await context.shutro.bootstrap({ reason: 'budget figures' }, async (env) => (await env.model('res.company').search({})).ids);
39
+ for (const company of companies)
40
+ await context.shutro.bootstrap({ reason: 'budget figures', company }, (env) => env.asSuperuser({ reason: 'budget figures' }, (su) => refreshBudgets(su)));
41
+ }
42
+ catch (error) {
43
+ app.log.error({ err: error }, 'budget figures');
44
+ }
45
+ };
46
+ const timer = setInterval(() => void run(), 3_600_000);
47
+ timer.unref();
48
+ app.addHook('onClose', async () => clearInterval(timer));
49
+ }
50
+ export const accountBudget = defineModule({
51
+ shutro: accountBudgetShutro,
52
+ kosh: '^0.1.0',
53
+ hooks: { demo: budgetDemo },
54
+ depends: [accounting, purchaseAccount],
55
+ accessLevels: { user: { label: 'Budgets', groups: ['account_budget.user'] } },
56
+ routes: (context) => registerBudgetRoutes(context),
57
+ // Beyond a budget's warn line, a purchase order needs an Accounting manager as well (RFC 0003 approvals).
58
+ approvals: [
59
+ {
60
+ name: 'Purchases beyond a budget',
61
+ model: 'purchase.order',
62
+ onApproved: 'confirm',
63
+ onRejected: 'reject',
64
+ levels: [
65
+ {
66
+ name: 'Beyond the budget',
67
+ condition: { overBudget: true },
68
+ approverRole: 'account.manager',
69
+ },
70
+ ],
71
+ },
72
+ ],
73
+ events: [{ topic: 'account.budget.approved', model: 'account.budget', label: 'Budget approved' }],
74
+ documents: [
75
+ {
76
+ key: 'budget_report',
77
+ name: 'Budget against actuals',
78
+ model: 'account.budget',
79
+ layout: {
80
+ paper: 'A4',
81
+ orientation: 'landscape',
82
+ header: '{{company.name}} — {{name}}',
83
+ footer: 'Page {{page}} of {{pages}}',
84
+ blocks: [
85
+ { kind: 'heading', id: 'title', text: '{{name}}: {{dateFrom}} to {{dateTo}}', level: 1 },
86
+ {
87
+ kind: 'table',
88
+ id: 'lines',
89
+ bind: 'lines',
90
+ columns: [
91
+ { label: 'What for', bind: 'name' },
92
+ { label: 'Cost centre', bind: 'analytic.name' },
93
+ { label: 'Account', bind: 'account.displayName' },
94
+ { label: 'Planned', bind: 'planned' },
95
+ { label: 'Actual', bind: 'actual' },
96
+ { label: 'Committed', bind: 'committed' },
97
+ { label: 'Left', bind: 'available' },
98
+ { label: 'Used %', bind: 'used' },
99
+ ],
100
+ },
101
+ { kind: 'fields', id: 'totals', items: [{ label: 'Planned in all', bind: 'planned' }] },
102
+ ],
103
+ },
104
+ },
105
+ ],
106
+ importTemplates: [
107
+ {
108
+ key: 'budgets',
109
+ model: 'account.budget',
110
+ label: 'Budgets (with their lines)',
111
+ columns: [
112
+ { header: 'Budget', field: 'name' },
113
+ { header: 'From', field: 'dateFrom' },
114
+ { header: 'To', field: 'dateTo' },
115
+ { header: 'What for', field: 'lines.name' },
116
+ { header: 'Cost centre', field: 'lines.analytic' },
117
+ { header: 'Account', field: 'lines.account' },
118
+ { header: 'Planned', field: 'lines.planned' },
119
+ { header: 'Control', field: 'lines.control' },
120
+ ],
121
+ },
122
+ ],
123
+ actions: {
124
+ 'accounting.action_budgets': action(Budget, { label: 'Budgets', views: ['list', 'form'] }),
125
+ 'accounting.action_budget_lines': action(BudgetLine, {
126
+ label: 'Budget lines',
127
+ views: ['list', 'pivot'],
128
+ }),
129
+ },
130
+ menus: [
131
+ {
132
+ id: 'accounting.budgets',
133
+ parent: 'accounting.root',
134
+ label: 'Budgets',
135
+ action: 'accounting.action_budgets',
136
+ sequence: 7,
137
+ },
138
+ {
139
+ id: 'accounting.budget_lines',
140
+ parent: 'accounting.reporting',
141
+ label: 'Budget against actuals',
142
+ action: 'accounting.action_budget_lines',
143
+ sequence: 9,
144
+ },
145
+ ],
146
+ views: {
147
+ 'account.budget.list': list(Budget, {
148
+ columns: ['name', 'dateFrom', 'dateTo', 'planned', 'state'],
149
+ }),
150
+ 'account.budget.form': form(Budget, (k) => ({
151
+ header: {
152
+ statusbar: 'state',
153
+ buttons: [
154
+ k.button('approve', { primary: true, label: 'Approve' }),
155
+ k.button('close', { label: 'Close' }),
156
+ k.button('redraft', { label: 'Back to draft' }),
157
+ ],
158
+ },
159
+ sheet: [
160
+ k.group('main', ['name', 'dateFrom', 'dateTo', 'planned'], {
161
+ description: 'Approved budgets are compared with the books every hour and checked when purchase orders are submitted.',
162
+ }),
163
+ k.lines('lines', [
164
+ { field: 'name', id: 'line_name' },
165
+ 'analytic',
166
+ 'account',
167
+ { field: 'planned', id: 'line_planned' },
168
+ 'control',
169
+ 'actual',
170
+ 'committed',
171
+ 'available',
172
+ { field: 'used', id: 'line_used', widget: 'progress' },
173
+ ]),
174
+ ],
175
+ chatter: true,
176
+ })),
177
+ 'account.budget.line.list': list(BudgetLine, {
178
+ columns: [
179
+ 'budget',
180
+ 'name',
181
+ 'analytic',
182
+ 'account',
183
+ 'planned',
184
+ 'actual',
185
+ 'committed',
186
+ 'available',
187
+ { field: 'used', widget: 'progress' },
188
+ ],
189
+ decorations: { danger: { available: { lt: 0 } } },
190
+ }),
191
+ 'account.budget.line.pivot': pivot(BudgetLine, {
192
+ rows: ['analytic'],
193
+ cols: ['budget'],
194
+ measures: [{ sum: 'planned' }, { sum: 'actual' }, { sum: 'committed' }, { sum: 'available' }],
195
+ }),
196
+ },
197
+ viewExtensions: [
198
+ {
199
+ view: 'purchase.order.form',
200
+ operations: [
201
+ {
202
+ append: 'dates',
203
+ nodes: [
204
+ field({ field: 'overBudget', id: 'order_over_budget' }),
205
+ field({ field: 'budgetNote', id: 'order_budget_note' }),
206
+ ],
207
+ },
208
+ ],
209
+ },
210
+ ],
211
+ search: {
212
+ 'account.budget': search(Budget, {
213
+ fields: ['name'],
214
+ filters: { approved: { label: 'Approved', domain: { state: 'approved' }, group: 'state' } },
215
+ groupBy: ['state'],
216
+ }),
217
+ 'account.budget.line': search(BudgetLine, {
218
+ fields: ['name', 'analytic.name'],
219
+ filters: { over: { label: 'Overspent', domain: { available: { lt: 0 } }, group: 'state' } },
220
+ groupBy: ['budget', 'analytic', 'account', 'control'],
221
+ }),
222
+ },
223
+ });