@things-factory/sales-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 (178) hide show
  1. package/dist-server/tsconfig.tsbuildinfo +1 -1
  2. package/package.json +13 -13
  3. package/server/constants/attachment-type.ts +9 -0
  4. package/server/constants/index.ts +7 -0
  5. package/server/constants/load-type.ts +4 -0
  6. package/server/constants/order.ts +203 -0
  7. package/server/constants/product-group-type.ts +4 -0
  8. package/server/constants/release-good.ts +9 -0
  9. package/server/constants/transfer-order-type.ts +6 -0
  10. package/server/constants/validation-error-code.ts +3 -0
  11. package/server/constants/vas-target-type.ts +25 -0
  12. package/server/controllers/ecommerce/ecommerce-controller.ts +122 -0
  13. package/server/controllers/ecommerce/index.ts +2 -0
  14. package/server/controllers/ecommerce/sellercraft-controller.ts +182 -0
  15. package/server/controllers/index.ts +2 -0
  16. package/server/controllers/order-controller.ts +296 -0
  17. package/server/errors/index.ts +1 -0
  18. package/server/errors/validation-error.ts +25 -0
  19. package/server/index.ts +5 -0
  20. package/server/migrations/index.ts +9 -0
  21. package/server/service/arrival-notice/arrival-notice-mutation.ts +1152 -0
  22. package/server/service/arrival-notice/arrival-notice-query.ts +549 -0
  23. package/server/service/arrival-notice/arrival-notice-types.ts +310 -0
  24. package/server/service/arrival-notice/arrival-notice.ts +202 -0
  25. package/server/service/arrival-notice/index.ts +9 -0
  26. package/server/service/claim/claim-mutation.ts +308 -0
  27. package/server/service/claim/claim-query.ts +122 -0
  28. package/server/service/claim/claim-types.ts +130 -0
  29. package/server/service/claim/claim.ts +140 -0
  30. package/server/service/claim/index.ts +9 -0
  31. package/server/service/claim-detail/claim-detail-mutation.ts +102 -0
  32. package/server/service/claim-detail/claim-detail-query.ts +55 -0
  33. package/server/service/claim-detail/claim-detail-types.ts +47 -0
  34. package/server/service/claim-detail/claim-detail.ts +69 -0
  35. package/server/service/claim-detail/index.ts +9 -0
  36. package/server/service/claim-order/claim-order-mutation.ts +101 -0
  37. package/server/service/claim-order/claim-order-query.ts +47 -0
  38. package/server/service/claim-order/claim-order-types.ts +35 -0
  39. package/server/service/claim-order/claim-order.ts +81 -0
  40. package/server/service/claim-order/index.ts +9 -0
  41. package/server/service/collection-order/collection-order-mutation.ts +245 -0
  42. package/server/service/collection-order/collection-order-query.ts +97 -0
  43. package/server/service/collection-order/collection-order-types.ts +165 -0
  44. package/server/service/collection-order/collection-order.ts +135 -0
  45. package/server/service/collection-order/index.ts +9 -0
  46. package/server/service/delivery-order/delivery-order-mutation.ts +967 -0
  47. package/server/service/delivery-order/delivery-order-query.ts +631 -0
  48. package/server/service/delivery-order/delivery-order-types.ts +268 -0
  49. package/server/service/delivery-order/delivery-order.ts +258 -0
  50. package/server/service/delivery-order/index.ts +9 -0
  51. package/server/service/draft-release-good/draft-release-good-mutation.ts +765 -0
  52. package/server/service/draft-release-good/draft-release-good-query.ts +354 -0
  53. package/server/service/draft-release-good/draft-release-good-type.ts +261 -0
  54. package/server/service/draft-release-good/draft-release-good.ts +284 -0
  55. package/server/service/draft-release-good/index.ts +9 -0
  56. package/server/service/goods-receival-note/goods-receival-note-mutation.ts +129 -0
  57. package/server/service/goods-receival-note/goods-receival-note-query.ts +280 -0
  58. package/server/service/goods-receival-note/goods-receival-note-types.ts +105 -0
  59. package/server/service/goods-receival-note/goods-receival-note.ts +127 -0
  60. package/server/service/goods-receival-note/index.ts +9 -0
  61. package/server/service/index.ts +238 -0
  62. package/server/service/inventory-check/index.ts +9 -0
  63. package/server/service/inventory-check/inventory-check-mutation.ts +149 -0
  64. package/server/service/inventory-check/inventory-check-query.ts +48 -0
  65. package/server/service/inventory-check/inventory-check-types.ts +48 -0
  66. package/server/service/inventory-check/inventory-check.ts +90 -0
  67. package/server/service/invoice/index.ts +9 -0
  68. package/server/service/invoice/invoice-mutation.ts +95 -0
  69. package/server/service/invoice/invoice-query.ts +53 -0
  70. package/server/service/invoice/invoice-types.ts +279 -0
  71. package/server/service/invoice/invoice.ts +230 -0
  72. package/server/service/invoice-product/index.ts +9 -0
  73. package/server/service/invoice-product/invoice-product-mutation.ts +54 -0
  74. package/server/service/invoice-product/invoice-product-query.ts +54 -0
  75. package/server/service/invoice-product/invoice-product-types.ts +84 -0
  76. package/server/service/invoice-product/invoice-product.ts +92 -0
  77. package/server/service/job-sheet/index.ts +9 -0
  78. package/server/service/job-sheet/job-sheet-mutation.ts +92 -0
  79. package/server/service/job-sheet/job-sheet-query.ts +112 -0
  80. package/server/service/job-sheet/job-sheet-types.ts +78 -0
  81. package/server/service/job-sheet/job-sheet.ts +102 -0
  82. package/server/service/manifest/index.ts +6 -0
  83. package/server/service/manifest/manifest-mutation.ts +190 -0
  84. package/server/service/manifest/manifest-query.ts +149 -0
  85. package/server/service/manifest/manifest-type.ts +84 -0
  86. package/server/service/manifest/manifest.ts +114 -0
  87. package/server/service/order-inventory/index.ts +9 -0
  88. package/server/service/order-inventory/order-inventory-mutation.ts +54 -0
  89. package/server/service/order-inventory/order-inventory-query.ts +722 -0
  90. package/server/service/order-inventory/order-inventory-types.ts +238 -0
  91. package/server/service/order-inventory/order-inventory.ts +401 -0
  92. package/server/service/order-product/index.ts +9 -0
  93. package/server/service/order-product/order-product-mutation.ts +48 -0
  94. package/server/service/order-product/order-product-query.ts +89 -0
  95. package/server/service/order-product/order-product-types.ts +335 -0
  96. package/server/service/order-product/order-product.ts +362 -0
  97. package/server/service/order-tote/index.ts +9 -0
  98. package/server/service/order-tote/order-tote-mutation.ts +31 -0
  99. package/server/service/order-tote/order-tote-query.ts +112 -0
  100. package/server/service/order-tote/order-tote-types.ts +47 -0
  101. package/server/service/order-tote/order-tote.ts +73 -0
  102. package/server/service/order-tote-item/index.ts +9 -0
  103. package/server/service/order-tote-item/order-tote-item-mutation.ts +31 -0
  104. package/server/service/order-tote-item/order-tote-item-query.ts +82 -0
  105. package/server/service/order-tote-item/order-tote-item-types.ts +56 -0
  106. package/server/service/order-tote-item/order-tote-item.ts +72 -0
  107. package/server/service/order-tote-seal/index.ts +9 -0
  108. package/server/service/order-tote-seal/order-tote-seal-mutation.ts +31 -0
  109. package/server/service/order-tote-seal/order-tote-seal-query.ts +59 -0
  110. package/server/service/order-tote-seal/order-tote-seal-types.ts +41 -0
  111. package/server/service/order-tote-seal/order-tote-seal.ts +46 -0
  112. package/server/service/order-vas/index.ts +9 -0
  113. package/server/service/order-vas/order-vas-mutation.ts +20 -0
  114. package/server/service/order-vas/order-vas-query.ts +72 -0
  115. package/server/service/order-vas/order-vas-types.ts +159 -0
  116. package/server/service/order-vas/order-vas.ts +207 -0
  117. package/server/service/others/index.ts +5 -0
  118. package/server/service/others/other-query.ts +563 -0
  119. package/server/service/others/other-types.ts +115 -0
  120. package/server/service/purchase-order/index.ts +9 -0
  121. package/server/service/purchase-order/purchase-order-mutation.ts +458 -0
  122. package/server/service/purchase-order/purchase-order-query.ts +90 -0
  123. package/server/service/purchase-order/purchase-order-types.ts +154 -0
  124. package/server/service/purchase-order/purchase-order.ts +172 -0
  125. package/server/service/purchase-order-other-charge/index.ts +9 -0
  126. package/server/service/purchase-order-other-charge/purchase-order-other-charge-mutation.ts +31 -0
  127. package/server/service/purchase-order-other-charge/purchase-order-other-charge-query.ts +52 -0
  128. package/server/service/purchase-order-other-charge/purchase-order-other-charge-types.ts +44 -0
  129. package/server/service/purchase-order-other-charge/purchase-order-other-charge.ts +68 -0
  130. package/server/service/release-good/index.ts +9 -0
  131. package/server/service/release-good/release-good-mutation.ts +1686 -0
  132. package/server/service/release-good/release-good-query.ts +980 -0
  133. package/server/service/release-good/release-good-types.ts +662 -0
  134. package/server/service/release-good/release-good.ts +490 -0
  135. package/server/service/retail-replenishment-order/index.ts +9 -0
  136. package/server/service/retail-replenishment-order/retail-replenishment-order-mutation.ts +382 -0
  137. package/server/service/retail-replenishment-order/retail-replenishment-order-query.ts +54 -0
  138. package/server/service/retail-replenishment-order/retail-replenishment-order-types.ts +101 -0
  139. package/server/service/retail-replenishment-order/retail-replenishment-order.ts +115 -0
  140. package/server/service/return-order/index.ts +9 -0
  141. package/server/service/return-order/return-order-mutation.ts +516 -0
  142. package/server/service/return-order/return-order-query.ts +226 -0
  143. package/server/service/return-order/return-order-types.ts +196 -0
  144. package/server/service/return-order/return-order.ts +127 -0
  145. package/server/service/reverse-kitting-order/index.ts +9 -0
  146. package/server/service/reverse-kitting-order/reverse-kitting-order-mutation.ts +500 -0
  147. package/server/service/reverse-kitting-order/reverse-kitting-order-query.ts +197 -0
  148. package/server/service/reverse-kitting-order/reverse-kitting-order-type.ts +173 -0
  149. package/server/service/reverse-kitting-order/reverse-kitting-order.ts +121 -0
  150. package/server/service/reverse-kitting-order-inventory/index.ts +9 -0
  151. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-mutation.ts +129 -0
  152. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-query.ts +52 -0
  153. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-type.ts +95 -0
  154. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory.ts +143 -0
  155. package/server/service/shipping-order/index.ts +9 -0
  156. package/server/service/shipping-order/shipping-order-mutation.ts +61 -0
  157. package/server/service/shipping-order/shipping-order-query.ts +61 -0
  158. package/server/service/shipping-order/shipping-order-types.ts +89 -0
  159. package/server/service/shipping-order/shipping-order.ts +129 -0
  160. package/server/service/transfer-order/index.ts +9 -0
  161. package/server/service/transfer-order/transfer-order-mutation.ts +309 -0
  162. package/server/service/transfer-order/transfer-order-query.ts +66 -0
  163. package/server/service/transfer-order/transfer-order-types.ts +97 -0
  164. package/server/service/transfer-order/transfer-order.ts +117 -0
  165. package/server/service/vas/index.ts +9 -0
  166. package/server/service/vas/vas-mutation.ts +106 -0
  167. package/server/service/vas/vas-query.ts +60 -0
  168. package/server/service/vas/vas-types.ts +71 -0
  169. package/server/service/vas/vas.ts +77 -0
  170. package/server/service/vas-order/index.ts +9 -0
  171. package/server/service/vas-order/vas-order-mutation.ts +259 -0
  172. package/server/service/vas-order/vas-order-query.ts +119 -0
  173. package/server/service/vas-order/vas-order-types.ts +49 -0
  174. package/server/service/vas-order/vas-order.ts +81 -0
  175. package/server/utils/datetime-util.ts +54 -0
  176. package/server/utils/index.ts +3 -0
  177. package/server/utils/inventory-util.ts +1155 -0
  178. package/server/utils/order-no-generator.ts +146 -0
