shutro-erp 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/dist/account_asset/.kosh/bindings.d.ts +22 -0
  2. package/dist/account_asset/.kosh/bindings.js +15 -0
  3. package/dist/account_asset/.kosh/schema.d.ts +1755 -0
  4. package/dist/account_asset/board.d.ts +61 -0
  5. package/dist/account_asset/board.js +86 -0
  6. package/dist/account_asset/books.d.ts +42 -0
  7. package/dist/account_asset/books.js +398 -0
  8. package/dist/account_asset/demo.d.ts +7 -0
  9. package/dist/account_asset/demo.js +72 -0
  10. package/dist/account_asset/index.d.ts +9 -0
  11. package/dist/account_asset/index.js +335 -0
  12. package/dist/account_asset/module.d.ts +7622 -0
  13. package/dist/account_asset/module.js +230 -0
  14. package/dist/account_budget/.kosh/bindings.d.ts +22 -0
  15. package/dist/account_budget/.kosh/bindings.js +15 -0
  16. package/dist/account_budget/.kosh/schema.d.ts +1767 -0
  17. package/dist/account_budget/budget.d.ts +5 -0
  18. package/dist/account_budget/budget.js +142 -0
  19. package/dist/account_budget/demo.d.ts +6 -0
  20. package/dist/account_budget/demo.js +30 -0
  21. package/dist/account_budget/index.d.ts +4 -0
  22. package/dist/account_budget/index.js +223 -0
  23. package/dist/account_budget/module.d.ts +13863 -0
  24. package/dist/account_budget/module.js +167 -0
  25. package/dist/account_portal/.kosh/bindings.js +1 -1
  26. package/dist/account_portal/.kosh/schema.d.ts +123 -4
  27. package/dist/account_portal/module.d.ts +146 -0
  28. package/dist/accounting/.kosh/bindings.js +1 -1
  29. package/dist/accounting/.kosh/schema.d.ts +123 -4
  30. package/dist/accounting/index.d.ts +1 -1
  31. package/dist/accounting/index.js +131 -3
  32. package/dist/accounting/module.d.ts +296 -0
  33. package/dist/accounting/module.js +32 -1
  34. package/dist/approvals/.kosh/bindings.d.ts +22 -0
  35. package/dist/approvals/.kosh/bindings.js +15 -0
  36. package/dist/approvals/.kosh/schema.d.ts +611 -0
  37. package/dist/approvals/index.d.ts +18 -0
  38. package/dist/approvals/index.js +302 -0
  39. package/dist/approvals/mails.d.ts +25 -0
  40. package/dist/approvals/mails.js +82 -0
  41. package/dist/approvals/module.d.ts +1 -0
  42. package/dist/approvals/module.js +12 -0
  43. package/dist/approvals/web/History.d.ts +4 -0
  44. package/dist/approvals/web/History.js +13 -0
  45. package/dist/approvals/web/Inbox.d.ts +9 -0
  46. package/dist/approvals/web/Inbox.js +114 -0
  47. package/dist/approvals/web/Mine.d.ts +7 -0
  48. package/dist/approvals/web/Mine.js +27 -0
  49. package/dist/approvals/web/index.d.ts +13 -0
  50. package/dist/approvals/web/index.js +22 -0
  51. package/dist/approvals/web/messages.d.ts +2 -0
  52. package/dist/approvals/web/messages.js +119 -0
  53. package/dist/approvals/web/shared.d.ts +59 -0
  54. package/dist/approvals/web/shared.js +46 -0
  55. package/dist/attendance/.kosh/bindings.d.ts +22 -0
  56. package/dist/attendance/.kosh/bindings.js +15 -0
  57. package/dist/attendance/.kosh/schema.d.ts +1048 -0
  58. package/dist/attendance/days.d.ts +96 -0
  59. package/dist/attendance/days.js +430 -0
  60. package/dist/attendance/demo.d.ts +7 -0
  61. package/dist/attendance/demo.js +58 -0
  62. package/dist/attendance/index.d.ts +4 -0
  63. package/dist/attendance/index.js +513 -0
  64. package/dist/attendance/module.d.ts +3969 -0
  65. package/dist/attendance/module.js +412 -0
  66. package/dist/attendance/routes.d.ts +16 -0
  67. package/dist/attendance/routes.js +266 -0
  68. package/dist/attendance/web/Check.d.ts +8 -0
  69. package/dist/attendance/web/Check.js +40 -0
  70. package/dist/attendance/web/Kiosk.d.ts +8 -0
  71. package/dist/attendance/web/Kiosk.js +62 -0
  72. package/dist/attendance/web/PinButton.d.ts +7 -0
  73. package/dist/attendance/web/PinButton.js +29 -0
  74. package/dist/attendance/web/index.d.ts +13 -0
  75. package/dist/attendance/web/index.js +22 -0
  76. package/dist/attendance/web/messages.d.ts +2 -0
  77. package/dist/attendance/web/messages.js +61 -0
  78. package/dist/cli/init.js +32 -0
  79. package/dist/cli/templates.d.ts +1 -1
  80. package/dist/cli/templates.js +89 -0
  81. package/dist/contacts/module.js +13 -2
  82. package/dist/crm/.kosh/bindings.js +1 -1
  83. package/dist/crm/.kosh/schema.d.ts +2 -1
  84. package/dist/crm/module.d.ts +2 -0
  85. package/dist/crm/module.js +2 -1
  86. package/dist/documents/.kosh/bindings.d.ts +22 -0
  87. package/dist/documents/.kosh/bindings.js +15 -0
  88. package/dist/documents/.kosh/schema.d.ts +862 -0
  89. package/dist/documents/demo.d.ts +6 -0
  90. package/dist/documents/demo.js +22 -0
  91. package/dist/documents/documents.d.ts +98 -0
  92. package/dist/documents/documents.js +318 -0
  93. package/dist/documents/index.d.ts +30 -0
  94. package/dist/documents/index.js +442 -0
  95. package/dist/documents/module.d.ts +2781 -0
  96. package/dist/documents/module.js +214 -0
  97. package/dist/documents/web/Versions.d.ts +7 -0
  98. package/dist/documents/web/Versions.js +45 -0
  99. package/dist/documents/web/index.d.ts +11 -0
  100. package/dist/documents/web/index.js +16 -0
  101. package/dist/documents/web/messages.d.ts +2 -0
  102. package/dist/documents/web/messages.js +21 -0
  103. package/dist/event_account/.kosh/bindings.js +1 -1
  104. package/dist/event_account/.kosh/schema.d.ts +123 -4
  105. package/dist/event_account/module.d.ts +146 -0
  106. package/dist/expense/.kosh/bindings.d.ts +22 -0
  107. package/dist/expense/.kosh/bindings.js +15 -0
  108. package/dist/expense/.kosh/schema.d.ts +1299 -0
  109. package/dist/expense/demo.d.ts +7 -0
  110. package/dist/expense/demo.js +69 -0
  111. package/dist/expense/index.d.ts +3 -0
  112. package/dist/expense/index.js +495 -0
  113. package/dist/expense/module.d.ts +4747 -0
  114. package/dist/expense/module.js +647 -0
  115. package/dist/expense_account/.kosh/bindings.d.ts +22 -0
  116. package/dist/expense_account/.kosh/bindings.js +15 -0
  117. package/dist/expense_account/.kosh/schema.d.ts +1936 -0
  118. package/dist/expense_account/index.d.ts +3 -0
  119. package/dist/expense_account/index.js +74 -0
  120. package/dist/expense_account/module.d.ts +9153 -0
  121. package/dist/expense_account/module.js +318 -0
  122. package/dist/helpdesk/.kosh/bindings.d.ts +22 -0
  123. package/dist/helpdesk/.kosh/bindings.js +15 -0
  124. package/dist/helpdesk/.kosh/schema.d.ts +885 -0
  125. package/dist/helpdesk/demo.d.ts +7 -0
  126. package/dist/helpdesk/demo.js +65 -0
  127. package/dist/helpdesk/hours.d.ts +17 -0
  128. package/dist/helpdesk/hours.js +94 -0
  129. package/dist/helpdesk/index.d.ts +10 -0
  130. package/dist/helpdesk/index.js +461 -0
  131. package/dist/helpdesk/module.d.ts +2940 -0
  132. package/dist/helpdesk/module.js +326 -0
  133. package/dist/helpdesk/routes.d.ts +12 -0
  134. package/dist/helpdesk/routes.js +132 -0
  135. package/dist/helpdesk/sla.d.ts +37 -0
  136. package/dist/helpdesk/sla.js +226 -0
  137. package/dist/hr/index.d.ts +1 -1
  138. package/dist/hr/index.js +1 -1
  139. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  140. package/dist/l10n_bd/.kosh/schema.d.ts +123 -4
  141. package/dist/l10n_bd/module.d.ts +146 -0
  142. package/dist/l10n_bd_payroll/.kosh/bindings.d.ts +22 -0
  143. package/dist/l10n_bd_payroll/.kosh/bindings.js +15 -0
  144. package/dist/l10n_bd_payroll/.kosh/schema.d.ts +2312 -0
  145. package/dist/l10n_bd_payroll/data.d.ts +47 -0
  146. package/dist/l10n_bd_payroll/data.js +347 -0
  147. package/dist/l10n_bd_payroll/index.d.ts +4 -0
  148. package/dist/l10n_bd_payroll/index.js +24 -0
  149. package/dist/l10n_bd_payroll/module.d.ts +12932 -0
  150. package/dist/l10n_bd_payroll/module.js +86 -0
  151. package/dist/l10n_in/.kosh/bindings.js +1 -1
  152. package/dist/l10n_in/.kosh/schema.d.ts +123 -4
  153. package/dist/l10n_in/module.d.ts +147 -0
  154. package/dist/mail/inbound/handle.js +6 -1
  155. package/dist/maintenance_stock/.kosh/bindings.js +1 -1
  156. package/dist/maintenance_stock/.kosh/schema.d.ts +77 -2
  157. package/dist/maintenance_stock/module.d.ts +788 -66
  158. package/dist/modules-sdk/index.d.ts +1 -1
  159. package/dist/modules-sdk/manifest.d.ts +39 -2
  160. package/dist/mrp/.kosh/bindings.js +1 -1
  161. package/dist/mrp/.kosh/schema.d.ts +77 -2
  162. package/dist/mrp/index.d.ts +1 -1
  163. package/dist/mrp/index.js +2 -1
  164. package/dist/mrp/module.d.ts +781 -54
  165. package/dist/mrp/module.js +64 -2
  166. package/dist/mrp_account/.kosh/bindings.js +1 -1
  167. package/dist/mrp_account/.kosh/schema.d.ts +198 -5
  168. package/dist/mrp_account/module.d.ts +4852 -2541
  169. package/dist/payment/.kosh/bindings.js +1 -1
  170. package/dist/payment/.kosh/schema.d.ts +125 -5
  171. package/dist/payment/index.d.ts +41 -0
  172. package/dist/payment/index.js +131 -74
  173. package/dist/payment/module.d.ts +210 -6
  174. package/dist/payment/module.js +19 -3
  175. package/dist/payment/settle.js +10 -1
  176. package/dist/payroll/.kosh/bindings.d.ts +22 -0
  177. package/dist/payroll/.kosh/bindings.js +15 -0
  178. package/dist/payroll/.kosh/schema.d.ts +1390 -0
  179. package/dist/payroll/compute.d.ts +35 -0
  180. package/dist/payroll/compute.js +398 -0
  181. package/dist/payroll/demo.d.ts +55 -0
  182. package/dist/payroll/demo.js +121 -0
  183. package/dist/payroll/formula.d.ts +62 -0
  184. package/dist/payroll/formula.js +320 -0
  185. package/dist/payroll/index.d.ts +230 -0
  186. package/dist/payroll/index.js +713 -0
  187. package/dist/payroll/module.d.ts +9390 -0
  188. package/dist/payroll/module.js +606 -0
  189. package/dist/payroll/routes.d.ts +10 -0
  190. package/dist/payroll/routes.js +112 -0
  191. package/dist/payroll_account/.kosh/bindings.d.ts +22 -0
  192. package/dist/payroll_account/.kosh/bindings.js +15 -0
  193. package/dist/payroll_account/.kosh/schema.d.ts +2308 -0
  194. package/dist/payroll_account/index.d.ts +3 -0
  195. package/dist/payroll_account/index.js +40 -0
  196. package/dist/payroll_account/module.d.ts +12396 -0
  197. package/dist/payroll_account/module.js +256 -0
  198. package/dist/permissions/approvals.d.ts +131 -9
  199. package/dist/permissions/approvals.js +662 -57
  200. package/dist/permissions/index.d.ts +1 -1
  201. package/dist/permissions/index.js +2 -2
  202. package/dist/permissions/models.js +191 -12
  203. package/dist/permissions/routes.d.ts +6 -1
  204. package/dist/permissions/routes.js +37 -4
  205. package/dist/permissions/web/ApprovalPanel.d.ts +5 -4
  206. package/dist/permissions/web/ApprovalPanel.js +39 -13
  207. package/dist/permissions/web/index.d.ts +6 -4
  208. package/dist/permissions/web/index.js +13 -4
  209. package/dist/permissions/web/messages.d.ts +2 -0
  210. package/dist/permissions/web/messages.js +43 -0
  211. package/dist/portal/index.js +1 -1
  212. package/dist/pos/.kosh/bindings.js +1 -1
  213. package/dist/pos/.kosh/schema.d.ts +123 -4
  214. package/dist/pos/index.js +4 -0
  215. package/dist/pos/module.d.ts +147 -0
  216. package/dist/pos_stock/.kosh/bindings.js +1 -1
  217. package/dist/pos_stock/.kosh/schema.d.ts +198 -5
  218. package/dist/pos_stock/module.d.ts +914 -46
  219. package/dist/product/.kosh/bindings.js +1 -1
  220. package/dist/product/.kosh/schema.d.ts +2 -1
  221. package/dist/product/index.js +13 -0
  222. package/dist/product/module.d.ts +2 -0
  223. package/dist/product/module.js +2 -1
  224. package/dist/project/.kosh/bindings.js +1 -1
  225. package/dist/project/.kosh/schema.d.ts +672 -1
  226. package/dist/project/index.d.ts +3 -1
  227. package/dist/project/index.js +901 -14
  228. package/dist/project/module.d.ts +9892 -390
  229. package/dist/project/module.js +1530 -13
  230. package/dist/project/routes.d.ts +44 -0
  231. package/dist/project/routes.js +314 -0
  232. package/dist/project/schedule.d.ts +72 -0
  233. package/dist/project/schedule.js +192 -0
  234. package/dist/project/web/Refresh.d.ts +8 -0
  235. package/dist/project/web/Refresh.js +29 -0
  236. package/dist/project/web/Schedule.d.ts +9 -0
  237. package/dist/project/web/Schedule.js +93 -0
  238. package/dist/project/web/Structure.d.ts +8 -0
  239. package/dist/project/web/Structure.js +86 -0
  240. package/dist/project/web/Workload.d.ts +8 -0
  241. package/dist/project/web/Workload.js +43 -0
  242. package/dist/project/web/index.d.ts +14 -0
  243. package/dist/project/web/index.js +25 -0
  244. package/dist/project/web/messages.d.ts +2 -0
  245. package/dist/project/web/messages.js +85 -0
  246. package/dist/project_account/.kosh/bindings.d.ts +22 -0
  247. package/dist/project_account/.kosh/bindings.js +15 -0
  248. package/dist/project_account/.kosh/schema.d.ts +2241 -0
  249. package/dist/project_account/index.d.ts +3 -0
  250. package/dist/project_account/index.js +27 -0
  251. package/dist/project_account/module.d.ts +11539 -0
  252. package/dist/project_account/module.js +76 -0
  253. package/dist/project_portal/.kosh/bindings.js +1 -1
  254. package/dist/project_portal/.kosh/schema.d.ts +672 -1
  255. package/dist/project_portal/module.d.ts +4798 -129
  256. package/dist/project_purchase/.kosh/bindings.d.ts +22 -0
  257. package/dist/project_purchase/.kosh/bindings.js +15 -0
  258. package/dist/project_purchase/.kosh/schema.d.ts +2320 -0
  259. package/dist/project_purchase/index.d.ts +9 -0
  260. package/dist/project_purchase/index.js +22 -0
  261. package/dist/project_purchase/module.d.ts +25147 -0
  262. package/dist/project_purchase/module.js +56 -0
  263. package/dist/purchase/.kosh/bindings.js +1 -1
  264. package/dist/purchase/.kosh/schema.d.ts +97 -4
  265. package/dist/purchase/module.d.ts +13 -2
  266. package/dist/purchase/module.js +10 -1
  267. package/dist/purchase_account/.kosh/bindings.js +1 -1
  268. package/dist/purchase_account/.kosh/schema.d.ts +126 -6
  269. package/dist/purchase_account/index.js +1 -0
  270. package/dist/purchase_account/module.d.ts +176 -1
  271. package/dist/purchase_account/module.js +13 -2
  272. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  273. package/dist/purchase_portal/.kosh/schema.d.ts +97 -4
  274. package/dist/purchase_portal/module.d.ts +6 -1
  275. package/dist/purchase_stock/.kosh/bindings.js +1 -1
  276. package/dist/purchase_stock/.kosh/schema.d.ts +174 -5
  277. package/dist/purchase_stock/index.d.ts +1 -1
  278. package/dist/purchase_stock/index.js +9 -2
  279. package/dist/purchase_stock/module.d.ts +840 -68
  280. package/dist/purchase_stock/module.js +242 -6
  281. package/dist/purchase_stock_account/.kosh/bindings.js +1 -1
  282. package/dist/purchase_stock_account/.kosh/schema.d.ts +203 -7
  283. package/dist/purchase_stock_account/module.d.ts +8163 -5514
  284. package/dist/purchase_stock_account/module.js +11 -5
  285. package/dist/recruitment/.kosh/bindings.js +1 -1
  286. package/dist/recruitment/.kosh/schema.d.ts +2 -1
  287. package/dist/recruitment/module.d.ts +2 -0
  288. package/dist/recruitment/module.js +2 -1
  289. package/dist/sale_account/.kosh/bindings.js +1 -1
  290. package/dist/sale_account/.kosh/schema.d.ts +123 -4
  291. package/dist/sale_account/module.d.ts +147 -0
  292. package/dist/sale_portal/.kosh/bindings.js +1 -1
  293. package/dist/sale_portal/.kosh/schema.d.ts +2 -1
  294. package/dist/sale_portal/module.d.ts +1 -0
  295. package/dist/sale_project/.kosh/bindings.js +1 -1
  296. package/dist/sale_project/.kosh/schema.d.ts +673 -1
  297. package/dist/sale_project/module.d.ts +4800 -129
  298. package/dist/sale_project/module.js +17 -1
  299. package/dist/sale_stock/.kosh/bindings.js +1 -1
  300. package/dist/sale_stock/.kosh/schema.d.ts +77 -2
  301. package/dist/sale_stock/module.d.ts +789 -66
  302. package/dist/sales/.kosh/bindings.js +1 -1
  303. package/dist/sales/.kosh/schema.d.ts +2 -1
  304. package/dist/sales/index.js +4 -0
  305. package/dist/sales/module.d.ts +1 -0
  306. package/dist/sign/.kosh/bindings.d.ts +22 -0
  307. package/dist/sign/.kosh/bindings.js +15 -0
  308. package/dist/sign/.kosh/schema.d.ts +990 -0
  309. package/dist/sign/index.d.ts +14 -0
  310. package/dist/sign/index.js +350 -0
  311. package/dist/sign/module.d.ts +4478 -0
  312. package/dist/sign/module.js +158 -0
  313. package/dist/sign/sign.d.ts +82 -0
  314. package/dist/sign/sign.js +474 -0
  315. package/dist/stock/.kosh/bindings.js +1 -1
  316. package/dist/stock/.kosh/schema.d.ts +77 -2
  317. package/dist/stock/demo.d.ts +2 -1
  318. package/dist/stock/demo.js +28 -1
  319. package/dist/stock/index.d.ts +2 -1
  320. package/dist/stock/index.js +233 -4
  321. package/dist/stock/module.d.ts +2363 -837
  322. package/dist/stock/module.js +569 -14
  323. package/dist/stock/replenish.d.ts +38 -0
  324. package/dist/stock/replenish.js +176 -0
  325. package/dist/stock/web/Replenishment.d.ts +8 -0
  326. package/dist/stock/web/Replenishment.js +84 -0
  327. package/dist/stock/web/index.d.ts +4 -2
  328. package/dist/stock/web/index.js +6 -2
  329. package/dist/stock/web/messages.js +52 -0
  330. package/dist/stock_account/.kosh/bindings.js +1 -1
  331. package/dist/stock_account/.kosh/schema.d.ts +198 -5
  332. package/dist/stock_account/index.js +10 -0
  333. package/dist/stock_account/module.d.ts +969 -101
  334. package/dist/trade_finance/index.js +2 -0
  335. package/dist/trade_finance/module.js +2 -0
  336. package/dist/trade_finance_account/.kosh/bindings.js +1 -1
  337. package/dist/trade_finance_account/.kosh/schema.d.ts +123 -4
  338. package/dist/trade_finance_account/index.js +1 -0
  339. package/dist/trade_finance_account/module.d.ts +146 -0
  340. package/dist/trade_finance_account/module.js +1 -0
  341. package/dist/trade_finance_purchase/.kosh/bindings.js +1 -1
  342. package/dist/trade_finance_purchase/.kosh/schema.d.ts +97 -4
  343. package/dist/trade_finance_purchase/module.d.ts +6 -1
  344. package/dist/trade_finance_sale/.kosh/bindings.js +1 -1
  345. package/dist/trade_finance_sale/.kosh/schema.d.ts +2 -1
  346. package/dist/trade_finance_sale/module.d.ts +1 -0
  347. package/dist/ui/app.js +24 -12
  348. package/dist/ui/components/AppIcon.js +8 -1
  349. package/dist/ui/i18n/messages.d.ts +4 -0
  350. package/dist/ui/i18n/messages.js +8 -0
  351. package/dist/ui/views/FormView.js +4 -2
  352. package/dist/ui/views/KanbanView.js +9 -1
  353. package/dist/ui/views/ListView.js +4 -2
  354. package/dist/ui/views/widgets.js +7 -1
  355. package/dist/website/index.js +1 -0
  356. package/dist/website/module.js +1 -0
  357. package/dist/website_crm/.kosh/bindings.js +1 -1
  358. package/dist/website_crm/.kosh/schema.d.ts +2 -1
  359. package/dist/website_crm/module.d.ts +1 -0
  360. package/dist/website_sale/.kosh/bindings.d.ts +22 -0
  361. package/dist/website_sale/.kosh/bindings.js +15 -0
  362. package/dist/website_sale/.kosh/schema.d.ts +2284 -0
  363. package/dist/website_sale/couriers.d.ts +50 -0
  364. package/dist/website_sale/couriers.js +59 -0
  365. package/dist/website_sale/demo.d.ts +7 -0
  366. package/dist/website_sale/demo.js +90 -0
  367. package/dist/website_sale/growth.d.ts +31 -0
  368. package/dist/website_sale/growth.js +163 -0
  369. package/dist/website_sale/index.d.ts +49 -0
  370. package/dist/website_sale/index.js +538 -0
  371. package/dist/website_sale/module.d.ts +22027 -0
  372. package/dist/website_sale/module.js +397 -0
  373. package/dist/website_sale/shipments.d.ts +16 -0
  374. package/dist/website_sale/shipments.js +113 -0
  375. package/dist/website_sale/shop.d.ts +81 -0
  376. package/dist/website_sale/shop.js +649 -0
  377. package/dist/website_sale_stock/.kosh/bindings.d.ts +22 -0
  378. package/dist/website_sale_stock/.kosh/bindings.js +15 -0
  379. package/dist/website_sale_stock/.kosh/schema.d.ts +2681 -0
  380. package/dist/website_sale_stock/index.d.ts +9 -0
  381. package/dist/website_sale_stock/index.js +20 -0
  382. package/dist/website_sale_stock/module.d.ts +24998 -0
  383. package/dist/website_sale_stock/module.js +28 -0
  384. package/package.json +83 -2
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: e6900370f0e9c944
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c50b4a215467041d
2
2
  // Bindings of module `payment`: 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,10 +1,11 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: e6900370f0e9c944
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c50b4a215467041d
2
2
  // Schema view of module `payment` (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
 
