shutro-erp 0.3.4 → 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 (618) 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 +176 -6
  27. package/dist/account_portal/module.d.ts +505 -6
  28. package/dist/accounting/.kosh/bindings.js +1 -1
  29. package/dist/accounting/.kosh/schema.d.ts +176 -6
  30. package/dist/accounting/index.d.ts +1 -1
  31. package/dist/accounting/index.js +344 -4
  32. package/dist/accounting/module.d.ts +513 -5
  33. package/dist/accounting/module.js +55 -3
  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/calendar/.kosh/bindings.d.ts +22 -0
  79. package/dist/calendar/.kosh/bindings.js +15 -0
  80. package/dist/calendar/.kosh/schema.d.ts +795 -0
  81. package/dist/calendar/demo.d.ts +6 -0
  82. package/dist/calendar/demo.js +24 -0
  83. package/dist/calendar/index.d.ts +3 -0
  84. package/dist/calendar/index.js +291 -0
  85. package/dist/calendar/module.d.ts +1705 -0
  86. package/dist/calendar/module.js +180 -0
  87. package/dist/cli/init.js +80 -0
  88. package/dist/cli/templates.d.ts +1 -1
  89. package/dist/cli/templates.js +226 -0
  90. package/dist/contacts/.kosh/bindings.js +1 -1
  91. package/dist/contacts/.kosh/schema.d.ts +78 -3
  92. package/dist/contacts/demo.js +30 -1
  93. package/dist/contacts/index.d.ts +1 -1
  94. package/dist/contacts/index.js +155 -9
  95. package/dist/contacts/module.d.ts +338 -2
  96. package/dist/contacts/module.js +93 -5
  97. package/dist/crm/.kosh/bindings.d.ts +22 -0
  98. package/dist/crm/.kosh/bindings.js +15 -0
  99. package/dist/crm/.kosh/schema.d.ts +800 -0
  100. package/dist/crm/demo.d.ts +6 -0
  101. package/dist/crm/demo.js +45 -0
  102. package/dist/crm/index.d.ts +3 -0
  103. package/dist/crm/index.js +361 -0
  104. package/dist/crm/module.d.ts +1845 -0
  105. package/dist/crm/module.js +208 -0
  106. package/dist/documents/.kosh/bindings.d.ts +22 -0
  107. package/dist/documents/.kosh/bindings.js +15 -0
  108. package/dist/documents/.kosh/schema.d.ts +862 -0
  109. package/dist/documents/demo.d.ts +6 -0
  110. package/dist/documents/demo.js +22 -0
  111. package/dist/documents/documents.d.ts +98 -0
  112. package/dist/documents/documents.js +318 -0
  113. package/dist/documents/index.d.ts +30 -0
  114. package/dist/documents/index.js +442 -0
  115. package/dist/documents/module.d.ts +2781 -0
  116. package/dist/documents/module.js +214 -0
  117. package/dist/documents/web/Versions.d.ts +7 -0
  118. package/dist/documents/web/Versions.js +45 -0
  119. package/dist/documents/web/index.d.ts +11 -0
  120. package/dist/documents/web/index.js +16 -0
  121. package/dist/documents/web/messages.d.ts +2 -0
  122. package/dist/documents/web/messages.js +21 -0
  123. package/dist/event/.kosh/bindings.d.ts +22 -0
  124. package/dist/event/.kosh/bindings.js +15 -0
  125. package/dist/event/.kosh/schema.d.ts +843 -0
  126. package/dist/event/demo.d.ts +6 -0
  127. package/dist/event/demo.js +65 -0
  128. package/dist/event/index.d.ts +14 -0
  129. package/dist/event/index.js +333 -0
  130. package/dist/event/mails.d.ts +15 -0
  131. package/dist/event/mails.js +112 -0
  132. package/dist/event/module.d.ts +2800 -0
  133. package/dist/event/module.js +323 -0
  134. package/dist/event/web/CheckInBox.d.ts +9 -0
  135. package/dist/event/web/CheckInBox.js +87 -0
  136. package/dist/event/web/index.d.ts +11 -0
  137. package/dist/event/web/index.js +16 -0
  138. package/dist/event/web/messages.d.ts +2 -0
  139. package/dist/event/web/messages.js +23 -0
  140. package/dist/event_account/.kosh/bindings.d.ts +22 -0
  141. package/dist/event_account/.kosh/bindings.js +15 -0
  142. package/dist/event_account/.kosh/schema.d.ts +1758 -0
  143. package/dist/event_account/index.d.ts +3 -0
  144. package/dist/event_account/index.js +28 -0
  145. package/dist/event_account/module.d.ts +7114 -0
  146. package/dist/event_account/module.js +90 -0
  147. package/dist/expense/.kosh/bindings.d.ts +22 -0
  148. package/dist/expense/.kosh/bindings.js +15 -0
  149. package/dist/expense/.kosh/schema.d.ts +1299 -0
  150. package/dist/expense/demo.d.ts +7 -0
  151. package/dist/expense/demo.js +69 -0
  152. package/dist/expense/index.d.ts +3 -0
  153. package/dist/expense/index.js +495 -0
  154. package/dist/expense/module.d.ts +4747 -0
  155. package/dist/expense/module.js +647 -0
  156. package/dist/expense_account/.kosh/bindings.d.ts +22 -0
  157. package/dist/expense_account/.kosh/bindings.js +15 -0
  158. package/dist/expense_account/.kosh/schema.d.ts +1936 -0
  159. package/dist/expense_account/index.d.ts +3 -0
  160. package/dist/expense_account/index.js +74 -0
  161. package/dist/expense_account/module.d.ts +9153 -0
  162. package/dist/expense_account/module.js +318 -0
  163. package/dist/helpdesk/.kosh/bindings.d.ts +22 -0
  164. package/dist/helpdesk/.kosh/bindings.js +15 -0
  165. package/dist/helpdesk/.kosh/schema.d.ts +885 -0
  166. package/dist/helpdesk/demo.d.ts +7 -0
  167. package/dist/helpdesk/demo.js +65 -0
  168. package/dist/helpdesk/hours.d.ts +17 -0
  169. package/dist/helpdesk/hours.js +94 -0
  170. package/dist/helpdesk/index.d.ts +10 -0
  171. package/dist/helpdesk/index.js +461 -0
  172. package/dist/helpdesk/module.d.ts +2940 -0
  173. package/dist/helpdesk/module.js +326 -0
  174. package/dist/helpdesk/routes.d.ts +12 -0
  175. package/dist/helpdesk/routes.js +132 -0
  176. package/dist/helpdesk/sla.d.ts +37 -0
  177. package/dist/helpdesk/sla.js +226 -0
  178. package/dist/hr/.kosh/bindings.d.ts +22 -0
  179. package/dist/hr/.kosh/bindings.js +15 -0
  180. package/dist/hr/.kosh/schema.d.ts +878 -0
  181. package/dist/hr/demo.d.ts +6 -0
  182. package/dist/hr/demo.js +60 -0
  183. package/dist/hr/index.d.ts +3 -0
  184. package/dist/hr/index.js +483 -0
  185. package/dist/hr/module.d.ts +2611 -0
  186. package/dist/hr/module.js +350 -0
  187. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  188. package/dist/l10n_bd/.kosh/schema.d.ts +176 -6
  189. package/dist/l10n_bd/module.d.ts +505 -6
  190. package/dist/l10n_bd_payroll/.kosh/bindings.d.ts +22 -0
  191. package/dist/l10n_bd_payroll/.kosh/bindings.js +15 -0
  192. package/dist/l10n_bd_payroll/.kosh/schema.d.ts +2312 -0
  193. package/dist/l10n_bd_payroll/data.d.ts +47 -0
  194. package/dist/l10n_bd_payroll/data.js +347 -0
  195. package/dist/l10n_bd_payroll/index.d.ts +4 -0
  196. package/dist/l10n_bd_payroll/index.js +24 -0
  197. package/dist/l10n_bd_payroll/module.d.ts +12932 -0
  198. package/dist/l10n_bd_payroll/module.js +86 -0
  199. package/dist/l10n_in/.kosh/bindings.js +1 -1
  200. package/dist/l10n_in/.kosh/schema.d.ts +176 -6
  201. package/dist/l10n_in/module.d.ts +527 -7
  202. package/dist/mail/inbound/handle.js +6 -1
  203. package/dist/maintenance/.kosh/bindings.d.ts +22 -0
  204. package/dist/maintenance/.kosh/bindings.js +15 -0
  205. package/dist/maintenance/.kosh/schema.d.ts +911 -0
  206. package/dist/maintenance/demo.d.ts +6 -0
  207. package/dist/maintenance/demo.js +60 -0
  208. package/dist/maintenance/index.d.ts +3 -0
  209. package/dist/maintenance/index.js +422 -0
  210. package/dist/maintenance/module.d.ts +3545 -0
  211. package/dist/maintenance/module.js +446 -0
  212. package/dist/maintenance_stock/.kosh/bindings.d.ts +22 -0
  213. package/dist/maintenance_stock/.kosh/bindings.js +15 -0
  214. package/dist/maintenance_stock/.kosh/schema.d.ts +1446 -0
  215. package/dist/maintenance_stock/index.d.ts +9 -0
  216. package/dist/maintenance_stock/index.js +52 -0
  217. package/dist/maintenance_stock/module.d.ts +7675 -0
  218. package/dist/maintenance_stock/module.js +192 -0
  219. package/dist/modules-sdk/index.d.ts +1 -1
  220. package/dist/modules-sdk/manifest.d.ts +109 -2
  221. package/dist/modules-sdk/manifest.js +35 -1
  222. package/dist/mrp/.kosh/bindings.d.ts +22 -0
  223. package/dist/mrp/.kosh/bindings.js +15 -0
  224. package/dist/mrp/.kosh/schema.d.ts +1453 -0
  225. package/dist/mrp/demo.d.ts +7 -0
  226. package/dist/mrp/demo.js +42 -0
  227. package/dist/mrp/index.d.ts +3 -0
  228. package/dist/mrp/index.js +393 -0
  229. package/dist/mrp/module.d.ts +9335 -0
  230. package/dist/mrp/module.js +757 -0
  231. package/dist/mrp_account/.kosh/bindings.d.ts +22 -0
  232. package/dist/mrp_account/.kosh/bindings.js +15 -0
  233. package/dist/mrp_account/.kosh/schema.d.ts +2299 -0
  234. package/dist/mrp_account/index.d.ts +3 -0
  235. package/dist/mrp_account/index.js +22 -0
  236. package/dist/mrp_account/module.d.ts +23151 -0
  237. package/dist/mrp_account/module.js +123 -0
  238. package/dist/payment/.kosh/bindings.js +1 -1
  239. package/dist/payment/.kosh/schema.d.ts +178 -7
  240. package/dist/payment/index.d.ts +41 -0
  241. package/dist/payment/index.js +131 -74
  242. package/dist/payment/module.d.ts +569 -12
  243. package/dist/payment/module.js +19 -3
  244. package/dist/payment/settle.js +10 -1
  245. package/dist/payroll/.kosh/bindings.d.ts +22 -0
  246. package/dist/payroll/.kosh/bindings.js +15 -0
  247. package/dist/payroll/.kosh/schema.d.ts +1390 -0
  248. package/dist/payroll/compute.d.ts +35 -0
  249. package/dist/payroll/compute.js +398 -0
  250. package/dist/payroll/demo.d.ts +55 -0
  251. package/dist/payroll/demo.js +121 -0
  252. package/dist/payroll/formula.d.ts +62 -0
  253. package/dist/payroll/formula.js +320 -0
  254. package/dist/payroll/index.d.ts +230 -0
  255. package/dist/payroll/index.js +713 -0
  256. package/dist/payroll/module.d.ts +9390 -0
  257. package/dist/payroll/module.js +606 -0
  258. package/dist/payroll/routes.d.ts +10 -0
  259. package/dist/payroll/routes.js +112 -0
  260. package/dist/payroll_account/.kosh/bindings.d.ts +22 -0
  261. package/dist/payroll_account/.kosh/bindings.js +15 -0
  262. package/dist/payroll_account/.kosh/schema.d.ts +2308 -0
  263. package/dist/payroll_account/index.d.ts +3 -0
  264. package/dist/payroll_account/index.js +40 -0
  265. package/dist/payroll_account/module.d.ts +12396 -0
  266. package/dist/payroll_account/module.js +256 -0
  267. package/dist/permissions/approvals.d.ts +131 -9
  268. package/dist/permissions/approvals.js +662 -57
  269. package/dist/permissions/index.d.ts +1 -1
  270. package/dist/permissions/index.js +2 -2
  271. package/dist/permissions/models.js +191 -12
  272. package/dist/permissions/routes.d.ts +6 -1
  273. package/dist/permissions/routes.js +37 -4
  274. package/dist/permissions/web/ApprovalPanel.d.ts +5 -4
  275. package/dist/permissions/web/ApprovalPanel.js +39 -13
  276. package/dist/permissions/web/index.d.ts +6 -4
  277. package/dist/permissions/web/index.js +13 -4
  278. package/dist/permissions/web/messages.d.ts +2 -0
  279. package/dist/permissions/web/messages.js +43 -0
  280. package/dist/portal/.kosh/bindings.js +1 -1
  281. package/dist/portal/.kosh/schema.d.ts +78 -3
  282. package/dist/portal/index.js +1 -1
  283. package/dist/portal/module.d.ts +166 -2
  284. package/dist/pos/.kosh/bindings.d.ts +22 -0
  285. package/dist/pos/.kosh/bindings.js +15 -0
  286. package/dist/pos/.kosh/schema.d.ts +1809 -0
  287. package/dist/pos/accounting.d.ts +10 -0
  288. package/dist/pos/accounting.js +149 -0
  289. package/dist/pos/demo.d.ts +6 -0
  290. package/dist/pos/demo.js +90 -0
  291. package/dist/pos/index.d.ts +9 -0
  292. package/dist/pos/index.js +353 -0
  293. package/dist/pos/module.d.ts +9783 -0
  294. package/dist/pos/module.js +423 -0
  295. package/dist/pos/routes.d.ts +39 -0
  296. package/dist/pos/routes.js +368 -0
  297. package/dist/pos/web/Register.d.ts +9 -0
  298. package/dist/pos/web/Register.js +252 -0
  299. package/dist/pos/web/index.d.ts +11 -0
  300. package/dist/pos/web/index.js +16 -0
  301. package/dist/pos/web/messages.d.ts +2 -0
  302. package/dist/pos/web/messages.js +87 -0
  303. package/dist/pos_stock/.kosh/bindings.d.ts +22 -0
  304. package/dist/pos_stock/.kosh/bindings.js +15 -0
  305. package/dist/pos_stock/.kosh/schema.d.ts +2208 -0
  306. package/dist/pos_stock/index.d.ts +9 -0
  307. package/dist/pos_stock/index.js +35 -0
  308. package/dist/pos_stock/module.d.ts +12803 -0
  309. package/dist/pos_stock/module.js +115 -0
  310. package/dist/product/.kosh/bindings.js +1 -1
  311. package/dist/product/.kosh/schema.d.ts +52 -1
  312. package/dist/product/index.js +94 -4
  313. package/dist/product/module.d.ts +45 -1
  314. package/dist/product/module.js +11 -3
  315. package/dist/project/.kosh/bindings.js +1 -1
  316. package/dist/project/.kosh/schema.d.ts +725 -3
  317. package/dist/project/index.d.ts +3 -1
  318. package/dist/project/index.js +1045 -18
  319. package/dist/project/module.d.ts +10168 -458
  320. package/dist/project/module.js +1578 -14
  321. package/dist/project/routes.d.ts +44 -0
  322. package/dist/project/routes.js +314 -0
  323. package/dist/project/schedule.d.ts +72 -0
  324. package/dist/project/schedule.js +192 -0
  325. package/dist/project/web/Refresh.d.ts +8 -0
  326. package/dist/project/web/Refresh.js +29 -0
  327. package/dist/project/web/Schedule.d.ts +9 -0
  328. package/dist/project/web/Schedule.js +93 -0
  329. package/dist/project/web/Structure.d.ts +8 -0
  330. package/dist/project/web/Structure.js +86 -0
  331. package/dist/project/web/Workload.d.ts +8 -0
  332. package/dist/project/web/Workload.js +43 -0
  333. package/dist/project/web/index.d.ts +14 -0
  334. package/dist/project/web/index.js +25 -0
  335. package/dist/project/web/messages.d.ts +2 -0
  336. package/dist/project/web/messages.js +85 -0
  337. package/dist/project_account/.kosh/bindings.d.ts +22 -0
  338. package/dist/project_account/.kosh/bindings.js +15 -0
  339. package/dist/project_account/.kosh/schema.d.ts +2241 -0
  340. package/dist/project_account/index.d.ts +3 -0
  341. package/dist/project_account/index.js +27 -0
  342. package/dist/project_account/module.d.ts +11539 -0
  343. package/dist/project_account/module.js +76 -0
  344. package/dist/project_portal/.kosh/bindings.js +1 -1
  345. package/dist/project_portal/.kosh/schema.d.ts +725 -3
  346. package/dist/project_portal/module.d.ts +5137 -119
  347. package/dist/project_purchase/.kosh/bindings.d.ts +22 -0
  348. package/dist/project_purchase/.kosh/bindings.js +15 -0
  349. package/dist/project_purchase/.kosh/schema.d.ts +2320 -0
  350. package/dist/project_purchase/index.d.ts +9 -0
  351. package/dist/project_purchase/index.js +22 -0
  352. package/dist/project_purchase/module.d.ts +25147 -0
  353. package/dist/project_purchase/module.js +56 -0
  354. package/dist/purchase/.kosh/bindings.js +1 -1
  355. package/dist/purchase/.kosh/schema.d.ts +150 -6
  356. package/dist/purchase/index.js +163 -3
  357. package/dist/purchase/module.d.ts +228 -5
  358. package/dist/purchase/module.js +30 -3
  359. package/dist/purchase_account/.kosh/bindings.js +1 -1
  360. package/dist/purchase_account/.kosh/schema.d.ts +180 -8
  361. package/dist/purchase_account/index.js +27 -1
  362. package/dist/purchase_account/module.d.ts +591 -30
  363. package/dist/purchase_account/module.js +13 -2
  364. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  365. package/dist/purchase_portal/.kosh/schema.d.ts +150 -6
  366. package/dist/purchase_portal/module.d.ts +372 -6
  367. package/dist/purchase_stock/.kosh/bindings.d.ts +22 -0
  368. package/dist/purchase_stock/.kosh/bindings.js +15 -0
  369. package/dist/purchase_stock/.kosh/schema.d.ts +1479 -0
  370. package/dist/purchase_stock/index.d.ts +7 -0
  371. package/dist/purchase_stock/index.js +98 -0
  372. package/dist/purchase_stock/module.d.ts +7535 -0
  373. package/dist/purchase_stock/module.js +380 -0
  374. package/dist/purchase_stock_account/.kosh/bindings.d.ts +22 -0
  375. package/dist/purchase_stock_account/.kosh/bindings.js +15 -0
  376. package/dist/purchase_stock_account/.kosh/schema.d.ts +2155 -0
  377. package/dist/purchase_stock_account/index.d.ts +3 -0
  378. package/dist/purchase_stock_account/index.js +24 -0
  379. package/dist/purchase_stock_account/module.d.ts +38015 -0
  380. package/dist/purchase_stock_account/module.js +168 -0
  381. package/dist/recruitment/.kosh/bindings.d.ts +22 -0
  382. package/dist/recruitment/.kosh/bindings.js +15 -0
  383. package/dist/recruitment/.kosh/schema.d.ts +991 -0
  384. package/dist/recruitment/demo.d.ts +6 -0
  385. package/dist/recruitment/demo.js +45 -0
  386. package/dist/recruitment/index.d.ts +3 -0
  387. package/dist/recruitment/index.js +385 -0
  388. package/dist/recruitment/module.d.ts +3249 -0
  389. package/dist/recruitment/module.js +194 -0
  390. package/dist/recruitment/web/HireButton.d.ts +9 -0
  391. package/dist/recruitment/web/HireButton.js +32 -0
  392. package/dist/recruitment/web/index.d.ts +11 -0
  393. package/dist/recruitment/web/index.js +16 -0
  394. package/dist/recruitment/web/messages.d.ts +2 -0
  395. package/dist/recruitment/web/messages.js +19 -0
  396. package/dist/reporting/documents.d.ts +5 -0
  397. package/dist/reporting/documents.js +28 -1
  398. package/dist/reporting/index.d.ts +1 -1
  399. package/dist/reporting/index.js +4 -2
  400. package/dist/reporting/models.js +9 -0
  401. package/dist/reporting/overviews.d.ts +16 -0
  402. package/dist/reporting/overviews.js +56 -0
  403. package/dist/reporting/routes-documents.js +1 -1
  404. package/dist/reporting/routes.js +138 -80
  405. package/dist/reporting/web/DashboardView.d.ts +11 -0
  406. package/dist/reporting/web/DashboardView.js +2 -2
  407. package/dist/reporting/web/DesignerView.js +5 -0
  408. package/dist/reporting/web/Overview.d.ts +9 -0
  409. package/dist/reporting/web/Overview.js +53 -0
  410. package/dist/reporting/web/index.d.ts +1 -0
  411. package/dist/reporting/web/index.js +4 -1
  412. package/dist/reporting/web/messages.js +9 -0
  413. package/dist/sale_account/.kosh/bindings.js +1 -1
  414. package/dist/sale_account/.kosh/schema.d.ts +181 -6
  415. package/dist/sale_account/index.js +22 -1
  416. package/dist/sale_account/module.d.ts +639 -38
  417. package/dist/sale_portal/.kosh/bindings.js +1 -1
  418. package/dist/sale_portal/.kosh/schema.d.ts +59 -3
  419. package/dist/sale_portal/module.d.ts +435 -5
  420. package/dist/sale_project/.kosh/bindings.js +1 -1
  421. package/dist/sale_project/.kosh/schema.d.ts +732 -3
  422. package/dist/sale_project/module.d.ts +5349 -208
  423. package/dist/sale_project/module.js +17 -1
  424. package/dist/sale_stock/.kosh/bindings.d.ts +22 -0
  425. package/dist/sale_stock/.kosh/bindings.js +15 -0
  426. package/dist/sale_stock/.kosh/schema.d.ts +1303 -0
  427. package/dist/sale_stock/index.d.ts +7 -0
  428. package/dist/sale_stock/index.js +84 -0
  429. package/dist/sale_stock/module.d.ts +7514 -0
  430. package/dist/sale_stock/module.js +146 -0
  431. package/dist/sales/.kosh/bindings.js +1 -1
  432. package/dist/sales/.kosh/schema.d.ts +59 -3
  433. package/dist/sales/index.js +195 -4
  434. package/dist/sales/module.d.ts +356 -3
  435. package/dist/sales/module.js +78 -3
  436. package/dist/server/api/metadata.d.ts +5 -0
  437. package/dist/server/api/metadata.js +5 -0
  438. package/dist/server/api/rest.js +64 -1
  439. package/dist/server/api/views.js +1 -0
  440. package/dist/server/app-settings.d.ts +7 -0
  441. package/dist/server/app-settings.js +10 -0
  442. package/dist/server/auth/base.js +9 -0
  443. package/dist/server/index.d.ts +1 -0
  444. package/dist/server/index.js +1 -0
  445. package/dist/settings/app-settings.d.ts +2 -0
  446. package/dist/settings/app-settings.js +518 -0
  447. package/dist/settings/index.d.ts +1 -0
  448. package/dist/settings/index.js +15 -0
  449. package/dist/settings/people.js +29 -5
  450. package/dist/settings/web/AppSettingsPage.d.ts +11 -0
  451. package/dist/settings/web/AppSettingsPage.js +210 -0
  452. package/dist/settings/web/OverviewPage.js +16 -3
  453. package/dist/settings/web/PeoplePage.js +20 -6
  454. package/dist/settings/web/index.d.ts +1 -0
  455. package/dist/settings/web/index.js +3 -0
  456. package/dist/settings/web/messages.js +118 -2
  457. package/dist/sign/.kosh/bindings.d.ts +22 -0
  458. package/dist/sign/.kosh/bindings.js +15 -0
  459. package/dist/sign/.kosh/schema.d.ts +990 -0
  460. package/dist/sign/index.d.ts +14 -0
  461. package/dist/sign/index.js +350 -0
  462. package/dist/sign/module.d.ts +4478 -0
  463. package/dist/sign/module.js +158 -0
  464. package/dist/sign/sign.d.ts +82 -0
  465. package/dist/sign/sign.js +474 -0
  466. package/dist/stock/.kosh/bindings.d.ts +22 -0
  467. package/dist/stock/.kosh/bindings.js +15 -0
  468. package/dist/stock/.kosh/schema.d.ts +1222 -0
  469. package/dist/stock/demo.d.ts +8 -0
  470. package/dist/stock/demo.js +82 -0
  471. package/dist/stock/index.d.ts +4 -0
  472. package/dist/stock/index.js +903 -0
  473. package/dist/stock/module.d.ts +7856 -0
  474. package/dist/stock/module.js +1880 -0
  475. package/dist/stock/replenish.d.ts +38 -0
  476. package/dist/stock/replenish.js +176 -0
  477. package/dist/stock/web/Replenishment.d.ts +8 -0
  478. package/dist/stock/web/Replenishment.js +84 -0
  479. package/dist/stock/web/ScanBox.d.ts +8 -0
  480. package/dist/stock/web/ScanBox.js +90 -0
  481. package/dist/stock/web/index.d.ts +13 -0
  482. package/dist/stock/web/index.js +20 -0
  483. package/dist/stock/web/messages.d.ts +2 -0
  484. package/dist/stock/web/messages.js +77 -0
  485. package/dist/stock_account/.kosh/bindings.d.ts +22 -0
  486. package/dist/stock_account/.kosh/bindings.js +15 -0
  487. package/dist/stock_account/.kosh/schema.d.ts +2068 -0
  488. package/dist/stock_account/index.d.ts +3 -0
  489. package/dist/stock_account/index.js +140 -0
  490. package/dist/stock_account/module.d.ts +11523 -0
  491. package/dist/stock_account/module.js +339 -0
  492. package/dist/storage/attachments.d.ts +5 -0
  493. package/dist/storage/attachments.js +12 -1
  494. package/dist/storage/models.js +3 -0
  495. package/dist/storage/routes.js +13 -2
  496. package/dist/todo/.kosh/bindings.d.ts +22 -0
  497. package/dist/todo/.kosh/bindings.js +15 -0
  498. package/dist/todo/.kosh/schema.d.ts +732 -0
  499. package/dist/todo/demo.d.ts +6 -0
  500. package/dist/todo/demo.js +35 -0
  501. package/dist/todo/index.d.ts +3 -0
  502. package/dist/todo/index.js +187 -0
  503. package/dist/todo/module.d.ts +1180 -0
  504. package/dist/todo/module.js +130 -0
  505. package/dist/trade_finance/.kosh/bindings.d.ts +22 -0
  506. package/dist/trade_finance/.kosh/bindings.js +15 -0
  507. package/dist/trade_finance/.kosh/schema.d.ts +884 -0
  508. package/dist/trade_finance/demo.d.ts +6 -0
  509. package/dist/trade_finance/demo.js +63 -0
  510. package/dist/trade_finance/index.d.ts +3 -0
  511. package/dist/trade_finance/index.js +415 -0
  512. package/dist/trade_finance/module.d.ts +3779 -0
  513. package/dist/trade_finance/module.js +507 -0
  514. package/dist/trade_finance_account/.kosh/bindings.d.ts +22 -0
  515. package/dist/trade_finance_account/.kosh/bindings.js +15 -0
  516. package/dist/trade_finance_account/.kosh/schema.d.ts +1830 -0
  517. package/dist/trade_finance_account/index.d.ts +3 -0
  518. package/dist/trade_finance_account/index.js +93 -0
  519. package/dist/trade_finance_account/module.d.ts +8074 -0
  520. package/dist/trade_finance_account/module.js +245 -0
  521. package/dist/trade_finance_purchase/.kosh/bindings.d.ts +22 -0
  522. package/dist/trade_finance_purchase/.kosh/bindings.js +15 -0
  523. package/dist/trade_finance_purchase/.kosh/schema.d.ts +1246 -0
  524. package/dist/trade_finance_purchase/index.d.ts +8 -0
  525. package/dist/trade_finance_purchase/index.js +50 -0
  526. package/dist/trade_finance_purchase/module.d.ts +4257 -0
  527. package/dist/trade_finance_purchase/module.js +44 -0
  528. package/dist/trade_finance_sale/.kosh/bindings.d.ts +22 -0
  529. package/dist/trade_finance_sale/.kosh/bindings.js +15 -0
  530. package/dist/trade_finance_sale/.kosh/schema.d.ts +1072 -0
  531. package/dist/trade_finance_sale/index.d.ts +8 -0
  532. package/dist/trade_finance_sale/index.js +50 -0
  533. package/dist/trade_finance_sale/module.d.ts +4281 -0
  534. package/dist/trade_finance_sale/module.js +44 -0
  535. package/dist/ui/api.d.ts +2 -1
  536. package/dist/ui/api.js +2 -1
  537. package/dist/ui/app.js +26 -13
  538. package/dist/ui/components/AppIcon.js +30 -1
  539. package/dist/ui/components/primitives.d.ts +2 -0
  540. package/dist/ui/components/primitives.js +7 -1
  541. package/dist/ui/i18n/messages.d.ts +27 -0
  542. package/dist/ui/i18n/messages.js +46 -0
  543. package/dist/ui/index.d.ts +1 -0
  544. package/dist/ui/index.js +1 -0
  545. package/dist/ui/offline/queue.d.ts +5 -1
  546. package/dist/ui/offline/queue.js +2 -0
  547. package/dist/ui/registry.d.ts +5 -0
  548. package/dist/ui/shell/Home.js +55 -4
  549. package/dist/ui/views/FormView.js +102 -19
  550. package/dist/ui/views/KanbanView.d.ts +2 -0
  551. package/dist/ui/views/KanbanView.js +40 -3
  552. package/dist/ui/views/ListView.js +110 -11
  553. package/dist/ui/views/StatsRow.d.ts +14 -0
  554. package/dist/ui/views/StatsRow.js +88 -0
  555. package/dist/ui/views/widgets.d.ts +2 -1
  556. package/dist/ui/views/widgets.js +200 -1
  557. package/dist/views/builders.d.ts +19 -2
  558. package/dist/views/builders.js +21 -1
  559. package/dist/views/condition.d.ts +6 -0
  560. package/dist/views/condition.js +20 -0
  561. package/dist/views/documents.d.ts +8 -0
  562. package/dist/views/extend.d.ts +2 -2
  563. package/dist/views/extend.js +11 -1
  564. package/dist/views/index.d.ts +2 -2
  565. package/dist/views/index.js +2 -2
  566. package/dist/views/types.d.ts +52 -5
  567. package/dist/views/validate.js +39 -1
  568. package/dist/website/.kosh/bindings.d.ts +22 -0
  569. package/dist/website/.kosh/bindings.js +15 -0
  570. package/dist/website/.kosh/schema.d.ts +881 -0
  571. package/dist/website/demo.d.ts +6 -0
  572. package/dist/website/demo.js +115 -0
  573. package/dist/website/index.d.ts +9 -0
  574. package/dist/website/index.js +251 -0
  575. package/dist/website/module.d.ts +2987 -0
  576. package/dist/website/module.js +282 -0
  577. package/dist/website/render.d.ts +45 -0
  578. package/dist/website/render.js +102 -0
  579. package/dist/website/routes.d.ts +12 -0
  580. package/dist/website/routes.js +246 -0
  581. package/dist/website/web/PagePreview.d.ts +7 -0
  582. package/dist/website/web/PagePreview.js +33 -0
  583. package/dist/website/web/index.d.ts +11 -0
  584. package/dist/website/web/index.js +16 -0
  585. package/dist/website/web/messages.d.ts +2 -0
  586. package/dist/website/web/messages.js +15 -0
  587. package/dist/website_crm/.kosh/bindings.d.ts +22 -0
  588. package/dist/website_crm/.kosh/bindings.js +15 -0
  589. package/dist/website_crm/.kosh/schema.d.ts +967 -0
  590. package/dist/website_crm/index.d.ts +3 -0
  591. package/dist/website_crm/index.js +39 -0
  592. package/dist/website_crm/module.d.ts +2956 -0
  593. package/dist/website_crm/module.js +44 -0
  594. package/dist/website_sale/.kosh/bindings.d.ts +22 -0
  595. package/dist/website_sale/.kosh/bindings.js +15 -0
  596. package/dist/website_sale/.kosh/schema.d.ts +2284 -0
  597. package/dist/website_sale/couriers.d.ts +50 -0
  598. package/dist/website_sale/couriers.js +59 -0
  599. package/dist/website_sale/demo.d.ts +7 -0
  600. package/dist/website_sale/demo.js +90 -0
  601. package/dist/website_sale/growth.d.ts +31 -0
  602. package/dist/website_sale/growth.js +163 -0
  603. package/dist/website_sale/index.d.ts +49 -0
  604. package/dist/website_sale/index.js +538 -0
  605. package/dist/website_sale/module.d.ts +22027 -0
  606. package/dist/website_sale/module.js +397 -0
  607. package/dist/website_sale/shipments.d.ts +16 -0
  608. package/dist/website_sale/shipments.js +113 -0
  609. package/dist/website_sale/shop.d.ts +81 -0
  610. package/dist/website_sale/shop.js +649 -0
  611. package/dist/website_sale_stock/.kosh/bindings.d.ts +22 -0
  612. package/dist/website_sale_stock/.kosh/bindings.js +15 -0
  613. package/dist/website_sale_stock/.kosh/schema.d.ts +2681 -0
  614. package/dist/website_sale_stock/index.d.ts +9 -0
  615. package/dist/website_sale_stock/index.js +20 -0
  616. package/dist/website_sale_stock/module.d.ts +24998 -0
  617. package/dist/website_sale_stock/module.js +28 -0
  618. package/package.json +200 -2
