shutro-erp 0.3.5 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (768) hide show
  1. package/dist/account_asset/.kosh/bindings.js +15 -0
  2. package/dist/{mrp_account → account_asset}/.kosh/schema.d.ts +785 -614
  3. package/dist/account_asset/board.d.ts +61 -0
  4. package/dist/account_asset/board.js +86 -0
  5. package/dist/account_asset/books.d.ts +42 -0
  6. package/dist/account_asset/books.js +398 -0
  7. package/dist/account_asset/demo.d.ts +7 -0
  8. package/dist/account_asset/demo.js +72 -0
  9. package/dist/account_asset/i18n/bn.d.ts +2 -0
  10. package/dist/account_asset/i18n/bn.js +97 -0
  11. package/dist/account_asset/index.d.ts +9 -0
  12. package/dist/account_asset/index.js +337 -0
  13. package/dist/account_asset/module.d.ts +11076 -0
  14. package/dist/account_asset/module.js +230 -0
  15. package/dist/account_budget/.kosh/bindings.js +15 -0
  16. package/dist/account_budget/.kosh/schema.d.ts +2841 -0
  17. package/dist/account_budget/budget.d.ts +5 -0
  18. package/dist/account_budget/budget.js +142 -0
  19. package/dist/account_budget/demo.d.ts +6 -0
  20. package/dist/account_budget/demo.js +30 -0
  21. package/dist/account_budget/i18n/bn.d.ts +2 -0
  22. package/dist/account_budget/i18n/bn.js +63 -0
  23. package/dist/account_budget/index.d.ts +4 -0
  24. package/dist/account_budget/index.js +237 -0
  25. package/dist/account_budget/module.d.ts +27289 -0
  26. package/dist/account_budget/module.js +182 -0
  27. package/dist/account_portal/.kosh/bindings.js +1 -1
  28. package/dist/account_portal/.kosh/schema.d.ts +651 -10
  29. package/dist/account_portal/i18n/bn.d.ts +2 -0
  30. package/dist/account_portal/i18n/bn.js +6 -0
  31. package/dist/account_portal/index.js +2 -0
  32. package/dist/account_portal/module.d.ts +5212 -1592
  33. package/dist/accounting/.kosh/bindings.js +1 -1
  34. package/dist/accounting/.kosh/schema.d.ts +651 -10
  35. package/dist/accounting/closing.js +1 -0
  36. package/dist/accounting/fiscal.d.ts +578 -0
  37. package/dist/accounting/fiscal.js +401 -0
  38. package/dist/accounting/followups.d.ts +618 -0
  39. package/dist/accounting/followups.js +420 -0
  40. package/dist/accounting/i18n/bn.d.ts +2 -0
  41. package/dist/accounting/i18n/bn.js +425 -0
  42. package/dist/accounting/index.d.ts +3 -1
  43. package/dist/accounting/index.js +780 -5
  44. package/dist/accounting/module.d.ts +5386 -1543
  45. package/dist/accounting/module.js +155 -18
  46. package/dist/accounting/statements.d.ts +878 -0
  47. package/dist/accounting/statements.js +728 -0
  48. package/dist/accounting/web/BankReconcilePage.d.ts +9 -0
  49. package/dist/accounting/web/BankReconcilePage.js +138 -0
  50. package/dist/accounting/web/FollowupsPage.d.ts +8 -0
  51. package/dist/accounting/web/FollowupsPage.js +54 -0
  52. package/dist/accounting/web/PostingPreview.d.ts +8 -0
  53. package/dist/accounting/web/PostingPreview.js +26 -0
  54. package/dist/accounting/web/index.d.ts +3 -0
  55. package/dist/accounting/web/index.js +9 -0
  56. package/dist/accounting/web/messages.js +140 -0
  57. package/dist/approvals/.kosh/bindings.d.ts +22 -0
  58. package/dist/approvals/.kosh/bindings.js +15 -0
  59. package/dist/approvals/.kosh/schema.d.ts +879 -0
  60. package/dist/approvals/demo.d.ts +7 -0
  61. package/dist/approvals/demo.js +41 -0
  62. package/dist/approvals/i18n/bn.d.ts +2 -0
  63. package/dist/approvals/i18n/bn.js +133 -0
  64. package/dist/approvals/index.d.ts +36 -0
  65. package/dist/approvals/index.js +772 -0
  66. package/dist/approvals/mails.d.ts +30 -0
  67. package/dist/approvals/mails.js +87 -0
  68. package/dist/approvals/module.d.ts +2930 -0
  69. package/dist/approvals/module.js +473 -0
  70. package/dist/approvals/web/Config.d.ts +12 -0
  71. package/dist/approvals/web/Config.js +60 -0
  72. package/dist/approvals/web/History.d.ts +4 -0
  73. package/dist/approvals/web/History.js +13 -0
  74. package/dist/approvals/web/Inbox.d.ts +9 -0
  75. package/dist/approvals/web/Inbox.js +114 -0
  76. package/dist/approvals/web/Matrix.d.ts +9 -0
  77. package/dist/approvals/web/Matrix.js +26 -0
  78. package/dist/approvals/web/Mine.d.ts +7 -0
  79. package/dist/approvals/web/Mine.js +27 -0
  80. package/dist/approvals/web/index.d.ts +15 -0
  81. package/dist/approvals/web/index.js +29 -0
  82. package/dist/approvals/web/messages.d.ts +2 -0
  83. package/dist/approvals/web/messages.js +211 -0
  84. package/dist/approvals/web/shared.d.ts +59 -0
  85. package/dist/approvals/web/shared.js +46 -0
  86. package/dist/approvals_purchase/.kosh/bindings.d.ts +22 -0
  87. package/dist/approvals_purchase/.kosh/bindings.js +15 -0
  88. package/dist/approvals_purchase/.kosh/schema.d.ts +1997 -0
  89. package/dist/approvals_purchase/i18n/bn.d.ts +2 -0
  90. package/dist/approvals_purchase/i18n/bn.js +5 -0
  91. package/dist/approvals_purchase/index.d.ts +3 -0
  92. package/dist/approvals_purchase/index.js +47 -0
  93. package/dist/approvals_purchase/module.d.ts +12670 -0
  94. package/dist/approvals_purchase/module.js +84 -0
  95. package/dist/attendance/.kosh/bindings.d.ts +22 -0
  96. package/dist/attendance/.kosh/bindings.js +15 -0
  97. package/dist/attendance/.kosh/schema.d.ts +1106 -0
  98. package/dist/attendance/days.d.ts +96 -0
  99. package/dist/attendance/days.js +430 -0
  100. package/dist/attendance/demo.d.ts +7 -0
  101. package/dist/attendance/demo.js +58 -0
  102. package/dist/attendance/i18n/bn.d.ts +2 -0
  103. package/dist/attendance/i18n/bn.js +147 -0
  104. package/dist/attendance/index.d.ts +4 -0
  105. package/dist/attendance/index.js +515 -0
  106. package/dist/attendance/module.d.ts +4413 -0
  107. package/dist/attendance/module.js +412 -0
  108. package/dist/attendance/routes.d.ts +16 -0
  109. package/dist/attendance/routes.js +266 -0
  110. package/dist/attendance/web/Check.d.ts +8 -0
  111. package/dist/attendance/web/Check.js +40 -0
  112. package/dist/attendance/web/Kiosk.d.ts +8 -0
  113. package/dist/attendance/web/Kiosk.js +62 -0
  114. package/dist/attendance/web/PinButton.d.ts +7 -0
  115. package/dist/attendance/web/PinButton.js +29 -0
  116. package/dist/attendance/web/index.d.ts +13 -0
  117. package/dist/attendance/web/index.js +22 -0
  118. package/dist/attendance/web/messages.d.ts +2 -0
  119. package/dist/attendance/web/messages.js +61 -0
  120. package/dist/automation/engine.js +1 -1
  121. package/dist/calendar/.kosh/bindings.js +1 -1
  122. package/dist/calendar/.kosh/schema.d.ts +2 -1
  123. package/dist/calendar/i18n/bn.d.ts +2 -0
  124. package/dist/calendar/i18n/bn.js +80 -0
  125. package/dist/calendar/index.js +77 -0
  126. package/dist/calendar/module.d.ts +26 -0
  127. package/dist/calendar/module.js +14 -4
  128. package/dist/cli/apps.js +25 -5
  129. package/dist/cli/init.js +46 -4
  130. package/dist/cli/templates.d.ts +1 -1
  131. package/dist/cli/templates.js +123 -5
  132. package/dist/contacts/.kosh/bindings.js +1 -1
  133. package/dist/contacts/.kosh/schema.d.ts +2 -1
  134. package/dist/contacts/i18n/bn.d.ts +2 -0
  135. package/dist/contacts/i18n/bn.js +67 -0
  136. package/dist/contacts/index.js +3 -0
  137. package/dist/contacts/module.d.ts +42 -0
  138. package/dist/contacts/module.js +19 -3
  139. package/dist/crm/.kosh/bindings.js +1 -1
  140. package/dist/crm/.kosh/schema.d.ts +3 -1
  141. package/dist/crm/i18n/bn.d.ts +2 -0
  142. package/dist/crm/i18n/bn.js +80 -0
  143. package/dist/crm/index.js +22 -0
  144. package/dist/crm/module.d.ts +22 -0
  145. package/dist/crm/module.js +6 -3
  146. package/dist/documents/.kosh/bindings.d.ts +22 -0
  147. package/dist/documents/.kosh/bindings.js +15 -0
  148. package/dist/documents/.kosh/schema.d.ts +863 -0
  149. package/dist/documents/demo.d.ts +6 -0
  150. package/dist/documents/demo.js +22 -0
  151. package/dist/documents/documents.d.ts +98 -0
  152. package/dist/documents/documents.js +318 -0
  153. package/dist/documents/i18n/bn.d.ts +2 -0
  154. package/dist/documents/i18n/bn.js +83 -0
  155. package/dist/documents/index.d.ts +30 -0
  156. package/dist/documents/index.js +569 -0
  157. package/dist/documents/module.d.ts +2801 -0
  158. package/dist/documents/module.js +215 -0
  159. package/dist/documents/web/Versions.d.ts +7 -0
  160. package/dist/documents/web/Versions.js +45 -0
  161. package/dist/documents/web/index.d.ts +11 -0
  162. package/dist/documents/web/index.js +16 -0
  163. package/dist/documents/web/messages.d.ts +2 -0
  164. package/dist/documents/web/messages.js +21 -0
  165. package/dist/event/.kosh/bindings.js +1 -1
  166. package/dist/event/.kosh/schema.d.ts +2 -1
  167. package/dist/event/i18n/bn.d.ts +2 -0
  168. package/dist/event/i18n/bn.js +101 -0
  169. package/dist/event/index.js +66 -0
  170. package/dist/event/module.d.ts +20 -0
  171. package/dist/event/module.js +8 -1
  172. package/dist/event_account/.kosh/bindings.js +1 -1
  173. package/dist/event_account/.kosh/schema.d.ts +651 -10
  174. package/dist/event_account/i18n/bn.d.ts +2 -0
  175. package/dist/event_account/i18n/bn.js +5 -0
  176. package/dist/event_account/index.js +2 -0
  177. package/dist/event_account/module.d.ts +5133 -1513
  178. package/dist/expense/.kosh/bindings.d.ts +22 -0
  179. package/dist/expense/.kosh/bindings.js +15 -0
  180. package/dist/expense/.kosh/schema.d.ts +1620 -0
  181. package/dist/expense/demo.d.ts +7 -0
  182. package/dist/expense/demo.js +69 -0
  183. package/dist/expense/i18n/bn.d.ts +2 -0
  184. package/dist/expense/i18n/bn.js +155 -0
  185. package/dist/expense/index.d.ts +3 -0
  186. package/dist/expense/index.js +502 -0
  187. package/dist/expense/module.d.ts +6768 -0
  188. package/dist/expense/module.js +649 -0
  189. package/dist/expense_account/.kosh/bindings.d.ts +22 -0
  190. package/dist/expense_account/.kosh/bindings.js +15 -0
  191. package/dist/expense_account/.kosh/schema.d.ts +2515 -0
  192. package/dist/expense_account/i18n/bn.d.ts +2 -0
  193. package/dist/expense_account/i18n/bn.js +15 -0
  194. package/dist/expense_account/index.d.ts +3 -0
  195. package/dist/expense_account/index.js +76 -0
  196. package/dist/expense_account/module.d.ts +14628 -0
  197. package/dist/expense_account/module.js +318 -0
  198. package/dist/helpdesk/.kosh/bindings.d.ts +22 -0
  199. package/dist/helpdesk/.kosh/bindings.js +15 -0
  200. package/dist/helpdesk/.kosh/schema.d.ts +886 -0
  201. package/dist/helpdesk/demo.d.ts +7 -0
  202. package/dist/helpdesk/demo.js +65 -0
  203. package/dist/helpdesk/hours.d.ts +17 -0
  204. package/dist/helpdesk/hours.js +94 -0
  205. package/dist/helpdesk/i18n/bn.d.ts +2 -0
  206. package/dist/helpdesk/i18n/bn.js +127 -0
  207. package/dist/helpdesk/index.d.ts +10 -0
  208. package/dist/helpdesk/index.js +463 -0
  209. package/dist/helpdesk/module.d.ts +2960 -0
  210. package/dist/helpdesk/module.js +326 -0
  211. package/dist/helpdesk/routes.d.ts +12 -0
  212. package/dist/helpdesk/routes.js +132 -0
  213. package/dist/helpdesk/sla.d.ts +37 -0
  214. package/dist/helpdesk/sla.js +226 -0
  215. package/dist/hr/.kosh/bindings.js +1 -1
  216. package/dist/hr/.kosh/schema.d.ts +59 -1
  217. package/dist/hr/demo.js +11 -1
  218. package/dist/hr/i18n/bn.d.ts +2 -0
  219. package/dist/hr/i18n/bn.js +126 -0
  220. package/dist/hr/index.d.ts +1 -1
  221. package/dist/hr/index.js +158 -12
  222. package/dist/hr/module.d.ts +932 -59
  223. package/dist/hr/module.js +114 -17
  224. package/dist/indent/.kosh/bindings.d.ts +22 -0
  225. package/dist/indent/.kosh/bindings.js +15 -0
  226. package/dist/indent/.kosh/schema.d.ts +2084 -0
  227. package/dist/indent/demo.d.ts +7 -0
  228. package/dist/indent/demo.js +48 -0
  229. package/dist/indent/i18n/bn.d.ts +2 -0
  230. package/dist/indent/i18n/bn.js +143 -0
  231. package/dist/indent/index.d.ts +3 -0
  232. package/dist/indent/index.js +450 -0
  233. package/dist/indent/module.d.ts +13424 -0
  234. package/dist/indent/module.js +792 -0
  235. package/dist/indent_purchase/.kosh/bindings.d.ts +22 -0
  236. package/dist/indent_purchase/.kosh/bindings.js +15 -0
  237. package/dist/indent_purchase/.kosh/schema.d.ts +2710 -0
  238. package/dist/indent_purchase/i18n/bn.d.ts +2 -0
  239. package/dist/indent_purchase/i18n/bn.js +13 -0
  240. package/dist/indent_purchase/index.d.ts +3 -0
  241. package/dist/indent_purchase/index.js +61 -0
  242. package/dist/indent_purchase/module.d.ts +27950 -0
  243. package/dist/indent_purchase/module.js +163 -0
  244. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  245. package/dist/l10n_bd/.kosh/schema.d.ts +651 -10
  246. package/dist/l10n_bd/i18n/bn.d.ts +2 -0
  247. package/dist/l10n_bd/i18n/bn.js +69 -0
  248. package/dist/l10n_bd/index.js +2 -0
  249. package/dist/l10n_bd/module.d.ts +5212 -1592
  250. package/dist/l10n_bd_payroll/.kosh/bindings.d.ts +22 -0
  251. package/dist/l10n_bd_payroll/.kosh/bindings.js +15 -0
  252. package/dist/l10n_bd_payroll/.kosh/schema.d.ts +2891 -0
  253. package/dist/l10n_bd_payroll/data.d.ts +47 -0
  254. package/dist/l10n_bd_payroll/data.js +347 -0
  255. package/dist/l10n_bd_payroll/i18n/bn.d.ts +2 -0
  256. package/dist/l10n_bd_payroll/i18n/bn.js +4 -0
  257. package/dist/l10n_bd_payroll/index.d.ts +4 -0
  258. package/dist/l10n_bd_payroll/index.js +26 -0
  259. package/dist/l10n_bd_payroll/module.d.ts +17294 -0
  260. package/dist/l10n_bd_payroll/module.js +86 -0
  261. package/dist/l10n_bd_pos/.kosh/bindings.d.ts +22 -0
  262. package/dist/{mrp_account → l10n_bd_pos}/.kosh/bindings.js +2 -2
  263. package/dist/l10n_bd_pos/.kosh/schema.d.ts +2341 -0
  264. package/dist/l10n_bd_pos/i18n/bn.d.ts +2 -0
  265. package/dist/l10n_bd_pos/i18n/bn.js +32 -0
  266. package/dist/l10n_bd_pos/index.d.ts +3 -0
  267. package/dist/l10n_bd_pos/index.js +111 -0
  268. package/dist/{mrp_account → l10n_bd_pos}/module.d.ts +9047 -6981
  269. package/dist/l10n_bd_pos/module.js +43 -0
  270. package/dist/l10n_in/.kosh/bindings.js +1 -1
  271. package/dist/l10n_in/.kosh/schema.d.ts +651 -10
  272. package/dist/l10n_in/i18n/bn.d.ts +2 -0
  273. package/dist/l10n_in/i18n/bn.js +95 -0
  274. package/dist/l10n_in/index.js +2 -0
  275. package/dist/l10n_in/module.d.ts +6778 -1580
  276. package/dist/l10n_in/module.js +25 -5
  277. package/dist/l10n_in/web/GstSettings.js +2 -2
  278. package/dist/mail/inbound/handle.js +8 -5
  279. package/dist/mail/inbound/models.js +5 -3
  280. package/dist/mail/index.d.ts +12 -1
  281. package/dist/mail/index.js +139 -2
  282. package/dist/mail/send.d.ts +56 -0
  283. package/dist/mail/send.js +394 -0
  284. package/dist/mail/web/SendButton.d.ts +9 -0
  285. package/dist/mail/web/SendButton.js +71 -0
  286. package/dist/mail/web/SendSelected.d.ts +8 -0
  287. package/dist/mail/web/SendSelected.js +33 -0
  288. package/dist/mail/web/index.d.ts +2 -0
  289. package/dist/mail/web/index.js +6 -0
  290. package/dist/mail/web/messages.js +36 -0
  291. package/dist/maintenance/.kosh/bindings.js +1 -1
  292. package/dist/maintenance/.kosh/schema.d.ts +2 -1
  293. package/dist/maintenance/i18n/bn.d.ts +2 -0
  294. package/dist/maintenance/i18n/bn.js +132 -0
  295. package/dist/maintenance/index.js +85 -0
  296. package/dist/maintenance/module.d.ts +25 -0
  297. package/dist/maintenance/module.js +27 -9
  298. package/dist/maintenance_stock/.kosh/bindings.js +1 -1
  299. package/dist/maintenance_stock/.kosh/schema.d.ts +374 -3
  300. package/dist/maintenance_stock/i18n/bn.d.ts +2 -0
  301. package/dist/maintenance_stock/i18n/bn.js +21 -0
  302. package/dist/maintenance_stock/index.js +2 -0
  303. package/dist/maintenance_stock/module.d.ts +6095 -1327
  304. package/dist/maintenance_stock/module.js +1 -0
  305. package/dist/modules-sdk/apps.d.ts +10 -0
  306. package/dist/modules-sdk/apps.js +32 -0
  307. package/dist/modules-sdk/index.d.ts +1 -1
  308. package/dist/modules-sdk/manifest.d.ts +105 -2
  309. package/dist/payment/.kosh/bindings.js +1 -1
  310. package/dist/payment/.kosh/schema.d.ts +653 -11
  311. package/dist/payment/i18n/bn.d.ts +2 -0
  312. package/dist/payment/i18n/bn.js +59 -0
  313. package/dist/payment/index.d.ts +41 -0
  314. package/dist/payment/index.js +216 -74
  315. package/dist/payment/module.d.ts +5353 -1675
  316. package/dist/payment/module.js +36 -6
  317. package/dist/payment/settle.js +11 -1
  318. package/dist/payroll/.kosh/bindings.d.ts +22 -0
  319. package/dist/payroll/.kosh/bindings.js +15 -0
  320. package/dist/payroll/.kosh/schema.d.ts +1448 -0
  321. package/dist/payroll/compute.d.ts +35 -0
  322. package/dist/payroll/compute.js +398 -0
  323. package/dist/payroll/demo.d.ts +55 -0
  324. package/dist/payroll/demo.js +121 -0
  325. package/dist/payroll/formula.d.ts +62 -0
  326. package/dist/payroll/formula.js +320 -0
  327. package/dist/payroll/i18n/bn.d.ts +2 -0
  328. package/dist/payroll/i18n/bn.js +206 -0
  329. package/dist/payroll/index.d.ts +230 -0
  330. package/dist/payroll/index.js +715 -0
  331. package/dist/{mrp → payroll}/module.d.ts +4294 -2624
  332. package/dist/payroll/module.js +606 -0
  333. package/dist/payroll/routes.d.ts +10 -0
  334. package/dist/payroll/routes.js +112 -0
  335. package/dist/payroll_account/.kosh/bindings.d.ts +22 -0
  336. package/dist/payroll_account/.kosh/bindings.js +15 -0
  337. package/dist/payroll_account/.kosh/schema.d.ts +2887 -0
  338. package/dist/payroll_account/i18n/bn.d.ts +2 -0
  339. package/dist/payroll_account/i18n/bn.js +10 -0
  340. package/dist/payroll_account/index.d.ts +3 -0
  341. package/dist/payroll_account/index.js +42 -0
  342. package/dist/payroll_account/module.d.ts +16738 -0
  343. package/dist/payroll_account/module.js +256 -0
  344. package/dist/permissions/approvals.d.ts +227 -12
  345. package/dist/permissions/approvals.js +1421 -67
  346. package/dist/permissions/index.d.ts +1 -1
  347. package/dist/permissions/index.js +2 -2
  348. package/dist/permissions/models.js +364 -13
  349. package/dist/permissions/routes.d.ts +9 -1
  350. package/dist/permissions/routes.js +72 -5
  351. package/dist/permissions/web/ApprovalPanel.d.ts +5 -4
  352. package/dist/permissions/web/ApprovalPanel.js +75 -11
  353. package/dist/permissions/web/index.d.ts +6 -4
  354. package/dist/permissions/web/index.js +13 -4
  355. package/dist/permissions/web/messages.d.ts +2 -0
  356. package/dist/permissions/web/messages.js +95 -0
  357. package/dist/portal/.kosh/bindings.js +1 -1
  358. package/dist/portal/.kosh/schema.d.ts +2 -1
  359. package/dist/portal/documents.d.ts +3 -0
  360. package/dist/portal/documents.js +21 -1
  361. package/dist/portal/i18n/bn.d.ts +2 -0
  362. package/dist/portal/i18n/bn.js +33 -0
  363. package/dist/portal/index.js +3 -1
  364. package/dist/portal/module.d.ts +20 -0
  365. package/dist/portal/routes-documents.js +76 -0
  366. package/dist/pos/.kosh/bindings.js +1 -1
  367. package/dist/pos/.kosh/schema.d.ts +652 -10
  368. package/dist/pos/i18n/bn.d.ts +2 -0
  369. package/dist/pos/i18n/bn.js +133 -0
  370. package/dist/pos/index.js +87 -1
  371. package/dist/pos/module.d.ts +6967 -1709
  372. package/dist/pos/module.js +49 -5
  373. package/dist/pos/routes.js +80 -7
  374. package/dist/pos/web/Register.js +2 -5
  375. package/dist/pos_stock/.kosh/bindings.js +1 -1
  376. package/dist/pos_stock/.kosh/schema.d.ts +822 -12
  377. package/dist/pos_stock/i18n/bn.d.ts +2 -0
  378. package/dist/pos_stock/i18n/bn.js +6 -0
  379. package/dist/pos_stock/index.js +2 -0
  380. package/dist/pos_stock/module.d.ts +11241 -2851
  381. package/dist/product/.kosh/bindings.js +1 -1
  382. package/dist/product/.kosh/schema.d.ts +203 -1
  383. package/dist/product/i18n/bn.d.ts +2 -0
  384. package/dist/product/i18n/bn.js +175 -0
  385. package/dist/product/index.d.ts +1 -0
  386. package/dist/product/index.js +301 -1
  387. package/dist/product/module.d.ts +1727 -0
  388. package/dist/product/module.js +67 -6
  389. package/dist/product/pricelist.d.ts +575 -0
  390. package/dist/product/pricelist.js +257 -0
  391. package/dist/product/variants.d.ts +908 -0
  392. package/dist/product/variants.js +251 -0
  393. package/dist/production/.kosh/bindings.d.ts +22 -0
  394. package/dist/production/.kosh/bindings.js +15 -0
  395. package/dist/production/.kosh/schema.d.ts +2345 -0
  396. package/dist/{mrp → production}/demo.d.ts +1 -1
  397. package/dist/{mrp → production}/demo.js +5 -5
  398. package/dist/production/depth.d.ts +790 -0
  399. package/dist/production/depth.js +262 -0
  400. package/dist/production/i18n/bn.d.ts +2 -0
  401. package/dist/production/i18n/bn.js +350 -0
  402. package/dist/production/index.d.ts +6 -0
  403. package/dist/production/index.js +1256 -0
  404. package/dist/production/module.d.ts +17327 -0
  405. package/dist/production/module.js +1333 -0
  406. package/dist/production/plan.d.ts +921 -0
  407. package/dist/production/plan.js +511 -0
  408. package/dist/production/schedule.d.ts +656 -0
  409. package/dist/production/schedule.js +309 -0
  410. package/dist/production_account/.kosh/bindings.d.ts +22 -0
  411. package/dist/production_account/.kosh/bindings.js +15 -0
  412. package/dist/production_account/.kosh/schema.d.ts +3496 -0
  413. package/dist/production_account/i18n/bn.d.ts +2 -0
  414. package/dist/production_account/i18n/bn.js +93 -0
  415. package/dist/production_account/index.d.ts +4 -0
  416. package/dist/production_account/index.js +246 -0
  417. package/dist/production_account/module.d.ts +1192 -0
  418. package/dist/{mrp_account → production_account}/module.js +72 -18
  419. package/dist/production_account/overhead.d.ts +1195 -0
  420. package/dist/production_account/overhead.js +554 -0
  421. package/dist/project/.kosh/bindings.js +1 -1
  422. package/dist/project/.kosh/schema.d.ts +735 -1
  423. package/dist/project/i18n/bn.d.ts +2 -0
  424. package/dist/project/i18n/bn.js +383 -0
  425. package/dist/project/index.d.ts +3 -1
  426. package/dist/project/index.js +1024 -14
  427. package/dist/project/module.d.ts +9912 -390
  428. package/dist/project/module.js +1590 -14
  429. package/dist/project/routes.d.ts +44 -0
  430. package/dist/project/routes.js +314 -0
  431. package/dist/project/schedule.d.ts +72 -0
  432. package/dist/project/schedule.js +192 -0
  433. package/dist/project/web/Refresh.d.ts +8 -0
  434. package/dist/project/web/Refresh.js +29 -0
  435. package/dist/project/web/Schedule.d.ts +9 -0
  436. package/dist/project/web/Schedule.js +93 -0
  437. package/dist/project/web/Structure.d.ts +8 -0
  438. package/dist/project/web/Structure.js +86 -0
  439. package/dist/project/web/Workload.d.ts +8 -0
  440. package/dist/project/web/Workload.js +43 -0
  441. package/dist/project/web/index.d.ts +14 -0
  442. package/dist/project/web/index.js +25 -0
  443. package/dist/project/web/messages.d.ts +2 -0
  444. package/dist/project/web/messages.js +85 -0
  445. package/dist/project_account/.kosh/bindings.d.ts +22 -0
  446. package/dist/project_account/.kosh/bindings.js +15 -0
  447. package/dist/project_account/.kosh/schema.d.ts +2763 -0
  448. package/dist/project_account/i18n/bn.d.ts +2 -0
  449. package/dist/project_account/i18n/bn.js +6 -0
  450. package/dist/project_account/index.d.ts +3 -0
  451. package/dist/project_account/index.js +29 -0
  452. package/dist/project_account/module.d.ts +15013 -0
  453. package/dist/project_account/module.js +76 -0
  454. package/dist/project_portal/.kosh/bindings.js +1 -1
  455. package/dist/project_portal/.kosh/schema.d.ts +735 -1
  456. package/dist/project_portal/i18n/bn.d.ts +2 -0
  457. package/dist/project_portal/i18n/bn.js +6 -0
  458. package/dist/project_portal/index.js +2 -0
  459. package/dist/project_portal/module.d.ts +4796 -87
  460. package/dist/project_purchase/.kosh/bindings.d.ts +22 -0
  461. package/dist/project_purchase/.kosh/bindings.js +15 -0
  462. package/dist/project_purchase/.kosh/schema.d.ts +3393 -0
  463. package/dist/project_purchase/i18n/bn.d.ts +2 -0
  464. package/dist/project_purchase/i18n/bn.js +4 -0
  465. package/dist/project_purchase/index.d.ts +9 -0
  466. package/dist/project_purchase/index.js +24 -0
  467. package/dist/project_purchase/module.d.ts +38613 -0
  468. package/dist/project_purchase/module.js +56 -0
  469. package/dist/purchase/.kosh/bindings.js +1 -1
  470. package/dist/purchase/.kosh/schema.d.ts +908 -5
  471. package/dist/purchase/comparison.d.ts +993 -0
  472. package/dist/purchase/comparison.js +415 -0
  473. package/dist/purchase/extras.d.ts +1509 -0
  474. package/dist/purchase/extras.js +445 -0
  475. package/dist/purchase/i18n/bn.d.ts +2 -0
  476. package/dist/purchase/i18n/bn.js +413 -0
  477. package/dist/purchase/index.d.ts +5 -0
  478. package/dist/purchase/index.js +1280 -4
  479. package/dist/purchase/module.d.ts +7147 -395
  480. package/dist/purchase/module.js +303 -10
  481. package/dist/purchase/request.d.ts +696 -0
  482. package/dist/purchase/request.js +446 -0
  483. package/dist/purchase/tender.d.ts +1208 -0
  484. package/dist/purchase/tender.js +507 -0
  485. package/dist/purchase/vendorprice.d.ts +340 -0
  486. package/dist/purchase/vendorprice.js +153 -0
  487. package/dist/purchase_account/.kosh/bindings.js +1 -1
  488. package/dist/purchase_account/.kosh/schema.d.ts +1209 -16
  489. package/dist/purchase_account/i18n/bn.d.ts +2 -0
  490. package/dist/purchase_account/i18n/bn.js +22 -0
  491. package/dist/purchase_account/index.js +20 -0
  492. package/dist/purchase_account/module.d.ts +12232 -2028
  493. package/dist/purchase_account/module.js +252 -9
  494. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  495. package/dist/purchase_portal/.kosh/schema.d.ts +908 -5
  496. package/dist/purchase_portal/i18n/bn.d.ts +2 -0
  497. package/dist/purchase_portal/i18n/bn.js +5 -0
  498. package/dist/purchase_portal/index.js +2 -0
  499. package/dist/purchase_portal/module.d.ts +6853 -352
  500. package/dist/purchase_stock/.kosh/bindings.js +1 -1
  501. package/dist/purchase_stock/.kosh/schema.d.ts +1096 -21
  502. package/dist/purchase_stock/i18n/bn.d.ts +2 -0
  503. package/dist/purchase_stock/i18n/bn.js +19 -0
  504. package/dist/purchase_stock/index.d.ts +2 -2
  505. package/dist/purchase_stock/index.js +38 -2
  506. package/dist/purchase_stock/module.d.ts +12930 -1612
  507. package/dist/purchase_stock/module.js +317 -9
  508. package/dist/purchase_stock/scorecard.d.ts +22 -0
  509. package/dist/purchase_stock/scorecard.js +77 -0
  510. package/dist/purchase_stock/web/Scorecard.d.ts +7 -0
  511. package/dist/purchase_stock/web/Scorecard.js +22 -0
  512. package/dist/purchase_stock/web/index.d.ts +11 -0
  513. package/dist/purchase_stock/web/index.js +16 -0
  514. package/dist/purchase_stock/web/messages.d.ts +2 -0
  515. package/dist/purchase_stock/web/messages.js +27 -0
  516. package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
  517. package/dist/purchase_stock_account/.kosh/schema.d.ts +1444 -20
  518. package/dist/purchase_stock_account/i18n/bn.d.ts +2 -0
  519. package/dist/purchase_stock_account/i18n/bn.js +8 -0
  520. package/dist/purchase_stock_account/index.js +18 -0
  521. package/dist/purchase_stock_account/module.d.ts +7 -35346
  522. package/dist/purchase_stock_account/module.js +35 -8
  523. package/dist/recruitment/.kosh/bindings.js +1 -1
  524. package/dist/recruitment/.kosh/schema.d.ts +60 -1
  525. package/dist/recruitment/i18n/bn.d.ts +2 -0
  526. package/dist/recruitment/i18n/bn.js +93 -0
  527. package/dist/recruitment/index.js +64 -0
  528. package/dist/recruitment/module.d.ts +460 -8
  529. package/dist/recruitment/module.js +13 -4
  530. package/dist/reporting/documents.d.ts +5 -0
  531. package/dist/reporting/documents.js +11 -1
  532. package/dist/reporting/index.d.ts +1 -1
  533. package/dist/reporting/index.js +1 -1
  534. package/dist/reporting/web/CalendarView.d.ts +18 -5
  535. package/dist/reporting/web/CalendarView.js +163 -29
  536. package/dist/reporting/web/messages.js +18 -0
  537. package/dist/sale_account/.kosh/bindings.js +1 -1
  538. package/dist/sale_account/.kosh/schema.d.ts +763 -18
  539. package/dist/sale_account/i18n/bn.d.ts +2 -0
  540. package/dist/sale_account/i18n/bn.js +48 -0
  541. package/dist/sale_account/index.d.ts +1 -1
  542. package/dist/sale_account/index.js +102 -4
  543. package/dist/sale_account/module.d.ts +8241 -2052
  544. package/dist/sale_account/module.js +535 -46
  545. package/dist/sale_crm/.kosh/bindings.d.ts +22 -0
  546. package/dist/sale_crm/.kosh/bindings.js +15 -0
  547. package/dist/{mrp → sale_crm}/.kosh/schema.d.ts +391 -494
  548. package/dist/sale_crm/i18n/bn.d.ts +2 -0
  549. package/dist/sale_crm/i18n/bn.js +9 -0
  550. package/dist/sale_crm/index.d.ts +7 -0
  551. package/dist/sale_crm/index.js +104 -0
  552. package/dist/sale_crm/module.d.ts +5609 -0
  553. package/dist/sale_crm/module.js +73 -0
  554. package/dist/sale_portal/.kosh/bindings.js +1 -1
  555. package/dist/sale_portal/.kosh/schema.d.ts +292 -4
  556. package/dist/sale_portal/i18n/bn.d.ts +2 -0
  557. package/dist/sale_portal/i18n/bn.js +7 -0
  558. package/dist/sale_portal/index.js +10 -0
  559. package/dist/sale_portal/module.d.ts +2563 -292
  560. package/dist/sale_project/.kosh/bindings.js +1 -1
  561. package/dist/sale_project/.kosh/schema.d.ts +1025 -4
  562. package/dist/sale_project/i18n/bn.d.ts +2 -0
  563. package/dist/sale_project/i18n/bn.js +12 -0
  564. package/dist/sale_project/index.js +2 -0
  565. package/dist/sale_project/module.d.ts +9280 -762
  566. package/dist/sale_project/module.js +17 -1
  567. package/dist/sale_stock/.kosh/bindings.js +1 -1
  568. package/dist/sale_stock/.kosh/schema.d.ts +463 -6
  569. package/dist/sale_stock/i18n/bn.d.ts +2 -0
  570. package/dist/sale_stock/i18n/bn.js +15 -0
  571. package/dist/sale_stock/index.js +2 -0
  572. package/dist/sale_stock/module.d.ts +8355 -1334
  573. package/dist/sale_stock/module.js +20 -3
  574. package/dist/sales/.kosh/bindings.js +1 -1
  575. package/dist/sales/.kosh/schema.d.ts +292 -4
  576. package/dist/sales/i18n/bn.d.ts +2 -0
  577. package/dist/sales/i18n/bn.js +128 -0
  578. package/dist/sales/index.js +124 -5
  579. package/dist/sales/module.d.ts +3568 -633
  580. package/dist/sales/module.js +306 -11
  581. package/dist/server/api/duplicate.d.ts +14 -0
  582. package/dist/server/api/duplicate.js +75 -0
  583. package/dist/server/api/explain.d.ts +70 -0
  584. package/dist/server/api/explain.js +111 -0
  585. package/dist/server/api/metadata.d.ts +2 -0
  586. package/dist/server/api/metadata.js +9 -0
  587. package/dist/server/api/openapi.js +15 -0
  588. package/dist/server/api/rest.d.ts +1 -0
  589. package/dist/server/api/rest.js +76 -12
  590. package/dist/server/api/views.js +1 -1
  591. package/dist/server/apps.d.ts +16 -1
  592. package/dist/server/apps.js +164 -2
  593. package/dist/server/auth/base.js +2 -0
  594. package/dist/server/auth/service.d.ts +8 -0
  595. package/dist/server/auth/service.js +19 -0
  596. package/dist/server/events.d.ts +13 -0
  597. package/dist/server/events.js +22 -0
  598. package/dist/server/i18n.d.ts +27 -0
  599. package/dist/server/i18n.js +143 -0
  600. package/dist/server/index.d.ts +2 -0
  601. package/dist/server/index.js +2 -0
  602. package/dist/server/server.js +6 -0
  603. package/dist/settings/company.d.ts +3 -1
  604. package/dist/settings/company.js +26 -5
  605. package/dist/settings/routes.d.ts +10 -0
  606. package/dist/settings/routes.js +19 -3
  607. package/dist/settings/web/AppsPage.d.ts +3 -2
  608. package/dist/settings/web/AppsPage.js +26 -8
  609. package/dist/settings/web/CompaniesPage.js +91 -6
  610. package/dist/settings/web/messages.js +64 -0
  611. package/dist/sign/.kosh/bindings.d.ts +22 -0
  612. package/dist/{mrp → sign}/.kosh/bindings.js +2 -2
  613. package/dist/sign/.kosh/schema.d.ts +991 -0
  614. package/dist/sign/i18n/bn.d.ts +2 -0
  615. package/dist/sign/i18n/bn.js +97 -0
  616. package/dist/sign/index.d.ts +29 -0
  617. package/dist/sign/index.js +478 -0
  618. package/dist/sign/module.d.ts +4518 -0
  619. package/dist/sign/module.js +167 -0
  620. package/dist/sign/sign.d.ts +82 -0
  621. package/dist/sign/sign.js +474 -0
  622. package/dist/stock/.kosh/bindings.js +1 -1
  623. package/dist/stock/.kosh/schema.d.ts +374 -3
  624. package/dist/stock/demo.d.ts +2 -1
  625. package/dist/stock/demo.js +28 -1
  626. package/dist/stock/i18n/bn.d.ts +2 -0
  627. package/dist/stock/i18n/bn.js +311 -0
  628. package/dist/stock/index.d.ts +4 -1
  629. package/dist/stock/index.js +674 -6
  630. package/dist/stock/ledger.d.ts +78 -0
  631. package/dist/stock/ledger.js +582 -0
  632. package/dist/stock/module.d.ts +6142 -1380
  633. package/dist/stock/module.js +780 -26
  634. package/dist/stock/replenish.d.ts +38 -0
  635. package/dist/stock/replenish.js +191 -0
  636. package/dist/stock/returns.d.ts +157 -0
  637. package/dist/stock/returns.js +163 -0
  638. package/dist/stock/web/Ledger.d.ts +9 -0
  639. package/dist/stock/web/Ledger.js +108 -0
  640. package/dist/stock/web/Operations.d.ts +8 -0
  641. package/dist/stock/web/Operations.js +33 -0
  642. package/dist/stock/web/Replenishment.d.ts +8 -0
  643. package/dist/stock/web/Replenishment.js +84 -0
  644. package/dist/stock/web/ReturnButton.d.ts +7 -0
  645. package/dist/stock/web/ReturnButton.js +62 -0
  646. package/dist/stock/web/index.d.ts +7 -2
  647. package/dist/stock/web/index.js +15 -2
  648. package/dist/stock/web/messages.js +206 -0
  649. package/dist/stock_account/.kosh/bindings.js +1 -1
  650. package/dist/stock_account/.kosh/schema.d.ts +878 -12
  651. package/dist/stock_account/i18n/bn.d.ts +2 -0
  652. package/dist/stock_account/i18n/bn.js +73 -0
  653. package/dist/stock_account/index.d.ts +1 -0
  654. package/dist/stock_account/index.js +141 -3
  655. package/dist/stock_account/landed.d.ts +429 -0
  656. package/dist/stock_account/landed.js +335 -0
  657. package/dist/stock_account/module.d.ts +12143 -3391
  658. package/dist/stock_account/module.js +135 -6
  659. package/dist/stock_account/web/LandedPreview.d.ts +7 -0
  660. package/dist/stock_account/web/LandedPreview.js +23 -0
  661. package/dist/stock_account/web/index.d.ts +11 -0
  662. package/dist/stock_account/web/index.js +16 -0
  663. package/dist/stock_account/web/messages.d.ts +2 -0
  664. package/dist/stock_account/web/messages.js +27 -0
  665. package/dist/todo/i18n/bn.d.ts +2 -0
  666. package/dist/todo/i18n/bn.js +66 -0
  667. package/dist/todo/index.js +59 -0
  668. package/dist/todo/module.d.ts +5 -0
  669. package/dist/todo/module.js +5 -3
  670. package/dist/trade_finance/.kosh/bindings.js +1 -1
  671. package/dist/trade_finance/.kosh/schema.d.ts +2 -1
  672. package/dist/trade_finance/i18n/bn.d.ts +2 -0
  673. package/dist/trade_finance/i18n/bn.js +162 -0
  674. package/dist/trade_finance/index.js +95 -0
  675. package/dist/trade_finance/module.d.ts +26 -0
  676. package/dist/trade_finance/module.js +29 -8
  677. package/dist/trade_finance_account/.kosh/bindings.js +1 -1
  678. package/dist/trade_finance_account/.kosh/schema.d.ts +651 -10
  679. package/dist/trade_finance_account/i18n/bn.d.ts +2 -0
  680. package/dist/trade_finance_account/i18n/bn.js +27 -0
  681. package/dist/trade_finance_account/index.js +3 -0
  682. package/dist/trade_finance_account/module.d.ts +5129 -1509
  683. package/dist/trade_finance_account/module.js +2 -0
  684. package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
  685. package/dist/trade_finance_purchase/.kosh/schema.d.ts +908 -5
  686. package/dist/trade_finance_purchase/i18n/bn.d.ts +2 -0
  687. package/dist/trade_finance_purchase/i18n/bn.js +6 -0
  688. package/dist/trade_finance_purchase/index.js +2 -0
  689. package/dist/trade_finance_purchase/module.d.ts +6909 -408
  690. package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
  691. package/dist/trade_finance_sale/.kosh/schema.d.ts +292 -4
  692. package/dist/trade_finance_sale/i18n/bn.d.ts +2 -0
  693. package/dist/trade_finance_sale/i18n/bn.js +6 -0
  694. package/dist/trade_finance_sale/index.js +2 -0
  695. package/dist/trade_finance_sale/module.d.ts +2602 -331
  696. package/dist/ui/api.d.ts +2 -0
  697. package/dist/ui/app.d.ts +9 -0
  698. package/dist/ui/app.js +47 -15
  699. package/dist/ui/components/AppIcon.js +9 -2
  700. package/dist/ui/components/Explain.d.ts +69 -0
  701. package/dist/ui/components/Explain.js +62 -0
  702. package/dist/ui/context.d.ts +8 -1
  703. package/dist/ui/context.js +34 -1
  704. package/dist/ui/i18n/messages.d.ts +40 -0
  705. package/dist/ui/i18n/messages.js +80 -0
  706. package/dist/ui/index.d.ts +2 -1
  707. package/dist/ui/index.js +1 -0
  708. package/dist/ui/registry.d.ts +14 -0
  709. package/dist/ui/registry.js +10 -0
  710. package/dist/ui/views/FormView.d.ts +6 -0
  711. package/dist/ui/views/FormView.js +51 -12
  712. package/dist/ui/views/KanbanView.js +9 -1
  713. package/dist/ui/views/ListView.d.ts +8 -0
  714. package/dist/ui/views/ListView.js +14 -5
  715. package/dist/ui/views/StatsRow.js +2 -1
  716. package/dist/ui/views/widgets.js +7 -1
  717. package/dist/views/extend.js +12 -0
  718. package/dist/views/types.d.ts +13 -2
  719. package/dist/views/validate.js +8 -1
  720. package/dist/website/.kosh/bindings.js +1 -1
  721. package/dist/website/.kosh/schema.d.ts +2 -1
  722. package/dist/website/i18n/bn.d.ts +2 -0
  723. package/dist/website/i18n/bn.js +113 -0
  724. package/dist/website/index.js +37 -0
  725. package/dist/website/module.d.ts +20 -0
  726. package/dist/website/module.js +30 -5
  727. package/dist/website_crm/.kosh/bindings.js +1 -1
  728. package/dist/website_crm/.kosh/schema.d.ts +3 -1
  729. package/dist/website_crm/i18n/bn.d.ts +2 -0
  730. package/dist/website_crm/i18n/bn.js +5 -0
  731. package/dist/website_crm/index.js +2 -0
  732. package/dist/website_crm/module.d.ts +41 -0
  733. package/dist/website_sale/.kosh/bindings.d.ts +22 -0
  734. package/dist/website_sale/.kosh/bindings.js +15 -0
  735. package/dist/website_sale/.kosh/schema.d.ts +2909 -0
  736. package/dist/website_sale/couriers.d.ts +50 -0
  737. package/dist/website_sale/couriers.js +59 -0
  738. package/dist/website_sale/demo.d.ts +7 -0
  739. package/dist/website_sale/demo.js +90 -0
  740. package/dist/website_sale/growth.d.ts +31 -0
  741. package/dist/website_sale/growth.js +163 -0
  742. package/dist/website_sale/i18n/bn.d.ts +2 -0
  743. package/dist/website_sale/i18n/bn.js +132 -0
  744. package/dist/website_sale/index.d.ts +49 -0
  745. package/dist/website_sale/index.js +620 -0
  746. package/dist/website_sale/module.d.ts +35182 -0
  747. package/dist/website_sale/module.js +419 -0
  748. package/dist/website_sale/shipments.d.ts +16 -0
  749. package/dist/website_sale/shipments.js +113 -0
  750. package/dist/website_sale/shop.d.ts +81 -0
  751. package/dist/website_sale/shop.js +662 -0
  752. package/dist/website_sale_stock/.kosh/bindings.d.ts +22 -0
  753. package/dist/website_sale_stock/.kosh/bindings.js +15 -0
  754. package/dist/website_sale_stock/.kosh/schema.d.ts +3400 -0
  755. package/dist/website_sale_stock/i18n/bn.d.ts +2 -0
  756. package/dist/website_sale_stock/i18n/bn.js +4 -0
  757. package/dist/website_sale_stock/index.d.ts +9 -0
  758. package/dist/website_sale_stock/index.js +22 -0
  759. package/dist/website_sale_stock/module.d.ts +11 -0
  760. package/dist/website_sale_stock/module.js +32 -0
  761. package/package.json +117 -8
  762. package/dist/mrp/index.d.ts +0 -3
  763. package/dist/mrp/index.js +0 -392
  764. package/dist/mrp/module.js +0 -695
  765. package/dist/mrp_account/index.d.ts +0 -3
  766. package/dist/mrp_account/index.js +0 -22
  767. /package/dist/{mrp → account_asset}/.kosh/bindings.d.ts +0 -0
  768. /package/dist/{mrp_account → account_budget}/.kosh/bindings.d.ts +0 -0
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Attendance's routes (RFC 0024 §2.2):
3
+ *
4
+ * - `GET /api/v1/attendance/me` the user's employee, whether checked in and since when, today's day
5
+ * - `POST /api/v1/attendance/punch` `{ latitude?, longitude? }`: the user checks in or out from the
6
+ * phone — inside a site's radius where its geofence is on
7
+ * - `GET /api/v1/attendance/kiosk/people` kiosks: the people who check in there (names only)
8
+ * - `POST /api/v1/attendance/kiosk/punch` kiosks: `{ badge }` or `{ employee, pin }`; five wrong PINs lock
9
+ * the person at the kiosks for 15 minutes
10
+ * - `POST /api/v1/attendance/employees/:id/pin` managers: `{ pin }` (4 to 8 digits), stored hashed
11
+ * - `POST /api/v1/attendance/import` managers: `{ format: 'zkteco' | 'csv', content }`
12
+ * - `POST /api/v1/attendance/days/compute` managers: `{ from, to, employees? }`
13
+ * - `GET /api/v1/attendance/formats` the device file formats
14
+ */
15
+ import { audit, HttpProblem, hashPassword, verifyPassword } from '../server/index.js';
16
+ import { orm } from '../server/orm.js';
17
+ import { DEVICE_FORMATS, distanceMetres, importPunches, localDate, punch, recomputeDays, timeZoneOf, } from './days.js';
18
+ const DATE = /^\d{4}-\d{2}-\d{2}$/;
19
+ const LOCK_AFTER = 5;
20
+ const LOCK_MS = 15 * 60_000;
21
+ /** Wrong PINs per employee at the kiosks of this node: `{ count, until }`. */
22
+ const failures = new Map();
23
+ const isManager = (env) => env.administrator || env.groups.has('attendance.manager');
24
+ const asProblem = (error) => {
25
+ if (error instanceof orm.ValidationError)
26
+ throw new HttpProblem(422, 'invalid', 'Not possible', error.message);
27
+ throw error;
28
+ };
29
+ export function registerAttendanceRoutes({ app }) {
30
+ const managers = (env) => {
31
+ if (!isManager(env))
32
+ throw new HttpProblem(403, 'access', 'Attendance managers', 'This needs the Attendance manager role.');
33
+ };
34
+ /** The user's own employee. @throws {HttpProblem} 404 without one */
35
+ const ownEmployee = async (su, uid) => {
36
+ const [e] = await (await su.model('hr.employee').search({ where: { user: uid }, limit: 1 })).load({ company: true });
37
+ if (e === undefined)
38
+ throw new HttpProblem(404, 'no-employee', 'Not an employee', 'Ask HR to add you as an employee.');
39
+ return e;
40
+ };
41
+ app.get('/api/v1/attendance/me', async (request) => request.env(async (raw) => {
42
+ const env = raw;
43
+ return env.asSuperuser({ reason: 'own attendance' }, async (su) => {
44
+ const e = await ownEmployee(su, env.uid);
45
+ const [open] = await (await su
46
+ .model('attendance.record')
47
+ .search({ where: { employee: e.id, checkOut: { isNull: true } }, limit: 1 })).load(['checkIn']);
48
+ const tz = await timeZoneOf(su);
49
+ const [today] = await (await su
50
+ .model('attendance.day')
51
+ .search({ where: { employee: e.id, date: localDate(new Date(), tz) }, limit: 1 })).load(['status', 'workedHours', 'lateMinutes', 'overtimeHours']);
52
+ return {
53
+ employee: { id: e.id, name: e.name },
54
+ checkedInSince: open === undefined ? null : open.checkIn.toISOString(),
55
+ today: today === undefined
56
+ ? null
57
+ : {
58
+ status: today.status,
59
+ workedHours: today.workedHours.toString(),
60
+ lateMinutes: today.lateMinutes,
61
+ overtimeHours: today.overtimeHours.toString(),
62
+ },
63
+ };
64
+ });
65
+ }, { write: true }));
66
+ app.post('/api/v1/attendance/punch', async (request) => {
67
+ const body = (request.body ?? {});
68
+ const lat = typeof body['latitude'] === 'number' ? body['latitude'] : null;
69
+ const lon = typeof body['longitude'] === 'number' ? body['longitude'] : null;
70
+ if ((lat === null) !== (lon === null) ||
71
+ (lat !== null && (Math.abs(lat) > 90 || Math.abs(lon) > 180)))
72
+ throw new HttpProblem(422, 'invalid-location', 'Invalid location', 'Send latitude and longitude together.');
73
+ return request.env(async (raw) => {
74
+ const env = raw;
75
+ if (!env.administrator && !env.groups.has('attendance.user'))
76
+ throw new HttpProblem(403, 'access', 'Attendance', 'This needs access to Attendance.');
77
+ return env.asSuperuser({ reason: 'check in from the phone' }, async (su) => {
78
+ const e = await ownEmployee(su, env.uid);
79
+ // The nearest site with coordinates; its geofence decides.
80
+ const sites = [
81
+ ...(await (await su.model('attendance.site').search({
82
+ where: { company: e.company.id, latitude: { isNull: false } },
83
+ })).load(['latitude', 'longitude', 'radius', 'geofence', 'name'])),
84
+ ];
85
+ let site = null;
86
+ let inside = null;
87
+ let distance = null;
88
+ if (sites.length > 0) {
89
+ const fenced = sites.some((s) => s.geofence);
90
+ if (lat === null || lon === null) {
91
+ if (fenced)
92
+ throw new HttpProblem(422, 'location-needed', 'Location needed', 'Allow the location so the check-in is on site.');
93
+ }
94
+ else {
95
+ const measured = sites
96
+ .map((s) => ({
97
+ s,
98
+ d: distanceMetres({ lat, lon }, { lat: Number(s.latitude), lon: Number(s.longitude) }),
99
+ }))
100
+ .sort((a, b) => a.d - b.d);
101
+ const nearest = measured[0];
102
+ site = nearest.s.id;
103
+ distance = nearest.d;
104
+ inside = nearest.d <= nearest.s.radius;
105
+ if (!inside && nearest.s.geofence)
106
+ throw new HttpProblem(422, 'outside-site', 'Not on site', `You are ${nearest.d} m from ${nearest.s.name}; check in within ${nearest.s.radius} m.`);
107
+ }
108
+ }
109
+ const out = await punch(su, e.id, new Date(), {
110
+ source: 'phone',
111
+ site,
112
+ inside,
113
+ distance,
114
+ }).catch(asProblem);
115
+ return out;
116
+ });
117
+ }, { write: true });
118
+ });
119
+ app.get('/api/v1/attendance/kiosk/people', async (request) => request.env(async (raw) => {
120
+ const env = raw;
121
+ if (!env.administrator && !env.groups.has('attendance.kiosk') && !isManager(env))
122
+ throw new HttpProblem(403, 'access', 'Kiosk', 'This needs the kiosk role.');
123
+ return env.asSuperuser({ reason: 'kiosk people' }, async (su) => ({
124
+ people: [
125
+ ...(await (await su.model('hr.employee').search({
126
+ where: { company: env.companyId, attendancePin: { isNull: false } },
127
+ })).load(['name'])),
128
+ ]
129
+ .map((e) => ({ id: e.id, name: e.name }))
130
+ .sort((a, b) => a.name.localeCompare(b.name)),
131
+ }));
132
+ }, { write: true }));
133
+ app.post('/api/v1/attendance/kiosk/punch', async (request) => {
134
+ const body = (request.body ?? {});
135
+ const badge = typeof body['badge'] === 'string' ? body['badge'].trim() : '';
136
+ const pin = typeof body['pin'] === 'string' ? body['pin'] : '';
137
+ const employee = Number(body['employee']);
138
+ const site = body['site'] === undefined || body['site'] === null ? null : Number(body['site']);
139
+ if (badge === '' && (!Number.isSafeInteger(employee) || pin === ''))
140
+ throw new HttpProblem(422, 'who', 'Who is it?', 'Scan the badge, or choose your name and type your PIN.');
141
+ return request.env(async (raw) => {
142
+ const env = raw;
143
+ if (!env.administrator && !env.groups.has('attendance.kiosk') && !isManager(env))
144
+ throw new HttpProblem(403, 'access', 'Kiosk', 'This needs the kiosk role.');
145
+ return env.asSuperuser({ reason: 'kiosk check-in' }, async (su) => {
146
+ let who;
147
+ if (badge !== '') {
148
+ const [e] = await (await su.model('hr.employee').search({
149
+ where: { attendanceBadge: badge, company: env.companyId },
150
+ limit: 1,
151
+ })).load(['name']);
152
+ if (e === undefined)
153
+ throw new HttpProblem(404, 'unknown-badge', 'Unknown badge', 'This badge belongs to nobody here.');
154
+ who = { id: e.id, name: e.name };
155
+ }
156
+ else {
157
+ const lock = failures.get(employee);
158
+ if (lock !== undefined && lock.until > Date.now())
159
+ throw new HttpProblem(429, 'locked', 'Locked', 'Too many wrong PINs: try again in 15 minutes.');
160
+ const [e] = await (await su.model('hr.employee').search({
161
+ where: { id: employee, company: env.companyId },
162
+ limit: 1,
163
+ })).load(['name', 'attendancePin']);
164
+ const ok = e?.attendancePin != null && (await verifyPassword(pin, e.attendancePin));
165
+ if (e === undefined || !ok) {
166
+ const count = (lock?.until ?? 0) > Date.now() ? 0 : (lock?.count ?? 0) + 1;
167
+ failures.set(employee, {
168
+ count: count >= LOCK_AFTER ? 0 : count,
169
+ until: count >= LOCK_AFTER ? Date.now() + LOCK_MS : 0,
170
+ });
171
+ await audit(env, {
172
+ kind: 'attendance.kiosk_pin_failed',
173
+ summary: `A wrong kiosk PIN for employee ${employee}.`,
174
+ targetModel: 'hr.employee',
175
+ targetId: employee,
176
+ ip: request.ip,
177
+ });
178
+ throw new HttpProblem(401, 'wrong-pin', 'Wrong PIN', 'The PIN does not match.');
179
+ }
180
+ failures.delete(employee);
181
+ who = { id: e.id, name: e.name };
182
+ }
183
+ const out = await punch(su, who.id, new Date(), { source: 'kiosk', site }).catch(asProblem);
184
+ return { ...out, employee: who };
185
+ });
186
+ }, { write: true });
187
+ });
188
+ app.post('/api/v1/attendance/employees/:id/pin', async (request) => {
189
+ const id = Number(request.params.id);
190
+ const pin = request.body?.['pin'];
191
+ if (typeof pin !== 'string' || !/^\d{4,8}$/.test(pin))
192
+ throw new HttpProblem(422, 'invalid-pin', 'Invalid PIN', 'A PIN is 4 to 8 digits.');
193
+ return request.env(async (raw) => {
194
+ const env = raw;
195
+ managers(env);
196
+ const hashed = await hashPassword(pin);
197
+ return env.asSuperuser({ reason: 'kiosk PIN' }, async (su) => {
198
+ const found = await su
199
+ .model('hr.employee')
200
+ .search({ where: { id: id }, limit: 1 });
201
+ if (found.length === 0)
202
+ throw new HttpProblem(404, 'missing-record', 'Not found', `There is no employee ${id}.`);
203
+ await found.write({ attendancePin: hashed });
204
+ await audit(env, {
205
+ kind: 'attendance.pin_set',
206
+ summary: `Kiosk PIN set for employee ${id}.`,
207
+ targetModel: 'hr.employee',
208
+ targetId: id,
209
+ ip: request.ip,
210
+ });
211
+ await su.flush();
212
+ return { id, pin: true };
213
+ });
214
+ }, { write: true });
215
+ });
216
+ app.get('/api/v1/attendance/formats', async () => ({
217
+ formats: DEVICE_FORMATS.map((f) => ({ key: f.key, label: f.label })),
218
+ }));
219
+ app.post('/api/v1/attendance/import', async (request) => {
220
+ const body = (request.body ?? {});
221
+ const format = DEVICE_FORMATS.find((f) => f.key === body['format']);
222
+ const content = body['content'];
223
+ if (format === undefined || typeof content !== 'string' || content.length > 5_000_000)
224
+ throw new HttpProblem(422, 'invalid-file', 'Invalid file', `Give the format (${DEVICE_FORMATS.map((f) => f.key).join(', ')}) and the file's text.`);
225
+ const punches = format.parse(content);
226
+ return request.env(async (raw) => {
227
+ const env = raw;
228
+ managers(env);
229
+ return env.asSuperuser({ reason: 'device import' }, async (su) => {
230
+ const result = await importPunches(su, punches).catch(asProblem);
231
+ await audit(env, {
232
+ kind: 'attendance.imported',
233
+ summary: `${result.imported} punches imported from a ${format.label} file.`,
234
+ details: { ...result },
235
+ ip: request.ip,
236
+ });
237
+ return { read: punches.length, ...result };
238
+ });
239
+ }, { write: true });
240
+ });
241
+ app.post('/api/v1/attendance/days/compute', async (request) => {
242
+ const body = (request.body ?? {});
243
+ const from = body['from'];
244
+ const to = body['to'];
245
+ if (typeof from !== 'string' ||
246
+ typeof to !== 'string' ||
247
+ !DATE.test(from) ||
248
+ !DATE.test(to) ||
249
+ to < from)
250
+ throw new HttpProblem(422, 'invalid-dates', 'Invalid dates', 'Give from and to as YYYY-MM-DD, in order.');
251
+ if (Date.parse(to) - Date.parse(from) > 92 * 86_400_000)
252
+ throw new HttpProblem(422, 'too-long', 'Too long', 'Compute at most three months at a time.');
253
+ return request.env(async (raw) => {
254
+ const env = raw;
255
+ managers(env);
256
+ return env.asSuperuser({ reason: 'attendance days' }, async (su) => {
257
+ const ids = Array.isArray(body['employees'])
258
+ ? body['employees'].map(Number)
259
+ : (await su.model('hr.employee').search({ where: { company: env.companyId } })).ids.map(Number);
260
+ const written = await recomputeDays(su, ids, from, to);
261
+ await su.flush();
262
+ return { written };
263
+ });
264
+ }, { write: true });
265
+ });
266
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Check in from the phone (RFC 0024 §2.2): one large button that checks in, or out when checked in. The phone's
3
+ * location goes with it when the browser gives it; the server decides whether it is on site (the site's geofence)
4
+ * and keeps only inside or outside and the distance. Today's worked hours and lateness under it.
5
+ */
6
+ import { type PageProps } from '../../ui/index.js';
7
+ import type { ReactElement } from 'react';
8
+ export declare function Check({ api }: PageProps): ReactElement;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Check in from the phone (RFC 0024 §2.2): one large button that checks in, or out when checked in. The phone's
4
+ * location goes with it when the browser gives it; the server decides whether it is on site (the site's geofence)
5
+ * and keeps only inside or outside and the distance. Today's worked hours and lateness under it.
6
+ */
7
+ import { Alert, Button, Spinner, useKosh } from '../../ui/index.js';
8
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
9
+ import { useTranslation } from 'react-i18next';
10
+ /** The phone's position, or nothing when the browser has none or it is refused (the server then decides). */
11
+ function position() {
12
+ if (typeof navigator === 'undefined' || navigator.geolocation === undefined)
13
+ return Promise.resolve(null);
14
+ return new Promise((resolve) => navigator.geolocation.getCurrentPosition((p) => resolve({ latitude: p.coords.latitude, longitude: p.coords.longitude }), () => resolve(null), { enableHighAccuracy: true, timeout: 10_000, maximumAge: 30_000 }));
15
+ }
16
+ export function Check({ api }) {
17
+ const { t } = useTranslation('attendance');
18
+ const { format } = useKosh();
19
+ const queryClient = useQueryClient();
20
+ const me = useQuery({
21
+ queryKey: ['attendance', 'me'],
22
+ queryFn: () => api.call('GET', '/api/v1/attendance/me'),
23
+ retry: false,
24
+ });
25
+ const tap = useMutation({
26
+ mutationFn: async () => {
27
+ const where = await position();
28
+ return api.call('POST', '/api/v1/attendance/punch', where ?? {});
29
+ },
30
+ onSuccess: () => void queryClient.invalidateQueries({ queryKey: ['attendance', 'me'] }),
31
+ });
32
+ if (me.isPending)
33
+ return _jsx(Spinner, { label: t('loading') });
34
+ if (me.error !== null)
35
+ return _jsx(Alert, { tone: "danger", children: me.error.message });
36
+ const since = me.data.checkedInSince;
37
+ return (_jsxs("div", { className: "mx-auto grid max-w-md gap-6 p-4 text-center", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: me.data.employee.name }), _jsx("p", { role: "status", className: "text-sm text-muted-foreground", children: since === null ? t('notIn') : t('inSince', { time: format.datetime(since) }) })] }), _jsx(Button, { variant: "primary", className: "h-32 text-2xl", busy: tap.isPending, onClick: () => tap.mutate(), children: since === null ? t('checkIn') : t('checkOut') }), tap.error === null ? null : _jsx(Alert, { tone: "danger", children: tap.error.message }), tap.data === undefined ? null : (_jsx("p", { className: "text-sm", children: t(tap.data.action === 'in' ? 'doneIn' : 'doneOut', {
38
+ time: format.datetime(tap.data.at),
39
+ }) })), me.data.today === null ? null : (_jsxs("dl", { className: "grid grid-cols-3 gap-2 rounded-lg border p-3 text-sm", children: [_jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground", children: t('worked') }), _jsx("dd", { className: "font-semibold tabular-nums", children: me.data.today.workedHours })] }), _jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground", children: t('late') }), _jsx("dd", { className: "font-semibold tabular-nums", children: me.data.today.lateMinutes })] }), _jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground", children: t('overtime') }), _jsx("dd", { className: "font-semibold tabular-nums", children: me.data.today.overtimeHours })] })] })), _jsx("p", { className: "text-xs text-muted-foreground", children: t('locationNote') })] }));
40
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The kiosk (RFC 0024 §2.2): a tablet at the gate, signed in with the kiosk role. A badge scanned into the box (a
3
+ * scanner types its code and Enter), or a name chosen and a PIN typed on the pad, checks the person in or out;
4
+ * the screen greets them and clears itself after a few seconds. Five wrong PINs lock the person for 15 minutes.
5
+ */
6
+ import { type PageProps } from '../../ui/index.js';
7
+ import { type ReactElement } from 'react';
8
+ export declare function Kiosk({ api }: PageProps): ReactElement;
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The kiosk (RFC 0024 §2.2): a tablet at the gate, signed in with the kiosk role. A badge scanned into the box (a
4
+ * scanner types its code and Enter), or a name chosen and a PIN typed on the pad, checks the person in or out;
5
+ * the screen greets them and clears itself after a few seconds. Five wrong PINs lock the person for 15 minutes.
6
+ */
7
+ import { Alert, Button, Input } from '../../ui/index.js';
8
+ import { useMutation, useQuery } from '@tanstack/react-query';
9
+ import { useEffect, useRef, useState } from 'react';
10
+ import { useTranslation } from 'react-i18next';
11
+ const KEYS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '⌫', '0', '✓'];
12
+ export function Kiosk({ api }) {
13
+ const { t } = useTranslation('attendance');
14
+ const people = useQuery({
15
+ queryKey: ['attendance', 'kiosk', 'people'],
16
+ queryFn: () => api
17
+ .call('GET', '/api/v1/attendance/kiosk/people')
18
+ .then((r) => r.people),
19
+ });
20
+ const [badge, setBadge] = useState('');
21
+ const [person, setPerson] = useState(null);
22
+ const [pin, setPin] = useState('');
23
+ const box = useRef(null);
24
+ const punch = useMutation({
25
+ mutationFn: (body) => api.call('POST', '/api/v1/attendance/kiosk/punch', body),
26
+ onSettled: () => {
27
+ setBadge('');
28
+ setPin('');
29
+ setPerson(null);
30
+ },
31
+ });
32
+ // The greeting clears itself; the badge box keeps the focus for the next scan.
33
+ useEffect(() => {
34
+ if (punch.data === undefined && punch.error === null)
35
+ return;
36
+ const timer = window.setTimeout(() => {
37
+ punch.reset();
38
+ box.current?.focus();
39
+ }, 4000);
40
+ return () => window.clearTimeout(timer);
41
+ }, [punch]);
42
+ const press = (key) => {
43
+ if (key === '⌫')
44
+ setPin((p) => p.slice(0, -1));
45
+ else if (key === '✓') {
46
+ if (person !== null && pin.length >= 4)
47
+ punch.mutate({ employee: person.id, pin });
48
+ }
49
+ else if (pin.length < 8)
50
+ setPin((p) => p + key);
51
+ };
52
+ return (_jsxs("div", { className: "mx-auto grid max-w-2xl gap-6 p-4", children: [_jsx("h1", { className: "text-center text-2xl font-semibold", children: t('kioskTitle') }), punch.data === undefined ? null : (_jsx("p", { role: "status", className: "rounded-lg bg-success/10 p-6 text-center text-xl font-semibold", children: t(punch.data.action === 'in' ? 'welcome' : 'goodbye', {
53
+ name: punch.data.employee.name,
54
+ }) })), punch.error === null ? null : _jsx(Alert, { tone: "danger", children: punch.error.message }), _jsx("form", { onSubmit: (e) => {
55
+ e.preventDefault();
56
+ if (badge.trim() !== '')
57
+ punch.mutate({ badge: badge.trim() });
58
+ }, children: _jsx(Input, { ref: box, autoFocus: true, "aria-label": t('badge'), placeholder: t('badgeHint'), value: badge, onChange: (e) => setBadge(e.target.value), className: "h-12 text-center text-lg" }) }), _jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsx("nav", { "aria-label": t('people'), className: "max-h-80 overflow-y-auto rounded-lg border", children: _jsx("ul", { children: (people.data ?? []).map((p) => (_jsx("li", { children: _jsx("button", { type: "button", "aria-pressed": person?.id === p.id, onClick: () => {
59
+ setPerson(p);
60
+ setPin('');
61
+ }, className: `w-full px-3 py-2 text-start hover:bg-muted ${person?.id === p.id ? 'bg-accent text-accent-foreground' : ''}`, children: p.name }) }, p.id))) }) }), _jsxs("div", { className: "grid gap-2", children: [_jsx("p", { "aria-live": "polite", className: "text-center text-sm text-muted-foreground", children: person === null ? t('choose') : t('pinFor', { name: person.name }) }), _jsx("output", { "aria-label": t('pin'), className: "h-10 text-center text-2xl tracking-[0.5em]", children: '•'.repeat(pin.length) }), _jsx("div", { className: "grid grid-cols-3 gap-2", children: KEYS.map((k) => (_jsx(Button, { variant: k === '✓' ? 'primary' : 'secondary', className: "h-14 text-xl", "aria-label": k === '⌫' ? t('erase') : k === '✓' ? t('enter') : k, disabled: person === null || punch.isPending, onClick: () => press(k), children: k }, k))) })] })] })] }));
62
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Set the kiosk PIN on an employee's form (RFC 0024 §2.2), placed by a view extension. Shown to those who may read
3
+ * the person's attendance details (Attendance managers); the PIN goes to the server, which stores only its hash.
4
+ */
5
+ import { type NodeComponentProps } from '../../ui/index.js';
6
+ import { type ReactElement } from 'react';
7
+ export declare function PinButton({ record, api }: NodeComponentProps): ReactElement | null;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Set the kiosk PIN on an employee's form (RFC 0024 §2.2), placed by a view extension. Shown to those who may read
4
+ * the person's attendance details (Attendance managers); the PIN goes to the server, which stores only its hash.
5
+ */
6
+ import { Alert, Button, Dialog, Input, Label } from '../../ui/index.js';
7
+ import { useMutation } from '@tanstack/react-query';
8
+ import { useId, useState } from 'react';
9
+ import { useTranslation } from 'react-i18next';
10
+ export function PinButton({ record, api }) {
11
+ const { t } = useTranslation('attendance');
12
+ const id = useId();
13
+ const [open, setOpen] = useState(false);
14
+ const [pin, setPin] = useState('');
15
+ const save = useMutation({
16
+ mutationFn: () => api.call('POST', `/api/v1/attendance/employees/${String(record?.['id'])}/pin`, { pin }),
17
+ onSuccess: () => {
18
+ setPin('');
19
+ setOpen(false);
20
+ },
21
+ });
22
+ // The badge is readable by Attendance managers only: without it, nothing to set here.
23
+ if (record === null || typeof record['id'] !== 'number' || !('attendanceBadge' in record))
24
+ return null;
25
+ return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { size: "sm", variant: "secondary", onClick: () => setOpen(true), children: t('setPin') }), save.isSuccess ? (_jsx("span", { className: "text-sm text-muted-foreground", children: t('pinSaved') })) : null, _jsx(Dialog, { open: open, onOpenChange: setOpen, title: t('setPin'), description: t('pinHelp'), children: _jsxs("form", { className: "grid gap-3", onSubmit: (e) => {
26
+ e.preventDefault();
27
+ save.mutate();
28
+ }, children: [_jsx(Label, { htmlFor: id, children: t('newPin') }), _jsx(Input, { id: id, inputMode: "numeric", autoComplete: "off", pattern: "[0-9]{4,8}", value: pin, onChange: (e) => setPin(e.target.value.replace(/\D/g, '').slice(0, 8)) }), save.error === null ? null : _jsx(Alert, { tone: "danger", children: save.error.message }), _jsx(Button, { type: "submit", variant: "primary", busy: save.isPending, disabled: pin.length < 4, children: t('savePin') })] }) })] }));
29
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * The web contribution of `shutro-erp/attendance`: the phone check-in page, the kiosk and the PIN on employee forms.
4
+ */
5
+ import { type Registry } from '../../ui/index.js';
6
+ import type { i18n } from 'i18next';
7
+ import { messages } from './messages.js';
8
+ export { Check } from './Check.js';
9
+ export { Kiosk } from './Kiosk.js';
10
+ export { PinButton } from './PinButton.js';
11
+ /** Registers the pages (and the messages in `i18n`, when given). */
12
+ export declare function registerAttendanceWeb(registry: Registry, i18n?: i18n): Registry;
13
+ export { messages as attendanceMessages };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * The web contribution of `shutro-erp/attendance`: the phone check-in page, the kiosk and the PIN on employee forms.
4
+ */
5
+ import { addMessages } from '../../ui/index.js';
6
+ import { Check } from './Check.js';
7
+ import { Kiosk } from './Kiosk.js';
8
+ import { messages } from './messages.js';
9
+ import { PinButton } from './PinButton.js';
10
+ export { Check } from './Check.js';
11
+ export { Kiosk } from './Kiosk.js';
12
+ export { PinButton } from './PinButton.js';
13
+ /** Registers the pages (and the messages in `i18n`, when given). */
14
+ export function registerAttendanceWeb(registry, i18n) {
15
+ registry.registerPage('attendance.Check', Check);
16
+ registry.registerPage('attendance.Kiosk', Kiosk);
17
+ registry.registerComponent('attendance.Pin', PinButton);
18
+ if (i18n !== undefined)
19
+ addMessages(i18n, 'attendance', messages);
20
+ return registry;
21
+ }
22
+ export { messages as attendanceMessages };
@@ -0,0 +1,2 @@
1
+ /** Messages of the Attendance pages (namespace `attendance`), in English and Bangla. */
2
+ export declare const messages: Readonly<Record<string, object>>;
@@ -0,0 +1,61 @@
1
+ /** Messages of the Attendance pages (namespace `attendance`), in English and Bangla. */
2
+ export const messages = {
3
+ en: {
4
+ loading: 'Loading…',
5
+ notIn: 'Not checked in.',
6
+ inSince: 'Checked in since {{time}}.',
7
+ checkIn: 'Check in',
8
+ checkOut: 'Check out',
9
+ doneIn: 'Checked in at {{time}}.',
10
+ doneOut: 'Checked out at {{time}}.',
11
+ worked: 'Worked today (h)',
12
+ late: 'Late (min)',
13
+ overtime: 'Overtime (h)',
14
+ locationNote: 'Your location goes with the check-in so the server can tell whether you are on site; only “inside” or “outside” and the distance are kept.',
15
+ kioskTitle: 'Check in or out',
16
+ badge: 'Badge',
17
+ badgeHint: 'Scan your badge',
18
+ people: 'People',
19
+ choose: 'Or choose your name, then type your PIN',
20
+ pinFor: 'PIN for {{name}}',
21
+ pin: 'PIN',
22
+ erase: 'Erase',
23
+ enter: 'Enter',
24
+ welcome: 'Welcome, {{name}}! Checked in.',
25
+ goodbye: 'Goodbye, {{name}}! Checked out.',
26
+ setPin: 'Set the kiosk PIN',
27
+ pinHelp: 'Four to eight digits, typed at the kiosk with the person’s name. Only its hash is kept.',
28
+ newPin: 'New PIN',
29
+ savePin: 'Save the PIN',
30
+ pinSaved: 'PIN saved.',
31
+ },
32
+ bn: {
33
+ loading: 'লোড হচ্ছে…',
34
+ notIn: 'চেক-ইন করা হয়নি।',
35
+ inSince: '{{time}} থেকে চেক-ইন করা আছে।',
36
+ checkIn: 'চেক-ইন',
37
+ checkOut: 'চেক-আউট',
38
+ doneIn: '{{time}}-এ চেক-ইন হয়েছে।',
39
+ doneOut: '{{time}}-এ চেক-আউট হয়েছে।',
40
+ worked: 'আজ কাজ (ঘণ্টা)',
41
+ late: 'দেরি (মিনিট)',
42
+ overtime: 'ওভারটাইম (ঘণ্টা)',
43
+ locationNote: 'আপনি অফিসে আছেন কি না তা যাচাই করতে চেক-ইনের সাথে আপনার অবস্থান যায়; শুধু “ভেতরে” বা “বাইরে” এবং দূরত্ব রাখা হয়।',
44
+ kioskTitle: 'চেক-ইন বা চেক-আউট',
45
+ badge: 'ব্যাজ',
46
+ badgeHint: 'আপনার ব্যাজ স্ক্যান করুন',
47
+ people: 'কর্মী',
48
+ choose: 'অথবা আপনার নাম বেছে নিয়ে পিন দিন',
49
+ pinFor: '{{name}}-এর পিন',
50
+ pin: 'পিন',
51
+ erase: 'মুছুন',
52
+ enter: 'নিশ্চিত',
53
+ welcome: 'স্বাগতম, {{name}}! চেক-ইন হয়েছে।',
54
+ goodbye: 'বিদায়, {{name}}! চেক-আউট হয়েছে।',
55
+ setPin: 'কিয়স্ক পিন দিন',
56
+ pinHelp: 'চার থেকে আট অঙ্ক, কিয়স্কে নামের সাথে দিতে হয়। শুধু এর হ্যাশ রাখা হয়।',
57
+ newPin: 'নতুন পিন',
58
+ savePin: 'পিন সংরক্ষণ করুন',
59
+ pinSaved: 'পিন সংরক্ষিত।',
60
+ },
61
+ };
@@ -476,7 +476,7 @@ async function scopeFor(context, rule, change, depth) {
476
476
  : change.uid
477
477
  : (rule.runAsUser ?? null);
478
478
  const actorName = async (id) => context.shutro.bootstrap({ reason: 'automation actor' }, async (su) => {
479
- const [u] = await rows(su, 'res.users', { id, active: { in: [true, false] } }, ['name']);
479
+ const [u] = await rows(su.withFlags({ activeTest: false }), 'res.users', { id }, ['name']);
480
480
  return String(u?.['name'] ?? '');
481
481
  });
482
482
  if ((rule.runAs === 'system' || change.timed !== undefined) && uid === null)
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: ea3894a43dbbf85d
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 8ba76e6f1fdbe5e8
2
2
  // Bindings of module `calendar`: import the definition API from here to get types scoped to what it can see.
3
3
  export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
4
4
  import { definitions } from '../../server/orm.js';
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: ea3894a43dbbf85d
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 8ba76e6f1fdbe5e8
2
2
  // Schema view of module `calendar` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
3
3
  import type { F } from '../../server/orm.js';
4
4
 
@@ -699,6 +699,7 @@ export interface ResPartner {
699
699
  readonly parent: F.Many2one<'res.partner'>;
700
700
  readonly contacts: F.One2many<'res.partner', { readonly required: true }>;
701
701
  readonly email: F.Char;
702
+ readonly lang: F.Selection<'en' | 'bn'>;
702
703
  readonly phone: F.Char;
703
704
  readonly mobile: F.Char;
704
705
  readonly website: F.Char;
@@ -0,0 +1,2 @@
1
+ /** Bangla for the module's labels, keyed by their English text (RFC 0023 §3.1; `pnpm i18n:extract`). */
2
+ export declare const bn: Readonly<Record<string, string>>;