@things-factory/worksheet-base 8.0.0-beta.8 → 8.0.0

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 (288) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +2 -0
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/graphql/resolvers/worksheet/vas-candidates.d.ts +2 -0
  4. package/dist-server/tsconfig.tsbuildinfo +1 -1
  5. package/dist-server/utils/inventory-util.d.ts +2 -0
  6. package/package.json +17 -17
  7. package/server/constants/index.ts +5 -0
  8. package/server/constants/rule-type.ts +4 -0
  9. package/server/constants/target-type.ts +6 -0
  10. package/server/constants/template.ts +12 -0
  11. package/server/constants/transaction-type.ts +9 -0
  12. package/server/constants/worksheet.ts +38 -0
  13. package/server/controllers/ecommerce/ecommerce-controller.ts +209 -0
  14. package/server/controllers/ecommerce/index.ts +2 -0
  15. package/server/controllers/ecommerce/sellercraft-controller.ts +358 -0
  16. package/server/controllers/inbound/index.ts +4 -0
  17. package/server/controllers/inbound/putaway-returning-worksheet-controller.ts +450 -0
  18. package/server/controllers/inbound/putaway-worksheet-controller.ts +454 -0
  19. package/server/controllers/inbound/unloading-returning-worksheet-controller.ts +291 -0
  20. package/server/controllers/inbound/unloading-worksheet-controller.ts +1400 -0
  21. package/server/controllers/index.ts +21 -0
  22. package/server/controllers/inspect/cycle-count-worksheet-controller.ts +537 -0
  23. package/server/controllers/inspect/index.ts +1 -0
  24. package/server/controllers/outbound/index.ts +5 -0
  25. package/server/controllers/outbound/loading-worksheet-controller.ts +377 -0
  26. package/server/controllers/outbound/packing-worksheet-controller.ts +449 -0
  27. package/server/controllers/outbound/picking-worksheet-controller.ts +1769 -0
  28. package/server/controllers/outbound/returning-worksheet-controller.ts +254 -0
  29. package/server/controllers/outbound/sorting-worksheet-controller.ts +554 -0
  30. package/server/controllers/render-elccl-grn.ts +228 -0
  31. package/server/controllers/render-fm-grn.ts +287 -0
  32. package/server/controllers/render-grn.ts +285 -0
  33. package/server/controllers/render-invoices.ts +201 -0
  34. package/server/controllers/render-job-sheet.ts +208 -0
  35. package/server/controllers/render-kimeda-grn.ts +185 -0
  36. package/server/controllers/render-manifest.ts +76 -0
  37. package/server/controllers/render-manual-do.ts +227 -0
  38. package/server/controllers/render-orientage-do.ts +376 -0
  39. package/server/controllers/render-orientage-grn.ts +191 -0
  40. package/server/controllers/render-po.ts +182 -0
  41. package/server/controllers/render-ro-do.ts +404 -0
  42. package/server/controllers/render-seebuu-grn.ts +208 -0
  43. package/server/controllers/vas/index.ts +1 -0
  44. package/server/controllers/vas/vas-worksheet-controller.ts +848 -0
  45. package/server/controllers/worksheet-controller.ts +1267 -0
  46. package/server/entities/index.ts +8 -0
  47. package/server/entities/warehouse-bizplace-onhand-inventory.ts +148 -0
  48. package/server/entities/worksheet-detail.ts +106 -0
  49. package/server/entities/worksheet-movement.ts +34 -0
  50. package/server/entities/worksheet.ts +100 -0
  51. package/server/graphql/index.ts +7 -0
  52. package/server/graphql/resolvers/index.ts +8 -0
  53. package/server/graphql/resolvers/pallet/index.ts +7 -0
  54. package/server/graphql/resolvers/pallet/pallet-outbound.ts +92 -0
  55. package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +137 -0
  56. package/server/graphql/resolvers/worksheet/cancel-draft-release-order.ts +20 -0
  57. package/server/graphql/resolvers/worksheet/check-inventory-release.ts +37 -0
  58. package/server/graphql/resolvers/worksheet/check-stock-take-current-location.ts +63 -0
  59. package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +213 -0
  60. package/server/graphql/resolvers/worksheet/create-worksheet.ts +21 -0
  61. package/server/graphql/resolvers/worksheet/cross-dock-picking.ts +173 -0
  62. package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +211 -0
  63. package/server/graphql/resolvers/worksheet/cycle-count-worksheet.ts +79 -0
  64. package/server/graphql/resolvers/worksheet/delete-worksheet.ts +21 -0
  65. package/server/graphql/resolvers/worksheet/delivery-order-by-worksheet.ts +104 -0
  66. package/server/graphql/resolvers/worksheet/fetch-delivery-order-ro.ts +191 -0
  67. package/server/graphql/resolvers/worksheet/fetch-sellercraft-document.ts +69 -0
  68. package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +36 -0
  69. package/server/graphql/resolvers/worksheet/find-release-orders-by-worksheet-no.ts +29 -0
  70. package/server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.ts +80 -0
  71. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-arrival-notice-worksheet.ts +100 -0
  72. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.ts +26 -0
  73. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet.ts +51 -0
  74. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-multiple-release-good-worksheet.ts +17 -0
  75. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-partial-putaway-return-worksheet.ts +69 -0
  76. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-partial-putaway-worksheet.ts +65 -0
  77. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-putaway-worksheet.ts +54 -0
  78. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-release-good-worksheet.ts +114 -0
  79. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-return-order-worksheet.ts +45 -0
  80. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-vas-order-worksheet.ts +35 -0
  81. package/server/graphql/resolvers/worksheet/generate-worksheet/index.ts +23 -0
  82. package/server/graphql/resolvers/worksheet/having-vas.ts +45 -0
  83. package/server/graphql/resolvers/worksheet/index.ts +142 -0
  84. package/server/graphql/resolvers/worksheet/inspecting/activate-cycle-count.ts +24 -0
  85. package/server/graphql/resolvers/worksheet/inspecting/add-extra-pallet.ts +49 -0
  86. package/server/graphql/resolvers/worksheet/inspecting/check-missing-pallet.ts +18 -0
  87. package/server/graphql/resolvers/worksheet/inspecting/complete-inspection.ts +41 -0
  88. package/server/graphql/resolvers/worksheet/inspecting/index.ts +17 -0
  89. package/server/graphql/resolvers/worksheet/inspecting/inspecting.ts +30 -0
  90. package/server/graphql/resolvers/worksheet/inspecting/relocate-pallet.ts +46 -0
  91. package/server/graphql/resolvers/worksheet/inspecting/undo-inspection.ts +23 -0
  92. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +150 -0
  93. package/server/graphql/resolvers/worksheet/loaded-inventories.ts +40 -0
  94. package/server/graphql/resolvers/worksheet/loading/activate-loading.ts +73 -0
  95. package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +165 -0
  96. package/server/graphql/resolvers/worksheet/loading/index.ts +11 -0
  97. package/server/graphql/resolvers/worksheet/loading/loading.ts +46 -0
  98. package/server/graphql/resolvers/worksheet/loading/undo-loading.ts +25 -0
  99. package/server/graphql/resolvers/worksheet/loading-worksheet.ts +150 -0
  100. package/server/graphql/resolvers/worksheet/not-tally-target-inventories.ts +34 -0
  101. package/server/graphql/resolvers/worksheet/packing/activate-packing.ts +69 -0
  102. package/server/graphql/resolvers/worksheet/packing/complete-packing.ts +102 -0
  103. package/server/graphql/resolvers/worksheet/packing/index.ts +13 -0
  104. package/server/graphql/resolvers/worksheet/packing/packing.ts +59 -0
  105. package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +70 -0
  106. package/server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.ts +24 -0
  107. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +378 -0
  108. package/server/graphql/resolvers/worksheet/palletizing-pallets.ts +142 -0
  109. package/server/graphql/resolvers/worksheet/pending-cancellation-release-order.ts +234 -0
  110. package/server/graphql/resolvers/worksheet/picking/activate-batch-picking.ts +40 -0
  111. package/server/graphql/resolvers/worksheet/picking/activate-picking.ts +98 -0
  112. package/server/graphql/resolvers/worksheet/picking/assign-picking-inventories.ts +50 -0
  113. package/server/graphql/resolvers/worksheet/picking/assign-picking-worker.ts +44 -0
  114. package/server/graphql/resolvers/worksheet/picking/batch-picking.ts +32 -0
  115. package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +137 -0
  116. package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +282 -0
  117. package/server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.ts +121 -0
  118. package/server/graphql/resolvers/worksheet/picking/index.ts +31 -0
  119. package/server/graphql/resolvers/worksheet/picking/my-picking-assignment-status.ts +35 -0
  120. package/server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.ts +96 -0
  121. package/server/graphql/resolvers/worksheet/picking/picking.ts +55 -0
  122. package/server/graphql/resolvers/worksheet/picking/scan-product-batch-picking.ts +52 -0
  123. package/server/graphql/resolvers/worksheet/picking/scan-product-picking.ts +25 -0
  124. package/server/graphql/resolvers/worksheet/picking/seal-tote.ts +25 -0
  125. package/server/graphql/resolvers/worksheet/picking/undo-picking-assignment.ts +31 -0
  126. package/server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.ts +24 -0
  127. package/server/graphql/resolvers/worksheet/picking-worksheet.ts +147 -0
  128. package/server/graphql/resolvers/worksheet/proceed-extra-products.ts +242 -0
  129. package/server/graphql/resolvers/worksheet/putaway/activate-putaway.ts +51 -0
  130. package/server/graphql/resolvers/worksheet/putaway/complete-putaway.ts +105 -0
  131. package/server/graphql/resolvers/worksheet/putaway/index.ts +11 -0
  132. package/server/graphql/resolvers/worksheet/putaway/putaway.ts +26 -0
  133. package/server/graphql/resolvers/worksheet/putaway/undo-putaway.ts +25 -0
  134. package/server/graphql/resolvers/worksheet/putaway-return/activate-putaway-return.ts +55 -0
  135. package/server/graphql/resolvers/worksheet/putaway-return/complete-putaway-return.ts +38 -0
  136. package/server/graphql/resolvers/worksheet/putaway-return/index.ts +11 -0
  137. package/server/graphql/resolvers/worksheet/putaway-return/putaway-return.ts +30 -0
  138. package/server/graphql/resolvers/worksheet/putaway-return/undo-putaway-return.ts +29 -0
  139. package/server/graphql/resolvers/worksheet/putaway-returning-worksheet.ts +83 -0
  140. package/server/graphql/resolvers/worksheet/putaway-worksheet.ts +82 -0
  141. package/server/graphql/resolvers/worksheet/recommend-putway-location.ts +133 -0
  142. package/server/graphql/resolvers/worksheet/reject-cancellation-release-order.ts +186 -0
  143. package/server/graphql/resolvers/worksheet/relocate-pallet.ts +67 -0
  144. package/server/graphql/resolvers/worksheet/replace-picking-pallets.ts +127 -0
  145. package/server/graphql/resolvers/worksheet/return-worksheet.ts +70 -0
  146. package/server/graphql/resolvers/worksheet/returning/activate-return.ts +24 -0
  147. package/server/graphql/resolvers/worksheet/returning/complete-return.ts +39 -0
  148. package/server/graphql/resolvers/worksheet/returning/index.ts +9 -0
  149. package/server/graphql/resolvers/worksheet/returning/returning.ts +26 -0
  150. package/server/graphql/resolvers/worksheet/sorting/activate-sorting.ts +25 -0
  151. package/server/graphql/resolvers/worksheet/sorting/complete-order-sorting.ts +40 -0
  152. package/server/graphql/resolvers/worksheet/sorting/complete-worksheet-sorting.ts +23 -0
  153. package/server/graphql/resolvers/worksheet/sorting/index.ts +13 -0
  154. package/server/graphql/resolvers/worksheet/sorting/scan-product-sorting.ts +31 -0
  155. package/server/graphql/resolvers/worksheet/sorting/sorting-product.ts +32 -0
  156. package/server/graphql/resolvers/worksheet/sorting-worksheet.ts +87 -0
  157. package/server/graphql/resolvers/worksheet/transfer.ts +176 -0
  158. package/server/graphql/resolvers/worksheet/unloaded-inventories-by-reusable-pallet.ts +54 -0
  159. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +78 -0
  160. package/server/graphql/resolvers/worksheet/unloading/activate-unloading.ts +56 -0
  161. package/server/graphql/resolvers/worksheet/unloading/complete-product-scan-unload.ts +25 -0
  162. package/server/graphql/resolvers/worksheet/unloading/complete-unloading-partially.ts +25 -0
  163. package/server/graphql/resolvers/worksheet/unloading/complete-unloading.ts +76 -0
  164. package/server/graphql/resolvers/worksheet/unloading/index.ts +21 -0
  165. package/server/graphql/resolvers/worksheet/unloading/scan-product-unload.ts +26 -0
  166. package/server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.ts +26 -0
  167. package/server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.ts +24 -0
  168. package/server/graphql/resolvers/worksheet/unloading/undo-unloading.ts +25 -0
  169. package/server/graphql/resolvers/worksheet/unloading/unload.ts +26 -0
  170. package/server/graphql/resolvers/worksheet/unloading-return/activate-unloading-return.ts +28 -0
  171. package/server/graphql/resolvers/worksheet/unloading-return/complete-unload-return-partially.ts +29 -0
  172. package/server/graphql/resolvers/worksheet/unloading-return/complete-unload-returning.ts +91 -0
  173. package/server/graphql/resolvers/worksheet/unloading-return/index.ts +9 -0
  174. package/server/graphql/resolvers/worksheet/unloading-return-worksheet.ts +75 -0
  175. package/server/graphql/resolvers/worksheet/unloading-worksheet.ts +98 -0
  176. package/server/graphql/resolvers/worksheet/update-worksheet.ts +25 -0
  177. package/server/graphql/resolvers/worksheet/vas/activate-vas.ts +25 -0
  178. package/server/graphql/resolvers/worksheet/vas/assign-vas-inventories.ts +25 -0
  179. package/server/graphql/resolvers/worksheet/vas/complete-vas.ts +72 -0
  180. package/server/graphql/resolvers/worksheet/vas/execute-vas.ts +31 -0
  181. package/server/graphql/resolvers/worksheet/vas/index.ts +15 -0
  182. package/server/graphql/resolvers/worksheet/vas/undo-vas-inventory.ts +24 -0
  183. package/server/graphql/resolvers/worksheet/vas/undo-vas.ts +24 -0
  184. package/server/graphql/resolvers/worksheet/vas-candidates.ts +177 -0
  185. package/server/graphql/resolvers/worksheet/vas-inventories.ts +41 -0
  186. package/server/graphql/resolvers/worksheet/vas-transactions/common-utils.ts +1182 -0
  187. package/server/graphql/resolvers/worksheet/vas-transactions/index.ts +5 -0
  188. package/server/graphql/resolvers/worksheet/vas-transactions/interfaces/index.ts +56 -0
  189. package/server/graphql/resolvers/worksheet/vas-transactions/interfaces/relabeling.ts +20 -0
  190. package/server/graphql/resolvers/worksheet/vas-transactions/interfaces/repackaging.ts +27 -0
  191. package/server/graphql/resolvers/worksheet/vas-transactions/interfaces/repalletizing.ts +14 -0
  192. package/server/graphql/resolvers/worksheet/vas-transactions/interfaces/unpacking.ts +14 -0
  193. package/server/graphql/resolvers/worksheet/vas-transactions/relabeling/check-relabelable.ts +96 -0
  194. package/server/graphql/resolvers/worksheet/vas-transactions/relabeling/complete-relabeling.ts +93 -0
  195. package/server/graphql/resolvers/worksheet/vas-transactions/relabeling/index.ts +4 -0
  196. package/server/graphql/resolvers/worksheet/vas-transactions/relabeling/relabeling.ts +105 -0
  197. package/server/graphql/resolvers/worksheet/vas-transactions/relabeling/undo-relabeling.ts +40 -0
  198. package/server/graphql/resolvers/worksheet/vas-transactions/repackaging/complete-repackaging.ts +236 -0
  199. package/server/graphql/resolvers/worksheet/vas-transactions/repackaging/index.ts +3 -0
  200. package/server/graphql/resolvers/worksheet/vas-transactions/repackaging/repackaging.ts +402 -0
  201. package/server/graphql/resolvers/worksheet/vas-transactions/repackaging/undo-repackaging.ts +166 -0
  202. package/server/graphql/resolvers/worksheet/vas-transactions/repalletizing/complete-repalletizing.ts +116 -0
  203. package/server/graphql/resolvers/worksheet/vas-transactions/repalletizing/index.ts +3 -0
  204. package/server/graphql/resolvers/worksheet/vas-transactions/repalletizing/repalletizing.ts +167 -0
  205. package/server/graphql/resolvers/worksheet/vas-transactions/repalletizing/undo-repalletizing.ts +74 -0
  206. package/server/graphql/resolvers/worksheet/vas-transactions/unpacking/complete-unpacking.ts +20 -0
  207. package/server/graphql/resolvers/worksheet/vas-transactions/unpacking/index.ts +2 -0
  208. package/server/graphql/resolvers/worksheet/vas-transactions/unpacking/unpacking.ts +164 -0
  209. package/server/graphql/resolvers/worksheet/vas-worksheet.ts +110 -0
  210. package/server/graphql/resolvers/worksheet/worksheet-by-order-no.ts +43 -0
  211. package/server/graphql/resolvers/worksheet/worksheet-with-pagination.ts +46 -0
  212. package/server/graphql/resolvers/worksheet/worksheet.ts +330 -0
  213. package/server/graphql/resolvers/worksheet/worksheets.ts +493 -0
  214. package/server/graphql/resolvers/worksheet-detail/check-progressing-pallet.ts +22 -0
  215. package/server/graphql/resolvers/worksheet-detail/create-worksheet-detail.ts +38 -0
  216. package/server/graphql/resolvers/worksheet-detail/delete-worksheet-detail.ts +18 -0
  217. package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.ts +206 -0
  218. package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details.ts +165 -0
  219. package/server/graphql/resolvers/worksheet-detail/generate-carton-id.ts +26 -0
  220. package/server/graphql/resolvers/worksheet-detail/generate-pallet-id.ts +94 -0
  221. package/server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.ts +259 -0
  222. package/server/graphql/resolvers/worksheet-detail/generate-release-good-worksheet-details.ts +142 -0
  223. package/server/graphql/resolvers/worksheet-detail/index.ts +34 -0
  224. package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +165 -0
  225. package/server/graphql/resolvers/worksheet-detail/update-worksheet-detail.ts +39 -0
  226. package/server/graphql/resolvers/worksheet-detail/worksheet-detail.ts +19 -0
  227. package/server/graphql/resolvers/worksheet-detail/worksheet-details-by-product-group.ts +56 -0
  228. package/server/graphql/resolvers/worksheet-detail/worksheet-details.ts +21 -0
  229. package/server/graphql/resolvers/worksheet-movement/create-worksheet-movement.ts +17 -0
  230. package/server/graphql/resolvers/worksheet-movement/delete-worksheet-movement.ts +12 -0
  231. package/server/graphql/resolvers/worksheet-movement/index.ts +17 -0
  232. package/server/graphql/resolvers/worksheet-movement/update-worksheet-movement.ts +15 -0
  233. package/server/graphql/resolvers/worksheet-movement/worksheet-movement.ts +10 -0
  234. package/server/graphql/resolvers/worksheet-movement/worksheet-movements.ts +14 -0
  235. package/server/graphql/types/index.ts +15 -0
  236. package/server/graphql/types/pallet/index.ts +12 -0
  237. package/server/graphql/types/pallet/pallet.ts +7 -0
  238. package/server/graphql/types/worksheet/arrival-notice-worksheet.ts +8 -0
  239. package/server/graphql/types/worksheet/batch-pick-worksheet-info.ts +9 -0
  240. package/server/graphql/types/worksheet/contact-point-info.ts +12 -0
  241. package/server/graphql/types/worksheet/cycle-count-worksheet.ts +16 -0
  242. package/server/graphql/types/worksheet/delivery-info.ts +11 -0
  243. package/server/graphql/types/worksheet/delivery-order-info.ts +25 -0
  244. package/server/graphql/types/worksheet/delivery-order-ro.ts +15 -0
  245. package/server/graphql/types/worksheet/delivery-worksheet.ts +7 -0
  246. package/server/graphql/types/worksheet/executing-worksheet.ts +8 -0
  247. package/server/graphql/types/worksheet/find-release-orders-by-task-no.ts +8 -0
  248. package/server/graphql/types/worksheet/goods-delivery-note.ts +8 -0
  249. package/server/graphql/types/worksheet/index.ts +750 -0
  250. package/server/graphql/types/worksheet/inventory-check-worksheet.ts +7 -0
  251. package/server/graphql/types/worksheet/loaded-worksheet-detail.ts +9 -0
  252. package/server/graphql/types/worksheet/multiple-release-good-worksheet.ts +8 -0
  253. package/server/graphql/types/worksheet/my-picking-assignment-status.ts +9 -0
  254. package/server/graphql/types/worksheet/new-worksheet.ts +10 -0
  255. package/server/graphql/types/worksheet/picking-assignment-status.ts +9 -0
  256. package/server/graphql/types/worksheet/product-approval.ts +11 -0
  257. package/server/graphql/types/worksheet/release-good-worksheet.ts +8 -0
  258. package/server/graphql/types/worksheet/return-order-worksheet.ts +8 -0
  259. package/server/graphql/types/worksheet/sellercraft-document.ts +8 -0
  260. package/server/graphql/types/worksheet/vas-order-worksheet.ts +7 -0
  261. package/server/graphql/types/worksheet/vas-worksheet.ts +8 -0
  262. package/server/graphql/types/worksheet/worksheet-detail-info.ts +68 -0
  263. package/server/graphql/types/worksheet/worksheet-info.ts +33 -0
  264. package/server/graphql/types/worksheet/worksheet-list.ts +8 -0
  265. package/server/graphql/types/worksheet/worksheet-patch.ts +19 -0
  266. package/server/graphql/types/worksheet/worksheet-with-pagination.ts +9 -0
  267. package/server/graphql/types/worksheet/worksheet.ts +34 -0
  268. package/server/graphql/types/worksheet-detail/index.ts +81 -0
  269. package/server/graphql/types/worksheet-detail/inventory-detail.ts +39 -0
  270. package/server/graphql/types/worksheet-detail/new-worksheet-detail.ts +20 -0
  271. package/server/graphql/types/worksheet-detail/pallet-info.ts +8 -0
  272. package/server/graphql/types/worksheet-detail/worksheet-detail-list.ts +8 -0
  273. package/server/graphql/types/worksheet-detail/worksheet-detail-patch.ts +28 -0
  274. package/server/graphql/types/worksheet-detail/worksheet-detail.ts +29 -0
  275. package/server/graphql/types/worksheet-movement/index.ts +30 -0
  276. package/server/graphql/types/worksheet-movement/new-worksheet-movement.ts +8 -0
  277. package/server/graphql/types/worksheet-movement/worksheet-movement-list.ts +8 -0
  278. package/server/graphql/types/worksheet-movement/worksheet-movement-patch.ts +8 -0
  279. package/server/graphql/types/worksheet-movement/worksheet-movement.ts +10 -0
  280. package/server/index.ts +14 -0
  281. package/server/middlewares/index.ts +3 -0
  282. package/server/migrations/index.ts +9 -0
  283. package/server/routes.ts +80 -0
  284. package/server/utils/datetime-util.ts +54 -0
  285. package/server/utils/index.ts +4 -0
  286. package/server/utils/inventory-util.ts +390 -0
  287. package/server/utils/worksheet-no-generator.ts +206 -0
  288. package/server/utils/worksheet-util.ts +85 -0
