@things-factory/operato-hub 6.1.83 → 6.1.85

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 (189) hide show
  1. package/dist-server/tsconfig.tsbuildinfo +1 -1
  2. package/package.json +46 -46
  3. package/server/controllers/bizplace-initializer/codes.ts +0 -32
  4. package/server/controllers/bizplace-initializer/dataset/codes.ts +0 -398
  5. package/server/controllers/bizplace-initializer/dataset/groups.ts +0 -21
  6. package/server/controllers/bizplace-initializer/dataset/index.ts +0 -5
  7. package/server/controllers/bizplace-initializer/dataset/menus.ts +0 -500
  8. package/server/controllers/bizplace-initializer/dataset/roles-privileges.ts +0 -402
  9. package/server/controllers/bizplace-initializer/dataset/settings.ts +0 -91
  10. package/server/controllers/bizplace-initializer/generate-bizplace-domain-roles.ts +0 -29
  11. package/server/controllers/bizplace-initializer/generate-bizplace-domain.ts +0 -56
  12. package/server/controllers/bizplace-initializer/groups.ts +0 -19
  13. package/server/controllers/bizplace-initializer/index.ts +0 -5
  14. package/server/controllers/bizplace-initializer/menus.ts +0 -42
  15. package/server/controllers/bizplace-initializer/settings.ts +0 -20
  16. package/server/controllers/company-initializer/business-register.ts +0 -59
  17. package/server/controllers/company-initializer/codes.ts +0 -147
  18. package/server/controllers/company-initializer/generate-company-roles.ts +0 -119
  19. package/server/controllers/company-initializer/index.ts +0 -6
  20. package/server/controllers/company-initializer/menus.ts +0 -359
  21. package/server/controllers/company-initializer/settings.ts +0 -33
  22. package/server/controllers/company-initializer/transporter.ts +0 -20
  23. package/server/controllers/index.ts +0 -0
  24. package/server/controllers/invitation.ts +0 -132
  25. package/server/controllers/utils/make-invitation-token.ts +0 -5
  26. package/server/controllers/utils/save-invitation-token.ts +0 -9
  27. package/server/entities/index.ts +0 -0
  28. package/server/errors/index.ts +0 -1
  29. package/server/errors/validation-error.ts +0 -17
  30. package/server/graphql/index.ts +0 -7
  31. package/server/graphql/resolvers/generators/generate-bizplace.ts +0 -40
  32. package/server/graphql/resolvers/generators/generate-company.ts +0 -76
  33. package/server/graphql/resolvers/generators/index.ts +0 -9
  34. package/server/graphql/resolvers/generators/update-domain-extType.ts +0 -55
  35. package/server/graphql/resolvers/index.ts +0 -8
  36. package/server/graphql/resolvers/invitations/index.ts +0 -5
  37. package/server/graphql/resolvers/invitations/partner-invitation.ts +0 -62
  38. package/server/graphql/resolvers/oauth2/company-roles-by-scope.ts +0 -38
  39. package/server/graphql/resolvers/oauth2/index.ts +0 -5
  40. package/server/graphql/resolvers/synchronization/auto-update-all-marketplace-product-variation-quantity.ts +0 -180
  41. package/server/graphql/resolvers/synchronization/create-dat-shipments.ts +0 -64
  42. package/server/graphql/resolvers/synchronization/fetch-sync-invoices.ts +0 -52
  43. package/server/graphql/resolvers/synchronization/fetch-sync-products.ts +0 -99
  44. package/server/graphql/resolvers/synchronization/fetch-sync-purchase-orders.ts +0 -75
  45. package/server/graphql/resolvers/synchronization/index.ts +0 -26
  46. package/server/graphql/resolvers/synchronization/sellercraft-pack-marketplace-order.ts +0 -91
  47. package/server/graphql/resolvers/synchronization/sync-all-products-to-sellercraft.ts +0 -39
  48. package/server/graphql/resolvers/synchronization/sync-products-from-account.ts +0 -40
  49. package/server/graphql/resolvers/synchronization/sync-products-to-account.ts +0 -64
  50. package/server/graphql/resolvers/synchronization/sync-products-to-sellercraft.ts +0 -176
  51. package/server/graphql/types/generators/generate-bizplace-input.ts +0 -11
  52. package/server/graphql/types/generators/generate-company-input.ts +0 -11
  53. package/server/graphql/types/generators/index.ts +0 -11
  54. package/server/graphql/types/generators/update-domain-type-input.ts +0 -8
  55. package/server/graphql/types/index.ts +0 -10
  56. package/server/graphql/types/invitations/index.ts +0 -5
  57. package/server/graphql/types/oauth2/company-role.ts +0 -8
  58. package/server/graphql/types/oauth2/index.ts +0 -7
  59. package/server/graphql/types/synchronization/index.ts +0 -33
  60. package/server/graphql/types/synchronization/sync-invoice-list.ts +0 -8
  61. package/server/graphql/types/synchronization/sync-invoice-set.ts +0 -38
  62. package/server/graphql/types/synchronization/sync-product-list.ts +0 -8
  63. package/server/graphql/types/synchronization/sync-product-set.ts +0 -8
  64. package/server/graphql/types/synchronization/sync-purchase-order-list.ts +0 -8
  65. package/server/graphql/types/synchronization/sync-purchase-order-set.ts +0 -28
  66. package/server/index.ts +0 -37
  67. package/server/middlewares/business-middleware.ts +0 -32
  68. package/server/middlewares/index.ts +0 -20
  69. package/server/middlewares/store-middleware.ts +0 -36
  70. package/server/middlewares/warehouse-middleware.ts +0 -36
  71. package/server/migrations/1597668478399-SeedBusinessDomain.ts +0 -34
  72. package/server/migrations/1597668478401-SeedBusinessRoles.ts +0 -377
  73. package/server/migrations/1608009991065-SeedUser.ts +0 -64
  74. package/server/migrations/index.ts +0 -9
  75. package/server/routers/api/index.ts +0 -3
  76. package/server/routers/api/restful-apis/unstable/add-contact-point.ts +0 -89
  77. package/server/routers/api/restful-apis/unstable/add-draft-release-order.ts +0 -198
  78. package/server/routers/api/restful-apis/unstable/add-inbound-order.ts +0 -246
  79. package/server/routers/api/restful-apis/unstable/add-marketplace-order.ts +0 -171
  80. package/server/routers/api/restful-apis/unstable/add-products.ts +0 -112
  81. package/server/routers/api/restful-apis/unstable/add-release-order.ts +0 -1061
  82. package/server/routers/api/restful-apis/unstable/add-sales-invoice.ts +0 -144
  83. package/server/routers/api/restful-apis/unstable/bizplace.ts +0 -45
  84. package/server/routers/api/restful-apis/unstable/cancel-marketplace-order.ts +0 -81
  85. package/server/routers/api/restful-apis/unstable/cancel-release-order.ts +0 -91
  86. package/server/routers/api/restful-apis/unstable/get-contact-point-list.ts +0 -110
  87. package/server/routers/api/restful-apis/unstable/get-delivery-order-detail.ts +0 -46
  88. package/server/routers/api/restful-apis/unstable/get-delivery-order-list.ts +0 -121
  89. package/server/routers/api/restful-apis/unstable/get-delivery-orders.ts +0 -178
  90. package/server/routers/api/restful-apis/unstable/get-goods-received-notes.ts +0 -134
  91. package/server/routers/api/restful-apis/unstable/get-inbound-order-detail.ts +0 -128
  92. package/server/routers/api/restful-apis/unstable/get-inbound-order-list.ts +0 -126
  93. package/server/routers/api/restful-apis/unstable/get-inventory-overall-product-group.ts +0 -99
  94. package/server/routers/api/restful-apis/unstable/get-inventory-product-group.ts +0 -107
  95. package/server/routers/api/restful-apis/unstable/get-marketplace-order-shipping-list.ts +0 -156
  96. package/server/routers/api/restful-apis/unstable/get-marketplace-store-list.ts +0 -81
  97. package/server/routers/api/restful-apis/unstable/get-onhand-inventories.ts +0 -125
  98. package/server/routers/api/restful-apis/unstable/get-partners.ts +0 -26
  99. package/server/routers/api/restful-apis/unstable/get-products.ts +0 -216
  100. package/server/routers/api/restful-apis/unstable/get-release-order-detail.ts +0 -138
  101. package/server/routers/api/restful-apis/unstable/get-release-order-list.ts +0 -199
  102. package/server/routers/api/restful-apis/unstable/get-warehouses.ts +0 -19
  103. package/server/routers/api/restful-apis/unstable/index.ts +0 -32
  104. package/server/routers/api/restful-apis/unstable/reject-inbound-order.ts +0 -46
  105. package/server/routers/api/restful-apis/unstable/set-marketplace-order-delivered.ts +0 -60
  106. package/server/routers/api/restful-apis/unstable/set-marketplace-order-failed-delivery.ts +0 -60
  107. package/server/routers/api/restful-apis/unstable/update-marketplace-order.ts +0 -111
  108. package/server/routers/api/restful-apis/unstable/update-marketplace-shipping-order.ts +0 -107
  109. package/server/routers/api/restful-apis/unstable/update-release-order-details.ts +0 -94
  110. package/server/routers/api/restful-apis/v1/add-contact-point.ts +0 -77
  111. package/server/routers/api/restful-apis/v1/add-draft-release-order.ts +0 -196
  112. package/server/routers/api/restful-apis/v1/add-inbound-order.ts +0 -243
  113. package/server/routers/api/restful-apis/v1/add-marketplace-order.ts +0 -172
  114. package/server/routers/api/restful-apis/v1/add-products.ts +0 -112
  115. package/server/routers/api/restful-apis/v1/add-release-order.ts +0 -967
  116. package/server/routers/api/restful-apis/v1/bizplace.ts +0 -45
  117. package/server/routers/api/restful-apis/v1/cancel-marketplace-order.ts +0 -81
  118. package/server/routers/api/restful-apis/v1/cancel-release-order.ts +0 -91
  119. package/server/routers/api/restful-apis/v1/get-contact-point-list.ts +0 -110
  120. package/server/routers/api/restful-apis/v1/get-delivery-order-detail.ts +0 -46
  121. package/server/routers/api/restful-apis/v1/get-delivery-order-list.ts +0 -121
  122. package/server/routers/api/restful-apis/v1/get-delivery-orders.ts +0 -178
  123. package/server/routers/api/restful-apis/v1/get-goods-received-notes.ts +0 -134
  124. package/server/routers/api/restful-apis/v1/get-inbound-order-detail.ts +0 -128
  125. package/server/routers/api/restful-apis/v1/get-inbound-order-list.ts +0 -126
  126. package/server/routers/api/restful-apis/v1/get-inventory-overall-product-group.ts +0 -99
  127. package/server/routers/api/restful-apis/v1/get-inventory-product-group.ts +0 -112
  128. package/server/routers/api/restful-apis/v1/get-marketplace-order-shipping-list.ts +0 -156
  129. package/server/routers/api/restful-apis/v1/get-marketplace-store-list.ts +0 -81
  130. package/server/routers/api/restful-apis/v1/get-onhand-inventories.ts +0 -125
  131. package/server/routers/api/restful-apis/v1/get-partners.ts +0 -26
  132. package/server/routers/api/restful-apis/v1/get-products.ts +0 -216
  133. package/server/routers/api/restful-apis/v1/get-release-order-detail.ts +0 -134
  134. package/server/routers/api/restful-apis/v1/get-release-order-list.ts +0 -198
  135. package/server/routers/api/restful-apis/v1/get-warehouses.ts +0 -19
  136. package/server/routers/api/restful-apis/v1/index.ts +0 -31
  137. package/server/routers/api/restful-apis/v1/reject-inbound-order.ts +0 -46
  138. package/server/routers/api/restful-apis/v1/set-marketplace-order-delivered.ts +0 -60
  139. package/server/routers/api/restful-apis/v1/set-marketplace-order-failed-delivery.ts +0 -60
  140. package/server/routers/api/restful-apis/v1/update-marketplace-order.ts +0 -111
  141. package/server/routers/api/restful-apis/v1/update-marketplace-shipping-order.ts +0 -104
  142. package/server/routers/api/restful-apis/v1/update-release-order-details.ts +0 -94
  143. package/server/routers/api/restful-apis/v2/add-contact-point.ts +0 -77
  144. package/server/routers/api/restful-apis/v2/add-draft-release-order.ts +0 -196
  145. package/server/routers/api/restful-apis/v2/add-inbound-order.ts +0 -243
  146. package/server/routers/api/restful-apis/v2/add-marketplace-order.ts +0 -172
  147. package/server/routers/api/restful-apis/v2/add-products.ts +0 -112
  148. package/server/routers/api/restful-apis/v2/add-release-order.ts +0 -967
  149. package/server/routers/api/restful-apis/v2/bizplace.ts +0 -45
  150. package/server/routers/api/restful-apis/v2/cancel-marketplace-order.ts +0 -81
  151. package/server/routers/api/restful-apis/v2/cancel-release-order.ts +0 -91
  152. package/server/routers/api/restful-apis/v2/get-contact-point-list.ts +0 -110
  153. package/server/routers/api/restful-apis/v2/get-delivery-order-detail.ts +0 -46
  154. package/server/routers/api/restful-apis/v2/get-delivery-order-list.ts +0 -121
  155. package/server/routers/api/restful-apis/v2/get-delivery-orders.ts +0 -178
  156. package/server/routers/api/restful-apis/v2/get-goods-received-notes.ts +0 -134
  157. package/server/routers/api/restful-apis/v2/get-inbound-order-detail.ts +0 -128
  158. package/server/routers/api/restful-apis/v2/get-inbound-order-list.ts +0 -126
  159. package/server/routers/api/restful-apis/v2/get-inventory-overall-product-group.ts +0 -99
  160. package/server/routers/api/restful-apis/v2/get-inventory-product-group.ts +0 -112
  161. package/server/routers/api/restful-apis/v2/get-marketplace-order-shipping-list.ts +0 -156
  162. package/server/routers/api/restful-apis/v2/get-marketplace-store-list.ts +0 -81
  163. package/server/routers/api/restful-apis/v2/get-onhand-inventories.ts +0 -125
  164. package/server/routers/api/restful-apis/v2/get-partners.ts +0 -26
  165. package/server/routers/api/restful-apis/v2/get-products.ts +0 -216
  166. package/server/routers/api/restful-apis/v2/get-release-order-detail.ts +0 -134
  167. package/server/routers/api/restful-apis/v2/get-release-order-list.ts +0 -198
  168. package/server/routers/api/restful-apis/v2/get-warehouses.ts +0 -19
  169. package/server/routers/api/restful-apis/v2/index.ts +0 -31
  170. package/server/routers/api/restful-apis/v2/reject-inbound-order.ts +0 -46
  171. package/server/routers/api/restful-apis/v2/set-marketplace-order-delivered.ts +0 -60
  172. package/server/routers/api/restful-apis/v2/set-marketplace-order-failed-delivery.ts +0 -60
  173. package/server/routers/api/restful-apis/v2/update-marketplace-order.ts +0 -111
  174. package/server/routers/api/restful-apis/v2/update-marketplace-shipping-order.ts +0 -104
  175. package/server/routers/api/restful-apis/v2/update-release-order-details.ts +0 -94
  176. package/server/routers/auth-invitation-router.ts +0 -25
  177. package/server/routers/business/bizplace-register-router.ts +0 -31
  178. package/server/routers/business/business-register-router.ts +0 -32
  179. package/server/routers/business/index.ts +0 -3
  180. package/server/routers/business/path-base-business-router.ts +0 -15
  181. package/server/routes.ts +0 -28
  182. package/server/templates/account-unlock-email.ts +0 -64
  183. package/server/templates/invitation-email.ts +0 -65
  184. package/server/templates/reset-password-email.ts +0 -64
  185. package/server/templates/verification-email.ts +0 -65
  186. package/server/utils/build-map.ts +0 -18
  187. package/server/utils/get-warehouses.ts +0 -115
  188. package/server/utils/index.ts +0 -3
  189. package/server/utils/order-no-generator.ts +0 -8