5
5
  /** Model name → model type (RFC 0002 §7.7). */
6
6
  export interface SchemaView {
7
7
  readonly 'account.account': AccountAccount;
8
+ readonly 'account.analytic': AccountAnalytic;
8
9
  readonly 'account.fiscal.year': AccountFiscalYear;
9
10
  readonly 'account.full.reconcile': AccountFullReconcile;
10
11
  readonly 'account.journal': AccountJournal;
@@ -18,9 +19,12 @@ export interface SchemaView {
18
19
  readonly 'account.tax': AccountTax;
19
20
  readonly 'account.tax.component': AccountTaxComponent;
20
21
  readonly 'account.withholding': AccountWithholding;
22
+ readonly 'approval.delegation': ApprovalDelegation;
21
23
  readonly 'approval.level': ApprovalLevel;
24
+ readonly 'approval.link': ApprovalLink;
22
25
  readonly 'approval.policy': ApprovalPolicy;
23
26
  readonly 'approval.request': ApprovalRequest;
27
+ readonly 'approval.vote': ApprovalVote;
24
28
  readonly 'audit.event': AuditEvent;
25
29
  readonly 'auth.api_key': AuthApiKey;
26
30
  readonly 'auth.credential': AuthCredential;
@@ -95,6 +99,30 @@ export interface AccountAccount {
95
99
  export interface AccountAccountMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'account.account'> {
96
100
  }
97
101
 
102
+ /** `account.analytic` (owner: accounting). */
103
+ export interface AccountAnalytic {
104
+ readonly name: 'account.analytic';
105
+ readonly fields: {
106
+ readonly id: F.Id<'account.analytic'>;
107
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
108
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
109
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
110
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
111
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
112
+ readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
113
+ readonly company: F.Many2one<'res.company', { readonly required: true; readonly default: true }>;
114
+ readonly code: F.Char;
115
+ readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
116
+ readonly parent: F.Many2one<'account.analytic'>;
117
+ readonly note: F.Text;
118
+ };
119
+ readonly methods: AccountAnalyticMethods;
120
+ }
121
+
122
+ /** Methods of `account.analytic`: declared ones and transitions. */
123
+ export interface AccountAnalyticMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'account.analytic'> {
124
+ }
125
+
98
126
  /** `account.fiscal.year` (owner: accounting). */
99
127
  export interface AccountFiscalYear {
100
128
  readonly name: 'account.fiscal.year';
@@ -250,6 +278,7 @@ export interface AccountMoveLine {
250
278
  readonly lineKind: F.Selection<'entry' | 'product' | 'tax' | 'counterpart', { readonly required: true; readonly default: true }>;
251
279
  readonly invoice: F.Many2one<'account.move', { readonly readonly: true; readonly compute: true; readonly store: true }>;
252
280
  readonly product: F.Many2one<'product.product'>;
281
+ readonly analytic: F.Many2one<'account.analytic'>;
253
282
  readonly quantity: F.Decimal<{ readonly default: true }>;
254
283
  readonly priceUnit: F.Decimal<{ readonly default: true }>;
255
284
  readonly discount: F.Decimal<{ readonly default: true }>;
@@ -491,6 +520,29 @@ export interface AccountWithholding {
491
520
  export interface AccountWithholdingMethods extends F.Methods<typeof import('../../accounting/index.js').accountingShutro, 'account.withholding'> {
492
521
  }
493
522
 
523
+ /** `approval.delegation` (owner: permissions). */
524
+ export interface ApprovalDelegation {
525
+ readonly name: 'approval.delegation';
526
+ readonly fields: {
527
+ readonly id: F.Id<'approval.delegation'>;
528
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
529
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
530
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
531
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
532
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
533
+ readonly user: F.Many2one<'res.users', { readonly required: true; readonly default: true }>;
534
+ readonly delegate: F.Many2one<'res.users', { readonly required: true }>;
535
+ readonly dateFrom: F.DateOnly<{ readonly required: true }>;
536
+ readonly dateTo: F.DateOnly<{ readonly required: true }>;
537
+ readonly note: F.Char;
538
+ };
539
+ readonly methods: ApprovalDelegationMethods;
540
+ }
541
+
542
+ /** Methods of `approval.delegation`: declared ones and transitions. */
543
+ export interface ApprovalDelegationMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.delegation'> {
544
+ }
545
+
494
546
  /** `approval.level` (owner: permissions). */
495
547
  export interface ApprovalLevel {
496
548
  readonly name: 'approval.level';
@@ -505,7 +557,14 @@ export interface ApprovalLevel {
505
557
  readonly sequence: F.Integer<{ readonly default: true }>;
506
558
  readonly name: F.Char<{ readonly required: true }>;
507
559
  readonly condition: F.Json;
508
- readonly approverRole: F.Char<{ readonly required: true }>;
560
+ readonly approverKind: F.Selection<'role' | 'users' | 'manager' | 'field', { readonly required: true; readonly default: true }>;
561
+ readonly approverRole: F.Char;
562
+ readonly approverUsers: F.Many2many<'res.users', { readonly required: true }>;
563
+ readonly approverField: F.Char;
564
+ readonly quorum: F.Selection<'any' | 'all' | 'count', { readonly required: true; readonly default: true }>;
565
+ readonly quorumCount: F.Integer;
566
+ readonly deadlineHours: F.Integer;
567
+ readonly escalateRole: F.Char;
509
568
  };
510
569
  readonly methods: ApprovalLevelMethods;
511
570
  }
@@ -514,6 +573,29 @@ export interface ApprovalLevel {
514
573
  export interface ApprovalLevelMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.level'> {
515
574
  }
516
575
 
576
+ /** `approval.link` (owner: permissions). */
577
+ export interface ApprovalLink {
578
+ readonly name: 'approval.link';
579
+ readonly fields: {
580
+ readonly id: F.Id<'approval.link'>;
581
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
582
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
583
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
584
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
585
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
586
+ readonly request: F.Many2one<'approval.request', { readonly required: true }>;
587
+ readonly user: F.Many2one<'res.users', { readonly required: true }>;
588
+ readonly tokenHash: F.Char<{ readonly required: true }>;
589
+ readonly expiresAt: F.Datetime<{ readonly required: true }>;
590
+ readonly usedAt: F.Datetime;
591
+ };
592
+ readonly methods: ApprovalLinkMethods;
593
+ }
594
+
595
+ /** Methods of `approval.link`: declared ones and transitions. */
596
+ export interface ApprovalLinkMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.link'> {
597
+ }
598
+
517
599
  /** `approval.policy` (owner: permissions). */
518
600
  export interface ApprovalPolicy {
519
601
  readonly name: 'approval.policy';
@@ -531,6 +613,9 @@ export interface ApprovalPolicy {
531
613
  readonly company: F.Many2one<'res.company'>;
532
614
  readonly onApproved: F.Char;
533
615
  readonly onRejected: F.Char;
616
+ readonly onSentBack: F.Char;
617
+ readonly onWithdrawn: F.Char;
618
+ readonly reasonRequired: F.Bool<{ readonly required: true; readonly default: true }>;
534
619
  readonly levels: F.One2many<'approval.level', { readonly required: true }>;
535
620
  };
536
621
  readonly methods: ApprovalPolicyMethods;
@@ -557,8 +642,16 @@ export interface ApprovalRequest {
557
642
  readonly targetModel: F.Char<{ readonly required: true }>;
558
643
  readonly targetId: F.Integer<{ readonly required: true }>;
559
644
  readonly company: F.Many2one<'res.company'>;
560
- readonly approverRole: F.Char<{ readonly required: true }>;
561
- readonly state: F.Selection<'pending' | 'approved' | 'rejected' | 'cancelled', { readonly required: true; readonly default: true }>;
645
+ readonly approverRole: F.Char;
646
+ readonly approvers: F.Many2many<'res.users', { readonly required: true }>;
647
+ readonly required: F.Integer<{ readonly required: true; readonly default: true }>;
648
+ readonly round: F.Integer<{ readonly required: true; readonly default: true }>;
649
+ readonly votes: F.One2many<'approval.vote', { readonly required: true }>;
650
+ readonly dueAt: F.Datetime;
651
+ readonly remindedAt: F.Datetime;
652
+ readonly escalatedTo: F.Char;
653
+ readonly escalatedAt: F.Datetime;
654
+ readonly state: F.Selection<'pending' | 'approved' | 'rejected' | 'sent_back' | 'cancelled', { readonly required: true; readonly default: true }>;
562
655
  readonly requestedBy: F.Many2one<'res.users'>;
563
656
  readonly decidedBy: F.Many2one<'res.users'>;
564
657
  readonly decidedAt: F.Datetime;
@@ -571,6 +664,31 @@ export interface ApprovalRequest {
571
664
  export interface ApprovalRequestMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.request'> {
572
665
  }
573
666
 
667
+ /** `approval.vote` (owner: permissions). */
668
+ export interface ApprovalVote {
669
+ readonly name: 'approval.vote';
670
+ readonly fields: {
671
+ readonly id: F.Id<'approval.vote'>;
672
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
673
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
674
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
675
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
676
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
677
+ readonly request: F.Many2one<'approval.request', { readonly required: true }>;
678
+ readonly user: F.Many2one<'res.users', { readonly required: true }>;
679
+ readonly decision: F.Selection<'approve' | 'reject' | 'send_back', { readonly required: true }>;
680
+ readonly comment: F.Text;
681
+ readonly at: F.Datetime<{ readonly required: true }>;
682
+ readonly onBehalfOf: F.Many2one<'res.users'>;
683
+ readonly ip: F.Char;
684
+ };
685
+ readonly methods: ApprovalVoteMethods;
686
+ }
687
+
688
+ /** Methods of `approval.vote`: declared ones and transitions. */
689
+ export interface ApprovalVoteMethods extends F.Methods<typeof import('../../permissions/index.js').permissionsShutro, 'approval.vote'> {
690
+ }
691
+
574
692
  /** `audit.event` (owner: base). */
575
693
  export interface AuditEvent {
576
694
  readonly name: 'audit.event';
@@ -1122,7 +1240,7 @@ export interface PaymentTransaction {
1122
1240
  readonly company: F.Many2one<'res.company', { readonly required: true; readonly default: true }>;
1123
1241
  readonly reference: F.Char<{ readonly required: true; readonly default: true }>;
1124
1242
  readonly provider: F.Many2one<'payment.provider', { readonly required: true }>;
1125
- readonly move: F.Many2one<'account.move', { readonly required: true }>;
1243
+ readonly move: F.Many2one<'account.move'>;
1126
1244
  readonly partner: F.Many2one<'res.partner'>;
1127
1245
  readonly currency: F.Many2one<'res.currency', { readonly required: true }>;
1128
1246
  readonly amount: F.Monetary<'currency', { readonly required: true }>;
@@ -1131,6 +1249,7 @@ export interface PaymentTransaction {
1131
1249
  readonly payment: F.Many2one<'account.payment'>;
1132
1250
  readonly error: F.Text;
1133
1251
  readonly doneAt: F.Datetime;
1252
+ readonly returnUrl: F.Char;
1134
1253
  };
1135
1254
  readonly methods: PaymentTransactionMethods;
1136
1255
  }
@@ -1221,6 +1340,7 @@ export interface ProductCategory {
1221
1340
  readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
1222
1341
  readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
1223
1342
  readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
1343
+ readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
1224
1344
  readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
1225
1345
  readonly parent: F.Many2one<'product.category'>;
1226
1346
  };
@@ -13,8 +13,12 @@
13
13
  * - `GET|POST /api/v1/payment/return/:reference` back from the provider: on to the portal
14
14
  *
15
15
  * The callbacks arrive at `POST /api/v1/hooks/<token>` (the provider's endpoint, made with its first payment).
16
+ * Other apps start payments with `startPayment` (`website_sale`: a shop's checkout) and say what a transaction pays by
17
+ * overriding `payable()` on `payment.transaction`.
16
18
  */
17
19
  import { type KoshModule } from '../modules-sdk/index.js';
20
+ import { type Decimal } from '../server/orm.js';
21
+ import type { Env } from './.kosh/bindings.js';
18
22
  import { type PaymentAdapter } from './providers.js';
19
23
  export { type BkashOptions, bkashAdapter, bkashFromEnvironment } from './bkash.js';
20
24
  export { newReference, PaymentProvider, PaymentTransaction, PROVIDERS, paymentShutro, } from './module.js';
@@ -32,6 +36,43 @@ export interface PaymentOptions {
32
36
  /** The API's public address: where providers call back (`SHUTRO_ERP_API_URL`). */
33
37
  readonly apiUrl?: string;
34
38
  }
39
+ export interface StartPayment {
40
+ /** A provider of the company, enabled. */
41
+ readonly provider: number;
42
+ /** The invoice paid; null when another app's document waits for it (its link in `values`). */
43
+ readonly move?: number | null;
44
+ readonly partner: {
45
+ readonly id: number;
46
+ readonly name: string;
47
+ readonly email?: string | null;
48
+ readonly phone?: string | null;
49
+ readonly mobile?: string | null;
50
+ readonly street?: string | null;
51
+ readonly city?: string | null;
52
+ readonly zip?: string | null;
53
+ readonly country?: unknown;
54
+ } | null;
55
+ readonly currency: {
56
+ readonly id: number;
57
+ readonly name: string;
58
+ readonly decimalPlaces?: number | null;
59
+ };
60
+ readonly amount: Decimal;
61
+ readonly company: number;
62
+ readonly description: string;
63
+ /** Where the customer goes back to (the portal's document when absent). */
64
+ readonly returnUrl?: string;
65
+ /** More fields of the transaction (another app's link: `saleOrder`). */
66
+ readonly values?: Readonly<Record<string, unknown>>;
67
+ }
68
+ /**
69
+ * Starts a payment as the system: a pending transaction for `amount` with the provider, and where to send the
70
+ * customer. The provider must be enabled, configured on this server, and the fake never live.
71
+ */
72
+ export declare function startPayment(su: Env, input: StartPayment): Promise<{
73
+ reference: string;
74
+ redirectUrl: string;
75
+ }>;
35
76
  /** Online payments with explicit options (tests, installations wiring their own adapters). */
36
77
  export declare function paymentModule(options?: PaymentOptions): KoshModule;
37
78
  /** Online payments (the fake adapter; addresses from the environment). */
@@ -13,6 +13,8 @@
13
13
  * - `GET|POST /api/v1/payment/return/:reference` back from the provider: on to the portal
14
14
  *
15
15
  * The callbacks arrive at `POST /api/v1/hooks/<token>` (the provider's endpoint, made with its first payment).
16
+ * Other apps start payments with `startPayment` (`website_sale`: a shop's checkout) and say what a transaction pays by
17
+ * overriding `payable()` on `payment.transaction`.
16
18
  */
17
19
  import { accountPortal } from '../account_portal/index.js';
18
20
  import { accounting } from '../accounting/index.js';
@@ -21,7 +23,7 @@ import { defineModule } from '../modules-sdk/index.js';
21
23
  import { portalDocuments } from '../portal/index.js';
22
24
  import { HttpProblem } from '../server/index.js';
23
25
  import { orm } from '../server/orm.js';
24
- import { action, form, list } from '../views/index.js';
26
+ import { action, form, list, search } from '../views/index.js';
25
27
  import { bkashFromEnvironment } from './bkash.js';
26
28
  import { PaymentProvider, PaymentTransaction, paymentShutro } from './module.js';
27
29
  import { ADAPTERS, FAKE_SIGNATURE, fakeAdapter } from './providers.js';
@@ -56,6 +58,102 @@ function callbackHooks(adapters) {
56
58
  },
57
59
  }));
58
60
  }
61
+ /** The adapters and addresses of the running server (set when the routes are registered). */
62
+ let current = null;
63
+ const adapterOf = (code) => {
64
+ const adapter = current?.adapters.get(code);
65
+ if (adapter === undefined)
66
+ throw new HttpProblem(409, 'no-adapter', 'Provider unavailable', `The ${code} adapter is not installed.`);
67
+ return adapter;
68
+ };
69
+ /** The provider's callback endpoint (made on first use), with its token. */
70
+ async function endpointOf(su, provider) {
71
+ const [p] = await su
72
+ .model('payment.provider')
73
+ .browse([provider.id])
74
+ .load({ endpoint: true });
75
+ if (p?.endpoint !== null && p?.endpoint !== undefined)
76
+ return p.endpoint.token;
77
+ const made = await su
78
+ .model('webhook.endpoint')
79
+ .create([{ name: `${provider.name} callbacks`, hook: `payment.${provider.code}` }]);
80
+ await su
81
+ .model('payment.provider')
82
+ .browse([provider.id])
83
+ .write({ endpoint: made.ids[0] });
84
+ const [e] = await made.load({});
85
+ return e?.token ?? '';
86
+ }
87
+ /**
88
+ * Starts a payment as the system: a pending transaction for `amount` with the provider, and where to send the
89
+ * customer. The provider must be enabled, configured on this server, and the fake never live.
90
+ */
91
+ export async function startPayment(su, input) {
92
+ if (current === null)
93
+ throw new HttpProblem(503, 'no-payments', 'Payments unavailable', 'Payments are not set up.');
94
+ const urls = current.urls;
95
+ const [provider] = await (await su.model('payment.provider').search({
96
+ where: {
97
+ id: orm.asId(input.provider, 'payment.provider'),
98
+ state: { in: ['test', 'live'] },
99
+ company: orm.asId(input.company, 'res.company'),
100
+ },
101
+ limit: 1,
102
+ })).load({});
103
+ if (provider === undefined)
104
+ throw new HttpProblem(422, 'invalid-provider', 'No such provider', 'Choose one of the providers offered.');
105
+ const adapter = adapterOf(provider.code);
106
+ if (provider.code === 'fake' && provider.state === 'live')
107
+ throw new HttpProblem(409, 'fake-live', 'Test provider', 'The test provider moves no money: it cannot be live.');
108
+ if (!adapter.configured(provider.state === 'live' ? 'live' : 'test'))
109
+ throw new HttpProblem(409, 'not-configured', 'Provider not set up', `The ${provider.name} provider has no credentials for ${provider.state} payments on this server.`);
110
+ const token = await endpointOf(su, provider);
111
+ const created = await su.model('payment.transaction').create([
112
+ {
113
+ ...input.values,
114
+ provider: provider.id,
115
+ move: input.move ?? null,
116
+ partner: input.partner?.id ?? null,
117
+ currency: input.currency.id,
118
+ amount: input.amount.toFixed(),
119
+ company: input.company,
120
+ returnUrl: input.returnUrl ?? null,
121
+ },
122
+ ]);
123
+ await su.flush(); // company checks run in this superuser scope, not at commit (Shutro request #11)
124
+ const tx = su.model('payment.transaction').browse(created.ids);
125
+ const [t] = await tx.load({});
126
+ const reference = t?.reference ?? '';
127
+ const p = input.partner;
128
+ let started;
129
+ try {
130
+ started = await adapter.createPayment({
131
+ reference,
132
+ amount: input.amount.toFixed(input.currency.decimalPlaces ?? 2),
133
+ currency: input.currency.name,
134
+ description: input.description,
135
+ customer: {
136
+ name: p?.name ?? '',
137
+ email: p?.email ?? null,
138
+ phone: p?.phone ?? p?.mobile ?? null,
139
+ street: p?.street ?? null,
140
+ city: p?.city ?? null,
141
+ zip: p?.zip ?? null,
142
+ country: (p?.country ?? null),
143
+ },
144
+ returnUrl: `${urls.api}/api/v1/payment/return/${encodeURIComponent(reference)}`,
145
+ callbackUrl: `${urls.api}/api/v1/hooks/${token}`,
146
+ mode: provider.state === 'live' ? 'live' : 'test',
147
+ });
148
+ }
149
+ catch (error) {
150
+ throw new HttpProblem(502, 'provider-error', 'The payment could not start', error instanceof Error ? error.message : String(error));
151
+ }
152
+ if (started.providerReference !== undefined)
153
+ await tx.write({ providerReference: started.providerReference });
154
+ await su.flush();
155
+ return { reference, redirectUrl: started.redirectUrl };
156
+ }
59
157
  function registerPaymentRoutes(context, adapters, urls) {
60
158
  const { app } = context;
61
159
  const documents = portalDocuments(context.registry);
@@ -63,30 +161,7 @@ function registerPaymentRoutes(context, adapters, urls) {
63
161
  if (!env.groups.has('portal.user') || env.groups.has('base.user'))
64
162
  throw new HttpProblem(403, 'portal-only', 'Portal users only', 'This is the portal’s API.');
65
163
  };
66
- const adapterOf = (code) => {
67
- const adapter = adapters.get(code);
68
- if (adapter === undefined)
69
- throw new HttpProblem(409, 'no-adapter', 'Provider unavailable', `The ${code} adapter is not installed.`);
70
- return adapter;
71
- };
72
- /** The provider's callback endpoint (made on first use), with its token. */
73
- const endpointOf = async (su, provider) => {
74
- const [p] = await su
75
- .model('payment.provider')
76
- .browse([provider.id])
77
- .load({ endpoint: true });
78
- if (p?.endpoint !== null && p?.endpoint !== undefined)
79
- return p.endpoint.token;
80
- const made = await su
81
- .model('webhook.endpoint')
82
- .create([{ name: `${provider.name} callbacks`, hook: `payment.${provider.code}` }]);
83
- await su
84
- .model('payment.provider')
85
- .browse([provider.id])
86
- .write({ endpoint: made.ids[0] });
87
- const [e] = await made.load({});
88
- return e?.token ?? '';
89
- };
164
+ current = { adapters, urls };
90
165
  app.get('/api/portal/v1/payments/providers', async (request) => request.env((env) => {
91
166
  portalOnly(env);
92
167
  return env.asSuperuser({ reason: 'portal: payment providers' }, async (su) => {
@@ -137,11 +212,6 @@ function registerPaymentRoutes(context, adapters, urls) {
137
212
  })).load({});
138
213
  if (provider === undefined)
139
214
  throw new HttpProblem(422, 'invalid-provider', 'No such provider', 'Choose one of the providers offered.');
140
- const adapter = adapterOf(provider.code);
141
- if (provider.code === 'fake' && provider.state === 'live')
142
- throw new HttpProblem(409, 'fake-live', 'Test provider', 'The test provider moves no money: it cannot be live.');
143
- if (!adapter.configured(provider.state === 'live' ? 'live' : 'test'))
144
- throw new HttpProblem(409, 'not-configured', 'Provider not set up', `The ${provider.name} provider has no credentials for ${provider.state} payments on this server.`);
145
215
  const [move] = await su
146
216
  .model('account.move')
147
217
  .browse([id])
@@ -151,48 +221,15 @@ function registerPaymentRoutes(context, adapters, urls) {
151
221
  const due = move.amountResidual?.amount;
152
222
  if (due === undefined || !due.gt(0))
153
223
  throw new HttpProblem(409, 'not-payable', 'Nothing to pay', 'Nothing is due on this document.');
154
- const token = await endpointOf(su, provider);
155
- const created = await su.model('payment.transaction').create([
156
- {
157
- provider: provider.id,
158
- move: move.id,
159
- partner: (move.partner?.id ?? null),
160
- currency: move.currency.id,
161
- amount: due.toFixed(),
162
- company: company,
163
- },
164
- ]);
165
- await su.flush(); // company checks run in this superuser scope, not at commit (Shutro request #11)
166
- const [tx] = await created.load({});
167
- const reference = tx?.reference ?? '';
168
- let started;
169
- try {
170
- started = await adapter.createPayment({
171
- reference,
172
- amount: due.toFixed(move.currency.decimalPlaces ?? 2),
173
- currency: move.currency.name,
174
- description: `${d.spec.label} ${move.name}`,
175
- customer: {
176
- name: move.partner?.name ?? '',
177
- email: move.partner?.email ?? null,
178
- phone: move.partner?.phone ?? move.partner?.mobile ?? null,
179
- street: move.partner?.street ?? null,
180
- city: move.partner?.city ?? null,
181
- zip: move.partner?.zip ?? null,
182
- country: move.partner?.country ?? null,
183
- },
184
- returnUrl: `${urls.api}/api/v1/payment/return/${encodeURIComponent(reference)}`,
185
- callbackUrl: `${urls.api}/api/v1/hooks/${token}`,
186
- mode: provider.state === 'live' ? 'live' : 'test',
187
- });
188
- }
189
- catch (error) {
190
- throw new HttpProblem(502, 'provider-error', 'The payment could not start', error instanceof Error ? error.message : String(error));
191
- }
192
- if (started.providerReference !== undefined)
193
- await created.write({ providerReference: started.providerReference });
194
- await su.flush();
195
- return { reference, redirectUrl: started.redirectUrl };
224
+ return startPayment(su, {
225
+ provider: provider.id,
226
+ move: move.id,
227
+ partner: move.partner,
228
+ currency: move.currency,
229
+ amount: due,
230
+ company,
231
+ description: `${d.spec.label} ${move.name}`,
232
+ });
196
233
  });
197
234
  return reply.status(201).send(started);
198
235
  });
@@ -210,7 +247,7 @@ function registerPaymentRoutes(context, adapters, urls) {
210
247
  return t === undefined
211
248
  ? null
212
249
  : {
213
- move: t.move.id,
250
+ move: t.move?.id ?? 0,
214
251
  state: t.state,
215
252
  amount: t.amount.amount.toFixed(t.currency.decimalPlaces ?? 2),
216
253
  currency: t.currency.name,
@@ -294,7 +331,8 @@ function registerPaymentRoutes(context, adapters, urls) {
294
331
  return t === undefined
295
332
  ? null
296
333
  : {
297
- move: t.move.id,
334
+ move: t.move?.id ?? null,
335
+ returnUrl: t.returnUrl,
298
336
  company: t.company.id,
299
337
  state: t.state,
300
338
  code: t.provider.code,
@@ -322,6 +360,8 @@ function registerPaymentRoutes(context, adapters, urls) {
322
360
  }
323
361
  }
324
362
  const move = tx?.move ?? null;
363
+ if (tx?.returnUrl !== null && tx?.returnUrl !== undefined && tx.returnUrl !== '')
364
+ return reply.redirect(`${tx.returnUrl}${tx.returnUrl.includes('?') ? '&' : '?'}payment=${encodeURIComponent(reference)}`, 303);
325
365
  return reply.redirect(move === null
326
366
  ? `${urls.portal}/`
327
367
  : `${urls.portal}/d/${encodeURIComponent(payable)}/${move}?payment=${encodeURIComponent(reference)}`, 303);
@@ -391,11 +431,27 @@ export function paymentModule(options = {}) {
391
431
  sequence: 3.7,
392
432
  },
393
433
  ],
434
+ search: {
435
+ 'payment.provider': search(PaymentProvider, {
436
+ fields: ['name'],
437
+ groupBy: ['code', 'state'],
438
+ }),
439
+ 'payment.transaction': search(PaymentTransaction, {
440
+ fields: ['reference', 'providerReference', 'partner.name'],
441
+ filters: {
442
+ done: { label: 'Done', domain: { state: 'done' }, group: 'state' },
443
+ pending: { label: 'Pending', domain: { state: 'pending' }, group: 'state' },
444
+ failed: { label: 'Failed', domain: { state: 'failed' }, group: 'state' },
445
+ },
446
+ groupBy: ['provider', 'state', 'doneAt:month'],
447
+ }),
448
+ },
394
449
  views: {
395
450
  'payment.provider.list': list(PaymentProvider, {
396
451
  columns: ['name', 'code', 'state', 'journal'],
397
452
  }),
398
453
  'payment.provider.form': form(PaymentProvider, (k) => ({
454
+ chatter: true,
399
455
  sheet: [
400
456
  k.group('main', ['name', 'code', 'state']),
401
457
  k.group('accounting', ['journal', 'sequence', 'endpoint']),
@@ -405,6 +461,7 @@ export function paymentModule(options = {}) {
405
461
  columns: ['reference', 'move', 'partner', 'provider', 'amount', 'state', 'doneAt'],
406
462
  }),
407
463
  'payment.transaction.form': form(PaymentTransaction, (k) => ({
464
+ chatter: true,
408
465
  sheet: [
409
466
  k.group('main', ['reference', 'move', 'partner', 'provider']),
410
467
  k.group('outcome', [