@@ -0,0 +1,1400 @@
1
+ import { Equal, In, Not, SelectQueryBuilder } from 'typeorm'
2
+
3
+ import { Bizplace } from '@things-factory/biz-base'
4
+ import { generateId } from '@things-factory/id-rule-base'
5
+ import { Product, ProductDetail } from '@things-factory/product-base'
6
+ import {
7
+ ArrivalNotice,
8
+ ORDER_PRODUCT_STATUS,
9
+ ORDER_STATUS,
10
+ ORDER_TYPES,
11
+ ORDER_VAS_STATUS,
12
+ OrderInventory,
13
+ OrderNoGenerator,
14
+ OrderProduct,
15
+ OrderVas,
16
+ ReleaseGood,
17
+ ReturnOrder,
18
+ Vas,
19
+ VAS_TARGET_TYPES,
20
+ VAS_TYPES
21
+ } from '@things-factory/sales-base'
22
+ import { PartnerSetting, Setting } from '@things-factory/setting-base'
23
+ import { Domain } from '@things-factory/shell'
24
+ import {
25
+ Inventory,
26
+ INVENTORY_ITEM_SOURCE,
27
+ INVENTORY_STATUS,
28
+ INVENTORY_TRANSACTION_TYPE,
29
+ InventoryHistory,
30
+ InventoryItem,
31
+ InventoryNoGenerator,
32
+ Location,
33
+ Pallet,
34
+ Warehouse
35
+ } from '@things-factory/warehouse-base'
36
+
37
+ import { RULE_TYPE, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
38
+ import { Worksheet, WorksheetDetail } from '../../entities'
39
+ import { DateGenerator, generateInventoryHistory } from '../../utils'
40
+ import { VasWorksheetController } from '../vas/vas-worksheet-controller'
41
+
42
+ export type UnloadingWorksheetDetail = Partial<WorksheetDetail> & {
43
+ palletizingVasId: string
44
+ palletQty: number
45
+ palletizingDescription: string
46
+ }
47
+
48
+ export class UnloadingWorksheetController extends VasWorksheetController {
49
+ async generateUnloadingWorksheet(arrivalNoticeNo: string, bufferLocationId: string): Promise<Worksheet> {
50
+ try {
51
+ //@ts-ignore
52
+ let arrivalNotice: ArrivalNotice = await this.findRefOrder(
53
+ //@ts-ignore
54
+ ArrivalNotice,
55
+ {
56
+ domain: { id: this.domain.id },
57
+ name: arrivalNoticeNo,
58
+ status: ORDER_STATUS.ARRIVED
59
+ },
60
+ ['bizplace', 'orderProducts', 'orderVass']
61
+ )
62
+ const orderProducts: OrderProduct[] = arrivalNotice.orderProducts
63
+ const orderVASs: OrderVas[] = arrivalNotice.orderVass
64
+ const bufferLocation: Location = await this.trxMgr.getRepository(Location).findOneBy({ id: bufferLocationId })
65
+
66
+ const worksheet: Worksheet = await this.generateWorksheet(
67
+ WORKSHEET_TYPE.UNLOADING,
68
+ arrivalNotice,
69
+ orderProducts,
70
+ ORDER_STATUS.READY_TO_UNLOAD,
71
+ ORDER_PRODUCT_STATUS.READY_TO_UNLOAD,
72
+ { bufferLocation }
73
+ )
74
+
75
+ if (orderVASs?.length > 0) {
76
+ await this.generateVasWorksheet(arrivalNotice)
77
+ }
78
+
79
+ return worksheet
80
+ } catch (e) {
81
+ throw new Error(e)
82
+ }
83
+ }
84
+
85
+ async unload(worksheetDetailName: string, inventory: Partial<Inventory>, productBarcode: string): Promise<string> {
86
+ const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
87
+ where: {
88
+ name: worksheetDetailName,
89
+ status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED))
90
+ },
91
+ relations: [
92
+ 'bizplace',
93
+ 'worksheet',
94
+ 'worksheet.arrivalNotice',
95
+ 'worksheet.returnOrder',
96
+ 'worksheet.bufferLocation',
97
+ 'worksheet.bufferLocation.warehouse',
98
+ 'targetProduct',
99
+ 'targetProduct.product',
100
+ 'targetProduct.product.productDetails',
101
+ 'targetProduct.product.productDetails.childProductDetail',
102
+ 'targetInventory',
103
+ 'targetInventory.inventory',
104
+ 'targetInventory.product',
105
+ 'targetInventory.product.productDetails',
106
+ 'targetInventory.product.productDetails.childProductDetail'
107
+ ]
108
+ })
109
+ if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
110
+ const targetProduct: OrderProduct = worksheetDetail.targetProduct
111
+
112
+ if (targetProduct && targetProduct.status == ORDER_PRODUCT_STATUS.EDITED)
113
+ throw new Error('this product is pending for changes approval')
114
+
115
+ const bizplace: Bizplace = worksheetDetail.bizplace
116
+ const companyDomain: Domain = bizplace?.company?.domain
117
+ const worksheet: Worksheet = worksheetDetail.worksheet
118
+ const arrivalNotice: ArrivalNotice = worksheet.arrivalNotice
119
+ const returnOrder: ReturnOrder = worksheet.returnOrder
120
+ const orderId: string = Boolean(arrivalNotice?.id) ? arrivalNotice.id : returnOrder.id
121
+ const targetInventory: OrderInventory = worksheetDetail?.targetInventory
122
+ //@ts-ignore
123
+ const originInventory: OrderInventory = targetInventory ? targetInventory.inventory : null
124
+ const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
125
+ const batchIdRef: string = Boolean(arrivalNotice) ? targetProduct.batchIdRef : null
126
+ const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
127
+ const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
128
+ const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
129
+ const remark: string = Boolean(arrivalNotice) ? targetProduct.remark : targetInventory.remark
130
+ //@ts-ignore
131
+ const manufactureDate: number = Boolean(arrivalNotice) ? targetProduct.manufactureDate : null
132
+ let qty: number = inventory.qty
133
+ let uom: string = Boolean(arrivalNotice) ? targetProduct.uom : originInventory.uom
134
+ const location: Location = worksheet.bufferLocation
135
+ const warehouse: Warehouse = location.warehouse
136
+ const zone: string = location.zone
137
+ const unitCost: number = Boolean(arrivalNotice)
138
+ ? targetProduct?.unitPrice
139
+ ? ((targetProduct.packQty * targetProduct.unitPrice + targetProduct.miscAmt - targetProduct.discountAmt) *
140
+ (1 + targetProduct.taxRate / 100)) /
141
+ targetProduct.packQty
142
+ : 0
143
+ : null
144
+
145
+ const palletId: string = inventory?.palletId
146
+ const cartonId: string = inventory?.cartonId
147
+
148
+ if (!inventory?.palletId) {
149
+ inventory.palletId = await generateId({
150
+ domain: this.domain,
151
+ type: RULE_TYPE.LOT_NUMBER_ID,
152
+ seed: { date: DateGenerator.generateDate() }
153
+ })
154
+ if (inventory?.cartonId) await this.checkCartonDuplication(cartonId, orderId)
155
+ } else {
156
+ await this.checkPalletDuplication(palletId)
157
+ }
158
+
159
+ if (productBarcode) {
160
+ const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
161
+ const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
162
+ if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
163
+
164
+ const foundProductDetail: ProductDetail = productDetails.find(
165
+ (detail: ProductDetail) =>
166
+ detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
167
+ )
168
+
169
+ if (!foundProductDetail) {
170
+ const orderProductDetail: ProductDetail = productDetails.find(
171
+ (parentDetail: ProductDetail) =>
172
+ parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
173
+ )
174
+ if (!orderProductDetail)
175
+ throw new Error(
176
+ this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
177
+ )
178
+
179
+ if (arrivalNotice) {
180
+ uom = targetProduct.uom
181
+ } else {
182
+ uom = orderProductDetail.uom
183
+ }
184
+ qty = (await this.getChildQty(productDetails, productBarcode, orderProductDetail)) * qty
185
+ } else {
186
+ uom = foundProductDetail.uom
187
+ qty
188
+ }
189
+ }
190
+
191
+ const uomValue: number =
192
+ Math.round(
193
+ qty *
194
+ (Boolean(arrivalNotice)
195
+ ? targetProduct.uomValue
196
+ : targetInventory.returnUomValue / targetInventory.returnQty) *
197
+ 100
198
+ ) / 100
199
+
200
+ let newInventory: Partial<Inventory> = new Inventory()
201
+ newInventory.bizplace = bizplace
202
+ newInventory.name = InventoryNoGenerator.inventoryName()
203
+ newInventory.palletId = inventory.palletId
204
+ newInventory.cartonId = inventory.cartonId
205
+ newInventory.batchId = batchId
206
+ newInventory.product = product
207
+ newInventory.packingType = packingType
208
+ newInventory.packingSize = packingSize
209
+ newInventory.uom = uom
210
+ newInventory.remark = remark
211
+ newInventory.qty = qty
212
+ newInventory.uomValue = uomValue
213
+ newInventory.refOrderId = orderId
214
+ newInventory.unitCost = unitCost
215
+ if (inventory.reusablePallet?.id) {
216
+ newInventory.reusablePallet = await this.trxMgr
217
+ .getRepository(Pallet)
218
+ .findOneBy({ id: inventory.reusablePallet.id })
219
+ }
220
+ if (arrivalNotice) {
221
+ if (manufactureDate) {
222
+ //@ts-ignore
223
+ newInventory.manufactureDate = manufactureDate
224
+ } else if (inventory?.manufactureDate) {
225
+ newInventory.manufactureDate = new Date(inventory.manufactureDate)
226
+ }
227
+ newInventory.batchIdRef = batchIdRef
228
+ newInventory.orderProductId = targetProduct?.id
229
+ } else if (returnOrder) {
230
+ newInventory.orderInventoryId = targetInventory?.id
231
+ newInventory.refInventory = targetInventory?.inventory
232
+ }
233
+ newInventory.warehouse = warehouse
234
+ newInventory.location = location
235
+ newInventory.zone = zone
236
+ newInventory.status = INVENTORY_STATUS.UNLOADED
237
+
238
+ // product color, quality, zaho, work category
239
+ newInventory.productColor = inventory.productColor || ''
240
+ newInventory.productQuality = inventory.productQuality || ''
241
+ newInventory.auxInfo2 = inventory.auxInfo2 || null
242
+ newInventory.workCategory = inventory.workCategory || ''
243
+ newInventory.isMachineFiltering = inventory.isMachineFiltering || false
244
+ newInventory.origin = inventory.origin || ''
245
+
246
+ if (inventory?.expirationDate) {
247
+ newInventory.expirationDate = new Date(inventory.expirationDate)
248
+ }
249
+
250
+ newInventory = await this.transactionInventory(
251
+ newInventory,
252
+ Boolean(arrivalNotice) ? arrivalNotice : returnOrder,
253
+ newInventory.qty,
254
+ newInventory.uomValue,
255
+ INVENTORY_TRANSACTION_TYPE.UNLOADING
256
+ )
257
+
258
+ if (arrivalNotice) {
259
+ targetProduct.actualPalletQty++
260
+ targetProduct.actualPackQty += qty
261
+ targetProduct.status = ORDER_PRODUCT_STATUS.UNLOADED
262
+ targetProduct.updater = this.user
263
+ this.updateOrderTargets([targetProduct])
264
+ } else if (returnOrder) {
265
+ targetInventory.actualPalletQty++
266
+ targetInventory.actualPackQty += qty
267
+ targetInventory.status = ORDER_PRODUCT_STATUS.UNLOADED
268
+ targetInventory.updater = this.user
269
+ this.updateOrderTargets([targetInventory])
270
+ }
271
+
272
+ return inventory.palletId
273
+ }
274
+
275
+ async scanSerialNumberUnload(
276
+ worksheetDetailName: string,
277
+ serialNumber: string,
278
+ inventory: Partial<Inventory>
279
+ ): Promise<void> {
280
+ const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
281
+ where: {
282
+ name: worksheetDetailName,
283
+ status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED))
284
+ },
285
+ relations: [
286
+ 'bizplace',
287
+ 'worksheet',
288
+ 'worksheet.arrivalNotice',
289
+ 'worksheet.returnOrder',
290
+ 'worksheet.bufferLocation',
291
+ 'worksheet.bufferLocation.warehouse',
292
+ 'targetProduct',
293
+ 'targetProduct.product',
294
+ 'targetProduct.product.productDetails',
295
+ 'targetProduct.product.productDetails.childProductDetail',
296
+ 'targetInventory',
297
+ 'targetInventory.product',
298
+ 'targetInventory.product.productDetails',
299
+ 'targetInventory.product.productDetails.childProductDetail'
300
+ ]
301
+ })
302
+ if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
303
+
304
+ if (!inventory?.palletId)
305
+ inventory.palletId = await generateId({
306
+ domain: this.domain,
307
+ type: RULE_TYPE.LOT_NUMBER_ID,
308
+ seed: { date: DateGenerator.generateDate() }
309
+ })
310
+
311
+ const targetProduct: OrderProduct = worksheetDetail.targetProduct
312
+
313
+ if (targetProduct.status == ORDER_PRODUCT_STATUS.EDITED)
314
+ throw new Error('this product is pending for changes approval')
315
+
316
+ const bizplace: Bizplace = worksheetDetail.bizplace
317
+ const worksheet: Worksheet = worksheetDetail.worksheet
318
+ const arrivalNotice: ArrivalNotice = worksheet.arrivalNotice
319
+ const returnOrder: ReturnOrder = worksheet.returnOrder
320
+ const targetInventory: OrderInventory = worksheetDetail.targetInventory
321
+ const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
322
+ const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
323
+ const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
324
+ const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
325
+ let qty: number = 0
326
+ let uom: string = Boolean(arrivalNotice) ? targetProduct.uom : targetInventory.uom
327
+ const cartonId: string = inventory.cartonId
328
+ const orderId: string = Boolean(arrivalNotice) ? arrivalNotice.id : returnOrder.id
329
+ await this.checkSerialNumberDuplication(serialNumber, product)
330
+
331
+ qty++
332
+
333
+ const invQb: SelectQueryBuilder<Inventory> = await this.trxMgr
334
+ .getRepository(Inventory)
335
+ .createQueryBuilder('INV')
336
+ .where('INV.domain_id = :domainId', { domainId: this.domain.id })
337
+ .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: bizplace.id })
338
+ .andWhere('INV.product_id = :productId', { productId: product.id })
339
+ .andWhere('INV.batch_id = :batchId', { batchId: batchId })
340
+ .andWhere('INV.packing_type = :packingType', { packingType: packingType })
341
+ .andWhere('INV.packing_size = :packingSize', { packingSize: packingSize })
342
+
343
+ if (arrivalNotice) invQb.andWhere('INV.ref_order_id = :arrivalNoticeId', { arrivalNoticeId: arrivalNotice.id })
344
+ else if (returnOrder) invQb.andWhere('INV.ref_order_id = :returnOrderId', { returnOrderId: returnOrder.id })
345
+
346
+ if (inventory?.expirationDate) {
347
+ invQb.andWhere('INV.expiration_date = :expirationDate', {
348
+ expirationDate: inventory.expirationDate
349
+ })
350
+ }
351
+
352
+ if (inventory?.cartonId) invQb.andWhere('INV.carton_id = :cartonId', { cartonId: inventory.cartonId })
353
+ else invQb.andWhere('INV.pallet_id = :palletId', { palletId: inventory.palletId })
354
+
355
+ let foundInventory: Inventory = await invQb.getOne()
356
+
357
+ const batchIdRef: string = Boolean(arrivalNotice) ? targetProduct.batchIdRef : null
358
+ const remark: string = Boolean(arrivalNotice) ? targetProduct.remark : targetInventory.remark
359
+ //@ts-ignore
360
+ const manufactureDate: number = Boolean(arrivalNotice) ? targetProduct.manufactureDate : null
361
+ const location: Location = worksheet.bufferLocation
362
+ const warehouse: Warehouse = location.warehouse
363
+ const zone: string = location.zone
364
+ const unitCost: number = Boolean(arrivalNotice)
365
+ ? targetProduct?.unitPrice
366
+ ? ((targetProduct.packQty * targetProduct.unitPrice + targetProduct.miscAmt - targetProduct.discountAmt) *
367
+ (1 + targetProduct.taxRate / 100)) /
368
+ targetProduct.packQty
369
+ : 0
370
+ : null
371
+
372
+ if (!foundInventory) {
373
+ let newInventory: Partial<Inventory> = new Inventory()
374
+ newInventory.bizplace = bizplace
375
+ newInventory.domain = this.domain
376
+ newInventory.name = InventoryNoGenerator.inventoryName()
377
+ newInventory.palletId = inventory.palletId
378
+ newInventory.cartonId = inventory.cartonId
379
+ newInventory.batchId = batchId
380
+ newInventory.batchIdRef = batchIdRef
381
+ newInventory.product = product
382
+ newInventory.packingType = packingType
383
+ newInventory.packingSize = packingSize
384
+ newInventory.uom = uom
385
+ newInventory.remark = remark
386
+ newInventory.qty = qty
387
+ newInventory.uomValue =
388
+ Math.round(
389
+ qty *
390
+ (Boolean(arrivalNotice)
391
+ ? targetProduct.uomValue
392
+ : targetInventory.returnUomValue / targetInventory.returnQty) *
393
+ 100
394
+ ) / 100
395
+ //@ts-ignore
396
+ newInventory.manufactureDate = manufactureDate
397
+ newInventory.refOrderId = orderId
398
+ newInventory.unitCost = unitCost
399
+ if (inventory.reusablePallet?.id) {
400
+ newInventory.reusablePallet = await this.trxMgr
401
+ .getRepository(Pallet)
402
+ .findOneBy({ id: inventory.reusablePallet.id })
403
+ }
404
+ newInventory.orderProductId = Boolean(arrivalNotice) ? targetProduct.id : null
405
+ newInventory.orderInventoryId = Boolean(returnOrder) ? targetInventory.id : null
406
+ newInventory.warehouse = warehouse
407
+ newInventory.location = location
408
+ newInventory.zone = zone
409
+ newInventory.status = INVENTORY_STATUS.CHECKED
410
+ newInventory.creator = this.user
411
+
412
+ if (inventory?.expirationDate) {
413
+ newInventory.expirationDate = new Date(inventory.expirationDate)
414
+ }
415
+
416
+ if (arrivalNotice) {
417
+ targetProduct.actualPalletQty++
418
+ targetProduct.actualPackQty = Boolean(targetProduct.actualPackQty) ? targetProduct.actualPackQty + qty : qty
419
+ } else if (returnOrder) {
420
+ targetInventory.actualPalletQty++
421
+ targetInventory.actualPackQty = Boolean(targetInventory.actualPackQty)
422
+ ? targetInventory.actualPackQty + qty
423
+ : qty
424
+ }
425
+ foundInventory = await this.trxMgr.getRepository(Inventory).save(newInventory)
426
+ } else {
427
+ const updatedQty: number = foundInventory.qty + qty
428
+ foundInventory.expirationDate = foundInventory.expirationDate ? new Date(foundInventory.expirationDate) : null
429
+ foundInventory.qty = updatedQty
430
+ foundInventory.uomValue +=
431
+ Math.round(
432
+ qty *
433
+ (Boolean(arrivalNotice)
434
+ ? targetProduct.uomValue
435
+ : targetInventory.returnUomValue / targetInventory.returnQty) *
436
+ 100
437
+ ) / 100
438
+ if (arrivalNotice) targetProduct.actualPackQty = targetProduct.actualPackQty + qty
439
+ else if (returnOrder) targetInventory.actualPackQty = targetInventory.actualPackQty + qty
440
+ foundInventory = await this.trxMgr.getRepository(Inventory).save(foundInventory)
441
+ }
442
+
443
+ let inventoryItem: InventoryItem = new InventoryItem()
444
+ inventoryItem.name = InventoryNoGenerator.inventoryItemName()
445
+ inventoryItem.serialNumber = serialNumber
446
+ inventoryItem.status = foundInventory.status
447
+ inventoryItem.inboundOrderId = foundInventory.refOrderId
448
+ inventoryItem.product = product
449
+ inventoryItem.inventory = foundInventory
450
+ inventoryItem.source = INVENTORY_ITEM_SOURCE.INBOUND
451
+ inventoryItem.domain = this.domain
452
+ inventoryItem.creator = this.user
453
+ inventoryItem.updater = this.user
454
+
455
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
456
+
457
+ if (arrivalNotice) {
458
+ targetProduct.updater = this.user
459
+ this.updateOrderTargets([targetProduct])
460
+ } else if (returnOrder) {
461
+ targetInventory.updater = this.user
462
+ this.updateOrderTargets([targetInventory])
463
+ }
464
+ }
465
+
466
+ async scanProductUnload(
467
+ worksheetDetailName: string,
468
+ productBarcode: string,
469
+ inventory: Partial<Inventory>
470
+ ): Promise<void> {
471
+ const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
472
+ where: {
473
+ name: worksheetDetailName,
474
+ status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED))
475
+ },
476
+ relations: [
477
+ 'bizplace',
478
+ 'worksheet',
479
+ 'worksheet.arrivalNotice',
480
+ 'worksheet.returnOrder',
481
+ 'worksheet.bufferLocation',
482
+ 'worksheet.bufferLocation.warehouse',
483
+ 'targetProduct',
484
+ 'targetProduct.product',
485
+ 'targetProduct.product.productDetails',
486
+ 'targetProduct.product.productDetails.childProductDetail',
487
+ 'targetInventory',
488
+ 'targetInventory.product',
489
+ 'targetInventory.product.productDetails',
490
+ 'targetInventory.product.productDetails.childProductDetail'
491
+ ]
492
+ })
493
+ if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
494
+
495
+ if (!inventory?.palletId)
496
+ inventory.palletId = await generateId({
497
+ domain: this.domain,
498
+ type: RULE_TYPE.LOT_NUMBER_ID,
499
+ seed: { date: DateGenerator.generateDate() }
500
+ })
501
+
502
+ const targetProduct: OrderProduct = worksheetDetail.targetProduct
503
+
504
+ if (targetProduct.status == ORDER_PRODUCT_STATUS.EDITED)
505
+ throw new Error('this product is pending for changes approval')
506
+
507
+ const bizplace: Bizplace = worksheetDetail.bizplace
508
+ const worksheet: Worksheet = worksheetDetail.worksheet
509
+ const arrivalNotice: ArrivalNotice = worksheet.arrivalNotice
510
+ const returnOrder: ReturnOrder = worksheet.returnOrder
511
+ const targetInventory: OrderInventory = worksheetDetail.targetInventory
512
+ const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
513
+ const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
514
+ const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
515
+ const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
516
+ let qty: number = 0
517
+ let uom: string = Boolean(arrivalNotice) ? targetProduct.uom : targetInventory.uom
518
+ const cartonId: string = inventory.cartonId
519
+ const orderId: string = Boolean(arrivalNotice) ? arrivalNotice.id : returnOrder.id
520
+ await this.checkCartonDuplication(cartonId, orderId)
521
+
522
+ // search for matching product barcode
523
+ const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
524
+ const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
525
+ if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
526
+
527
+ // case for scanning parent packing type, packing size
528
+ const foundProductDetail: ProductDetail = productDetails.find(
529
+ (detail: ProductDetail) =>
530
+ detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
531
+ )
532
+
533
+ if (!foundProductDetail) {
534
+ const orderProductDetail: ProductDetail = productDetails.find(
535
+ (parentDetail: ProductDetail) =>
536
+ parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
537
+ )
538
+ if (!orderProductDetail)
539
+ throw new Error(
540
+ this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
541
+ )
542
+
543
+ if (arrivalNotice) {
544
+ uom = targetProduct.uom
545
+ } else {
546
+ uom = orderProductDetail.uom
547
+ }
548
+ qty = await this.getChildQty(productDetails, productBarcode, orderProductDetail)
549
+ } else {
550
+ uom = foundProductDetail.uom
551
+ qty++
552
+ }
553
+
554
+ const invQb: SelectQueryBuilder<Inventory> = await this.trxMgr
555
+ .getRepository(Inventory)
556
+ .createQueryBuilder('INV')
557
+ .where('INV.domain_id = :domainId', { domainId: this.domain.id })
558
+ .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: bizplace.id })
559
+ .andWhere('INV.product_id = :productId', { productId: product.id })
560
+ .andWhere('INV.batch_id = :batchId', { batchId: batchId })
561
+ .andWhere('INV.packing_type = :packingType', { packingType: packingType })
562
+ .andWhere('INV.packing_size = :packingSize', { packingSize: packingSize })
563
+
564
+ if (arrivalNotice) invQb.andWhere('INV.ref_order_id = :arrivalNoticeId', { arrivalNoticeId: arrivalNotice.id })
565
+ else if (returnOrder) invQb.andWhere('INV.ref_order_id = :returnOrderId', { returnOrderId: returnOrder.id })
566
+
567
+ if (inventory?.expirationDate) {
568
+ invQb.andWhere('INV.expiration_date = :expirationDate', {
569
+ expirationDate: inventory.expirationDate
570
+ })
571
+ }
572
+
573
+ if (inventory?.cartonId) invQb.andWhere('INV.carton_id = :cartonId', { cartonId: inventory.cartonId })
574
+ else invQb.andWhere('INV.pallet_id = :palletId', { palletId: inventory.palletId })
575
+
576
+ let foundInventory: Inventory = await invQb.getOne()
577
+
578
+ const batchIdRef: string = Boolean(arrivalNotice) ? targetProduct.batchIdRef : null
579
+ const remark: string = Boolean(arrivalNotice) ? targetProduct.remark : targetInventory.remark
580
+ //@ts-ignore
581
+ const manufactureDate: number = Boolean(arrivalNotice) ? targetProduct.manufactureDate : null
582
+ const location: Location = worksheet.bufferLocation
583
+ const warehouse: Warehouse = location.warehouse
584
+ const zone: string = location.zone
585
+ const unitCost: number = Boolean(arrivalNotice)
586
+ ? targetProduct?.unitPrice
587
+ ? ((targetProduct.packQty * targetProduct.unitPrice + targetProduct.miscAmt - targetProduct.discountAmt) *
588
+ (1 + targetProduct.taxRate / 100)) /
589
+ targetProduct.packQty
590
+ : 0
591
+ : null
592
+
593
+ if (!foundInventory) {
594
+ let newInventory: Partial<Inventory> = new Inventory()
595
+ newInventory.bizplace = bizplace
596
+ newInventory.domain = this.domain
597
+ newInventory.name = InventoryNoGenerator.inventoryName()
598
+ newInventory.palletId = inventory.palletId
599
+ newInventory.cartonId = inventory.cartonId
600
+ newInventory.batchId = batchId
601
+ newInventory.batchIdRef = batchIdRef
602
+ newInventory.product = product
603
+ newInventory.packingType = packingType
604
+ newInventory.packingSize = packingSize
605
+ newInventory.uom = uom
606
+ newInventory.remark = remark
607
+ newInventory.qty = qty
608
+ newInventory.uomValue =
609
+ Math.round(
610
+ qty *
611
+ (Boolean(arrivalNotice)
612
+ ? targetProduct.uomValue
613
+ : targetInventory.returnUomValue / targetInventory.returnQty) *
614
+ 100
615
+ ) / 100
616
+ //@ts-ignore
617
+ newInventory.manufactureDate = manufactureDate
618
+ newInventory.refOrderId = orderId
619
+ newInventory.unitCost = unitCost
620
+ if (inventory.reusablePallet?.id) {
621
+ newInventory.reusablePallet = await this.trxMgr
622
+ .getRepository(Pallet)
623
+ .findOneBy({ id: inventory.reusablePallet.id })
624
+ }
625
+ newInventory.orderProductId = Boolean(arrivalNotice) ? targetProduct.id : null
626
+ newInventory.orderInventoryId = Boolean(returnOrder) ? targetInventory.id : null
627
+ newInventory.warehouse = warehouse
628
+ newInventory.location = location
629
+ newInventory.zone = zone
630
+ newInventory.status = INVENTORY_STATUS.CHECKED
631
+ newInventory.creator = this.user
632
+
633
+ if (inventory?.expirationDate) {
634
+ newInventory.expirationDate = new Date(inventory.expirationDate)
635
+ }
636
+
637
+ if (arrivalNotice) {
638
+ targetProduct.actualPalletQty++
639
+ targetProduct.actualPackQty = Boolean(targetProduct.actualPackQty) ? targetProduct.actualPackQty + qty : qty
640
+ } else if (returnOrder) {
641
+ targetInventory.actualPalletQty++
642
+ targetInventory.actualPackQty = Boolean(targetInventory.actualPackQty)
643
+ ? targetInventory.actualPackQty + qty
644
+ : qty
645
+ }
646
+ await this.trxMgr.getRepository(Inventory).save(newInventory)
647
+ } else {
648
+ const updatedQty: number = foundInventory.qty + qty
649
+ foundInventory.expirationDate = foundInventory.expirationDate ? new Date(foundInventory.expirationDate) : null
650
+ foundInventory.qty = updatedQty
651
+ foundInventory.uomValue +=
652
+ Math.round(
653
+ qty *
654
+ (Boolean(arrivalNotice)
655
+ ? targetProduct.uomValue
656
+ : targetInventory.returnUomValue / targetInventory.returnQty) *
657
+ 100
658
+ ) / 100
659
+ if (arrivalNotice) targetProduct.actualPackQty = targetProduct.actualPackQty + qty
660
+ else if (returnOrder) targetInventory.actualPackQty = targetInventory.actualPackQty + qty
661
+ await this.trxMgr.getRepository(Inventory).save(foundInventory)
662
+ }
663
+
664
+ if (arrivalNotice) {
665
+ targetProduct.updater = this.user
666
+ this.updateOrderTargets([targetProduct])
667
+ } else if (returnOrder) {
668
+ targetInventory.updater = this.user
669
+ this.updateOrderTargets([targetInventory])
670
+ }
671
+ }
672
+
673
+ async completeProductScanUnload(worksheetDetailName: string, inventory: Partial<Inventory>): Promise<void> {
674
+ const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
675
+ where: {
676
+ name: worksheetDetailName,
677
+ status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED))
678
+ },
679
+ relations: [
680
+ 'bizplace',
681
+ 'worksheet',
682
+ 'worksheet.arrivalNotice',
683
+ 'worksheet.returnOrder',
684
+ 'worksheet.bufferLocation',
685
+ 'worksheet.bufferLocation.warehouse',
686
+ 'targetProduct',
687
+ 'targetProduct.product',
688
+ 'targetInventory',
689
+ 'targetInventory.product'
690
+ ]
691
+ })
692
+ if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
693
+
694
+ const bizplace: Bizplace = worksheetDetail.bizplace
695
+ const worksheet: Worksheet = worksheetDetail.worksheet
696
+ const arrivalNotice: ArrivalNotice = worksheet.arrivalNotice
697
+ const returnOrder: ReturnOrder = worksheet.returnOrder
698
+ const targetProduct: OrderProduct = worksheetDetail.targetProduct
699
+ const targetInventory: OrderInventory = worksheetDetail.targetInventory
700
+ const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
701
+ const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
702
+ const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
703
+ const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
704
+
705
+ const invQb: SelectQueryBuilder<Inventory> = await this.trxMgr
706
+ .getRepository(Inventory)
707
+ .createQueryBuilder('INV')
708
+ .where('INV.domain_id = :domainId', { domainId: this.domain.id })
709
+ .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: bizplace.id })
710
+ .andWhere('INV.product_id = :productId', { productId: product.id })
711
+ .andWhere('INV.batch_id = :batchId', { batchId: batchId })
712
+ .andWhere('INV.packing_type = :packingType', { packingType: packingType })
713
+ .andWhere('INV.packing_size = :packingSize', { packingSize: packingSize })
714
+
715
+ if (arrivalNotice) invQb.andWhere('INV.ref_order_id = :arrivalNoticeId', { arrivalNoticeId: arrivalNotice.id })
716
+ else if (returnOrder) invQb.andWhere('INV.ref_order_id = :returnOrderId', { returnOrderId: returnOrder.id })
717
+
718
+ if (inventory?.expirationDate) {
719
+ invQb.andWhere('INV.expiration_date = :expirationDate', {
720
+ expirationDate: inventory.expirationDate
721
+ })
722
+ }
723
+
724
+ if (inventory?.cartonId) invQb.andWhere('INV.carton_id = :cartonId', { cartonId: inventory.cartonId })
725
+ else invQb.andWhere('INV.pallet_id = :palletId', { palletId: inventory.palletId })
726
+
727
+ let foundInventory: Inventory = await invQb.getOne()
728
+ if (!foundInventory) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(foundInventory.palletId))
729
+
730
+ foundInventory.status = INVENTORY_STATUS.UNLOADED
731
+
732
+ foundInventory = await this.transactionInventory(
733
+ foundInventory,
734
+ Boolean(arrivalNotice) ? arrivalNotice : returnOrder,
735
+ foundInventory.qty,
736
+ foundInventory.uomValue,
737
+ INVENTORY_TRANSACTION_TYPE.UNLOADING
738
+ )
739
+ }
740
+
741
+ async undoUnload(orderType: string, orderNo: string, inventoryIds: [string]): Promise<void> {
742
+ for (var i = 0; i < inventoryIds.length; i++) {
743
+ const inventoryId: string = inventoryIds[i]
744
+ let inventory: Inventory = await this.trxMgr.getRepository(Inventory).findOne({
745
+ where: { domain: { id: this.domain.id }, id: inventoryId },
746
+ relations: ['location', 'product']
747
+ })
748
+
749
+ this.checkRecordValidity(inventory, {
750
+ status: (status: string) => {
751
+ const availableStatus: string[] = [INVENTORY_STATUS.UNLOADED, INVENTORY_STATUS.CHECKED]
752
+ if (availableStatus.indexOf(status) < 0) {
753
+ throw new Error(
754
+ this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE(
755
+ 'status',
756
+ 'Inventory current status unable to undo',
757
+ status
758
+ )
759
+ )
760
+ }
761
+ return true
762
+ }
763
+ })
764
+
765
+ const qty: number = inventory.qty
766
+
767
+ let targetProduct: OrderProduct
768
+ let targetInventory: OrderInventory
769
+ let arrivalNotice: ArrivalNotice
770
+ let returnOrder: ReturnOrder
771
+ let worksheetDetail: WorksheetDetail
772
+
773
+ if (orderType === ORDER_TYPES.ARRIVAL_NOTICE) {
774
+ arrivalNotice = await this.trxMgr.getRepository(ArrivalNotice).findOne({
775
+ where: { domain: { id: this.domain.id }, name: orderNo },
776
+ relations: ['orderProducts', 'orderProducts.product']
777
+ })
778
+
779
+ targetProduct = arrivalNotice.orderProducts.find(op => op.id === inventory.orderProductId)
780
+
781
+ if (inventory.status == INVENTORY_STATUS.UNLOADED) {
782
+ targetProduct.actualPackQty -= qty
783
+ targetProduct.actualPalletQty--
784
+ targetProduct.remark = null
785
+ targetProduct.issue = null
786
+ targetProduct.status = ORDER_PRODUCT_STATUS.UNLOADING
787
+ } else {
788
+ targetProduct.actualPackQty--
789
+ // targetProduct.actualPalletQty--
790
+ }
791
+ targetProduct.updater = this.user
792
+ await this.updateOrderTargets([targetProduct])
793
+
794
+ worksheetDetail = await this.trxMgr
795
+ .getRepository(WorksheetDetail)
796
+ .findOne({ where: { domain: { id: this.domain.id }, targetProduct: { id: targetProduct.id } } })
797
+ } else {
798
+ returnOrder = await this.trxMgr.getRepository(ReturnOrder).findOne({
799
+ where: { domain: { id: this.domain.id }, name: orderNo },
800
+ relations: ['orderInventories', 'orderInventories.inventory', 'orderInventories.product']
801
+ })
802
+
803
+ targetInventory = returnOrder.orderInventories.find(
804
+ oi =>
805
+ oi.batchId == inventory.batchId &&
806
+ oi.packingType == inventory.packingType &&
807
+ oi.product.id == inventory.product.id &&
808
+ oi.packingSize === inventory.packingSize
809
+ )
810
+ if (inventory.status == INVENTORY_STATUS.UNLOADED) {
811
+ targetInventory.actualPackQty -= qty
812
+ targetInventory.actualPalletQty--
813
+ targetInventory.status = ORDER_PRODUCT_STATUS.UNLOADING
814
+ } else {
815
+ targetInventory.actualPackQty--
816
+ // targetInventory.actualPalletQty--
817
+ }
818
+ targetInventory.updater = this.user
819
+ await this.updateOrderTargets([targetInventory])
820
+
821
+ worksheetDetail = await this.trxMgr
822
+ .getRepository(WorksheetDetail)
823
+ .findOne({ where: { domain: { id: this.domain.id }, targetInventory: { id: targetInventory.id } } })
824
+ }
825
+
826
+ if (inventory.status == INVENTORY_STATUS.CHECKED) {
827
+ inventory.qty--
828
+ inventory.uomValue =
829
+ Math.round(
830
+ inventory.qty *
831
+ (Boolean(orderType === ORDER_TYPES.ARRIVAL_NOTICE)
832
+ ? targetProduct.uomValue
833
+ : targetInventory.returnUomValue) *
834
+ 100
835
+ ) / 100
836
+ inventory.updater = this.user
837
+ await this.trxMgr.getRepository(Inventory).save(inventory)
838
+
839
+ if (inventory.qty == 0) {
840
+ inventory.lastSeq++
841
+ inventory.status = INVENTORY_STATUS.DELETED
842
+ inventory = await this.transactionInventory(
843
+ inventory,
844
+ Boolean(orderType === ORDER_TYPES.ARRIVAL_NOTICE) ? arrivalNotice : returnOrder,
845
+ -inventory.qty,
846
+ -inventory.uomValue,
847
+ INVENTORY_TRANSACTION_TYPE.UNDO_UNLOADING
848
+ )
849
+ inventory.qty = 0
850
+ inventory.uomValue = 0
851
+ inventory.updater = this.user
852
+ targetProduct.actualPalletQty--
853
+
854
+ await this.updateOrderTargets([targetProduct])
855
+
856
+ await this.trxMgr.getRepository(InventoryHistory).update({ inventory }, { inventory: null })
857
+
858
+ await this.trxMgr.getRepository(Inventory).delete({ id: inventory.id })
859
+ }
860
+ } else {
861
+ inventory.lastSeq++
862
+ inventory.status = INVENTORY_STATUS.DELETED
863
+ inventory = await this.transactionInventory(
864
+ inventory,
865
+ Boolean(orderType === ORDER_TYPES.ARRIVAL_NOTICE) ? arrivalNotice : returnOrder,
866
+ -inventory.qty,
867
+ -inventory.uomValue,
868
+ INVENTORY_TRANSACTION_TYPE.UNDO_UNLOADING
869
+ )
870
+ inventory.qty = 0
871
+ inventory.uomValue = 0
872
+ inventory.updater = this.user
873
+
874
+ await this.trxMgr.getRepository(InventoryHistory).update({ inventory }, { inventory: null })
875
+
876
+ await this.trxMgr.getRepository(Inventory).delete({ id: inventory.id })
877
+ }
878
+
879
+ worksheetDetail.issue = inventory.qty == 0 && worksheetDetail?.issue ? null : worksheetDetail.issue
880
+ worksheetDetail.status = WORKSHEET_STATUS.EXECUTING
881
+ worksheetDetail.updater = this.user
882
+ await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
883
+ }
884
+ }
885
+
886
+ async undoSerialNumberUnload(worksheetDetailName: string, inventoryItemId: string): Promise<void> {
887
+ const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
888
+ where: {
889
+ name: worksheetDetailName,
890
+ domain: { id: this.domain.id },
891
+ status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED))
892
+ },
893
+ relations: [
894
+ 'worksheet',
895
+ 'worksheet.arrivalNotice',
896
+ 'worksheet.returnOrder',
897
+ 'targetProduct',
898
+ 'targetProduct.product'
899
+ ]
900
+ })
901
+
902
+ let worksheet: Worksheet = worksheetDetail.worksheet
903
+ let arrivalNotice: ArrivalNotice = worksheet.arrivalNotice
904
+ let returnOrder: ReturnOrder = worksheet.returnOrder
905
+ let targetInventory: OrderInventory = worksheetDetail.targetInventory
906
+ let targetProduct: OrderProduct = worksheetDetail.targetProduct
907
+ let inventoryItem: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
908
+ where: { domain: { id: this.domain.id }, id: inventoryItemId },
909
+ relations: ['inventory', 'product']
910
+ })
911
+ let inventory: Inventory = inventoryItem.inventory
912
+
913
+ await this.trxMgr.getRepository(InventoryItem).delete(inventoryItem.id)
914
+
915
+ inventory.qty--
916
+ inventory.uomValue =
917
+ Math.round(
918
+ inventory.qty *
919
+ (Boolean(arrivalNotice)
920
+ ? targetProduct.uomValue
921
+ : targetInventory.returnUomValue / targetInventory.returnQty) *
922
+ 100
923
+ ) / 100
924
+ await this.trxMgr
925
+ .getRepository(Inventory)
926
+ .update({ id: inventory.id }, { qty: inventory.qty, uomValue: inventory.uomValue })
927
+
928
+ targetProduct.actualPackQty--
929
+
930
+ const inventoryItems: InventoryItem[] = await this.trxMgr.getRepository(InventoryItem).find({
931
+ where: { domain: { id: this.domain.id }, inboundOrderId: arrivalNotice.id, inventory: { id: inventory.id } }
932
+ })
933
+
934
+ if (inventoryItems?.length == 0) {
935
+ await this.trxMgr.getRepository(Inventory).delete(inventory.id)
936
+
937
+ targetProduct.actualPalletQty--
938
+ }
939
+
940
+ targetProduct.updater = this.user
941
+ await this.updateOrderTargets([targetProduct])
942
+ }
943
+
944
+ async activateUnloading(
945
+ worksheetNo: string,
946
+ unloadingWorksheetDetails: UnloadingWorksheetDetail[]
947
+ ): Promise<Worksheet> {
948
+ let worksheet: Worksheet = await this.findActivatableWorksheet(worksheetNo, WORKSHEET_TYPE.UNLOADING, [
949
+ 'bizplace',
950
+ 'arrivalNotice',
951
+ 'worksheetDetails',
952
+ 'worksheetDetails.targetProduct',
953
+ 'worksheetDetails.targetProduct.product',
954
+ 'worksheetDetails.targetVas'
955
+ ])
956
+
957
+ let arrivalNotice: ArrivalNotice = worksheet.arrivalNotice
958
+ let vasWorksheet: Worksheet = new Worksheet()
959
+
960
+ try {
961
+ vasWorksheet = await this.findWorksheetByRefOrder(arrivalNotice, WORKSHEET_TYPE.VAS)
962
+ } catch (e) {
963
+ // do nothing
964
+ }
965
+
966
+ if (!Object.keys(vasWorksheet).length || vasWorksheet?.status == WORKSHEET_STATUS.DONE) {
967
+ const bizplace: Bizplace = worksheet.bizplace
968
+ let worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
969
+
970
+ const targetProducts: OrderProduct[] = worksheetDetails.map((wsd: WorksheetDetail) => {
971
+ let targetProduct: OrderProduct = wsd.targetProduct
972
+
973
+ if (!targetProduct.palletQty) {
974
+ const { palletQty }: { palletQty: number } = this.findMatchedWSD(wsd.name, unloadingWorksheetDetails)
975
+ targetProduct.palletQty = palletQty
976
+ }
977
+ targetProduct.status = ORDER_PRODUCT_STATUS.UNLOADING
978
+ targetProduct.updater = this.user
979
+
980
+ return targetProduct
981
+ })
982
+ await this.updateOrderTargets(targetProducts)
983
+
984
+ arrivalNotice.status = ORDER_STATUS.PROCESSING
985
+ arrivalNotice.updater = this.user
986
+ this.updateRefOrder(arrivalNotice)
987
+
988
+ const palletizingWSDs: UnloadingWorksheetDetail[] = this.filterPalletizingWSDs(unloadingWorksheetDetails)
989
+ if (palletizingWSDs?.length) {
990
+ this.createPalletizingWSDs(bizplace, arrivalNotice, worksheetDetails, unloadingWorksheetDetails)
991
+ }
992
+
993
+ worksheet = await this.activateWorksheet(worksheet, worksheetDetails, unloadingWorksheetDetails)
994
+ } else if (vasWorksheet && vasWorksheet.status == WORKSHEET_STATUS.DEACTIVATED) {
995
+ await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
996
+ } else if (vasWorksheet && vasWorksheet.status == WORKSHEET_STATUS.EXECUTING) {
997
+ throw new Error(`There is pending VAS execution`)
998
+ }
999
+
1000
+ return worksheet
1001
+ }
1002
+
1003
+ async getProductScanningVal(arrivalNotice: ArrivalNotice) {
1004
+ let productScanning: string = 'false'
1005
+ const enableProductScanning: Setting = await this.trxMgr.getRepository(Setting).findOne({
1006
+ where: { domain: { id: this.domain.id }, category: 'id-rule', name: 'enable-product-scanning' }
1007
+ })
1008
+
1009
+ if (enableProductScanning) {
1010
+ productScanning = enableProductScanning.value
1011
+
1012
+ const partnerEnableProductScanning: PartnerSetting = await this.trxMgr.getRepository(PartnerSetting).findOne({
1013
+ where: {
1014
+ setting: { id: enableProductScanning.id },
1015
+ domain: { id: this.domain.id },
1016
+ partnerDomain: { id: arrivalNotice.bizplace?.domain.id }
1017
+ }
1018
+ })
1019
+
1020
+ if (partnerEnableProductScanning) productScanning = partnerEnableProductScanning.value
1021
+ }
1022
+
1023
+ return productScanning
1024
+ }
1025
+
1026
+ async getInputQtyVal(arrivalNotice: ArrivalNotice) {
1027
+ let inputQty: string = 'false'
1028
+ const enableInputQty: Setting = await this.trxMgr.getRepository(Setting).findOne({
1029
+ where: { domain: { id: this.domain.id }, category: 'id-rule', name: 'enable-input-qty' }
1030
+ })
1031
+
1032
+ if (enableInputQty) {
1033
+ inputQty = enableInputQty.value
1034
+
1035
+ const partnerEnableInputQty: PartnerSetting = await this.trxMgr.getRepository(PartnerSetting).findOne({
1036
+ where: {
1037
+ setting: { id: enableInputQty.id },
1038
+ domain: { id: this.domain.id },
1039
+ partnerDomain: { id: arrivalNotice.bizplace?.domain.id }
1040
+ }
1041
+ })
1042
+
1043
+ if (partnerEnableInputQty) inputQty = partnerEnableInputQty.value
1044
+ }
1045
+
1046
+ return inputQty
1047
+ }
1048
+
1049
+ // only creates inventory history upon partial or full unload when
1050
+ // productScanning is true
1051
+ // inputQty is false
1052
+ async createInventoryHistory(arrivalNotice: ArrivalNotice, inventories?: Inventory[]) {
1053
+ try {
1054
+ if (inventories === undefined) {
1055
+ const inventoryList = await this.trxMgr.getRepository(Inventory).findAndCount({
1056
+ where: {
1057
+ //@ts-ignore
1058
+ domain: { id: this.domain },
1059
+ refOrderId: arrivalNotice.id
1060
+ }
1061
+ })
1062
+
1063
+ inventories = inventoryList[0]
1064
+ }
1065
+
1066
+ for (const inventory of inventories) {
1067
+ await this.transactionInventory(
1068
+ inventory,
1069
+ arrivalNotice,
1070
+ inventory.qty,
1071
+ inventory.uomValue,
1072
+ INVENTORY_TRANSACTION_TYPE.UNLOADING
1073
+ )
1074
+ }
1075
+ } catch (e) {
1076
+ throw e
1077
+ }
1078
+ }
1079
+
1080
+ async completeUnloading(
1081
+ arrivalNoticeNo: string,
1082
+ unloadingWorksheetDetails: Partial<WorksheetDetail>[]
1083
+ ): Promise<void> {
1084
+ //@ts-ignore
1085
+ let arrivalNotice: ArrivalNotice = await this.findRefOrder(
1086
+ //@ts-ignore
1087
+ ArrivalNotice,
1088
+ {
1089
+ domain: { id: this.domain.id },
1090
+ name: arrivalNoticeNo,
1091
+ status: In([ORDER_STATUS.PROCESSING, ORDER_STATUS.PUTTING_AWAY])
1092
+ },
1093
+ ['orderProducts', 'releaseGood', 'bizplace', 'bizplace.domain']
1094
+ )
1095
+
1096
+ if (arrivalNotice.crossDocking) {
1097
+ // Picking worksheet for cross docking should be completed before complete it
1098
+ // Find picking worksheet
1099
+ const releaseGood: ReleaseGood = arrivalNotice.releaseGood
1100
+ const executingPickingWS: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
1101
+ where: {
1102
+ domain: { id: this.domain.id },
1103
+ releaseGood: { id: releaseGood.id },
1104
+ type: WORKSHEET_TYPE.PICKING,
1105
+ status: Not(Equal(WORKSHEET_STATUS.DONE))
1106
+ }
1107
+ })
1108
+
1109
+ if (executingPickingWS)
1110
+ throw new Error(`Picking should be completed before complete unloading for cross docking.`)
1111
+ }
1112
+
1113
+ if (arrivalNotice.orderProducts.some((op: OrderProduct) => op.status === ORDER_PRODUCT_STATUS.READY_TO_APPROVED)) {
1114
+ throw new Error(`There's non-approved order products`)
1115
+ }
1116
+
1117
+ let worksheet: Worksheet = await this.findWorksheetByRefOrder(arrivalNotice, WORKSHEET_TYPE.UNLOADING, [
1118
+ 'worksheetDetails',
1119
+ 'worksheetDetails.targetProduct'
1120
+ ])
1121
+ this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
1122
+
1123
+ const partiallyUnloadedCnt: number = await this.trxMgr.getRepository(Inventory).count({
1124
+ where: {
1125
+ domain: { id: this.domain.id },
1126
+ refOrderId: arrivalNotice.id,
1127
+ status: INVENTORY_STATUS.PARTIALLY_UNLOADED
1128
+ }
1129
+ })
1130
+ if (partiallyUnloadedCnt) {
1131
+ throw new Error('There is partially unloaded pallet, generate putaway worksheet before complete unloading.')
1132
+ }
1133
+
1134
+ if (unloadingWorksheetDetails.some((wsd: Partial<WorksheetDetail>) => wsd.issue)) {
1135
+ const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
1136
+ unloadingWorksheetDetails = this.renewWorksheetDetails(worksheetDetails, unloadingWorksheetDetails, 'name', {
1137
+ updater: this.user
1138
+ })
1139
+ const worksheetDetailsWithIssue: WorksheetDetail[] = unloadingWorksheetDetails.filter(
1140
+ (wsd: WorksheetDetail) => wsd.issue
1141
+ ) as WorksheetDetail[]
1142
+ if (worksheetDetailsWithIssue.length) {
1143
+ await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetailsWithIssue)
1144
+ }
1145
+
1146
+ const targetProductsWithIssue: OrderProduct[] = worksheetDetailsWithIssue.map((wsd: WorksheetDetail) => {
1147
+ let targetProduct: OrderProduct = wsd.targetProduct
1148
+ targetProduct.issue = wsd.issue
1149
+ return targetProduct
1150
+ })
1151
+ await this.updateOrderTargets(targetProductsWithIssue)
1152
+ }
1153
+
1154
+ if (arrivalNotice.status !== ORDER_STATUS.PUTTING_AWAY) {
1155
+ await this.completeWorksheet(worksheet, ORDER_STATUS.READY_TO_PUTAWAY)
1156
+ } else {
1157
+ await this.completeWorksheet(worksheet)
1158
+ }
1159
+
1160
+ const productScanning = await this.getProductScanningVal(arrivalNotice)
1161
+ const inputQty = await this.getInputQtyVal(arrivalNotice)
1162
+ if (productScanning === 'true' && inputQty === 'false') await this.createInventoryHistory(arrivalNotice)
1163
+
1164
+ const inventories: Inventory[] = await this.trxMgr.getRepository(Inventory).find({
1165
+ where: {
1166
+ domain: { id: this.domain.id },
1167
+ refOrderId: arrivalNotice.id,
1168
+ status: In([INVENTORY_STATUS.UNLOADED, INVENTORY_STATUS.CHECKED])
1169
+ },
1170
+ relations: ['domain', 'bizplace', 'product', 'warehouse', 'location']
1171
+ })
1172
+
1173
+ for (let inventory of inventories) {
1174
+ let inventoryItems: InventoryItem[] = await this.trxMgr.getRepository(InventoryItem).find({
1175
+ where: { domain: { id: this.domain.id }, inventory: { id: inventory.id } }
1176
+ })
1177
+
1178
+ if (inventoryItems?.length) {
1179
+ inventory.status = INVENTORY_STATUS.STORED
1180
+
1181
+ await Promise.all(
1182
+ inventoryItems.map(async inventoryItem => {
1183
+ await this.trxMgr
1184
+ .getRepository(InventoryItem)
1185
+ .update({ id: inventoryItem.id }, { status: INVENTORY_STATUS.STORED })
1186
+ })
1187
+ )
1188
+
1189
+ await generateInventoryHistory(
1190
+ inventory,
1191
+ arrivalNotice,
1192
+ INVENTORY_TRANSACTION_TYPE.UNLOADING,
1193
+ inventory.qty,
1194
+ inventory.uomValue,
1195
+ this.user,
1196
+ this.trxMgr
1197
+ )
1198
+ }
1199
+ }
1200
+
1201
+ let vasWorksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
1202
+ where: {
1203
+ arrivalNotice: { id: arrivalNotice.id },
1204
+ type: WORKSHEET_TYPE.VAS
1205
+ },
1206
+ relations: ['worksheetDetails', 'worksheetDetails.targetVas', 'worksheetDetails.targetVas.vas']
1207
+ })
1208
+
1209
+ if (vasWorksheet) {
1210
+ let serviceVasWorksheetDetails: WorksheetDetail[] = vasWorksheet.worksheetDetails.filter(
1211
+ x => x.targetVas.vas.type == VAS_TYPES.SERVICE && x.status != WORKSHEET_STATUS.DONE
1212
+ )
1213
+ let materialsVasWorksheetDetails: WorksheetDetail[] = vasWorksheet.worksheetDetails.filter(
1214
+ x => x.targetVas.vas.type == VAS_TYPES.MATERIALS
1215
+ )
1216
+ materialsVasWorksheetDetails.forEach((wsd: WorksheetDetail) => {
1217
+ wsd.status = WORKSHEET_STATUS.DONE
1218
+ wsd.updater = this.user
1219
+ })
1220
+ await this.trxMgr.getRepository(WorksheetDetail).save(materialsVasWorksheetDetails)
1221
+
1222
+ let targetVASs: OrderVas[] = materialsVasWorksheetDetails.map((wsd: WorksheetDetail) => {
1223
+ let targetVas: OrderVas = wsd.targetVas
1224
+ targetVas.status = ORDER_VAS_STATUS.TERMINATED
1225
+ targetVas.updater = this.user
1226
+ return targetVas
1227
+ })
1228
+
1229
+ if (targetVASs.length) await this.updateOrderTargets(targetVASs)
1230
+
1231
+ if (serviceVasWorksheetDetails.length <= 0) {
1232
+ vasWorksheet.status = WORKSHEET_STATUS.DONE
1233
+ vasWorksheet.updater = this.user
1234
+
1235
+ await this.trxMgr.getRepository(Worksheet).save(vasWorksheet)
1236
+ }
1237
+ }
1238
+ }
1239
+
1240
+ async completeUnloadingPartially(
1241
+ arrivalNoticeNo: string,
1242
+ unloadingWorksheetDetail: Partial<WorksheetDetail>[]
1243
+ ): Promise<Worksheet> {
1244
+ //@ts-ignore
1245
+ const arrivalNotice: ArrivalNotice = await this.findRefOrder(
1246
+ //@ts-ignore
1247
+ ArrivalNotice,
1248
+ {
1249
+ domain: { id: this.domain.id },
1250
+ name: arrivalNoticeNo,
1251
+ status: In([ORDER_STATUS.PROCESSING, ORDER_STATUS.PUTTING_AWAY])
1252
+ },
1253
+ ['bizplace', 'bizplace.domain']
1254
+ )
1255
+
1256
+ const worksheet: Worksheet = await this.findWorksheetByRefOrder(arrivalNotice, WORKSHEET_TYPE.UNLOADING, [
1257
+ 'worksheetDetails',
1258
+ 'worksheetDetails.targetProduct'
1259
+ ])
1260
+ this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
1261
+
1262
+ let worksheetDetails = worksheet.worksheetDetails.filter(({ name: itm1 }) =>
1263
+ unloadingWorksheetDetail.some(({ name: itm2 }) => itm2 === itm1)
1264
+ )
1265
+
1266
+ worksheetDetails.forEach((wsds: WorksheetDetail) => {
1267
+ wsds.status = WORKSHEET_STATUS.PARTIALLY_UNLOADED
1268
+ wsds.updater = this.user
1269
+ })
1270
+
1271
+ worksheetDetails = await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetails)
1272
+
1273
+ for (let i = 0; i < worksheetDetails.length; i++) {
1274
+ worksheetDetails[i].targetProduct.status = ORDER_PRODUCT_STATUS.PARTIALLY_UNLOADED
1275
+ worksheetDetails[i].targetProduct.remark = worksheetDetails[i].issue || worksheetDetails[i].targetProduct.remark
1276
+ await this.updateOrderTargets([worksheetDetails[i].targetProduct])
1277
+ }
1278
+
1279
+ let inventories: Inventory[] = await this.trxMgr.getRepository(Inventory).find({
1280
+ where: {
1281
+ domain: { id: this.domain.id },
1282
+ refOrderId: arrivalNotice.id,
1283
+ status: In([INVENTORY_STATUS.UNLOADED, INVENTORY_STATUS.CHECKED])
1284
+ }
1285
+ })
1286
+
1287
+ inventories.forEach((inventory: Inventory) => {
1288
+ inventory.status = INVENTORY_STATUS.PARTIALLY_UNLOADED
1289
+ inventory.updater = this.user
1290
+ })
1291
+ await this.trxMgr.getRepository(Inventory).save(inventories)
1292
+
1293
+ const productScanning = await this.getProductScanningVal(arrivalNotice)
1294
+ const inputQty = await this.getInputQtyVal(arrivalNotice)
1295
+ if (productScanning === 'true' && inputQty === 'false')
1296
+ await this.createInventoryHistory(arrivalNotice, inventories)
1297
+
1298
+ let vasWorksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
1299
+ where: {
1300
+ arrivalNotice: { id: arrivalNotice.id },
1301
+ type: WORKSHEET_TYPE.VAS
1302
+ },
1303
+ relations: ['worksheetDetails', 'worksheetDetails.targetVas', 'worksheetDetails.targetVas.vas']
1304
+ })
1305
+
1306
+ if (vasWorksheet) {
1307
+ let serviceVasWorksheetDetails: WorksheetDetail[] = vasWorksheet.worksheetDetails.filter(
1308
+ x => x.targetVas.vas.type == VAS_TYPES.SERVICE && x.status != WORKSHEET_STATUS.DONE
1309
+ )
1310
+ let materialsVasWorksheetDetails: WorksheetDetail[] = vasWorksheet.worksheetDetails.filter(
1311
+ x => x.targetVas.vas.type == VAS_TYPES.MATERIALS
1312
+ )
1313
+ materialsVasWorksheetDetails.forEach((wsd: WorksheetDetail) => {
1314
+ wsd.status = WORKSHEET_STATUS.DONE
1315
+ wsd.updater = this.user
1316
+ })
1317
+ await this.trxMgr.getRepository(WorksheetDetail).save(materialsVasWorksheetDetails)
1318
+
1319
+ let targetVASs: OrderVas[] = materialsVasWorksheetDetails.map((wsd: WorksheetDetail) => {
1320
+ let targetVas: OrderVas = wsd.targetVas
1321
+ targetVas.status = ORDER_VAS_STATUS.TERMINATED
1322
+ targetVas.updater = this.user
1323
+ return targetVas
1324
+ })
1325
+
1326
+ await this.updateOrderTargets(targetVASs)
1327
+
1328
+ if (serviceVasWorksheetDetails.length <= 0) {
1329
+ vasWorksheet.status = WORKSHEET_STATUS.DONE
1330
+ vasWorksheet.updater = this.user
1331
+
1332
+ await this.trxMgr.getRepository(Worksheet).save(vasWorksheet)
1333
+ }
1334
+ }
1335
+
1336
+ return worksheet
1337
+ }
1338
+
1339
+ async createPalletizingWSDs(
1340
+ bizplace: Bizplace,
1341
+ arrivalNotice: ArrivalNotice,
1342
+ worksheetDetails: WorksheetDetail[],
1343
+ palletizingWSDs: UnloadingWorksheetDetail[]
1344
+ ): Promise<void> {
1345
+ let palletizingOrderVASs: OrderVas[] = []
1346
+ let currentSetNo: number = 1
1347
+
1348
+ if (worksheetDetails.some((wd: WorksheetDetail) => wd.targetVas)) {
1349
+ const getSetNo: number[] = worksheetDetails.map((wd: WorksheetDetail) => wd.targetVas.set)
1350
+
1351
+ if (getSetNo.length > 0) {
1352
+ currentSetNo = Math.max(...getSetNo) + 1
1353
+ }
1354
+ }
1355
+
1356
+ for (let palletizingWSD of palletizingWSDs) {
1357
+ const palletizingVAS: Vas = await this.trxMgr.getRepository(Vas).findOne({
1358
+ where: { domain: { id: this.domain.id }, id: palletizingWSD.palletizingVasId }
1359
+ })
1360
+
1361
+ const targetProduct: OrderProduct = worksheetDetails.find(
1362
+ (wsd: WorksheetDetail) => wsd.name === palletizingWSD.name
1363
+ ).targetProduct
1364
+
1365
+ let palletizingOrderVas: OrderVas = new OrderVas()
1366
+ palletizingOrderVas.domain = this.domain
1367
+ palletizingOrderVas.bizplace = bizplace
1368
+ palletizingOrderVas.name = OrderNoGenerator.orderVas()
1369
+ palletizingOrderVas.arrivalNotice = arrivalNotice
1370
+ palletizingOrderVas.vas = palletizingVAS
1371
+ palletizingOrderVas.set = currentSetNo
1372
+ palletizingOrderVas.targetType = VAS_TARGET_TYPES.BATCH_AND_PRODUCT_TYPE
1373
+ palletizingOrderVas.targetBatchId = targetProduct.batchId
1374
+ palletizingOrderVas.qty = targetProduct.packQty
1375
+ palletizingOrderVas.targetProduct = targetProduct.product
1376
+ palletizingOrderVas.packingType = targetProduct.packingType
1377
+ palletizingOrderVas.description = palletizingWSD.palletizingDescription
1378
+ palletizingOrderVas.type = ORDER_TYPES.ARRIVAL_NOTICE
1379
+ palletizingOrderVas.status = ORDER_VAS_STATUS.COMPLETED
1380
+ palletizingOrderVas.creator = this.user
1381
+ palletizingOrderVas.updater = this.user
1382
+
1383
+ palletizingOrderVas = await this.trxMgr.getRepository(OrderVas).save(palletizingOrderVas)
1384
+ palletizingOrderVASs.push(palletizingOrderVas)
1385
+
1386
+ currentSetNo++
1387
+ }
1388
+
1389
+ let vasWorksheet: Worksheet = await this.findWorksheetByRefOrder(arrivalNotice, WORKSHEET_TYPE.VAS)
1390
+ if (!vasWorksheet) {
1391
+ await this.generateVasWorksheet(arrivalNotice)
1392
+ } else {
1393
+ await this.createWorksheetDetails(vasWorksheet, WORKSHEET_TYPE.VAS, palletizingOrderVASs)
1394
+ }
1395
+ }
1396
+
1397
+ filterPalletizingWSDs(unloadingWSDs: UnloadingWorksheetDetail[]): UnloadingWorksheetDetail[] {
1398
+ return unloadingWSDs.filter((wsd: UnloadingWorksheetDetail) => wsd.palletQty && wsd.palletizingDescription)
1399
+ }
1400
+ }