@@ -0,0 +1,382 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+ import { EntityManager, In, Repository } from 'typeorm'
3
+
4
+ import { User } from '@things-factory/auth-base'
5
+ import { Bizplace, getOutletBizplace } from '@things-factory/biz-base'
6
+ import { generateId } from '@things-factory/id-rule-base'
7
+ import { Product } from '@things-factory/product-base'
8
+ import { Setting } from '@things-factory/setting-base'
9
+ import { Domain, getRepository } from '@things-factory/shell'
10
+
11
+ import {
12
+ NewOrderProduct,
13
+ NewRetailReplenishmentOrder,
14
+ OrderProduct,
15
+ OrderVas,
16
+ RetailReplenishmentOrderPatch
17
+ } from '../'
18
+ import {
19
+ ORDER_NUMBER_RULE_TYPE,
20
+ ORDER_NUMBER_SETTING_KEY,
21
+ ORDER_PRODUCT_STATUS,
22
+ ORDER_STATUS,
23
+ TRANSFER_ORDER_TYPE
24
+ } from '../../constants'
25
+ import { OrderNoGenerator } from '../../utils'
26
+ import { generateTransferOrder } from '../transfer-order/transfer-order-mutation'
27
+ import { RetailReplenishmentOrder } from './retail-replenishment-order'
28
+
29
+ @Resolver(RetailReplenishmentOrder)
30
+ export class RetailReplenishmentOrderMutation {
31
+ @Directive('@transaction')
32
+ @Mutation(returns => Boolean)
33
+ async addRetailReplenishmentOrderProducts(
34
+ @Arg('sroNo') sroNo: string,
35
+ @Arg('orderProducts', type => [NewOrderProduct]) orderProducts: NewOrderProduct[],
36
+ @Ctx() context: ResolverContext
37
+ ): Promise<boolean> {
38
+ const { tx, user, domain } = context.state
39
+ const retailReplenishmentOrder: RetailReplenishmentOrder = await tx
40
+ .getRepository(RetailReplenishmentOrder)
41
+ .findOne({
42
+ where: { name: sroNo },
43
+ relations: ['bizplace', 'orderProducts']
44
+ })
45
+
46
+ await addRetailReplenishmentOrderProducts(domain, retailReplenishmentOrder, orderProducts, user, tx)
47
+ return true
48
+ }
49
+
50
+ @Directive('@transaction')
51
+ @Mutation(returns => RetailReplenishmentOrder)
52
+ async cancelRetailReplenishmentOrder(
53
+ @Arg('patch', type => RetailReplenishmentOrderPatch) patch: RetailReplenishmentOrderPatch,
54
+ @Ctx() context: ResolverContext
55
+ ): Promise<RetailReplenishmentOrder> {
56
+ const { tx, domain, user } = context.state
57
+ const bizplace: Bizplace = await getOutletBizplace(patch.warehouseId)
58
+
59
+ const retailReplenishmentOrder: RetailReplenishmentOrder = await tx
60
+ .getRepository(RetailReplenishmentOrder)
61
+ .findOne({
62
+ where: { domain: { id: domain.id }, bizplace: { id: bizplace.id }, name: patch.name },
63
+ relations: ['orderProducts']
64
+ })
65
+
66
+ if (!retailReplenishmentOrder) throw new Error(`Retail replenishment order does not exist.`)
67
+ if (!patch.status) throw new Error('Status was not specified.')
68
+ // if (status && (status !== ORDER_STATUS.PENDING_CANCEL || status !== ORDER_STATUS.CANCELLED))
69
+ // throw new Error(`Status provided was invalid.`)
70
+
71
+ let foundOPs: OrderProduct[] = retailReplenishmentOrder.orderProducts
72
+
73
+ // 1. Update status of order products based on status (to PENDING_CANCEL or CANCELLED)
74
+ if (foundOPs && foundOPs.length) {
75
+ foundOPs = foundOPs.map((orderProduct: OrderProduct) => {
76
+ orderProduct.status = patch.status
77
+ orderProduct.updater = user
78
+ return orderProduct
79
+ })
80
+ }
81
+ await tx.getRepository(OrderProduct).save(foundOPs)
82
+
83
+ // 2. Update retail replenishment order status
84
+ return await tx.getRepository(RetailReplenishmentOrder).save({
85
+ ...retailReplenishmentOrder,
86
+ remark: patch.remark, //think another way if warehouse confirm cancellation > no need to overwrite remark
87
+ status: patch.status,
88
+ updater: user
89
+ })
90
+ }
91
+
92
+ @Directive('@transaction')
93
+ @Mutation(returns => RetailReplenishmentOrder)
94
+ async createRetailReplenishmentOrder(
95
+ @Arg('retailReplenishmentOrder', type => NewRetailReplenishmentOrder)
96
+ retailReplenishmentOrder: NewRetailReplenishmentOrder,
97
+ @Ctx() context: ResolverContext
98
+ ): Promise<RetailReplenishmentOrder> {
99
+ const { tx, domain, user } = context.state
100
+ const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
101
+
102
+ let orderVass: OrderVas[] = retailReplenishmentOrder.orderVass as any
103
+ const myBizplace: Bizplace = await getOutletBizplace(retailReplenishmentOrder.warehouseId)
104
+
105
+ // #1 check for allocated qty to identify the status: APPROVED or PENDING
106
+ const allocatedQty: number = null
107
+ let status = allocatedQty ? ORDER_STATUS.PENDING : ORDER_STATUS.APPROVED
108
+ let remark = allocatedQty ? 'INSUFFICIENT QTY' : ''
109
+
110
+ let orderProducts: NewOrderProduct[] = retailReplenishmentOrder.orderProducts
111
+ orderProducts = orderProducts.map((op: NewOrderProduct) => {
112
+ return {
113
+ ...op,
114
+ status: allocatedQty ? ORDER_PRODUCT_STATUS.PENDING : ORDER_PRODUCT_STATUS.APPROVED,
115
+ remark
116
+ }
117
+ })
118
+
119
+ const rrNoSetting: Setting = await settingRepo.findOne({
120
+ where: {
121
+ domain: { id: domain.id },
122
+ name: ORDER_NUMBER_SETTING_KEY.RR_NUMBER_RULE
123
+ }
124
+ })
125
+
126
+ let orderNo: string = ''
127
+
128
+ if (rrNoSetting) {
129
+ orderNo = await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.RR_NUMBER, seed: {} })
130
+ } else {
131
+ orderNo = OrderNoGenerator.retailReplenishmentOrder()
132
+ }
133
+
134
+ // #2 Create Retail Replenishment Order
135
+ const createdRetailReplenishmentOrder: RetailReplenishmentOrder = await tx
136
+ .getRepository(RetailReplenishmentOrder)
137
+ .save({
138
+ ...retailReplenishmentOrder,
139
+ name: orderNo,
140
+ bizplace: myBizplace,
141
+ status,
142
+ domain,
143
+ creator: user,
144
+ updater: user
145
+ })
146
+
147
+ // #3 Create retail replenishment order products
148
+ await addRetailReplenishmentOrderProducts(domain, createdRetailReplenishmentOrder, orderProducts, user, tx)
149
+
150
+ // #4 generate transfer order if status is APPROVED
151
+ if (createdRetailReplenishmentOrder.status === ORDER_STATUS.APPROVED) {
152
+ const issuedDate: string = retailReplenishmentOrder.issuedDate
153
+ const remark: string = retailReplenishmentOrder.remark
154
+ const refNo: string = retailReplenishmentOrder.refNo
155
+ const ownTransport: boolean = retailReplenishmentOrder.ownTransport
156
+ const orderInventories: any[] = orderProducts.map((op: NewOrderProduct) => {
157
+ return {
158
+ batchId: op.batchId,
159
+ releaseQty: op.packQty,
160
+ product: op.product,
161
+ packingType: op.packingType
162
+ }
163
+ })
164
+
165
+ await generateTransferOrder(
166
+ {
167
+ issuedDate,
168
+ remark,
169
+ refNo,
170
+ type: TRANSFER_ORDER_TYPE.NORMAL,
171
+ ownTransport,
172
+ orderInventories,
173
+ orderVass,
174
+ bizplace: myBizplace,
175
+ retailReplenishmentOrder: createdRetailReplenishmentOrder
176
+ } as any,
177
+ domain,
178
+ user,
179
+ tx
180
+ )
181
+ }
182
+
183
+ return createdRetailReplenishmentOrder
184
+ }
185
+
186
+ @Directive('@transaction')
187
+ @Mutation(returns => RetailReplenishmentOrder)
188
+ async completeRetailReplenishmentOrder(
189
+ @Arg('patch', type => RetailReplenishmentOrderPatch) patch: RetailReplenishmentOrderPatch,
190
+ @Ctx() context: ResolverContext
191
+ ): Promise<RetailReplenishmentOrder> {
192
+ const { tx, domain, user } = context.state
193
+
194
+ const myBizplace: Bizplace = await getOutletBizplace(patch.warehouseId)
195
+ let targetOPs: NewOrderProduct[] = patch.orderProducts
196
+ let partialReceived: Boolean = false
197
+
198
+ // #1 Find Retail Replenishment Order
199
+ const foundRRO: RetailReplenishmentOrder = await tx.getRepository(RetailReplenishmentOrder).findOne({
200
+ where: { domain: { id: domain.id }, name: patch.name, bizplace: { id: myBizplace.id } },
201
+ relations: ['orderProducts']
202
+ })
203
+
204
+ if (!foundRRO) throw new Error(`Retail replenishment order does not exist.`)
205
+
206
+ if (foundRRO?.status && foundRRO.status === ORDER_STATUS.RECEIVED)
207
+ throw new Error(`Retail replenishment order is already completed.`)
208
+
209
+ // #2 Find related order inventories
210
+ let foundOPs: OrderProduct[] = await tx.getRepository(OrderProduct).find({
211
+ where: { domain: { id: domain.id } /* CONFIRMME regarding TYPEORM , transferOrder: foundRRO */ }
212
+ })
213
+ if (!foundOPs) throw new Error(`Order products were not found.`)
214
+
215
+ foundOPs = foundOPs.map((orderProduct: OrderProduct) => {
216
+ const foundTargetOP = targetOPs.filter(
217
+ (targetOP: NewOrderProduct) => targetOP.name === orderProduct.name && targetOP.batchId === orderProduct.batchId
218
+ )[0]
219
+
220
+ orderProduct.status = foundTargetOP.status
221
+ orderProduct.remark = foundTargetOP?.remark ? foundTargetOP.remark : null
222
+ if (orderProduct.status.includes(ORDER_PRODUCT_STATUS.NOT_RECEIVED)) partialReceived = true
223
+ orderProduct.updater = user
224
+
225
+ return orderProduct
226
+ })
227
+ await tx.getRepository(OrderProduct).save(foundOPs)
228
+
229
+ // #3 Update status of retail replenishment order (RECEIVED / PARTIALLY_RECEIVED)
230
+ return await tx.getRepository(RetailReplenishmentOrder).save({
231
+ ...foundRRO,
232
+ status: partialReceived ? ORDER_STATUS.PARTIAL_RECEIVED : ORDER_STATUS.RECEIVED,
233
+ updater: user
234
+ })
235
+ }
236
+
237
+ @Directive('@transaction')
238
+ @Mutation(returns => RetailReplenishmentOrder)
239
+ async updateRetailReplenishmentOrder(
240
+ @Arg('name') name: string,
241
+ @Arg('patch', type => RetailReplenishmentOrderPatch) patch: RetailReplenishmentOrderPatch,
242
+ @Ctx() context: ResolverContext
243
+ ): Promise<RetailReplenishmentOrder> {
244
+ const { tx, domain, user } = context.state
245
+
246
+ const bizplace: Bizplace = await getOutletBizplace(patch.warehouseId)
247
+ const repository = tx.getRepository(RetailReplenishmentOrder)
248
+
249
+ delete patch.warehouseId //exclude warehouse Id from patch
250
+
251
+ const retailReplenishmentOrder = await repository.findOne({
252
+ where: { domain: { id: domain.id }, name, bizplace: { id: bizplace.id } },
253
+ relations: ['orderProducts', 'orderProducts.product']
254
+ })
255
+
256
+ if (!retailReplenishmentOrder) throw new Error(`Retail replenishment order is not found.`)
257
+ if (retailReplenishmentOrder && retailReplenishmentOrder.status !== ORDER_STATUS.REJECTED)
258
+ throw new Error(`You are not allowed to update this order with status: ${retailReplenishmentOrder.status}`)
259
+
260
+ return await repository.save({
261
+ ...retailReplenishmentOrder,
262
+ ...patch,
263
+ status: ORDER_STATUS.PENDING_RECEIVE,
264
+ updater: user
265
+ })
266
+ }
267
+
268
+ @Directive('@transaction')
269
+ @Mutation(returns => [RetailReplenishmentOrder])
270
+ async updateMultipleRetailReplenishmentOrder(
271
+ @Arg('patches', type => [RetailReplenishmentOrderPatch]) patches: RetailReplenishmentOrderPatch[],
272
+ @Ctx() context: ResolverContext
273
+ ): Promise<RetailReplenishmentOrder[]> {
274
+ const { tx, domain, user } = context.state
275
+
276
+ let results: RetailReplenishmentOrder[] = []
277
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
278
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
279
+ const retailReplenishmentOrderRepo = tx.getRepository(RetailReplenishmentOrder)
280
+
281
+ if (_createRecords.length > 0) {
282
+ for (let i = 0; i < _createRecords.length; i++) {
283
+ const newRecord = _createRecords[i]
284
+
285
+ const result = await retailReplenishmentOrderRepo.save({
286
+ ...newRecord,
287
+ domain,
288
+ creator: user,
289
+ updater: user
290
+ })
291
+
292
+ results.push({ ...result, cuFlag: '+' })
293
+ }
294
+ }
295
+
296
+ if (_updateRecords.length > 0) {
297
+ for (let i = 0; i < _updateRecords.length; i++) {
298
+ const newRecord = _updateRecords[i]
299
+ const retailReplenishmentOrder = await retailReplenishmentOrderRepo.findOneBy({ id: newRecord.id })
300
+
301
+ const result = await retailReplenishmentOrderRepo.save({
302
+ ...retailReplenishmentOrder,
303
+ ...newRecord,
304
+ updater: user
305
+ })
306
+
307
+ results.push({ ...result, cuFlag: 'M' })
308
+ }
309
+ }
310
+
311
+ return results
312
+ }
313
+
314
+ @Directive('@transaction')
315
+ @Mutation(returns => Boolean)
316
+ async deleteRetailReplenishmentOrder(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<boolean> {
317
+ const { tx, domain } = context.state
318
+ await tx.getRepository(RetailReplenishmentOrder).delete({ domain: { id: domain.id }, name })
319
+ return true
320
+ }
321
+
322
+ @Directive('@transaction')
323
+ @Mutation(returns => Boolean)
324
+ async deleteRetailReplenishmentOrders(
325
+ @Arg('names', type => [String]) names: string[],
326
+ @Ctx() context: ResolverContext
327
+ ): Promise<boolean> {
328
+ const { tx, domain } = context.state
329
+ await tx.getRepository(RetailReplenishmentOrder).delete({
330
+ domain: { id: domain.id },
331
+ name: In(names)
332
+ })
333
+ return true
334
+ }
335
+ }
336
+ export async function addRetailReplenishmentOrderProducts(
337
+ domain: Domain,
338
+ retailReplenishmentOrder: RetailReplenishmentOrder,
339
+ orderProducts: (OrderProduct | NewOrderProduct)[],
340
+ user: User,
341
+ tx?: EntityManager
342
+ ): Promise<void> {
343
+ const productRepo: Repository<Product> = tx?.getRepository(Product) || getRepository(Product)
344
+ const orderProductRepo: Repository<OrderProduct> = tx?.getRepository(OrderProduct) || getRepository(OrderProduct)
345
+
346
+ if (!retailReplenishmentOrder?.bizplace || !retailReplenishmentOrder?.orderProducts?.length) {
347
+ retailReplenishmentOrder = await tx.getRepository(RetailReplenishmentOrder).findOne({
348
+ where: { id: retailReplenishmentOrder.id },
349
+ relations: ['bizplace', 'orderProducts']
350
+ })
351
+ }
352
+
353
+ orderProducts = await Promise.all(
354
+ orderProducts.map(async (op: OrderProduct) => {
355
+ const foundProduct = await productRepo.findOneBy({
356
+ domain: { id: domain.id },
357
+ sku: op.product.sku,
358
+ name: op.product.name
359
+ })
360
+ if (!foundProduct) throw new Error(`Product ${op.product.name} (${op.product.sku}) is not exist.`)
361
+
362
+ return {
363
+ ...op,
364
+ domain,
365
+ bizplace: retailReplenishmentOrder.bizplace,
366
+ name: OrderNoGenerator.orderProduct(),
367
+ product: foundProduct,
368
+ retailReplenishmentOrder,
369
+ //========= need to revise ===========
370
+ packingType: foundProduct.packingType,
371
+ uom: foundProduct.weightUnit,
372
+ uomValue: foundProduct.weight,
373
+ totalUomValue: `${(foundProduct.weight * op.packQty).toFixed(2)} ${foundProduct.weightUnit}`,
374
+ //====================================
375
+ creator: user,
376
+ updater: user
377
+ }
378
+ })
379
+ )
380
+
381
+ await orderProductRepo.save(orderProducts)
382
+ }
@@ -0,0 +1,54 @@
1
+ import { Arg, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { convertListParams, Domain, Filter, getRepository, Pagination, Sorting } from '@things-factory/shell'
5
+
6
+ import { RetailReplenishmentOrderList } from '../'
7
+ import { RetailReplenishmentOrder } from './retail-replenishment-order'
8
+
9
+ @Resolver(RetailReplenishmentOrder)
10
+ export class RetailReplenishmentOrderQuery {
11
+ @Query(returns => RetailReplenishmentOrderList)
12
+ async retailReplenishmentOrders(
13
+ @Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
14
+ @Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
15
+ @Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
16
+ ): Promise<RetailReplenishmentOrderList> {
17
+ const convertedParams = convertListParams({ filters, pagination, sortings })
18
+ const [items, total] = await getRepository(RetailReplenishmentOrder).findAndCount({
19
+ ...convertedParams,
20
+ relations: ['domain', 'orderProducts', 'orderProducts.product', 'creator', 'updater']
21
+ })
22
+ return { items, total }
23
+ }
24
+
25
+ @Query(returns => RetailReplenishmentOrder)
26
+ async retailReplenishmentOrder(
27
+ @Arg('name') name: string,
28
+ @Ctx() context: ResolverContext
29
+ ): Promise<RetailReplenishmentOrder> {
30
+ const { domain } = context.state
31
+
32
+ const repository = getRepository(RetailReplenishmentOrder)
33
+
34
+ return await repository.findOne({
35
+ where: { domain: { id: domain.id }, name },
36
+ relations: ['domain', 'orderProducts', 'orderProducts.product', 'creator', 'updater']
37
+ })
38
+ }
39
+
40
+ @FieldResolver(type => Domain)
41
+ async domain(@Root() retailReplenishmentOrder: RetailReplenishmentOrder): Promise<Domain> {
42
+ return await getRepository(Domain).findOneBy({ id: retailReplenishmentOrder.domainId })
43
+ }
44
+
45
+ @FieldResolver(type => User)
46
+ async creator(@Root() retailReplenishmentOrder: RetailReplenishmentOrder): Promise<User> {
47
+ return await getRepository(User).findOneBy({ id: retailReplenishmentOrder.creatorId })
48
+ }
49
+
50
+ @FieldResolver(type => User)
51
+ async updater(@Root() retailReplenishmentOrder: RetailReplenishmentOrder): Promise<User> {
52
+ return await getRepository(User).findOneBy({ id: retailReplenishmentOrder.updaterId })
53
+ }
54
+ }
@@ -0,0 +1,101 @@
1
+ import { Field, InputType, Int, ObjectType } from 'type-graphql'
2
+
3
+ import { ObjectRef } from '@things-factory/shell'
4
+
5
+ import { NewOrderProduct } from '../order-product/order-product-types'
6
+ import { RetailReplenishmentOrder } from './retail-replenishment-order'
7
+
8
+ @ObjectType()
9
+ export class RetailReplenishmentOrderList {
10
+ @Field(type => [RetailReplenishmentOrder], { nullable: true })
11
+ items: RetailReplenishmentOrder[]
12
+
13
+ @Field(type => Int, { nullable: false })
14
+ total: number
15
+ }
16
+
17
+ @InputType()
18
+ export class NewRetailReplenishmentOrder {
19
+ @Field({ nullable: true })
20
+ name: string
21
+
22
+ @Field({ nullable: true })
23
+ refNo: string
24
+
25
+ @Field({ nullable: true })
26
+ remark: string
27
+
28
+ ownTransport: boolean
29
+ @Field({ nullable: true })
30
+ truckNo: string
31
+
32
+ @Field({ nullable: true })
33
+ status: string
34
+
35
+ @Field(type => [ObjectRef], { nullable: true })
36
+ orderVass: ObjectRef[]
37
+
38
+ @Field(type => [NewOrderProduct], { nullable: true })
39
+ orderProducts: NewOrderProduct[]
40
+
41
+ @Field(type => ObjectRef, { nullable: true })
42
+ deliveryOrder: ObjectRef
43
+
44
+ @Field(type => ObjectRef, { nullable: true })
45
+ transferOrder: ObjectRef
46
+
47
+ @Field({ nullable: true })
48
+ issuedDate: string
49
+
50
+ @Field({ nullable: true })
51
+ description: string
52
+
53
+ @Field({ nullable: true })
54
+ warehouseId: string // outletID
55
+ }
56
+
57
+ @InputType()
58
+ export class RetailReplenishmentOrderPatch {
59
+ @Field({ nullable: true })
60
+ id: string
61
+
62
+ @Field({ nullable: true })
63
+ name: string
64
+
65
+ @Field({ nullable: true })
66
+ warehouseId: string // outletID
67
+
68
+ @Field({ nullable: true })
69
+ description: string
70
+
71
+ @Field({ nullable: true })
72
+ refNo: string
73
+
74
+ @Field({ nullable: true })
75
+ remark: string
76
+
77
+ ownTransport: boolean
78
+ @Field({ nullable: true })
79
+ truckNo: string
80
+
81
+ @Field({ nullable: true })
82
+ status: string
83
+
84
+ @Field(type => ObjectRef, { nullable: true })
85
+ orderVass: [ObjectRef]
86
+
87
+ @Field(type => [NewOrderProduct], { nullable: true })
88
+ orderProducts: [NewOrderProduct]
89
+
90
+ @Field(type => ObjectRef, { nullable: true })
91
+ deliveryOrder: [ObjectRef]
92
+
93
+ @Field(type => ObjectRef, { nullable: true })
94
+ transferOrder: ObjectRef
95
+
96
+ @Field({ nullable: true })
97
+ issuedDate: string
98
+
99
+ @Field({ nullable: true })
100
+ cuFlag: string
101
+ }
@@ -0,0 +1,115 @@
1
+ import { User } from '@things-factory/auth-base'
2
+ import { Bizplace } from '@things-factory/biz-base'
3
+ import { Domain } from '@things-factory/shell'
4
+ import { Field, ID, ObjectType } from 'type-graphql'
5
+ import {
6
+ Column,
7
+ CreateDateColumn,
8
+ Entity,
9
+ Index,
10
+ ManyToOne,
11
+ OneToMany,
12
+ PrimaryGeneratedColumn,
13
+ RelationId,
14
+ UpdateDateColumn
15
+ } from 'typeorm'
16
+ import { DeliveryOrder, OrderProduct, OrderVas } from '../'
17
+
18
+ @Entity()
19
+ @Index(
20
+ 'ix_retail_replenishment_order_0',
21
+ (retailReplenishmentOrder: RetailReplenishmentOrder) => [
22
+ retailReplenishmentOrder.domain,
23
+ retailReplenishmentOrder.name
24
+ ],
25
+ { unique: true }
26
+ )
27
+ @ObjectType()
28
+ export class RetailReplenishmentOrder {
29
+ @PrimaryGeneratedColumn('uuid')
30
+ @Field(type => ID)
31
+ readonly id: string
32
+
33
+ @ManyToOne(type => Domain)
34
+ @Field(type => Domain, { nullable: true })
35
+ domain: Domain
36
+
37
+ @RelationId((retailRepOrder: RetailReplenishmentOrder) => retailRepOrder.domain)
38
+ domainId: string
39
+
40
+ @Column()
41
+ @Field()
42
+ name: string
43
+
44
+ @ManyToOne(type => Bizplace)
45
+ @Field(type => Bizplace, { nullable: true })
46
+ bizplace: Bizplace
47
+
48
+ @RelationId((retailRepOrder: RetailReplenishmentOrder) => retailRepOrder.bizplace)
49
+ bizplaceId: string
50
+
51
+ @Column({ nullable: true })
52
+ @Field({ nullable: true })
53
+ description: string
54
+
55
+ @Column({ nullable: true })
56
+ @Field({ nullable: true })
57
+ refNo: string
58
+
59
+ @Column({ nullable: true })
60
+ @Field({ nullable: true })
61
+ remark: string
62
+
63
+ @Column({ default: false })
64
+ @Field()
65
+ ownTransport: Boolean
66
+
67
+ @Column({ nullable: true })
68
+ @Field({ nullable: true })
69
+ truckNo: string
70
+
71
+ @Column()
72
+ @Field()
73
+ status: string
74
+
75
+ @OneToMany(type => OrderVas, orderVas => orderVas.retailReplenishmentOrder)
76
+ @Field(type => [OrderVas], { nullable: true })
77
+ orderVass: OrderVas[]
78
+
79
+ @OneToMany(type => OrderProduct, orderProduct => orderProduct.retailReplenishmentOrder)
80
+ @Field(type => [OrderProduct], { nullable: true })
81
+ orderProducts: OrderProduct[]
82
+
83
+ @OneToMany(type => DeliveryOrder, deliveryOrder => deliveryOrder.retailReplenishmentOrder)
84
+ @Field(type => [DeliveryOrder], { nullable: true })
85
+ deliveryOrders: DeliveryOrder[]
86
+
87
+ @Column({ type: 'date' })
88
+ @Field()
89
+ issuedDate: Date
90
+
91
+ @CreateDateColumn()
92
+ @Field()
93
+ createdAt: Date
94
+
95
+ @UpdateDateColumn()
96
+ @Field()
97
+ updatedAt: Date
98
+
99
+ @ManyToOne(type => User)
100
+ @Field(type => User, { nullable: true })
101
+ creator: User
102
+
103
+ @RelationId((retailRepOrder: RetailReplenishmentOrder) => retailRepOrder.creator)
104
+ creatorId: string
105
+
106
+ @ManyToOne(type => User)
107
+ @Field(type => User, { nullable: true })
108
+ updater: User
109
+
110
+ @RelationId((retailRepOrder: RetailReplenishmentOrder) => retailRepOrder.updater)
111
+ updaterId: string
112
+
113
+ @Field({ nullable: true })
114
+ cuFlag: string
115
+ }
@@ -0,0 +1,9 @@
1
+ import { ReturnOrder } from './return-order'
2
+ import { ReturnOrderMutation } from './return-order-mutation'
3
+ import { ReturnOrderQuery } from './return-order-query'
4
+
5
+ export const entities = [ReturnOrder]
6
+ export const resolvers = [ReturnOrderQuery, ReturnOrderMutation]
7
+
8
+ export * from './return-order-mutation'
9
+ export * from './return-order-query'