@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,309 @@
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 { NewOrderInventory, NewTransferOrder, OrderInventory, RetailReplenishmentOrder, TransferOrderPatch } from '../'
12
+ import {
13
+ ORDER_INVENTORY_STATUS,
14
+ ORDER_NUMBER_RULE_TYPE,
15
+ ORDER_NUMBER_SETTING_KEY,
16
+ ORDER_STATUS,
17
+ ORDER_TYPES
18
+ } from '../../constants'
19
+ import { OrderNoGenerator } from '../../utils'
20
+ import { TransferOrder } from './transfer-order'
21
+
22
+ @Resolver(TransferOrder)
23
+ export class TransferOrderMutation {
24
+ @Directive('@transaction')
25
+ @Mutation(returns => Boolean)
26
+ async addTransferOrderInventories(
27
+ @Arg('toNo') toNo: string,
28
+ @Arg('orderInventories', type => [NewOrderInventory]) orderInventories: NewOrderInventory[],
29
+ @Ctx() context: ResolverContext
30
+ ): Promise<boolean> {
31
+ const { tx, domain, user } = context.state
32
+
33
+ const transferOrder: TransferOrder = await tx.getRepository(TransferOrder).findOne({
34
+ where: { name: toNo },
35
+ relations: ['bizplace', 'orderInventory']
36
+ })
37
+
38
+ await addTransferOrderInventories(domain, transferOrder, orderInventories, user, tx)
39
+ return true
40
+ }
41
+
42
+ @Directive('@transaction')
43
+ @Mutation(returns => TransferOrder)
44
+ async cancelTransferOrder(
45
+ @Arg('patch', type => TransferOrderPatch) patch: TransferOrderPatch,
46
+ @Ctx() context: ResolverContext
47
+ ): Promise<TransferOrder> {
48
+ const { tx, domain, user } = context.state
49
+
50
+ const bizplace: Bizplace = await getOutletBizplace(patch.warehouseId)
51
+
52
+ const transferOrder: TransferOrder = await tx.getRepository(TransferOrder).findOne({
53
+ where: { domain: { id: domain.id }, bizplace: { id: bizplace.id }, name: patch.name },
54
+ relations: ['bizplace', 'orderInventories']
55
+ })
56
+
57
+ if (!transferOrder) throw new Error(`Transfer order does not exist.`)
58
+ if (!patch.status) throw new Error('Status was not specified.')
59
+ // if (patch.status && (patch.status !== ORDER_STATUS.PENDING_CANCEL || patch.status !== ORDER_STATUS.CANCELLED))
60
+ // throw new Error(`Status provided was invalid.`)
61
+
62
+ let foundOIs: OrderInventory[] = transferOrder.orderInventories
63
+
64
+ // 1. Update status of order inventories based on status (to PENDING_CANCEL or CANCELLED)
65
+ if (foundOIs && foundOIs.length) {
66
+ foundOIs = foundOIs.map((oi: OrderInventory) => {
67
+ ;(oi.status = patch.status), (oi.updater = user)
68
+ return oi
69
+ })
70
+ }
71
+ await tx.getRepository(OrderInventory).save(foundOIs)
72
+
73
+ // 2. Update transfer order status
74
+ return await tx.getRepository(TransferOrder).save({
75
+ ...transferOrder,
76
+ remark: patch.remark, //think another way if warehouse confirm cancellation > no need to overwrite remark
77
+ status: patch.status,
78
+ updater: user
79
+ })
80
+ }
81
+
82
+ @Directive('@transaction')
83
+ @Mutation(returns => TransferOrder)
84
+ async createTransferOrder(
85
+ @Arg('transferOrder', type => NewTransferOrder) transferOrder: NewTransferOrder,
86
+ @Ctx() context: ResolverContext
87
+ ): Promise<TransferOrder> {
88
+ const { tx, domain, user } = context.state
89
+
90
+ let orderInventories: NewOrderInventory[] = transferOrder.orderInventories
91
+ const myBizplace: Bizplace = await getOutletBizplace(transferOrder.warehouseId)
92
+
93
+ // #1 Find the related retail replenishment order
94
+ const retailReplenishmentOrder: RetailReplenishmentOrder = await tx
95
+ .getRepository(RetailReplenishmentOrder)
96
+ .findOne({
97
+ where: { domain: { id: domain.id }, bizplace: { id: myBizplace.id }, refNo: transferOrder.refNo },
98
+ relations: ['domain', 'bizplace']
99
+ })
100
+
101
+ // #2 Create Transfer Order
102
+ const createdTransferOrder: TransferOrder = await tx.getRepository(TransferOrder).save({
103
+ ...(transferOrder as any),
104
+ name: OrderNoGenerator.transferOrder(),
105
+ bizplace: myBizplace,
106
+ retailReplenishmentOrder: retailReplenishmentOrder ? retailReplenishmentOrder.id : null,
107
+ status: ORDER_STATUS.PENDING_RECEIVE,
108
+ domain,
109
+ creator: user,
110
+ updater: user
111
+ })
112
+
113
+ // #3 Create Transfer Order inventories
114
+ await addTransferOrderInventories(
115
+ domain,
116
+ createdTransferOrder,
117
+ orderInventories.map((oi: NewOrderInventory) => {
118
+ return { ...oi, status: ORDER_INVENTORY_STATUS.PENDING_RECEIVE }
119
+ }),
120
+ user,
121
+ tx
122
+ )
123
+
124
+ return createdTransferOrder
125
+ }
126
+
127
+ @Directive('@transaction')
128
+ @Mutation(returns => Boolean)
129
+ async generateTransferOrder(
130
+ @Arg('transferOrder', type => NewTransferOrder) transferOrder: NewTransferOrder,
131
+ @Ctx() context: ResolverContext
132
+ ): Promise<boolean> {
133
+ const { tx, domain, user } = context.state
134
+
135
+ await generateTransferOrder(transferOrder, domain, user, tx)
136
+ return true
137
+ }
138
+
139
+ @Directive('@transaction')
140
+ @Mutation(returns => TransferOrder)
141
+ async completeTransferOrder(
142
+ @Arg('patch', type => TransferOrderPatch) patch: TransferOrderPatch,
143
+ @Ctx() context: ResolverContext
144
+ ): Promise<TransferOrder> {
145
+ const { tx, domain, user } = context.state
146
+
147
+ const myBizplace: Bizplace = await getOutletBizplace(patch.warehouseId)
148
+ let targetOIs: NewOrderInventory[] = patch.orderInventories
149
+ let partialReceived = false
150
+
151
+ // #1 Find Transfer Order
152
+ const foundTO: TransferOrder = await tx.getRepository(TransferOrder).findOne({
153
+ where: { domain: { id: domain.id }, name: patch.name, bizplace: { id: myBizplace.id } },
154
+ relations: ['bizplace', 'orderInventories']
155
+ })
156
+
157
+ if (!foundTO) throw new Error(`Transfer order does not exist.`)
158
+ if (foundTO && foundTO.status && foundTO.status === ORDER_STATUS.RECEIVED)
159
+ throw new Error(`Transfer order is already completed.`)
160
+
161
+ // #2 Find related order inventories
162
+ let foundOIs: OrderInventory[] = await tx.getRepository(OrderInventory).find({
163
+ where: { domain: { id: domain.id }, transferOrder: { id: foundTO.id } }
164
+ })
165
+
166
+ if (!foundOIs) throw new Error(`Order inventories were not found.`)
167
+
168
+ foundOIs = foundOIs.map((oi: OrderInventory) => {
169
+ targetOIs.forEach((toi: NewOrderInventory) => {
170
+ // #2.1 Update the status of order inventories accordingly
171
+ if (oi.name === toi.name && oi.batchId === toi.batchId) {
172
+ //need to add appropriate condition in future
173
+ oi.status = toi.status
174
+ if (toi.remark) oi.remark = toi.remark
175
+ }
176
+ // #2.2 Check the status of order inventories if there is unreceived item
177
+ if (toi.status.includes(ORDER_INVENTORY_STATUS.NOT_RECEIVED)) partialReceived = true
178
+ })
179
+ oi.updater = user
180
+ return oi
181
+ })
182
+ await tx.getRepository(OrderInventory).save(foundOIs)
183
+
184
+ // #3 Update status of stock replenishment order (RECEIVED / PARTIALLY_RECEIVED)
185
+ return await getRepository(TransferOrder).save({
186
+ ...foundTO,
187
+ status: partialReceived ? ORDER_STATUS.PARTIAL_RECEIVED : ORDER_STATUS.RECEIVED,
188
+ updater: user
189
+ })
190
+ }
191
+
192
+ @Directive('@transaction')
193
+ @Mutation(returns => Boolean)
194
+ async deleteTransferOrder(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<boolean> {
195
+ const { tx, domain } = context.state
196
+
197
+ await tx.getRepository(TransferOrder).delete({ domain: { id: domain.id }, name })
198
+ return true
199
+ }
200
+
201
+ @Directive('@transaction')
202
+ @Mutation(returns => Boolean)
203
+ async deleteTransferOrders(
204
+ @Arg('names', type => [String]) names: string[],
205
+ @Ctx() context: ResolverContext
206
+ ): Promise<boolean> {
207
+ const { tx, domain } = context.state
208
+ await tx.getRepository(TransferOrder).delete({
209
+ domain: { id: domain.id },
210
+ name: In(names)
211
+ })
212
+ return true
213
+ }
214
+ }
215
+
216
+ export async function addTransferOrderInventories(
217
+ domain: Domain,
218
+ transferOrder: TransferOrder,
219
+ orderInventories: (OrderInventory | NewOrderInventory)[],
220
+ user: User,
221
+ tx?: EntityManager
222
+ ): Promise<void> {
223
+ const productRepo: Repository<Product> = tx?.getRepository(Product) || getRepository(Product)
224
+ const orderInventoryRepo: Repository<OrderInventory> =
225
+ tx?.getRepository(OrderInventory) || getRepository(OrderInventory)
226
+
227
+ if (!transferOrder?.bizplace || !transferOrder?.orderInventories?.length) {
228
+ transferOrder = await tx.getRepository(TransferOrder).findOne({
229
+ where: { id: transferOrder.id } /* CONFIRMME regarding TYPEORM */,
230
+ relations: ['bizplace', 'orderInventories']
231
+ })
232
+ }
233
+
234
+ orderInventories = await Promise.all(
235
+ orderInventories.map(async (oi: OrderInventory) => {
236
+ const foundProduct: Product = await productRepo.findOneBy({
237
+ domain: { id: domain.id },
238
+ sku: oi.product.sku,
239
+ name: oi.product.name
240
+ })
241
+ return {
242
+ ...oi,
243
+ domain,
244
+ bizplace: transferOrder.bizplace,
245
+ name: OrderNoGenerator.orderInventory(),
246
+ product: foundProduct,
247
+ productName: foundProduct.name,
248
+ releaseWeight: foundProduct.weight * oi.releaseQty,
249
+ packingType: foundProduct.packingType,
250
+ type: ORDER_TYPES.TRANSFER_ORDER,
251
+ transferOrder,
252
+ creator: user,
253
+ updater: user
254
+ }
255
+ })
256
+ )
257
+
258
+ //add lock qty
259
+
260
+ await orderInventoryRepo.save(orderInventories as any)
261
+ }
262
+
263
+ export async function generateTransferOrder(
264
+ transferOrder: NewTransferOrder,
265
+ domain: Domain,
266
+ user: User,
267
+ tx?: EntityManager
268
+ ): Promise<TransferOrder> {
269
+ const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
270
+ let orderInventories: NewOrderInventory[] = transferOrder.orderInventories
271
+ let orderNo: string = ''
272
+
273
+ // find TO number rule setting
274
+ const toNoSetting: Setting = await settingRepo.findOne({
275
+ where: {
276
+ domain: { id: domain.id },
277
+ name: ORDER_NUMBER_SETTING_KEY.TO_NUMBER_RULE
278
+ }
279
+ })
280
+
281
+ if (toNoSetting) {
282
+ orderNo = await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.TO_NUMBER, seed: {} })
283
+ } else {
284
+ orderNo = OrderNoGenerator.transferOrder()
285
+ }
286
+
287
+ // #1 Create Transfer Order
288
+ const createdTransferOrder: TransferOrder = (await tx.getRepository(TransferOrder).save({
289
+ ...transferOrder,
290
+ name: orderNo,
291
+ status: ORDER_STATUS.PENDING_RECEIVE,
292
+ domain: domain,
293
+ creator: user,
294
+ updater: user
295
+ } as any)) as any
296
+
297
+ // #2 Create Transfer Order inventories
298
+ await addTransferOrderInventories(
299
+ domain,
300
+ createdTransferOrder,
301
+ orderInventories.map((oi: NewOrderInventory) => {
302
+ return { ...oi, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
303
+ }),
304
+ user,
305
+ tx
306
+ )
307
+
308
+ return createdTransferOrder
309
+ }
@@ -0,0 +1,66 @@
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 { TransferOrderList } from '../'
7
+ import { TransferOrder } from './transfer-order'
8
+
9
+ @Resolver(TransferOrder)
10
+ export class TransferOrderQuery {
11
+ @Query(returns => TransferOrderList)
12
+ async transferOrders(
13
+ @Ctx() context: ResolverContext,
14
+ @Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
15
+ @Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
16
+ @Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
17
+ ): Promise<TransferOrderList> {
18
+ const convertedParams = convertListParams({ filters, pagination, sortings })
19
+ const [items, total] = await getRepository(TransferOrder).findAndCount({
20
+ ...convertedParams,
21
+ relations: [
22
+ 'domain',
23
+ 'orderInventories',
24
+ 'orderInventories.inventory',
25
+ 'orderInventories.product',
26
+ 'creator',
27
+ 'updater'
28
+ ]
29
+ })
30
+ return { items, total }
31
+ }
32
+
33
+ @Query(returns => TransferOrder)
34
+ async transferOrder(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<TransferOrder> {
35
+ const { domain } = context.state
36
+
37
+ const repository = getRepository(TransferOrder)
38
+
39
+ return await repository.findOne({
40
+ where: { domain: { id: domain.id }, name },
41
+ relations: [
42
+ 'domain',
43
+ 'orderInventories',
44
+ 'orderInventories.inventory',
45
+ 'orderInventories.product',
46
+ 'creator',
47
+ 'updater'
48
+ ]
49
+ })
50
+ }
51
+
52
+ @FieldResolver(type => Domain)
53
+ async domain(@Root() transferOrder: TransferOrder): Promise<Domain> {
54
+ return await getRepository(Domain).findOneBy({ id: transferOrder.domainId })
55
+ }
56
+
57
+ @FieldResolver(type => User)
58
+ async creator(@Root() transferOrder: TransferOrder): Promise<User> {
59
+ return await getRepository(User).findOneBy({ id: transferOrder.creatorId })
60
+ }
61
+
62
+ @FieldResolver(type => User)
63
+ async updater(@Root() transferOrder: TransferOrder): Promise<User> {
64
+ return await getRepository(User).findOneBy({ id: transferOrder.updaterId })
65
+ }
66
+ }
@@ -0,0 +1,97 @@
1
+ import { ObjectRef } from '@things-factory/shell'
2
+ import { Field, InputType, Int, ObjectType } from 'type-graphql'
3
+ import { NewOrderInventory } from '../order-inventory/order-inventory-types'
4
+ import { TransferOrder } from './transfer-order'
5
+
6
+ @ObjectType()
7
+ export class TransferOrderList {
8
+ @Field(type => [TransferOrder], { nullable: true })
9
+ items: TransferOrder[]
10
+
11
+ @Field(type => Int, { nullable: true })
12
+ total: number
13
+ }
14
+
15
+ @InputType()
16
+ export class NewTransferOrder {
17
+ @Field({ nullable: true })
18
+ name: string
19
+
20
+ @Field({ nullable: true })
21
+ description: string
22
+
23
+ @Field({ nullable: true })
24
+ refNo: string
25
+
26
+ @Field({ nullable: true })
27
+ remark: string
28
+
29
+ @Field({ nullable: true })
30
+ ownTransport: Boolean
31
+
32
+ @Field({ nullable: true })
33
+ type: string
34
+
35
+ @Field({ nullable: true })
36
+ status: string
37
+
38
+ @Field(type => [ObjectRef], { nullable: true })
39
+ orderVas: [ObjectRef]
40
+
41
+ @Field(type => [NewOrderInventory], { nullable: true })
42
+ orderInventories: [NewOrderInventory]
43
+
44
+ @Field(type => ObjectRef, { nullable: true })
45
+ deliveryOrder: ObjectRef
46
+
47
+ @Field({ nullable: true })
48
+ issuedDate: string
49
+
50
+ @Field({ nullable: true })
51
+ warehouseId: string // outletID
52
+ }
53
+
54
+ @InputType()
55
+ export class TransferOrderPatch {
56
+ @Field({ nullable: true })
57
+ id: string
58
+
59
+ @Field({ nullable: true })
60
+ name: string
61
+
62
+ @Field({ nullable: true })
63
+ warehouseId: string // outletID
64
+
65
+ @Field({ nullable: true })
66
+ description: string
67
+
68
+ @Field({ nullable: true })
69
+ refNo: string
70
+
71
+ @Field({ nullable: true })
72
+ remark: string
73
+
74
+ @Field({ nullable: true })
75
+ ownTransport: Boolean
76
+
77
+ @Field({ nullable: true })
78
+ type: string
79
+
80
+ @Field({ nullable: true })
81
+ status: string
82
+
83
+ @Field(type => [ObjectRef], { nullable: true })
84
+ orderVas: [ObjectRef]
85
+
86
+ @Field(type => [NewOrderInventory], { nullable: true })
87
+ orderInventories: [NewOrderInventory]
88
+
89
+ @Field(type => [ObjectRef], { nullable: true })
90
+ deliveryOrder: [ObjectRef]
91
+
92
+ @Field({ nullable: true })
93
+ issuedDate: string
94
+
95
+ @Field({ nullable: true })
96
+ cuFlag: string
97
+ }
@@ -0,0 +1,117 @@
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
+ JoinColumn,
11
+ ManyToOne,
12
+ OneToMany,
13
+ OneToOne,
14
+ PrimaryGeneratedColumn,
15
+ RelationId,
16
+ UpdateDateColumn
17
+ } from 'typeorm'
18
+ import { DeliveryOrder, OrderInventory, OrderVas, RetailReplenishmentOrder } from '../'
19
+
20
+ @Entity()
21
+ @Index('ix_transfer_order_0', (transferOrder: TransferOrder) => [transferOrder.domain, transferOrder.name], {
22
+ unique: true
23
+ })
24
+ @ObjectType()
25
+ export class TransferOrder {
26
+ @PrimaryGeneratedColumn('uuid')
27
+ @Field(type => ID)
28
+ readonly id: string
29
+
30
+ @ManyToOne(type => Domain)
31
+ @Field(type => Domain, { nullable: true })
32
+ domain: Domain
33
+
34
+ @RelationId((transferOrder: TransferOrder) => transferOrder.domain)
35
+ domainId: string
36
+
37
+ @ManyToOne(type => Bizplace)
38
+ @Field(type => Bizplace, { nullable: true })
39
+ bizplace: Bizplace
40
+
41
+ @RelationId((transferOrder: TransferOrder) => transferOrder.bizplace)
42
+ bizplaceId: string
43
+
44
+ @Column()
45
+ @Field()
46
+ name: string
47
+
48
+ @Column({ nullable: true })
49
+ @Field({ nullable: true })
50
+ description: string
51
+
52
+ @Column({ nullable: true })
53
+ @Field({ nullable: true })
54
+ refNo: string
55
+
56
+ @Column({ nullable: true })
57
+ @Field({ nullable: true })
58
+ remark: string
59
+
60
+ @Column()
61
+ @Field()
62
+ ownTransport: Boolean
63
+
64
+ @Column()
65
+ @Field()
66
+ type: string
67
+
68
+ @Column()
69
+ @Field()
70
+ status: string
71
+
72
+ @OneToMany(type => OrderVas, orderVas => orderVas.transferOrder)
73
+ @Field(type => [OrderVas], { nullable: true })
74
+ orderVass: OrderVas[]
75
+
76
+ @OneToMany(type => OrderInventory, orderInventory => orderInventory.transferOrder)
77
+ @Field(type => [OrderInventory], { nullable: true })
78
+ orderInventories: OrderInventory[]
79
+
80
+ @OneToMany(type => DeliveryOrder, deliveryOrder => deliveryOrder.transferOrder)
81
+ @Field(type => [DeliveryOrder], { nullable: true })
82
+ deliveryOrders: DeliveryOrder[]
83
+
84
+ @OneToOne(type => RetailReplenishmentOrder)
85
+ @JoinColumn()
86
+ @Field(type => RetailReplenishmentOrder, { nullable: true })
87
+ retailReplenishmentOrder: RetailReplenishmentOrder
88
+
89
+ @RelationId((transferOrder: TransferOrder) => transferOrder.retailReplenishmentOrder)
90
+ retailReplenishmentOrderId: string
91
+
92
+ @Column({ type: 'date' })
93
+ @Field()
94
+ issuedDate: Date
95
+
96
+ @CreateDateColumn()
97
+ @Field()
98
+ createdAt: Date
99
+
100
+ @UpdateDateColumn()
101
+ @Field()
102
+ updatedAt: Date
103
+
104
+ @ManyToOne(type => User)
105
+ @Field(type => User, { nullable: true })
106
+ creator: User
107
+
108
+ @RelationId((transferOrder: TransferOrder) => transferOrder.creator)
109
+ creatorId: string
110
+
111
+ @ManyToOne(type => User)
112
+ @Field(type => User, { nullable: true })
113
+ updater: User
114
+
115
+ @RelationId((transferOrder: TransferOrder) => transferOrder.updater)
116
+ updaterId: string
117
+ }
@@ -0,0 +1,9 @@
1
+ import { Vas } from './vas'
2
+ import { VasMutation } from './vas-mutation'
3
+ import { VasQuery } from './vas-query'
4
+
5
+ export const entities = [Vas]
6
+ export const resolvers = [VasQuery, VasMutation]
7
+
8
+ export * from './vas-mutation'
9
+ export * from './vas-query'
@@ -0,0 +1,106 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+
3
+ import { NewVas, VasPatch } from '../'
4
+ import { Vas } from './vas'
5
+
6
+ @Resolver(Vas)
7
+ export class VasMutation {
8
+ @Directive('@privilege(category: "vas", privilege: "mutation")')
9
+ @Directive('@transaction')
10
+ @Mutation(returns => Vas)
11
+ async createVas(@Arg('vas', type => NewVas) vas: NewVas, @Ctx() context: ResolverContext): Promise<Vas> {
12
+ const { tx, domain, user } = context.state
13
+
14
+ return await tx.getRepository(Vas).save({
15
+ ...vas,
16
+ domain,
17
+ creator: user,
18
+ updater: user
19
+ })
20
+ }
21
+
22
+ @Directive('@privilege(category: "vas", privilege: "mutation")')
23
+ @Directive('@transaction')
24
+ @Mutation(returns => Vas)
25
+ async updateVas(
26
+ @Arg('name') name: string,
27
+ @Arg('patch', type => VasPatch) patch: VasPatch,
28
+ @Ctx() context: ResolverContext
29
+ ): Promise<Vas> {
30
+ const { tx, domain, user } = context.state
31
+
32
+ const vas = await tx.getRepository(Vas).findOneBy({ domain: { id: domain.id }, name })
33
+
34
+ return await tx.getRepository(Vas).save({
35
+ ...vas,
36
+ ...patch,
37
+ updater: user
38
+ })
39
+ }
40
+
41
+ @Directive('@privilege(category: "vas", privilege: "mutation")')
42
+ @Directive('@transaction')
43
+ @Mutation(returns => [Vas])
44
+ async updateMultipleVas(
45
+ @Arg('patches', type => [VasPatch]) patches: VasPatch[],
46
+ @Ctx() context: ResolverContext
47
+ ): Promise<Vas[]> {
48
+ const { tx, domain, user } = context.state
49
+
50
+ let results: Vas[] = []
51
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
52
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
53
+ const vasRepo = tx.getRepository(Vas)
54
+
55
+ if (_createRecords.length > 0) {
56
+ for (let i = 0; i < _createRecords.length; i++) {
57
+ const newRecord = _createRecords[i]
58
+
59
+ const result = await vasRepo.save({
60
+ ...newRecord,
61
+ domain,
62
+ creator: user,
63
+ updater: user
64
+ })
65
+
66
+ results.push({ ...result, cuFlag: '+' })
67
+ }
68
+ }
69
+
70
+ if (_updateRecords.length > 0) {
71
+ for (let i = 0; i < _updateRecords.length; i++) {
72
+ const newRecord = _updateRecords[i]
73
+ const vas = await vasRepo.findOneBy({ id: newRecord.id })
74
+
75
+ const result = await vasRepo.save({
76
+ ...vas,
77
+ ...newRecord,
78
+ updater: user
79
+ })
80
+
81
+ results.push({ ...result, cuFlag: 'M' })
82
+ }
83
+ }
84
+
85
+ return results
86
+ }
87
+
88
+ @Directive('@privilege(category: "vas", privilege: "mutation")')
89
+ @Directive('@transaction')
90
+ @Mutation(returns => Boolean)
91
+ async deleteVas(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
92
+ const { tx } = context.state
93
+
94
+ await tx.getRepository(Vas).delete(id)
95
+ return true
96
+ }
97
+
98
+ @Directive('@privilege(category: "vas", privilege: "mutation")')
99
+ @Directive('@transaction')
100
+ @Mutation(returns => Boolean)
101
+ async deleteVass(@Arg('ids', type => [String]) ids: string[], @Ctx() context: ResolverContext): Promise<boolean> {
102
+ const { tx } = context.state
103
+ await tx.getRepository(Vas).delete(ids)
104
+ return true
105
+ }
106
+ }