@@ -1,1061 +0,0 @@
1
- import { EntityManager, getConnection, In, Not, Repository, SelectQueryBuilder } from 'typeorm'
2
- import { v4 as uuidv4 } from 'uuid'
3
-
4
- import { restfulApiRouter as router } from '@things-factory/api'
5
- import { Bizplace, getCompanyBizplace } from '@things-factory/biz-base'
6
- import { logger } from '@things-factory/env'
7
- import { generateId } from '@things-factory/id-rule-base'
8
- import { createPayloadLog, PayloadType } from '@things-factory/integration-base'
9
- import { Sellercraft } from '@things-factory/integration-sellercraft'
10
- import { MarketplaceOrder } from '@things-factory/marketplace-base'
11
- import { ProductBundle, ProductDetail } from '@things-factory/product-base'
12
- import {
13
- createDraftReleaseGoodFunction,
14
- DRAFT_RELEASE_ORDER_STATUS,
15
- DraftReleaseGood,
16
- ORDER_INVENTORY_STATUS,
17
- ORDER_NUMBER_RULE_TYPE,
18
- ORDER_NUMBER_SETTING_KEY,
19
- ORDER_PRODUCT_STATUS,
20
- ORDER_STATUS,
21
- ORDER_TYPES,
22
- OrderInventory,
23
- OrderNoGenerator,
24
- OrderProduct,
25
- ReleaseGood,
26
- SellercraftController
27
- } from '@things-factory/sales-base'
28
- import { Setting } from '@things-factory/setting-base'
29
- import { Domain, getRepository } from '@things-factory/shell'
30
- import { Inventory, INVENTORY_STATUS, LOCATION_TYPE } from '@things-factory/warehouse-base'
31
-
32
- import { ValidationError } from '../../../../errors/index'
33
- import { businessMiddleware } from '../../../../middlewares/business-middleware'
34
- import { warehouseMiddleware } from '../../../../middlewares/warehouse-middleware'
35
-
36
- const debug = require('debug')('things-factory:operato-hub:restful-api:unstable:add-release-order')
37
- const apiVersion = 'unstable'
38
-
39
- router.post(
40
- `/${apiVersion}/warehouse/:warehouseId/add-release-order`,
41
- businessMiddleware,
42
- warehouseMiddleware,
43
- async (context, next) => {
44
- return await getConnection().transaction(async (tx: EntityManager) => {
45
- const { client, domain, user, application } = context.state
46
- const { warehouseId: customerBizplaceId } = context.params
47
- const { t } = context
48
- const bodyReq = context.request.body
49
- const requiredDraft: Boolean = bodyReq.hasOwnProperty('requiredDraft') ? bodyReq.requiredDraft : true
50
- let releaseGood
51
- let massagedData = { orderProducts: [], combinedItems: [] }
52
- // const isAutoAssign: Boolean = bodyReq.hasOwnProperty('isAutoAssign') ? bodyReq.isAutoAssign : true
53
-
54
- try {
55
- if (!customerBizplaceId) context.throw(404, t('error.warehouse id not found'))
56
-
57
- if (typeof bodyReq === undefined || !Object.keys(bodyReq)?.length) {
58
- context.throw(400, t('error.invalid body request format'))
59
- }
60
- debug('post:/add-release-order request.body', bodyReq)
61
- await checkMandatoryKey(context, bodyReq)
62
-
63
- // get customer company's bizplace
64
- const custCompanyBizplace: Bizplace = await getCompanyBizplace(null, null, customerBizplaceId, tx)
65
- const customerBizplace: Bizplace = await tx.getRepository(Bizplace).findOne({
66
- where: { id: customerBizplaceId },
67
- relations: ['domain']
68
- })
69
-
70
- releaseGood = {
71
- domain,
72
- bizplace: customerBizplace,
73
- companyBizplace: custCompanyBizplace,
74
- courierOption: bodyReq.courierOption,
75
- collectionOrderNo: bodyReq.collectionOrderNo,
76
- exportOption: bodyReq.exportOption,
77
- ownTransport: bodyReq.ownTransport,
78
- packingOption: bodyReq.packingOption,
79
- refNo: bodyReq.refNo,
80
- refNo2: bodyReq?.refNo2,
81
- refNo3: bodyReq?.refNo3,
82
- releaseDate: bodyReq.releaseDate,
83
- type: bodyReq.type,
84
- marketplaceOrderStatus: bodyReq?.marketplaceOrderStatus,
85
- remark: bodyReq?.remark || null,
86
- billingAddress: bodyReq?.billTo?.billingAddress || null,
87
- deliveryAddress1: bodyReq?.deliverTo?.deliveryAddress1 || null,
88
- deliveryAddress2: bodyReq?.deliverTo?.deliveryAddress2 || null,
89
- deliveryAddress3: bodyReq?.deliverTo?.deliveryAddress3 || null,
90
- deliveryAddress4: bodyReq?.deliverTo?.deliveryAddress4 || null,
91
- deliveryAddress5: bodyReq?.deliverTo?.deliveryAddress5 || null,
92
- attentionTo: bodyReq?.deliverTo?.attentionTo || null,
93
- attentionCompany: bodyReq?.deliverTo?.attentionCompany || null,
94
- city: bodyReq?.deliverTo?.city || null,
95
- state: bodyReq?.deliverTo?.state || null,
96
- postalCode: bodyReq?.deliverTo?.postalCode || null,
97
- country: bodyReq?.deliverTo?.country || null,
98
- phone1: bodyReq?.deliverTo?.phone1 || null,
99
- phone2: bodyReq?.deliverTo?.phone2 || null,
100
- email: bodyReq?.deliverTo?.email || null,
101
- transporter: bodyReq?.transporter,
102
- trackingNo: bodyReq?.trackingNo,
103
- airwayBill: bodyReq?.airwayBill,
104
- invoice: bodyReq?.invoice,
105
- packageId: bodyReq?.packageId,
106
- storeName: bodyReq?.storeName,
107
- storeId: bodyReq?.storeId,
108
- routeId: bodyReq?.routeId,
109
- stopId: bodyReq?.stopId,
110
- source: application?.type
111
- }
112
-
113
- // check existing order
114
- await checkExistingOrder(releaseGood, customerBizplace, bodyReq?.checkDuplicationValidation, context, tx)
115
-
116
- //massage data
117
- massagedData = await massageOrderItems(releaseGood, bodyReq.orderInventories, context)
118
-
119
- // validation
120
- let errorList = []
121
- await Promise.all(
122
- massagedData.combinedItems.map(async item => {
123
- let itemList = await tx.query(
124
- `
125
- select wboi.* from warehouse_bizplace_onhand_inventories wboi
126
- where wboi."domainId"= $1 and
127
- wboi."bizplaceId" = $2 and
128
- wboi."groupType" = 'SINGLE' and
129
- wboi."productId" = $3 and
130
- wboi."packingType" = $4 and
131
- wboi."packingSize" = $5 and
132
- wboi."uom" = $6 and
133
- wboi."remainQty" >= $7 and
134
- wboi."remainUomValue" >= $8
135
- `,
136
- [
137
- domain.id,
138
- customerBizplace.id,
139
- item.product.id,
140
- item.packingType,
141
- item.packingSize,
142
- item.uom,
143
- item.releaseQty,
144
- item.releaseUomValue
145
- ]
146
- )
147
- if (itemList.length <= 0) {
148
- errorList.push(
149
- JSON.stringify({
150
- code: 'insufficient stock',
151
- sku: item.product.sku,
152
- packingType: item.packingType,
153
- packingSize: item.packingSize,
154
- uom: item.uom,
155
- qty: item.releaseQty,
156
- uom_value: item.releaseUomValue
157
- })
158
- )
159
- }
160
- console.log()
161
- })
162
- )
163
-
164
- if (errorList.length > 0) {
165
- throw new ValidationError({
166
- errorCode: 'INSUFFICIENT_STOCK',
167
- message: 'insufficient stock',
168
- detail: errorList.join(', ')
169
- })
170
- }
171
- // assignment
172
- // console.time('assign')
173
- let assignedOrderProducts = await assignToInventory(massagedData.orderProducts, customerBizplace, context, tx)
174
- // console.timeEnd('assign')
175
-
176
- // create order
177
- // console.time('save')
178
- let result = await createReleaseGood(releaseGood, assignedOrderProducts, customerBizplace, context, tx)
179
- // console.timeEnd('save')
180
-
181
- let addReleaseGood = {
182
- id: result.id,
183
- name: result.name,
184
- refNo: result.refNo,
185
- refNo2: result.refNo2,
186
- refNo3: result.refNo3,
187
- status: result.status,
188
- truckNo: result.truckNo,
189
- ownTransport: result.ownTransport,
190
- crossDocking: result.crossDocking,
191
- marketplaceOrderStatus: result.marketplaceOrderStatus,
192
- billingAddress: result.billingAddress,
193
- deliveryAddress1: result.deliveryAddress1,
194
- deliveryAddress2: result.deliveryAddress2,
195
- deliveryAddress3: result.deliveryAddress3,
196
- deliveryAddress4: result.deliveryAddress4,
197
- deliveryAddress5: result.deliveryAddress5,
198
- attentionTo: result.attentionTo,
199
- attentionCompany: result.attentionCompany,
200
- city: result.city,
201
- state: result.state,
202
- postalCode: result.postalCode,
203
- country: result.country,
204
- phone1: result.phone1,
205
- phone2: result.phone2,
206
- email: result.email,
207
- transporter: result.transporter,
208
- trackingNo: result.trackingNo,
209
- airwayBill: result.airwayBill,
210
- invoice: result.invoice,
211
- type: result.type,
212
- packageId: result.packageId,
213
- storeName: result.storeName,
214
- storeId: result.storeId,
215
- routeId: result.routeId,
216
- stopId: result.stopId,
217
- exportOption: result.exportOption,
218
- releaseDate: result.releaseDate,
219
- collectionOrderNo: result.collectionOrderNo,
220
- bizplace: { name: result.bizplace.name },
221
- domain: { name: result.domain.name },
222
- orderInventories: result.orderInventories
223
- }
224
- // return body
225
- context.body = { result: { addReleaseGood } }
226
- createPayloadLog(
227
- customerBizplaceId,
228
- `/${apiVersion}/warehouse/:warehouseId/add-release-order`,
229
- bodyReq,
230
- context.body,
231
- context,
232
- PayloadType.INGESTION
233
- )
234
- } catch (error) {
235
- createPayloadLog(
236
- customerBizplaceId,
237
- `/${apiVersion}/warehouse/:warehouseId/add-release-order`,
238
- bodyReq,
239
- error,
240
- context,
241
- PayloadType.INGESTION
242
- )
243
-
244
- if (error.errorCode) {
245
- if (error.errorCode == 'INSUFFICIENT_STOCK' && requiredDraft) {
246
- const result = await createDraftOrder(releaseGood, massagedData.orderProducts, context)
247
- let createdDraftOrder = {
248
- id: result.id,
249
- name: result.name,
250
- refNo: result.refNo,
251
- refNo2: result.refNo2,
252
- refNo3: result.refNo3,
253
- status: result.status,
254
- truckNo: result.truckNo,
255
- ownTransport: result.ownTransport,
256
- marketplaceOrderStatus: result.marketplaceOrderStatus,
257
- billingAddress: result.billingAddress,
258
- deliveryAddress1: result.deliveryAddress1,
259
- deliveryAddress2: result.deliveryAddress2,
260
- deliveryAddress3: result.deliveryAddress3,
261
- deliveryAddress4: result.deliveryAddress4,
262
- deliveryAddress5: result.deliveryAddress5,
263
- attentionTo: result.attentionTo,
264
- attentionCompany: result.attentionCompany,
265
- city: result.city,
266
- state: result.state,
267
- postalCode: result.postalCode,
268
- country: result.country,
269
- phone1: result.phone1,
270
- phone2: result.phone2,
271
- email: result.email,
272
- type: result.type,
273
- packageId: result.packageId,
274
- exportOption: result.exportOption,
275
- releaseDate: result.releaseDate,
276
- collectionOrderNo: result.collectionOrderNo,
277
- bizplace: { name: result.bizplace.name },
278
- domain: { name: result.domain.name }
279
- }
280
- context.body = { result: { createdDraftOrder } }
281
- } else if (error.errorCode == 'EXISTING_ORDER') {
282
- context.body = {
283
- responseCode: 'E05',
284
- message: error.message,
285
- details: error.detail
286
- }
287
- } else {
288
- logger.error(`add-release-order: ${JSON.stringify(error)}`)
289
- context.throw(400, context.t(error))
290
- }
291
- } else {
292
- logger.error(`add-release-order: ${JSON.stringify(error)}`)
293
- context.throw(400, context.t(error))
294
- }
295
- }
296
- })
297
- }
298
- )
299
-
300
- async function checkMandatoryKey(context, params) {
301
- let noparams = ['releaseDate', 'exportOption'].filter(param => !(param in params))
302
-
303
- if ('ownTransport' in params) {
304
- if (params.ownTransport == true) {
305
- if (!params.hasOwnProperty('collectionOrderNo')) {
306
- noparams.push('collectionOrderNo')
307
- }
308
- }
309
- } else {
310
- noparams.push('ownTransport')
311
- }
312
-
313
- if ('exportOption' in params) {
314
- if (params.exportOption === true) {
315
- if (
316
- params.exportOption.filter(
317
- record =>
318
- !record.containerNo || !record.containerArrivalDate || !record.containerLeavingDate || !record.shipName
319
- ).length
320
- ) {
321
- noparams.push('exportOption')
322
- }
323
- }
324
- }
325
-
326
- if ('orderInventories' in params) {
327
- params.orderInventories.forEach((param, key) => {
328
- let noSubParams = []
329
-
330
- if (!param?.releaseQty) noSubParams.push('releaseQty')
331
-
332
- if (!param?.product) noSubParams.push('product')
333
-
334
- if (noSubParams?.length)
335
- context.throw(400, context.t('error.required param x not found', { x: `${noSubParams.join(', ')}` }))
336
- })
337
- } else {
338
- noparams.push('orderInventories')
339
- }
340
-
341
- if (noparams?.length) {
342
- context.throw(400, context.t('error.required param x not found', { x: `${noparams.join(', ')}` }))
343
- }
344
-
345
- return params
346
- }
347
-
348
- async function checkExistingOrder(releaseGood, bizplace, checkDuplicationValidation = true, context, tx) {
349
- const { domain, user } = context.state
350
- const refNo: string = releaseGood.refNo
351
- const refNo2: string = releaseGood.refNo2
352
- const refNo3: string = releaseGood.refNo3
353
-
354
- if (checkDuplicationValidation) {
355
- const foundDraftReleaseGood: DraftReleaseGood = await tx.getRepository(DraftReleaseGood).findOne({
356
- where: {
357
- domain: { id: domain.id },
358
- refNo: refNo || null,
359
- refNo2: refNo2 || null,
360
- refNo3: refNo3 || null,
361
- status: Not(In([DRAFT_RELEASE_ORDER_STATUS.CANCELLED]))
362
- }
363
- })
364
-
365
- if (foundDraftReleaseGood) {
366
- throw new ValidationError({
367
- errorCode: 'EXISTING_ORDER',
368
- message: 'existing draft release order found',
369
- detail: foundDraftReleaseGood.name
370
- })
371
- }
372
-
373
- const sellercraft: Sellercraft = await tx.getRepository(Sellercraft).findOneBy({ domain: bizplace.domain })
374
-
375
- if (sellercraft) {
376
- const sellercraftCtrl: SellercraftController = new SellercraftController(tx, bizplace.domain, user)
377
- await sellercraftCtrl.checkExistingReleaseGood(sellercraft, releaseGood)
378
- } else {
379
- const foundReleaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
380
- where: {
381
- domain: { id: domain.id },
382
- refNo,
383
- status: Not(In([ORDER_STATUS.CANCELLED, ORDER_STATUS.PENDING_CANCEL]))
384
- },
385
- relations: ['bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
386
- })
387
-
388
- if (foundReleaseGood) {
389
- const customerCompanyDomain: Domain = foundReleaseGood.bizplace.company.domain
390
- const marketplaceOrder: MarketplaceOrder = await tx.getRepository(MarketplaceOrder).findOne({
391
- where: { orderNo: refNo, domain: { id: customerCompanyDomain.id } }
392
- })
393
-
394
- // Need to restructure the validation
395
- if (marketplaceOrder?.isSplitted) {
396
- const refNo2: string = releaseGood.refNo2
397
- const foundSplittedReleaseGood = await tx.getRepository(ReleaseGood).findOne({
398
- where: {
399
- domain: { id: domain.id },
400
- refNo2,
401
- status: Not(In([ORDER_STATUS.CANCELLED, ORDER_STATUS.PENDING_CANCEL]))
402
- },
403
- relations: ['bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
404
- })
405
-
406
- if (foundSplittedReleaseGood)
407
- throw new ValidationError({
408
- errorCode: 'EXISTING_ORDER',
409
- message: 'existing release order found',
410
- detail: foundSplittedReleaseGood.name
411
- })
412
- } else {
413
- throw new ValidationError({
414
- errorCode: 'EXISTING_ORDER',
415
- message: 'existing release order found',
416
- detail: foundReleaseGood.name
417
- })
418
- }
419
- }
420
- }
421
- }
422
- }
423
-
424
- async function createDraftOrder(releaseGood, orderProducts, context) {
425
- return await getConnection().transaction(async (tx: EntityManager) => {
426
- return await createDraftReleaseGoodFunction(null, releaseGood, orderProducts, null, [], context, tx)
427
- })
428
- }
429
-
430
- async function createReleaseGood(
431
- releaseGood: any,
432
- orderProducts: OrderProduct[],
433
- bizplace: Bizplace,
434
- context: any,
435
- tx?: EntityManager
436
- ): Promise<ReleaseGood> {
437
- try {
438
- const { domain, user } = context.state
439
- const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
440
-
441
- if (orderProducts.length <= 0) {
442
- throw new ValidationError({
443
- errorCode: 'ITEM_NOT_FOUND',
444
- message: 'no order items found',
445
- detail: JSON.stringify(releaseGood)
446
- })
447
- }
448
-
449
- let newReleaseGood: ReleaseGood = new ReleaseGood()
450
-
451
- // find RO number rule setting
452
- const roNoSetting: Setting = await settingRepo.findOne({
453
- where: {
454
- domain: { id: domain.id },
455
- name: ORDER_NUMBER_SETTING_KEY.RO_NUMBER_RULE
456
- }
457
- })
458
-
459
- newReleaseGood = {
460
- name: roNoSetting
461
- ? await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.RO_NUMBER, seed: {} })
462
- : OrderNoGenerator.releaseGood(),
463
- domain: domain,
464
- bizplace: bizplace,
465
- collectionOrderNo: releaseGood.collectionOrderNo,
466
- courierOption: releaseGood.courierOption,
467
- exportOption: releaseGood.exportOption,
468
- ownTransport: releaseGood.ownTransport,
469
- packingOption: releaseGood.packingOption,
470
- marketplaceOrderStatus: releaseGood?.marketplaceOrderStatus || null,
471
- billingAddress: releaseGood?.billingAddress || null,
472
- deliveryAddress1: releaseGood?.deliveryAddress1 || null,
473
- deliveryAddress2: releaseGood?.deliveryAddress2 || null,
474
- deliveryAddress3: releaseGood?.deliveryAddress3 || null,
475
- deliveryAddress4: releaseGood?.deliveryAddress4 || null,
476
- deliveryAddress5: releaseGood?.deliveryAddress5 || null,
477
- attentionTo: releaseGood?.attentionTo || null,
478
- attentionCompany: releaseGood?.attentionCompany || null,
479
- city: releaseGood?.city || null,
480
- state: releaseGood?.state || null,
481
- postalCode: releaseGood?.postalCode || null,
482
- country: releaseGood?.country || null,
483
- phone1: releaseGood?.phone1 || null,
484
- phone2: releaseGood?.phone2 || null,
485
- email: releaseGood?.email || null,
486
- transporter: releaseGood?.transporter,
487
- trackingNo: releaseGood?.trackingNo,
488
- airwayBill: releaseGood?.airwayBill,
489
- invoice: releaseGood?.invoice,
490
- refNo: releaseGood.refNo,
491
- refNo2: releaseGood.refNo2 || null,
492
- refNo3: releaseGood.refNo3 || null,
493
- remark: releaseGood?.remark || null,
494
- releaseDate: releaseGood.releaseDate,
495
- truckNo: releaseGood.truckNo,
496
- type: releaseGood?.type ? releaseGood.type : 'b2b',
497
- status: ORDER_STATUS.PENDING_WORKSHEET,
498
- storeName: releaseGood?.storeName,
499
- storeId: releaseGood?.storeId,
500
- routeId: releaseGood?.routeId,
501
- stopId: releaseGood?.stopId,
502
- packageId: releaseGood?.packageId || null,
503
- noOfItems: orderProducts.length,
504
- source: releaseGood?.source,
505
- creator: user,
506
- updater: user,
507
- acceptedBy: user,
508
- acceptedAt: new Date()
509
- }
510
-
511
- let resultReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
512
- let combinedOrderInventories: OrderInventory[] = []
513
- let savedOrderProducts = await Promise.all(
514
- orderProducts.map(async orderProduct => {
515
- let orderInventories: OrderInventory[] = orderProduct.orderInventories
516
- orderProduct = Object.assign(new OrderProduct(), {
517
- ...orderProduct,
518
- name: uuidv4(),
519
- domain: domain,
520
- bizplace: bizplace,
521
- releaseGood: resultReleaseGood,
522
- type: ORDER_TYPES.RELEASE_OF_GOODS,
523
- status: ORDER_PRODUCT_STATUS.ASSIGNED
524
- })
525
- let result = await tx.getRepository(OrderProduct).save(orderProduct)
526
-
527
- for (let oiIdx = 0; oiIdx < orderInventories.length; oiIdx++) {
528
- let orderInventory = Object.assign(new OrderInventory(), {
529
- ...orderInventories[oiIdx],
530
- name: uuidv4(),
531
- domain: domain,
532
- bizplace: bizplace,
533
- releaseGood: resultReleaseGood,
534
- type: ORDER_TYPES.RELEASE_OF_GOODS,
535
- status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET
536
- })
537
- await tx.getRepository(OrderInventory).save(orderInventory)
538
-
539
- combinedOrderInventories.push({
540
- product: { name: orderInventory.product.name, sku: orderInventory.product.sku },
541
- batchId: orderInventory.batchId,
542
- packingType: orderInventory.packingType,
543
- packingSize: orderInventory.packingSize,
544
- releaseQty: orderInventory.releaseQty,
545
- releaseUomValue: orderInventory.releaseUomValue
546
- })
547
- }
548
-
549
- return result
550
- })
551
- )
552
-
553
- newReleaseGood.orderProducts = savedOrderProducts
554
- newReleaseGood.orderInventories = combinedOrderInventories
555
-
556
- return newReleaseGood
557
- } catch (error) {
558
- throw error
559
- }
560
- }
561
-
562
- async function massageOrderItems(
563
- releaseGood,
564
- inputOrderProducts,
565
- context
566
- ): Promise<{ orderProducts: OrderProduct[]; combinedItems: OrderProduct[] }> {
567
- const { t } = context
568
- try {
569
- let orderProducts: OrderProduct[] = []
570
- let errorList = []
571
- //combine any repeated skus
572
- inputOrderProducts = inputOrderProducts.reduce((acc, itm, idx) => {
573
- let { sku, refCode } = itm.product
574
- let { packingType, packingSize, batchId, releaseQty } = itm
575
-
576
- if (!sku && !refCode) {
577
- errorList.push(
578
- JSON.stringify({
579
- code: 'INVALID_DATA',
580
- message: 'sku or refCode not found',
581
- sku: sku,
582
- refCode: refCode,
583
- packingType: packingType?.trim(),
584
- packingSize: packingSize,
585
- qty: releaseQty
586
- })
587
- )
588
- }
589
-
590
- if (releaseQty <= 0) {
591
- errorList.push(
592
- JSON.stringify({
593
- code: 'INVALID_DATA',
594
- message: 'negative stock request',
595
- sku: sku,
596
- refCode: refCode,
597
- packingType: packingType?.trim(),
598
- packingSize: packingSize,
599
- qty: releaseQty
600
- })
601
- )
602
- }
603
-
604
- let existingIndex = acc.findIndex(
605
- itm =>
606
- itm?.sku == sku?.trim() &&
607
- itm?.refCode == refCode?.trim() &&
608
- itm?.packingType == packingType?.trim() &&
609
- itm?.packingSize == packingSize
610
- )
611
-
612
- if (existingIndex >= 0 && releaseQty > 0) {
613
- acc[existingIndex].releaseQty = acc[existingIndex].releaseQty + releaseQty
614
- } else {
615
- acc.push({
616
- sku: sku?.trim(),
617
- refCode: refCode?.trim(),
618
- packingType: packingType?.trim(),
619
- packingSize: packingSize,
620
- releaseQty: releaseQty
621
- })
622
- }
623
-
624
- return acc
625
- }, [])
626
-
627
- if (errorList.length > 0) {
628
- throw new ValidationError({
629
- errorCode: 'INVALID_DATA',
630
- message: 'invalid data',
631
- detail: errorList.join(', ')
632
- })
633
- }
634
-
635
- //find customer sku in system
636
- await Promise.all(
637
- inputOrderProducts.map(async inputOrderItem => {
638
- const sku: string = inputOrderItem.sku
639
- const refCode: string = inputOrderItem.refCode
640
- const packingType: string = inputOrderItem.packingType
641
- const packingSize: string = inputOrderItem.packingSize
642
-
643
- const qb: SelectQueryBuilder<ProductDetail> = getRepository(ProductDetail)
644
- .createQueryBuilder('PD')
645
- .innerJoinAndSelect('PD.product', 'PROD')
646
- .where('PROD.bizplace_id = :bizplaceId', { bizplaceId: releaseGood.companyBizplace.id })
647
-
648
- if (!sku && !refCode) {
649
- context.throw(404, t('error.sku or refCode not found'))
650
- }
651
-
652
- if (refCode) {
653
- qb.andWhere('PD.ref_code = :refCode', { refCode })
654
- }
655
-
656
- if (sku) {
657
- qb.andWhere('PROD.sku = :sku', { sku })
658
- }
659
-
660
- if (packingType) {
661
- qb.andWhere('PD.packing_type = :packingType', { packingType })
662
- }
663
-
664
- if ((!packingType && !refCode) || !packingSize) {
665
- qb.andWhere('PD.is_default = :isDefault', { isDefault: true })
666
- }
667
-
668
- const productDetail: ProductDetail = await qb.getOne()
669
-
670
- // order Product based on product detail
671
- if (productDetail) {
672
- let newOrderProduct: OrderInventory = Object.assign({}, inputOrderItem)
673
- newOrderProduct = {
674
- ...newOrderProduct,
675
- product: productDetail.product,
676
- productDetail: productDetail,
677
- packingType: productDetail.packingType,
678
- packingSize: packingSize || productDetail.packingSize,
679
- uom: productDetail.uom,
680
- uomValue: productDetail.uomValue,
681
- refCode: inputOrderItem.refCode,
682
- releaseQty: inputOrderItem.releaseQty,
683
- releaseUomValue: inputOrderItem.releaseQty * (productDetail.uomValue || 1),
684
- packQty: 0,
685
- actualPackQty: 0,
686
- palletQty: 0,
687
- actualPalletQty: 0,
688
- type: 'RELEASE_OF_GOODS',
689
- status: ORDER_PRODUCT_STATUS.ASSIGNED,
690
- batchId: '-'
691
- }
692
-
693
- newOrderProduct.orderInventories = [
694
- {
695
- ...newOrderProduct,
696
- packQty: 0,
697
- actualPackQty: 0,
698
- palletQty: 0,
699
- actualPalletQty: 0,
700
- type: 'RELEASE_OF_GOODS',
701
- status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET
702
- }
703
- ]
704
-
705
- orderProducts.push(newOrderProduct)
706
- }
707
-
708
- if (!productDetail) {
709
- const qb: SelectQueryBuilder<ProductDetail> = getRepository(ProductBundle)
710
- .createQueryBuilder('PB')
711
- .innerJoinAndSelect('PB.productBundleSettings', 'PBS')
712
- .innerJoinAndSelect('PBS.productDetail', 'PBD')
713
- .innerJoinAndSelect('PBD.product', 'PROD')
714
- .where('PB.bizplace_id = :bizplaceId', { bizplaceId: releaseGood.companyBizplace.id })
715
-
716
- if (!sku && !refCode) {
717
- context.throw(404, t('error.sku or refCode not found'))
718
- }
719
-
720
- if (refCode) {
721
- qb.andWhere('PB.ref_code = :refCode', { refCode })
722
- }
723
-
724
- if (sku) {
725
- qb.andWhere('PB.sku = :sku', { sku })
726
- }
727
-
728
- if (packingType) {
729
- qb.andWhere('PB.packing_type = :packingType', { packingType })
730
- }
731
-
732
- const foundProductBundle: ProductBundle = await qb.getOne()
733
-
734
- if (foundProductBundle) {
735
- let orderProduct = {
736
- productBundle: foundProductBundle,
737
- refCode,
738
- packingType: foundProductBundle.packingType,
739
- packingSize: packingSize || 1,
740
- uom: inputOrderItem?.uom,
741
- releaseQty: inputOrderItem.releaseQty,
742
- releaseUomValue: inputOrderItem.releaseQty,
743
- packQty: 0,
744
- actualPackQty: 0,
745
- palletQty: 0,
746
- actualPalletQty: 0,
747
- orderInventories: [],
748
- type: 'RELEASE_OF_GOODS',
749
- status: ORDER_PRODUCT_STATUS.ASSIGNED,
750
- batchId: '-'
751
- }
752
-
753
- const bundleProductSettings: any[] = foundProductBundle.productBundleSettings
754
- bundleProductSettings.map(bundleProductSetting => {
755
- const productDetailBundle: ProductDetail = bundleProductSetting.productDetail
756
-
757
- let newOrderInventory: OrderInventory = {
758
- product: productDetailBundle.product,
759
- productDetail: productDetailBundle,
760
- sku: productDetailBundle.product.sku,
761
- packingType: productDetailBundle.packingType,
762
- packingSize: productDetailBundle.packingSize,
763
- uom: productDetailBundle.uom,
764
- packQty: 0,
765
- actualPackQty: 0,
766
- palletQty: 0,
767
- actualPalletQty: 0,
768
- releaseQty: inputOrderItem.releaseQty * bundleProductSetting.bundleQty,
769
- releaseUomValue:
770
- inputOrderItem.releaseQty *
771
- bundleProductSetting.bundleQty *
772
- (productDetailBundle.uomValue <= 0 ? 1 : productDetailBundle.uomValue),
773
- type: 'RELEASE_OF_GOODS',
774
- status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET
775
- }
776
-
777
- orderProduct.orderInventories.push(newOrderInventory)
778
- })
779
- orderProducts.push(orderProduct)
780
- } else {
781
- if (sku && refCode) {
782
- context.throw(404, t(`error.sku ${sku} and refCode ${refCode} not exist in product / bundle master`))
783
- }
784
-
785
- if (sku) {
786
- context.throw(404, t(`error.sku ${sku} not exist in product / bundle master`))
787
- }
788
-
789
- if (refCode) {
790
- context.throw(404, t(`error.refCode ${refCode} not exist in product / bundle master`))
791
- }
792
- }
793
- }
794
- })
795
- )
796
-
797
- //combine any repeated skus
798
- let combinedItems: OrderProduct[] = orderProducts.reduce((acc, op, idx) => {
799
- let oi = op?.orderInventories || []
800
- oi.forEach(itm => {
801
- let { sku, refCode } = itm.product
802
- let { packingType, packingSize, batchId, releaseQty, product, productDetail, uom } = itm
803
-
804
- if (!sku && !refCode) {
805
- context.throw(404, t('error.sku or refCode not found'))
806
- }
807
- let existingIndex = acc.findIndex(
808
- itm =>
809
- itm?.sku == sku?.trim() &&
810
- itm?.refCode == refCode?.trim() &&
811
- itm?.packingType == packingType?.trim() &&
812
- itm?.packingSize == packingSize &&
813
- itm?.batchId == batchId?.trim() &&
814
- itm?.uom == uom?.trim()
815
- )
816
-
817
- if (existingIndex >= 0 && releaseQty > 0) {
818
- acc[existingIndex].releaseQty = acc[existingIndex].releaseQty + releaseQty
819
- acc[existingIndex].releaseUomValue =
820
- acc[existingIndex].releaseUomValue + releaseQty * (productDetail.uomValue <= 0 ? 1 : productDetail.uomValue)
821
- } else {
822
- let updateObj = {
823
- sku: sku?.trim(),
824
- packingType: packingType?.trim(),
825
- packingSize: packingSize,
826
- uom: uom?.trim(),
827
- releaseQty: releaseQty,
828
- releaseUomValue: releaseQty * (productDetail.uomValue <= 0 ? 1 : productDetail.uomValue),
829
- product,
830
- productDetail
831
- }
832
-
833
- if (refCode) updateObj['refCode'] = refCode.trim()
834
- updateObj['batchId'] = batchId ? batchId?.trim() : '-'
835
-
836
- acc.push(updateObj)
837
- }
838
- })
839
- return acc
840
- }, [])
841
-
842
- return { orderProducts, combinedItems }
843
- } catch (error) {
844
- throw error
845
- }
846
- }
847
-
848
- async function assignToInventory(orderProducts: OrderProduct[], customerBizplace, context, tx) {
849
- const { client, domain, user } = context.state
850
- for (let opIdx = 0; opIdx < orderProducts.length; opIdx++) {
851
- let orderProduct = orderProducts[opIdx]
852
-
853
- let assignedOrderInventories = []
854
- const pickingProductSetting: Setting = await tx.getRepository(Setting).findOne({
855
- where: { domain: { id: domain.id }, name: 'rule-for-picking-product' }
856
- })
857
-
858
- for (let oiIdx = 0; oiIdx < orderProducts[opIdx].orderInventories.length; oiIdx++) {
859
- const orderInventory = orderProduct.orderInventories[oiIdx]
860
- let sortings: any = []
861
-
862
- switch (orderInventory.product.pickingStrategy) {
863
- case 'LIFO':
864
- sortings.push({ name: 'iv.created_at', desc: true })
865
- if (pickingProductSetting?.value) {
866
- for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
867
- sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
868
- }
869
- } else {
870
- sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
871
- }
872
-
873
- break
874
- case 'FEFO':
875
- sortings.push({ name: 'iv.expiration_date', desc: false }, { name: 'iv.created_at', desc: false })
876
- if (pickingProductSetting?.value) {
877
- for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
878
- sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
879
- }
880
- } else {
881
- sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
882
- }
883
-
884
- break
885
- case 'FMFO':
886
- sortings.push({ name: 'iv.manufacture_date', desc: false }, { name: 'iv.created_at', desc: false })
887
- if (pickingProductSetting?.value) {
888
- for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
889
- sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
890
- }
891
- } else {
892
- sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
893
- }
894
-
895
- break
896
- case 'LOCATION':
897
- if (pickingProductSetting?.value) {
898
- for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
899
- sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
900
- }
901
- } else {
902
- sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
903
- }
904
-
905
- break
906
- //Every other case includes 'FIFO' will be applicable for this case
907
- default:
908
- sortings.push({ name: 'iv.created_at', desc: false })
909
- if (pickingProductSetting?.value) {
910
- for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
911
- sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
912
- }
913
- } else {
914
- sortings.push({ name: 'loc.name', desc: false })
915
- sortings.push({ name: 'iv.pallet_id', desc: false })
916
- }
917
- break
918
- }
919
-
920
- let queryFilters = []
921
-
922
- let queryStrings = queryFilters.reduce(
923
- (acc, itm, idx, arr) => {
924
- acc.values.push(itm.filters)
925
-
926
- switch (itm?.operator) {
927
- case 'notin':
928
- case 'in':
929
- acc.query.push(
930
- `${itm.query} ${itm.operator == 'notin' ? 'NOT IN' : 'IN'} (${itm.filtes
931
- .map((itm, idx) => {
932
- return `$${acc.values.length + 1}`
933
- })
934
- .join(',')})`
935
- )
936
- break
937
-
938
- default:
939
- acc.query.push(`${itm.query} ${itm?.operator ? itm.operator : '='} $${acc.values.length + 1}`)
940
- break
941
- }
942
- acc.query.push(`${itm.query} ${itm?.operator ? itm.operator : '='} $${acc.values.length + 1}`)
943
- },
944
- {
945
- query: [],
946
- values: []
947
- }
948
- )
949
-
950
- let sortQuery = sortings
951
- .map(itm => {
952
- return `${itm.name} ${itm.desc ? 'DESC' : 'ASC'}`
953
- })
954
- .join(`,`)
955
-
956
- let updatedInventories = await tx.getRepository(Inventory).query(
957
- `
958
- update inventories tgt set locked_qty = coalesce(locked_qty,0) + src.reserve_qty,
959
- locked_uom_value = coalesce(locked_uom_value,0) + src.reserve_uom_value,
960
- updated_at = NOW(),
961
- updater_id = $1
962
- from (
963
- select "id", "pallet_id","carton_id", "batch_id", "batch_id_ref", "unit", "uom", "packing_type", "packing_size", "manufacture_year",
964
- "reserve_qty", (("uom_value"/"qty") * "reserve_qty") as "reserve_uom_value" from (
965
- select "sort_seq", "id", "pallet_id", "batch_id", "batch_id_ref", "unit", "uom", "packing_type", "packing_size", "manufacture_year", "carton_id", "uom_value", "locked_uom_value", "qty", "locked_qty", "created_at",
966
- "release_qty", "release_uom_value", lock_amount,
967
- case when "lock_amount" < 0 then "available_qty" else "available_qty" - "lock_amount" end as "reserve_qty"
968
- from (
969
- select *,
970
- qty - locked_qty as available_qty,
971
- sum(qty - locked_qty - release_qty) over (order by sort_seq asc rows between unbounded preceding and current row) as lock_amount
972
- from (
973
- SELECT 0 as sort_seq, null as id, null as pallet_id, null as batch_id, null as batch_id_ref,
974
- null as unit, '${orderInventory.uom}' as uom, '${orderInventory.packingType}' as packing_type, '${
975
- orderInventory.packingSize
976
- }' as packing_size,
977
- null as manufacture_year, null as carton_id, 0 as uom_value, 0 as locked_uom_value, 0 as qty, 0 as locked_qty, null as created_at,
978
- '${orderInventory.releaseQty}' as release_qty, '${orderInventory.releaseUomValue}' as release_uom_value
979
- UNION
980
- (
981
- SELECT ROW_NUMBER() OVER(PARTITION BY iv.domain_id ORDER BY ${sortQuery}) as sort_seq,
982
- iv.id, iv.pallet_id, iv.batch_id, iv.batch_id_ref,
983
- iv.unit, iv.uom, iv.packing_type, iv.packing_size,
984
- iv.manufacture_year, iv.carton_id, iv.uom_value,
985
- coalesce(iv.locked_uom_value,0) as locked_uom_value, iv.qty, coalesce(iv.locked_qty,0) as locked_qty, iv.created_at,
986
- 0 as release_qty, 0 as release_uom_value
987
- FROM "inventories" "iv"
988
- INNER JOIN "locations" "loc" ON "loc"."id"="iv"."location_id"
989
- WHERE case when coalesce("iv"."locked_qty",0) < 0 then 0 else ("iv"."qty" - coalesce("iv"."locked_qty",0)) end > 0 AND
990
- "iv"."domain_id" = $2 AND "iv"."bizplace_id" = $3 AND "iv"."packing_type" = $4 AND "iv"."packing_size" = $5 AND "iv"."product_id" = $6 AND "iv"."status" = $7 AND "loc"."type" NOT IN ($8, $9)
991
- ${queryStrings.query.length > 0 ? `AND ${queryStrings.join(' AND ')}` : ''}
992
- ORDER BY ${sortQuery}
993
- )
994
- ) dt1
995
- ) dt2 where case when "lock_amount" < 0 then "available_qty" else "available_qty" - "lock_amount" end > 0
996
- ) dt3 where sort_seq > 0
997
- ) src where src.id = tgt.id
998
- returning
999
- tgt."id", tgt."qty", tgt."pallet_id", tgt."carton_id", tgt."batch_id", tgt."batch_id_ref", tgt."unit",
1000
- tgt."uom", tgt."packing_type", tgt."packing_size", tgt."manufacture_year",
1001
- tgt."locked_qty", tgt."uom_value", tgt."locked_uom_value", src."reserve_qty", src."reserve_uom_value";`,
1002
- [
1003
- user.id,
1004
- domain.id,
1005
- customerBizplace.id,
1006
- orderInventory.packingType,
1007
- orderInventory.packingSize,
1008
- orderInventory.product.id,
1009
- INVENTORY_STATUS.STORED,
1010
- LOCATION_TYPE.QUARANTINE,
1011
- LOCATION_TYPE.RESERVE,
1012
- ...queryStrings.values
1013
- ]
1014
- )
1015
-
1016
- let totalAssigned = updatedInventories[0].reduce((acc, inv) => {
1017
- return acc + inv.reserve_qty
1018
- }, 0)
1019
-
1020
- if (orderInventory.releaseQty != totalAssigned) {
1021
- throw new ValidationError({
1022
- errorCode: 'INSUFFICIENT_STOCK',
1023
- message: 'insufficient stock',
1024
- detail: JSON.stringify({
1025
- code: 'insufficient stock',
1026
- sku: orderInventory.product.sku,
1027
- packingType: orderInventory.packingType,
1028
- packingSize: orderInventory.packingSize,
1029
- uom: orderInventory.uom,
1030
- qty: orderInventory.releaseQty,
1031
- uom_value: orderInventory.releaseUomValue
1032
- })
1033
- })
1034
- }
1035
-
1036
- updatedInventories[0].forEach(inv => {
1037
- let oi = {
1038
- ...orderInventory,
1039
- inventory: { id: inv.id },
1040
- uom: inv.uom,
1041
- packingType: inv.packing_type,
1042
- batchId: inv.batch_id,
1043
- releaseQty: inv.reserve_qty,
1044
- releaseUomValue: inv.reserve_uom_value,
1045
- pickedQty: 0,
1046
- packedQty: 0,
1047
- type: ORDER_TYPES.RELEASE_OF_GOODS,
1048
- status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET,
1049
- domain: { id: domain.id },
1050
- bizplace: { id: customerBizplace.id }
1051
- }
1052
-
1053
- assignedOrderInventories.push(oi)
1054
- })
1055
- }
1056
-
1057
- orderProducts[opIdx].orderInventories = assignedOrderInventories
1058
- }
1059
-
1060
- return orderProducts
1061
- }