@@ -0,0 +1,35 @@
1
+ import { type Decimal } from '../server/orm.js';
2
+ import type { Env } from './.kosh/bindings.js';
3
+ /** A date-only value as `YYYY-MM-DD` (PostgreSQL dates read as local midnights). */
4
+ export declare function isoDate(v: unknown): string;
5
+ /** The month the fiscal year starts in (1–12), from App settings › Payroll. */
6
+ export declare function fiscalStartOf(env: Env): Promise<number>;
7
+ /** The fiscal year's first day for a date. */
8
+ export declare function fiscalYearStart(date: string, startMonth: number): string;
9
+ /** Computes the payslips of runs (replacing those it had); the run must be a draft or computed. */
10
+ export declare function computeRuns(env: Env, ids: readonly number[]): Promise<void>;
11
+ /** On approval: each running loan's instalment taken by its payslip; repaid loans finished. */
12
+ export declare function recordRepayments(env: Env, runIds: readonly number[]): Promise<void>;
13
+ export interface PaymentRow {
14
+ readonly employee: string;
15
+ readonly method: string;
16
+ readonly bank: string | null;
17
+ readonly branch: string | null;
18
+ readonly account: string | null;
19
+ readonly routing: string | null;
20
+ readonly wallet: string | null;
21
+ readonly walletNumber: string | null;
22
+ readonly amount: Decimal;
23
+ readonly reference: string;
24
+ }
25
+ /** A payment file format (RFC 0024 §3: an adapter; a generic bank file and the wallets' bulk files ship). */
26
+ export interface PaymentFormat {
27
+ readonly key: string;
28
+ readonly label: string;
29
+ /** The rows the file takes. */
30
+ readonly takes: (row: PaymentRow) => boolean;
31
+ readonly render: (rows: readonly PaymentRow[]) => string;
32
+ }
33
+ export declare const PAYMENT_FORMATS: readonly PaymentFormat[];
34
+ /** The rows of a run's payment files: each payslip's net (a correction: the difference), people with nothing out. */
35
+ export declare function paymentRows(env: Env, runId: number): Promise<PaymentRow[]>;
@@ -0,0 +1,398 @@
1
+ /**
2
+ * The payroll engine (RFC 0024 §2.3): a run's payslips computed from each person's running contract and its
3
+ * structure. Every rule sees these variables, then the codes of the rules before it:
4
+ *
5
+ * - `WAGE` (the contract's monthly wage), `PERIOD_DAYS`, `CONTRACT_DAYS` (the contract's days in the period: joiners
6
+ * and leavers paid in proportion), `SERVICE_MONTHS` (since joining), `MONTH`, `FY_MONTH` and `MONTHS_LEFT` (in the
7
+ * fiscal year that starts in the month of App settings › Payroll, July by default);
8
+ * - from Attendance's **approved** days: `PRESENT_DAYS`, `ABSENT_DAYS`, `LEAVE_DAYS`, `HOLIDAYS`, `LATE_DAYS`,
9
+ * `OVERTIME_HOURS` (approved), `OVERTIME_RATE` — a payslip warns when days of the period wait for approval;
10
+ * - `GROSS` and `DEDUCTIONS` (the totals of the rules before), `E_<CODE>` (the person's own values: a provident fund membership, a declared investment), `FESTIVAL` (the run
11
+ * pays a festival bonus), `INPUT_<CODE>` (the month's one-off inputs), `LOAN` (instalments of running loans, never more than remains),
12
+ * `YTD_<CODE>` (paid this fiscal year before the period), `P_<CODE>` (parameters in force), and `slab('CODE', x)`.
13
+ *
14
+ * Each line keeps the formula with its values. A formula that fails stops the run, naming the person and the rule.
15
+ */
16
+ import { installationSetting } from '../server/index.js';
17
+ import { orm } from '../server/orm.js';
18
+ import { evaluate, explain, FormulaError, parse } from './formula.js';
19
+ const ZERO = orm.toDecimal(0);
20
+ const DAY = 86_400_000;
21
+ /** A date-only value as `YYYY-MM-DD` (PostgreSQL dates read as local midnights). */
22
+ export function isoDate(v) {
23
+ if (!(v instanceof Date))
24
+ return String(v ?? '').slice(0, 10);
25
+ const pad = (n) => String(n).padStart(2, '0');
26
+ return `${v.getFullYear()}-${pad(v.getMonth() + 1)}-${pad(v.getDate())}`;
27
+ }
28
+ const days = (from, to) => Math.round((Date.parse(to) - Date.parse(from)) / DAY) + 1;
29
+ const later = (a, b) => (a > b ? a : b);
30
+ const earlier = (a, b) => (a < b ? a : b);
31
+ const inForce = (row, on) => (row.dateFrom == null || isoDate(row.dateFrom) <= on) &&
32
+ (row.dateTo == null || isoDate(row.dateTo) >= on);
33
+ /** The month the fiscal year starts in (1–12), from App settings › Payroll. */
34
+ export async function fiscalStartOf(env) {
35
+ const m = Number(await installationSetting(env, 'payroll.fiscalStart', '7'));
36
+ return Number.isInteger(m) && m >= 1 && m <= 12 ? m : 7;
37
+ }
38
+ /** The fiscal year's first day for a date. */
39
+ export function fiscalYearStart(date, startMonth) {
40
+ const [y, m] = date.split('-').map(Number);
41
+ const year = m >= startMonth ? y : y - 1;
42
+ return `${year}-${String(startMonth).padStart(2, '0')}-01`;
43
+ }
44
+ /** Computes the payslips of runs (replacing those it had); the run must be a draft or computed. */
45
+ export async function computeRuns(env, ids) {
46
+ const startMonth = await fiscalStartOf(env);
47
+ for (const run of await env
48
+ .model('payroll.run')
49
+ .browse(ids)
50
+ .load({ company: true, correctionOf: true })) {
51
+ const from = isoDate(run.dateFrom);
52
+ const to = isoDate(run.dateTo);
53
+ // The slips the run had are replaced.
54
+ const old = await env.model('payroll.slip').search({ where: { run: run.id } });
55
+ if (old.length > 0)
56
+ await old.unlink();
57
+ // Who: the people of the corrected run, else every running contract with a structure in the period.
58
+ let contracts = [
59
+ ...(await (await env.model('hr.contract').search({
60
+ where: {
61
+ company: run.company.id,
62
+ state: 'running',
63
+ structure: { isNull: false },
64
+ dateStart: { lte: to },
65
+ or: [{ dateEnd: { isNull: true } }, { dateEnd: { gte: from } }],
66
+ },
67
+ })).load({ employee: true, structure: true })),
68
+ ];
69
+ const previous = new Map();
70
+ if (run.correctionOf !== null) {
71
+ for (const s of await (await env.model('payroll.slip').search({ where: { run: run.correctionOf.id } })).load({ employee: true }))
72
+ previous.set(s.employee.id, s.net);
73
+ contracts = contracts.filter((c) => previous.has(c.employee.id));
74
+ }
75
+ // What is in force at the period's end: parameters and slab tables.
76
+ const parameters = new Map();
77
+ for (const p of [
78
+ ...(await (await env.model('payroll.parameter').search({ where: {} })).load(['code', 'value', 'dateFrom', 'dateTo'])),
79
+ ]
80
+ .filter((p) => inForce(p, to))
81
+ .sort((a, b) => isoDate(a.dateFrom ?? '').localeCompare(isoDate(b.dateFrom ?? ''))))
82
+ parameters.set(`P_${p.code}`, p.value);
83
+ const slabs = new Map();
84
+ for (const t of [
85
+ ...(await (await env.model('payroll.slab').search({ where: {} })).load({ bands: true })),
86
+ ]
87
+ .filter((t) => inForce(t, to))
88
+ .sort((a, b) => isoDate(a.dateFrom ?? '').localeCompare(isoDate(b.dateFrom ?? ''))))
89
+ slabs.set(t.code, {
90
+ bands: [...t.bands]
91
+ .sort((a, b) => a.sequence - b.sequence)
92
+ .map((b) => ({ upTo: b.upTo, rate: b.rate })),
93
+ });
94
+ const fyStart = fiscalYearStart(to, startMonth);
95
+ const month = Number(to.slice(5, 7));
96
+ const fyMonth = ((month - startMonth + 12) % 12) + 1;
97
+ // One payslip a person: by the most recent of their running contracts, the others named in a warning.
98
+ const byPerson = new Map();
99
+ for (const c of contracts)
100
+ byPerson.set(c.employee.id, [...(byPerson.get(c.employee.id) ?? []), c]);
101
+ for (const held of byPerson.values()) {
102
+ const sorted = [...held].sort((a, b) => isoDate(b.dateStart).localeCompare(isoDate(a.dateStart)) || b.id - a.id);
103
+ const contract = sorted[0];
104
+ const e = contract.employee;
105
+ const structure = contract.structure;
106
+ if (structure === null)
107
+ continue;
108
+ const variables = new Map(parameters);
109
+ const warnings = sorted.length > 1
110
+ ? [
111
+ `${sorted.length} running contracts in the period: paid by ${contract.name}; end the others.`,
112
+ ]
113
+ : [];
114
+ const set = (k, v) => variables.set(k, typeof v === 'number' ? orm.toDecimal(v) : v);
115
+ set('WAGE', contract.wage ?? ZERO);
116
+ set('PERIOD_DAYS', days(from, to));
117
+ const cFrom = later(from, isoDate(contract.dateStart));
118
+ const cTo = contract.dateEnd === null ? to : earlier(to, isoDate(contract.dateEnd));
119
+ set('CONTRACT_DAYS', cTo < cFrom ? 0 : days(cFrom, cTo));
120
+ const joined = isoDate(e.hireDate ?? contract.dateStart);
121
+ const [jy, jm] = joined.split('-').map(Number);
122
+ const [ty, tm] = to.split('-').map(Number);
123
+ set('SERVICE_MONTHS', Math.max(0, (ty - jy) * 12 + (tm - jm)));
124
+ set('MONTH', month);
125
+ set('FY_MONTH', fyMonth);
126
+ set('MONTHS_LEFT', 12 - fyMonth + 1);
127
+ set('FESTIVAL', run.festival ? 1 : 0);
128
+ // The person's own values in force at the period's end (the latest start wins).
129
+ for (const v of [
130
+ ...(await (await env.model('payroll.employee.value').search({ where: { employee: e.id } })).load(['code', 'value', 'dateFrom', 'dateTo'])),
131
+ ]
132
+ .filter((v) => inForce(v, to))
133
+ .sort((a, b) => isoDate(a.dateFrom ?? '').localeCompare(isoDate(b.dateFrom ?? ''))))
134
+ set(`E_${v.code}`, v.value);
135
+ // Attendance: approved days only.
136
+ const attendance = [
137
+ ...(await (await env.model('attendance.day').search({
138
+ where: { employee: e.id, date: { gte: from, lte: to } },
139
+ })).load(['status', 'state', 'lateMinutes', 'overtimeApproved', 'overtimeRate'])),
140
+ ];
141
+ const approved = attendance.filter((d) => d.state === 'approved');
142
+ const count = (status) => approved.filter((d) => d.status === status).length;
143
+ set('PRESENT_DAYS', count('present'));
144
+ set('ABSENT_DAYS', count('absent'));
145
+ set('LEAVE_DAYS', count('leave'));
146
+ set('HOLIDAYS', count('holiday'));
147
+ set('LATE_DAYS', approved.filter((d) => d.lateMinutes > 0).length);
148
+ const overtime = approved.reduce((s, d) => s.plus(d.overtimeApproved), ZERO);
149
+ set('OVERTIME_HOURS', overtime);
150
+ set('OVERTIME_RATE', approved.find((d) => d.overtimeApproved.gt(0))?.overtimeRate ?? orm.toDecimal(2));
151
+ const waiting = attendance.length - approved.length;
152
+ if (waiting > 0)
153
+ warnings.push(`${waiting} attendance day(s) of the period are not approved and are left out.`);
154
+ // Inputs of the period, running loans, and what was paid this fiscal year.
155
+ for (const i of await (await env
156
+ .model('payroll.input')
157
+ .search({ where: { employee: e.id, date: { gte: from, lte: to } } })).load(['code', 'amount']))
158
+ set(`INPUT_${i.code}`, (variables.get(`INPUT_${i.code}`) ?? ZERO).plus(i.amount));
159
+ let loan = ZERO;
160
+ for (const l of await (await env.model('payroll.loan').search({
161
+ where: { employee: e.id, state: 'running', dateStart: { lte: to } },
162
+ })).load(['installment', 'remaining']))
163
+ loan = loan.plus(l.installment.lt(l.remaining ?? ZERO) ? l.installment : (l.remaining ?? ZERO));
164
+ set('LOAN', loan);
165
+ for (const [code, amount] of await yearToDate(env, e.id, fyStart, from))
166
+ set(`YTD_${code}`, amount);
167
+ // The rules, in order.
168
+ const rules = [
169
+ ...(await (await env.model('payroll.rule').search({ where: { structure: structure.id } })).load([
170
+ 'sequence',
171
+ 'code',
172
+ 'name',
173
+ 'category',
174
+ 'formula',
175
+ 'condition',
176
+ 'appearsOnSlip',
177
+ 'dateFrom',
178
+ 'dateTo',
179
+ ])),
180
+ ]
181
+ .filter((r) => inForce(r, to))
182
+ .sort((a, b) => a.sequence - b.sequence || a.id - b.id);
183
+ const scope = {
184
+ variables,
185
+ slabs,
186
+ zero: (name) => name.startsWith('INPUT_') ||
187
+ name.startsWith('YTD_') ||
188
+ name.startsWith('E_') ||
189
+ rules.some((r) => r.code === name),
190
+ };
191
+ const lines = [];
192
+ const totals = { gross: ZERO, deductions: ZERO, contributions: ZERO };
193
+ set('GROSS', ZERO);
194
+ set('DEDUCTIONS', ZERO);
195
+ for (const rule of rules) {
196
+ let amount;
197
+ let why;
198
+ try {
199
+ if (rule.condition !== null &&
200
+ rule.condition.trim() !== '' &&
201
+ evaluate(parse(rule.condition), scope).isZero()) {
202
+ set(rule.code, ZERO);
203
+ continue;
204
+ }
205
+ why = explain(rule.formula, scope);
206
+ amount = evaluate(parse(rule.formula), scope).toDecimalPlaces(2);
207
+ }
208
+ catch (error) {
209
+ if (error instanceof FormulaError)
210
+ throw new orm.ValidationError('payroll.run', ['slips'], `${e.name}, rule ${rule.code}: ${error.message}`, 'Fix the rule in Payroll › Configuration › Structures, then compute again.');
211
+ throw error;
212
+ }
213
+ set(rule.code, amount);
214
+ if (rule.category === 'basic' || rule.category === 'allowance')
215
+ totals.gross = totals.gross.plus(amount);
216
+ else if (rule.category === 'deduction')
217
+ totals.deductions = totals.deductions.plus(amount);
218
+ else if (rule.category === 'contribution')
219
+ totals.contributions = totals.contributions.plus(amount);
220
+ // The totals so far, for the rules after this one (income tax reads the gross).
221
+ set('GROSS', totals.gross);
222
+ set('DEDUCTIONS', totals.deductions);
223
+ lines.push({
224
+ rule: rule.id,
225
+ sequence: rule.sequence,
226
+ code: rule.code,
227
+ name: rule.name,
228
+ category: rule.category,
229
+ amount: amount.toString(),
230
+ explanation: `${why} = ${amount.toString()}`.slice(0, 1000),
231
+ appearsOnSlip: rule.appearsOnSlip,
232
+ });
233
+ }
234
+ const net = totals.gross.minus(totals.deductions);
235
+ await env.model('payroll.slip').create([
236
+ {
237
+ name: `${run.name} ${e.name}`,
238
+ run: run.id,
239
+ company: run.company.id,
240
+ employee: e.id,
241
+ contract: contract.id,
242
+ structure: structure.id,
243
+ dateFrom: from,
244
+ dateTo: to,
245
+ gross: totals.gross.toString(),
246
+ deductions: totals.deductions.toString(),
247
+ contributions: totals.contributions.toString(),
248
+ net: net.toString(),
249
+ previousNet: previous.has(e.id) ? previous.get(e.id).toString() : null,
250
+ warnings: warnings.length === 0 ? null : warnings.join('\n'),
251
+ lines: { create: lines },
252
+ },
253
+ ]);
254
+ }
255
+ }
256
+ }
257
+ /**
258
+ * What the person was paid this fiscal year before `before`, by rule code: per period, the latest approved or paid
259
+ * payslip (a correction replaces the payslip it corrects).
260
+ */
261
+ async function yearToDate(env, employee, fyStart, before) {
262
+ const slips = [
263
+ ...(await (await env.model('payroll.slip').search({
264
+ where: {
265
+ employee: employee,
266
+ dateFrom: { gte: fyStart, lt: before },
267
+ 'run.state': { in: ['approved', 'paid'] },
268
+ },
269
+ })).load({ lines: true })),
270
+ ];
271
+ const latest = new Map();
272
+ for (const s of slips) {
273
+ const key = isoDate(s.dateFrom);
274
+ const kept = latest.get(key);
275
+ if (kept === undefined || s.id > kept.id)
276
+ latest.set(key, s);
277
+ }
278
+ const out = new Map();
279
+ for (const s of latest.values())
280
+ for (const l of s.lines)
281
+ out.set(l.code, (out.get(l.code) ?? ZERO).plus(l.amount));
282
+ return out;
283
+ }
284
+ /** On approval: each running loan's instalment taken by its payslip; repaid loans finished. */
285
+ export async function recordRepayments(env, runIds) {
286
+ for (const run of await env
287
+ .model('payroll.run')
288
+ .browse(runIds)
289
+ .load({ slips: true })) {
290
+ if (run.kind === 'correction')
291
+ continue;
292
+ for (const slip of run.slips) {
293
+ const taken = [
294
+ ...(await (await env.model('payroll.slip.line').search({ where: { slip: slip.id, code: 'LOAN' } })).load(['amount'])),
295
+ ].reduce((s, l) => s.plus(l.amount), ZERO);
296
+ let left = taken;
297
+ for (const loan of await (await env.model('payroll.loan').search({
298
+ where: {
299
+ employee: slip.employee.id,
300
+ state: 'running',
301
+ dateStart: { lte: isoDate(run.dateTo) },
302
+ },
303
+ order: ['dateStart asc', 'id asc'],
304
+ })).load(['installment', 'remaining'])) {
305
+ if (left.lte(0))
306
+ break;
307
+ const due = loan.installment.lt(loan.remaining ?? ZERO)
308
+ ? loan.installment
309
+ : (loan.remaining ?? ZERO);
310
+ const part = left.lt(due) ? left : due;
311
+ if (part.lte(0))
312
+ continue;
313
+ await env.model('payroll.loan.repayment').create([
314
+ {
315
+ loan: loan.id,
316
+ slip: slip.id,
317
+ date: isoDate(run.dateTo),
318
+ amount: part.toString(),
319
+ },
320
+ ]);
321
+ left = left.minus(part);
322
+ }
323
+ }
324
+ }
325
+ await env.flush();
326
+ const done = await env
327
+ .model('payroll.loan')
328
+ .search({ where: { state: 'running', remaining: { lte: '0' } } });
329
+ if (done.length > 0)
330
+ await done.finish();
331
+ }
332
+ const csv = (cells) => cells
333
+ .map((c) => (c === null ? '' : /[",\n]/.test(c) ? `"${c.replace(/"/g, '""')}"` : c))
334
+ .join(',');
335
+ const wallet = (provider, label) => ({
336
+ key: provider,
337
+ label,
338
+ takes: (r) => r.method === 'wallet' && r.wallet === provider,
339
+ render: (rows) => [
340
+ csv(['Wallet Number', 'Amount', 'Reference', 'Name']),
341
+ ...rows.map((r) => csv([r.walletNumber, r.amount.toFixed(2), r.reference, r.employee])),
342
+ ].join('\r\n'),
343
+ });
344
+ export const PAYMENT_FORMATS = [
345
+ {
346
+ key: 'bank',
347
+ label: 'Bank transfer (generic CSV)',
348
+ takes: (r) => r.method === 'bank',
349
+ render: (rows) => [
350
+ csv(['Name', 'Bank', 'Branch', 'Account Number', 'Routing Number', 'Amount', 'Reference']),
351
+ ...rows.map((r) => csv([
352
+ r.employee,
353
+ r.bank,
354
+ r.branch,
355
+ r.account,
356
+ r.routing,
357
+ r.amount.toFixed(2),
358
+ r.reference,
359
+ ])),
360
+ ].join('\r\n'),
361
+ },
362
+ wallet('bkash', 'bKash disbursement (CSV)'),
363
+ wallet('nagad', 'Nagad disbursement (CSV)'),
364
+ wallet('rocket', 'Rocket disbursement (CSV)'),
365
+ {
366
+ key: 'cash',
367
+ label: 'Cash sheet (CSV, with a column to sign)',
368
+ takes: (r) => r.method === 'cash',
369
+ render: (rows) => [
370
+ csv(['Name', 'Amount', 'Reference', 'Received (signature)']),
371
+ ...rows.map((r) => csv([r.employee, r.amount.toFixed(2), r.reference, ''])),
372
+ ].join('\r\n'),
373
+ },
374
+ ];
375
+ /** The rows of a run's payment files: each payslip's net (a correction: the difference), people with nothing out. */
376
+ export async function paymentRows(env, runId) {
377
+ const [run] = await env
378
+ .model('payroll.run')
379
+ .browse([runId])
380
+ .load({ slips: { employee: true } });
381
+ if (run === undefined)
382
+ return [];
383
+ return [...run.slips]
384
+ .map((s) => ({ slip: s, amount: run.kind === 'correction' ? (s.difference ?? ZERO) : s.net }))
385
+ .filter((x) => x.amount.gt(0))
386
+ .map(({ slip, amount }) => ({
387
+ employee: slip.employee.name,
388
+ method: slip.employee.payMethod ?? 'bank',
389
+ bank: slip.employee.bankName,
390
+ branch: slip.employee.bankBranch,
391
+ account: slip.employee.bankAccount,
392
+ routing: slip.employee.routingNumber,
393
+ wallet: slip.employee.walletProvider,
394
+ walletNumber: slip.employee.walletNumber,
395
+ amount,
396
+ reference: `${run.name}`,
397
+ }));
398
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Payroll's demo data (RFC 0008 §5.8): a Standard structure (basic 60% of the wage, house rent 40% of the basic,
3
+ * the rest as other allowances, overtime from approved attendance at the hourly basic, absence on the basic, loan
4
+ * instalments), Rahim's and Sumi's running contracts on it, a loan for Rahim, and last month's run computed for
5
+ * Dina to check and approve. The Bangladesh structure comes with `l10n_bd_payroll`.
6
+ */
7
+ import type { DemoContext } from '../modules-sdk/index.js';
8
+ export declare const STANDARD_RULES: readonly [{
9
+ readonly sequence: 10;
10
+ readonly code: 'BASIC';
11
+ readonly name: 'Basic';
12
+ readonly category: 'basic';
13
+ readonly formula: 'WAGE * 0.6 * CONTRACT_DAYS / PERIOD_DAYS';
14
+ }, {
15
+ readonly sequence: 20;
16
+ readonly code: 'HOUSE_RENT';
17
+ readonly name: 'House rent';
18
+ readonly category: 'allowance';
19
+ readonly formula: 'BASIC * 0.4';
20
+ }, {
21
+ readonly sequence: 30;
22
+ readonly code: 'OTHER';
23
+ readonly name: 'Other allowances';
24
+ readonly category: 'allowance';
25
+ readonly formula: 'WAGE * CONTRACT_DAYS / PERIOD_DAYS - BASIC - HOUSE_RENT';
26
+ }, {
27
+ readonly sequence: 40;
28
+ readonly code: 'OVERTIME';
29
+ readonly name: 'Overtime';
30
+ readonly category: 'allowance';
31
+ readonly formula: 'BASIC / 208 * OVERTIME_RATE * OVERTIME_HOURS';
32
+ readonly condition: 'OVERTIME_HOURS > 0';
33
+ }, {
34
+ readonly sequence: 50;
35
+ readonly code: 'BONUS';
36
+ readonly name: 'Bonus';
37
+ readonly category: 'allowance';
38
+ readonly formula: 'INPUT_BONUS';
39
+ readonly condition: 'INPUT_BONUS > 0';
40
+ }, {
41
+ readonly sequence: 60;
42
+ readonly code: 'ABSENCE';
43
+ readonly name: 'Absence';
44
+ readonly category: 'deduction';
45
+ readonly formula: 'BASIC / 30 * ABSENT_DAYS';
46
+ readonly condition: 'ABSENT_DAYS > 0';
47
+ }, {
48
+ readonly sequence: 70;
49
+ readonly code: 'LOAN';
50
+ readonly name: 'Loan instalment';
51
+ readonly category: 'deduction';
52
+ readonly formula: 'LOAN';
53
+ readonly condition: 'LOAN > 0';
54
+ }];
55
+ export declare function payrollDemo(ctx: DemoContext): Promise<string>;
@@ -0,0 +1,121 @@
1
+ const DINA = {
2
+ login: 'dina',
3
+ name: 'Dina Rahman',
4
+ groups: ['payroll.manager', 'hr.manager'],
5
+ };
6
+ const RAHIM = { login: 'rahim', name: 'Rahim Uddin', groups: ['payroll.user'] };
7
+ const SUMI = { login: 'sumi', name: 'Sumi Begum', groups: ['payroll.user'] };
8
+ export const STANDARD_RULES = [
9
+ {
10
+ sequence: 10,
11
+ code: 'BASIC',
12
+ name: 'Basic',
13
+ category: 'basic',
14
+ formula: 'WAGE * 0.6 * CONTRACT_DAYS / PERIOD_DAYS',
15
+ },
16
+ {
17
+ sequence: 20,
18
+ code: 'HOUSE_RENT',
19
+ name: 'House rent',
20
+ category: 'allowance',
21
+ formula: 'BASIC * 0.4',
22
+ },
23
+ {
24
+ sequence: 30,
25
+ code: 'OTHER',
26
+ name: 'Other allowances',
27
+ category: 'allowance',
28
+ formula: 'WAGE * CONTRACT_DAYS / PERIOD_DAYS - BASIC - HOUSE_RENT',
29
+ },
30
+ {
31
+ sequence: 40,
32
+ code: 'OVERTIME',
33
+ name: 'Overtime',
34
+ category: 'allowance',
35
+ formula: 'BASIC / 208 * OVERTIME_RATE * OVERTIME_HOURS',
36
+ condition: 'OVERTIME_HOURS > 0',
37
+ },
38
+ {
39
+ sequence: 50,
40
+ code: 'BONUS',
41
+ name: 'Bonus',
42
+ category: 'allowance',
43
+ formula: 'INPUT_BONUS',
44
+ condition: 'INPUT_BONUS > 0',
45
+ },
46
+ {
47
+ sequence: 60,
48
+ code: 'ABSENCE',
49
+ name: 'Absence',
50
+ category: 'deduction',
51
+ formula: 'BASIC / 30 * ABSENT_DAYS',
52
+ condition: 'ABSENT_DAYS > 0',
53
+ },
54
+ {
55
+ sequence: 70,
56
+ code: 'LOAN',
57
+ name: 'Loan instalment',
58
+ category: 'deduction',
59
+ formula: 'LOAN',
60
+ condition: 'LOAN > 0',
61
+ },
62
+ ];
63
+ export async function payrollDemo(ctx) {
64
+ const uid = async (user) => ctx.as(user, async (raw) => raw.userId);
65
+ const users = { rahim: await uid(RAHIM), sumi: await uid(SUMI) };
66
+ await ctx.as(DINA, async (raw) => {
67
+ const env = raw;
68
+ const structure = (await env
69
+ .model('payroll.structure')
70
+ .create([
71
+ { name: 'Standard', rules: { create: STANDARD_RULES.map((r) => ({ ...r })) } },
72
+ ])).ids[0];
73
+ const start = ctx.date(-400);
74
+ const people = {};
75
+ for (const [key, name, user, wage] of [
76
+ ['rahim', 'Rahim Uddin', users.rahim, '45000'],
77
+ ['sumi', 'Sumi Begum', users.sumi, '60000'],
78
+ ]) {
79
+ const found = await env.model('hr.employee').search({ where: { user }, limit: 1 });
80
+ const employee = found.ids[0] ?? (await env.model('hr.employee').create([{ name, user }])).ids[0];
81
+ if (employee === undefined)
82
+ continue;
83
+ people[key] = employee;
84
+ const contract = await env
85
+ .model('hr.contract')
86
+ .create([
87
+ { name: `${name} — employment`, employee, dateStart: start, wage, structure },
88
+ ]);
89
+ await env.model('hr.contract').browse(contract.ids).start();
90
+ }
91
+ // Last month, whole.
92
+ const today = ctx.date(0);
93
+ const [y, m] = today.split('-').map(Number);
94
+ const first = new Date(Date.UTC(y, m - 2, 1)).toISOString().slice(0, 10);
95
+ const last = new Date(Date.UTC(y, m - 1, 0)).toISOString().slice(0, 10);
96
+ const loan = await env.model('payroll.loan').create([
97
+ {
98
+ employee: people['rahim'],
99
+ amount: '12000',
100
+ installment: '2000',
101
+ dateStart: first,
102
+ },
103
+ ]);
104
+ await env.model('payroll.loan').browse(loan.ids).start();
105
+ await env.model('payroll.input').create([
106
+ {
107
+ employee: people['sumi'],
108
+ date: last,
109
+ code: 'BONUS',
110
+ amount: '5000',
111
+ note: 'Project delivered',
112
+ },
113
+ ]);
114
+ const run = await env
115
+ .model('payroll.run')
116
+ .create([{ title: 'Last month’s salaries', dateFrom: first, dateTo: last }]);
117
+ await env.flush();
118
+ await env.model('payroll.run').browse(run.ids).compute();
119
+ });
120
+ return 'Payroll: the Standard structure, two contracts on it, a loan, a bonus, last month’s run computed to approve.';
121
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The payroll formula language (RFC 0024 §2.3): small, safe and exact — never `eval`. Numbers are Shutro Decimals;
3
+ * names in capitals are variables (`WAGE`, `ABSENT_DAYS`, `INPUT_BONUS`, `P_HOUSE_RENT_PCT`, an earlier rule's code);
4
+ * functions are `min`, `max`, `abs`, `round(x, places)`, `floor`, `ceil`, `if(condition, then, else)` and
5
+ * `slab('TABLE', amount)` (a progressive table, such as income tax). Comparisons (`< <= > >= == !=`) and `and`, `or`,
6
+ * `not` give 1 or 0. A formula is at most 500 characters.
7
+ *
8
+ * `evaluate` returns the value and the formula with the values written in, for the payslip's explanation.
9
+ */
10
+ import { type Decimal } from '../server/orm.js';
11
+ export declare class FormulaError extends Error {
12
+ readonly name = "FormulaError";
13
+ }
14
+ /** A parsed formula. */
15
+ export type Node = {
16
+ readonly k: 'num';
17
+ readonly v: string;
18
+ } | {
19
+ readonly k: 'str';
20
+ readonly v: string;
21
+ } | {
22
+ readonly k: 'var';
23
+ readonly v: string;
24
+ } | {
25
+ readonly k: 'neg';
26
+ readonly a: Node;
27
+ } | {
28
+ readonly k: 'not';
29
+ readonly a: Node;
30
+ } | {
31
+ readonly k: 'bin';
32
+ readonly op: string;
33
+ readonly a: Node;
34
+ readonly b: Node;
35
+ } | {
36
+ readonly k: 'call';
37
+ readonly f: string;
38
+ readonly args: readonly Node[];
39
+ };
40
+ /** Parses a formula. @throws {FormulaError} on a mistake, saying where */
41
+ export declare function parse(text: string): Node;
42
+ /** The variables a formula reads. */
43
+ export declare function variablesOf(node: Node): string[];
44
+ /** A progressive table: bands of `upTo` (null: the rest) at a rate in percent. */
45
+ export interface Slab {
46
+ readonly bands: readonly {
47
+ readonly upTo: Decimal | null;
48
+ readonly rate: Decimal;
49
+ }[];
50
+ }
51
+ export interface Scope {
52
+ readonly variables: ReadonlyMap<string, Decimal>;
53
+ readonly slabs: ReadonlyMap<string, Slab>;
54
+ /** Names read as zero when unset (inputs not given this month, nothing paid yet this year). */
55
+ readonly zero?: (name: string) => boolean;
56
+ }
57
+ /** The tax of `amount` by a progressive table: each band at its rate. */
58
+ export declare function slabTax(slab: Slab, amount: Decimal): Decimal;
59
+ /** Evaluates a parsed formula. @throws {FormulaError} for an unknown variable or table, or a division by zero */
60
+ export declare function evaluate(node: Node, scope: Scope): Decimal;
61
+ /** The formula with its variables' values written in: `WAGE * 0.6` → `50000 × 0.6`. */
62
+ export declare function explain(text: string, scope: Scope): string;