@things-factory/sales-base 4.3.448 → 4.3.452

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 (55) hide show
  1. package/dist-server/constants/order.js +3 -1
  2. package/dist-server/constants/order.js.map +1 -1
  3. package/dist-server/service/draft-release-good/draft-release-good-create.js +587 -0
  4. package/dist-server/service/draft-release-good/draft-release-good-create.js.map +1 -0
  5. package/dist-server/service/draft-release-good/draft-release-good-mutation.js +3 -232
  6. package/dist-server/service/draft-release-good/draft-release-good-mutation.js.map +1 -1
  7. package/dist-server/service/draft-release-good/draft-release-good-query.js +59 -28
  8. package/dist-server/service/draft-release-good/draft-release-good-query.js.map +1 -1
  9. package/dist-server/service/draft-release-good/draft-release-good-type.js +33 -1
  10. package/dist-server/service/draft-release-good/draft-release-good-type.js.map +1 -1
  11. package/dist-server/service/draft-release-good/draft-release-good.js +2 -7
  12. package/dist-server/service/draft-release-good/draft-release-good.js.map +1 -1
  13. package/dist-server/service/draft-release-good/index.js +4 -2
  14. package/dist-server/service/draft-release-good/index.js.map +1 -1
  15. package/dist-server/service/order-vas/order-vas-mutation.js +46 -23
  16. package/dist-server/service/order-vas/order-vas-mutation.js.map +1 -1
  17. package/dist-server/service/order-vas/order-vas-query.js +34 -0
  18. package/dist-server/service/order-vas/order-vas-query.js.map +1 -1
  19. package/dist-server/service/order-vas/order-vas-types.js +4 -0
  20. package/dist-server/service/order-vas/order-vas-types.js.map +1 -1
  21. package/dist-server/service/order-vas/order-vas.js +22 -1
  22. package/dist-server/service/order-vas/order-vas.js.map +1 -1
  23. package/dist-server/service/order-vas-item/order-vas-item-type.js +8 -0
  24. package/dist-server/service/order-vas-item/order-vas-item-type.js.map +1 -1
  25. package/dist-server/service/order-vas-item/order-vas-item.js +5 -0
  26. package/dist-server/service/order-vas-item/order-vas-item.js.map +1 -1
  27. package/dist-server/service/release-good/release-good-mutation.js +5 -3
  28. package/dist-server/service/release-good/release-good-mutation.js.map +1 -1
  29. package/dist-server/service/release-good/release-good-query.js +4 -1
  30. package/dist-server/service/release-good/release-good-query.js.map +1 -1
  31. package/dist-server/service/release-good/release-good.js +9 -0
  32. package/dist-server/service/release-good/release-good.js.map +1 -1
  33. package/dist-server/service/vas/vas-mutation.js +5 -1
  34. package/dist-server/service/vas/vas-mutation.js.map +1 -1
  35. package/dist-server/utils/inventory-util.js +5 -3
  36. package/dist-server/utils/inventory-util.js.map +1 -1
  37. package/package.json +15 -15
  38. package/server/constants/order.ts +3 -1
  39. package/server/service/draft-release-good/draft-release-good-create.ts +715 -0
  40. package/server/service/draft-release-good/draft-release-good-mutation.ts +36 -288
  41. package/server/service/draft-release-good/draft-release-good-query.ts +109 -89
  42. package/server/service/draft-release-good/draft-release-good-type.ts +28 -2
  43. package/server/service/draft-release-good/draft-release-good.ts +2 -8
  44. package/server/service/draft-release-good/index.ts +4 -2
  45. package/server/service/order-vas/order-vas-mutation.ts +57 -29
  46. package/server/service/order-vas/order-vas-query.ts +43 -1
  47. package/server/service/order-vas/order-vas-types.ts +5 -8
  48. package/server/service/order-vas/order-vas.ts +19 -10
  49. package/server/service/order-vas-item/order-vas-item-type.ts +6 -0
  50. package/server/service/order-vas-item/order-vas-item.ts +4 -0
  51. package/server/service/release-good/release-good-mutation.ts +8 -2
  52. package/server/service/release-good/release-good-query.ts +7 -2
  53. package/server/service/release-good/release-good.ts +8 -0
  54. package/server/service/vas/vas-mutation.ts +4 -1
  55. package/server/utils/inventory-util.ts +29 -6
@@ -0,0 +1,715 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+ import { EntityManager, getConnection, getRepository, In, Repository } from 'typeorm'
3
+
4
+ import { Bizplace } from '@things-factory/biz-base'
5
+ import { logger } from '@things-factory/env'
6
+ import { ProductBundle } from '@things-factory/product-base'
7
+ import { PartnerSetting, Setting } from '@things-factory/setting-base'
8
+ import { Domain } from '@things-factory/shell'
9
+
10
+ // import { Location } from '@things-factory/warehouse-base'
11
+ import { bulkReleaseGoodsAvailableItemsFunction, DraftReleaseGood, DraftReleaseGoodInfos, OrderProduct } from '../'
12
+ import { DRAFT_RELEASE_ORDER_STATUS, ORDER_NUMBER_SETTING_KEY, ORDER_STATUS } from '../../constants'
13
+ import { ValidationError } from '../../errors'
14
+ import { InventoryUtil, OrderNoGenerator } from '../../utils'
15
+ import { ReleaseGood } from '../release-good/release-good'
16
+ import { SuccessReleasedDraftOrder } from './draft-release-good-type'
17
+ import { bulkGenerateReleaseGood, confirmReleaseGood, receiveReleaseGood } from '../release-good/release-good-mutation'
18
+
19
+ @Resolver(DraftReleaseGood)
20
+ export class DraftReleaseGoodCreate {
21
+ @Directive('@privilege(category: "order_customer", privilege: "mutation")')
22
+ @Directive('@transaction')
23
+ @Mutation(returns => [SuccessReleasedDraftOrder], {
24
+ nullable: true,
25
+ description: 'To generate Release Goods from Draft'
26
+ })
27
+ async generateReleaseGoodsfromDraft(
28
+ @Ctx() context: any,
29
+ @Arg('releaseInfo', type => [DraftReleaseGoodInfos]) releaseInfo: DraftReleaseGoodInfos[]
30
+ ): Promise<SuccessReleasedDraftOrder[] | null> {
31
+ let results = []
32
+
33
+ try {
34
+ const _generatePartialReleaseGoodsRecord = releaseInfo.filter(
35
+ item => item.releaseType === 'partial' && item.id !== ''
36
+ )
37
+ const _generateReleaseGoodsRecord = releaseInfo.filter(item => item.releaseType === 'release' && item.id !== '')
38
+
39
+ if (_generateReleaseGoodsRecord.length > 0) {
40
+ const result = await generateReleaseGoods(_generateReleaseGoodsRecord, context)
41
+ results.push(...result)
42
+ }
43
+
44
+ if (_generatePartialReleaseGoodsRecord.length > 0) {
45
+ const result = await generatePartialReleaseGoods(_generatePartialReleaseGoodsRecord, context)
46
+ results.push(...result)
47
+ }
48
+ return results
49
+ } catch (e) {
50
+ logger.error(e)
51
+ throw new Error('Failed Released Draft Orders')
52
+ }
53
+ }
54
+ }
55
+
56
+ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context: any) {
57
+ const { domain, user, tx } = context.state
58
+ try {
59
+ let ids = [] // Initialize the ids array outside the loop
60
+ ids = _generateReleaseGoodsRecord.map(item => item.id)
61
+ let releasedOrders = []
62
+
63
+ const updatableDraftOrders = await tx.getRepository(DraftReleaseGood).find({
64
+ where: {
65
+ domain,
66
+ id: In(ids),
67
+ status: In([DRAFT_RELEASE_ORDER_STATUS.DRAFT, DRAFT_RELEASE_ORDER_STATUS.PARTIAL_RELEASED])
68
+ },
69
+ order: {
70
+ createdAt: 'ASC'
71
+ },
72
+ relations: [
73
+ 'orderProducts',
74
+ 'orderProducts.product',
75
+ 'orderProducts.productBundle',
76
+ 'orderProducts.productBundle.productBundleSettings',
77
+ 'orderProducts.productBundle.productBundleSettings.product',
78
+ 'orderProducts.productBundle.productBundleSettings.productDetail',
79
+ 'shippingOrder',
80
+ 'bizplace',
81
+ 'bizplace.domain',
82
+ 'domain',
83
+ 'creator',
84
+ 'updater',
85
+ 'lastMileDelivery'
86
+ ]
87
+ })
88
+ let failReleaseOrder = []
89
+
90
+ if (updatableDraftOrders.length > 0) {
91
+ const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
92
+
93
+ const roNoSetting: Setting = await settingRepo.findOne({
94
+ where: {
95
+ domain,
96
+ name: ORDER_NUMBER_SETTING_KEY.RO_NUMBER_RULE
97
+ }
98
+ })
99
+
100
+ for (let index = 0; index < updatableDraftOrders.length; index++) {
101
+ await getConnection().transaction(async (tx: EntityManager) => {
102
+
103
+ const draftOrder = updatableDraftOrders[index]
104
+
105
+ let foundPermittedBizplace: Bizplace
106
+ let companyBizplace: Bizplace
107
+
108
+ if (draftOrder?.bizplace?.id) {
109
+ foundPermittedBizplace = await tx.getRepository(Bizplace).findOne(draftOrder.bizplace.id, {
110
+ relations: ['company', 'company.domain']
111
+ })
112
+ const companyDomain: Domain = foundPermittedBizplace.company.domain
113
+ companyBizplace = await tx.getRepository(Bizplace).findOne({ where: { domain: companyDomain } })
114
+ } else {
115
+ return false
116
+ }
117
+
118
+ const bizplaces: Bizplace[] = [foundPermittedBizplace, companyBizplace]
119
+
120
+ let loggerJson = JSON.stringify({ refNo: draftOrder.refNo, bizplaceId: draftOrder.bizplace.id, domain })
121
+ try {
122
+ console.time(`creating_order:${loggerJson}`)
123
+
124
+ draftOrder.orderProducts = draftOrder.orderProducts.filter(op => op.status == 'DRAFT')
125
+
126
+ let productIds = []
127
+
128
+ for (let item of draftOrder.orderProducts) {
129
+ if (item && item.product) {
130
+ productIds.push(item.product.id)
131
+ }
132
+ if (item && item.productBundle) {
133
+ for (let bundleSetting of item.productBundle.productBundleSettings) {
134
+ productIds.push(bundleSetting.product.id)
135
+ }
136
+ }
137
+ }
138
+
139
+ let productInventory = await InventoryUtil.bizplaceProductInventory(
140
+ bizplaces,
141
+ {
142
+ filters: [
143
+ {
144
+ name: 'productId',
145
+ operator: 'in',
146
+ value: productIds
147
+ }
148
+ ]
149
+ },
150
+ context,
151
+ tx
152
+ )
153
+
154
+ draftOrder.orderProducts = draftOrder.orderProducts.map(itm => {
155
+ let foundProductInv
156
+ if (itm.product) {
157
+ foundProductInv = productInventory.items.find(
158
+ i =>
159
+ (i.productDetailId == itm?.productDetailId || i.productId == itm?.productBundle?.id) &&
160
+ itm.releaseQty <= i.remainQty
161
+ )
162
+ if (!foundProductInv) {
163
+ failReleaseOrder.push(draftOrder.name)
164
+ }
165
+ } else {
166
+ itm.productBundle.productBundleSettings.map(pbs => {
167
+ foundProductInv = productInventory.items.find(
168
+ i =>
169
+ (i.productDetailId == pbs?.productDetail.id || i.productId == pbs?.product?.id) &&
170
+ itm.releaseQty <= i.remainQty
171
+ )
172
+ })
173
+ }
174
+ return {
175
+ ...itm,
176
+ releaseUomValue: (foundProductInv.remainUomValue / foundProductInv.remainQty) * itm.releaseQty,
177
+ status: foundProductInv ? 'suffice' : 'insufficient'
178
+ }
179
+ })
180
+
181
+ let insufficient = draftOrder.orderProducts.find(op => op.status == 'insufficient')
182
+ if (!insufficient) {
183
+ //create RO
184
+ let releaseGood = { ...draftOrder }
185
+ delete releaseGood.id
186
+ delete releaseGood.name
187
+ delete releaseGood.createdAt
188
+ delete releaseGood.createdBy
189
+ delete releaseGood.updatedAt
190
+ delete releaseGood.updatedBy
191
+
192
+ let orderInventories = []
193
+
194
+ for (let index = 0; index < draftOrder.orderProducts.length; index++) {
195
+ const itm: Partial<OrderProduct> = draftOrder.orderProducts[index]
196
+ let data = []
197
+ if (itm.productBundle) {
198
+ let bundle: ProductBundle = await tx.getRepository(ProductBundle).findOne({
199
+ where: { id: itm.productBundle.id },
200
+ relations: [
201
+ 'productBundleSettings',
202
+ 'productBundleSettings.productDetail',
203
+ 'productBundleSettings.product'
204
+ ]
205
+ })
206
+
207
+ for (let index2 = 0; index2 < bundle.productBundleSettings.length; index2++) {
208
+ const objProductBundleSetting = bundle.productBundleSettings[index2]
209
+ data.push({
210
+ sku: objProductBundleSetting.product.sku,
211
+ packingType: objProductBundleSetting.productDetail.packingType,
212
+ packingSize: objProductBundleSetting.productDetail.packingSize,
213
+ uom: objProductBundleSetting.productDetail.uom,
214
+ releaseQty: objProductBundleSetting.bundleQty * itm.releaseQty,
215
+ assignedQty: undefined,
216
+ assignedUomValue: undefined,
217
+ releaseUomValue: objProductBundleSetting.bundleQty * itm.releaseQty * itm.releaseUomValue
218
+ })
219
+ }
220
+ } else {
221
+ data = [
222
+ {
223
+ sku: itm.product.sku,
224
+ packingType: itm.packingType,
225
+ packingSize: itm.packingSize,
226
+ uom: itm.uom,
227
+ releaseQty: itm.releaseQty,
228
+ assignedQty: undefined,
229
+ assignedUomValue: undefined,
230
+ releaseUomValue: itm.releaseUomValue
231
+ }
232
+ ]
233
+ }
234
+
235
+ data.forEach(data => {
236
+ let existingOI = orderInventories.find(
237
+ itm =>
238
+ itm.sku == data.sku &&
239
+ itm.packingType == data.packingType &&
240
+ itm.packingSize == data.packingSize &&
241
+ itm.uom == data.uom
242
+ )
243
+
244
+
245
+ if (existingOI) {
246
+ existingOI.releaseQty = existingOI.releaseQty + data.releaseQty
247
+ existingOI.releaseUomValue = existingOI.releaseUomValue + data.uomValue
248
+ existingOI.uomValue = existingOI.uomValue + data.uomValue
249
+ } else {
250
+ orderInventories.push({ ...data, orderProduct: itm })
251
+ }
252
+ })
253
+ }
254
+
255
+ await getConnection().transaction(async (tx: EntityManager) => {
256
+ let availableItems: any[] = await bulkReleaseGoodsAvailableItemsFunction(
257
+ orderInventories,
258
+ draftOrder.bizplace.id,
259
+ context,
260
+ tx
261
+ )
262
+ if (availableItems.some(item => !item.releaseQty || item.releaseQty > item.assignedQty))
263
+ throw new ValidationError({
264
+ ...ValidationError.ERROR_CODES.INSUFFICIENT_STOCK,
265
+ detail: { data: JSON.stringify(availableItems) }
266
+ })
267
+ // update orderInventories if availableItems are valid
268
+ releaseGood.noOfItems = orderInventories.length
269
+
270
+ releaseGood.orderInventories = availableItems.map(itm => {
271
+ return {
272
+ ...itm,
273
+ releaseQty: itm.releaseQty,
274
+ releaseUomValue: itm.releaseUomValue,
275
+ uomValue: itm.uomValue
276
+ }
277
+ })
278
+ let createdReleaseGood: ReleaseGood = await bulkGenerateReleaseGood(
279
+ releaseGood,
280
+ releaseGood.bizplace.id,
281
+ roNoSetting,
282
+ domain,
283
+ user,
284
+ draftOrder,
285
+ tx
286
+ )
287
+ await tx
288
+ .getRepository(DraftReleaseGood)
289
+ .update({ id: draftOrder.id }, { status: DRAFT_RELEASE_ORDER_STATUS.SUBMITTED })
290
+
291
+ const directReceiveSetting: Setting = await tx.getRepository(Setting).findOne({
292
+ where: { domain, category: 'id-rule', name: 'enable-direct-receive-release-order' }
293
+ })
294
+
295
+ const partnerDirectReceiveSetting: PartnerSetting = await tx.getRepository(PartnerSetting).findOne({
296
+ where: { setting: directReceiveSetting, domain, partnerDomain: draftOrder.bizplace?.domain }
297
+ })
298
+
299
+ let settingValue
300
+
301
+ if (
302
+ !isNaN(partnerDirectReceiveSetting?.value) &&
303
+ !isNaN(parseFloat(partnerDirectReceiveSetting?.value))
304
+ ) {
305
+ settingValue = parseFloat(partnerDirectReceiveSetting.value)
306
+ } else {
307
+ settingValue = parseFloat(directReceiveSetting.value)
308
+ }
309
+
310
+ createdReleaseGood = await confirmReleaseGood(createdReleaseGood.name, context, tx)
311
+
312
+ if (settingValue > 1) {
313
+ createdReleaseGood = await receiveReleaseGood(createdReleaseGood.name, context, tx)
314
+ }
315
+ })
316
+ } else {
317
+ if (draftOrder.orderProducts.every(op => op.id === insufficient?.id)) {
318
+ failReleaseOrder.push(draftOrder?.name)
319
+ }
320
+ }
321
+ } catch (e) {
322
+ logger.error(`draft-release-good-mutation[generateReleaseGoodsFromDraft:${loggerJson}]: ${e?.message}`)
323
+ } finally {
324
+ console.timeEnd(`creating_order:${loggerJson}`)
325
+ }
326
+ })
327
+ }
328
+ }
329
+ releasedOrders = updatableDraftOrders.filter(drg => !drg.name.includes(failReleaseOrder))
330
+ releasedOrders = releasedOrders.map(item => {
331
+ return {
332
+ draftName: item.name
333
+ }
334
+ })
335
+ return releasedOrders
336
+ } catch (e) {
337
+ logger.error(`draft-release-good-mutation[generateReleaseGoodsFromDraft]: ${e?.message}`)
338
+ }
339
+ }
340
+
341
+ export async function generatePartialReleaseGoods(_generatePartialReleaseGoodsRecord, context: any) {
342
+ const { domain, user, tx } = context.state
343
+ try {
344
+ let ids = []
345
+ ids = _generatePartialReleaseGoodsRecord.map(item => item.id)
346
+ const selectedStatus = [
347
+ DRAFT_RELEASE_ORDER_STATUS.PARTIAL_RELEASED,
348
+ DRAFT_RELEASE_ORDER_STATUS.DRAFT,
349
+ DRAFT_RELEASE_ORDER_STATUS.TRANSFER
350
+ ]
351
+
352
+ const value = _generatePartialReleaseGoodsRecord[0]
353
+ const updatableDraftOrders = await tx.getRepository(DraftReleaseGood).find({
354
+ where: {
355
+ domain,
356
+ id: In(ids),
357
+ status: In(selectedStatus)
358
+ },
359
+ order: {
360
+ createdAt: 'ASC',
361
+ status: 'ASC'
362
+ },
363
+ relations: [
364
+ 'orderProducts',
365
+ 'orderProducts.product',
366
+ 'orderProducts.productDetail',
367
+ 'orderProducts.productBundle',
368
+ 'shippingOrder',
369
+ 'bizplace',
370
+ 'bizplace.domain',
371
+ 'domain',
372
+ 'creator',
373
+ 'updater',
374
+ 'lastMileDelivery'
375
+ ]
376
+ })
377
+
378
+ if (updatableDraftOrders.length > 0) {
379
+ // let createdReleaseGoods: ReleaseGood[] = []
380
+ const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
381
+
382
+ const roNoSetting: Setting = await settingRepo.findOne({
383
+ where: {
384
+ domain,
385
+ name: ORDER_NUMBER_SETTING_KEY.RO_NUMBER_RULE
386
+ }
387
+ })
388
+
389
+ for (let draftOrder of updatableDraftOrders) {
390
+ await getConnection().transaction(async (tx: EntityManager) => {
391
+ let foundPermittedBizplace: Bizplace
392
+ let companyBizplace: Bizplace
393
+
394
+ //remove op productBundle as there no support for partial release
395
+
396
+ if (draftOrder.orderProducts.some(itm => !itm.product)) {
397
+ draftOrder.orderProducts = draftOrder.orderProducts.filter(itm => itm.product)
398
+ }
399
+
400
+ if (draftOrder?.bizplace?.id) {
401
+ foundPermittedBizplace = await tx.getRepository(Bizplace).findOne(draftOrder.bizplace.id, {
402
+ relations: ['company', 'company.domain']
403
+ })
404
+ const companyDomain: Domain = foundPermittedBizplace.company.domain
405
+ companyBizplace = await tx.getRepository(Bizplace).findOne({ where: { domain: companyDomain } })
406
+ } else {
407
+ return false
408
+ }
409
+
410
+ const bizplaces: Bizplace[] = [foundPermittedBizplace, companyBizplace]
411
+
412
+ let loggerJson = JSON.stringify({ refNo: draftOrder.refNo, bizplaceId: draftOrder.bizplace.id, domain })
413
+ try {
414
+ console.time(`creating_order:${loggerJson}`)
415
+
416
+ let productInventory = await InventoryUtil.bizplaceProductInventory(
417
+ bizplaces,
418
+ {
419
+ filters: [
420
+ {
421
+ name: 'productId',
422
+ operator: 'in',
423
+ value: [
424
+ ...draftOrder.orderProducts
425
+ .filter(itm => itm?.product)
426
+ .map(itm => {
427
+ return itm.product.id
428
+ }),
429
+ ...draftOrder.orderProducts
430
+ .filter(itm => itm?.productBundle)
431
+ .map(itm => {
432
+ return itm.productBundle.id
433
+ })
434
+ ]
435
+ }
436
+ ]
437
+ },
438
+ context,
439
+ tx
440
+ )
441
+
442
+ draftOrder.orderProducts = draftOrder.orderProducts.filter(op => op.status == 'DRAFT')
443
+
444
+ if (!Array.isArray(draftOrder.orderProducts)) {
445
+ draftOrder.orderProducts = [draftOrder.orderProducts]
446
+ }
447
+
448
+ // if (!foundItem)
449
+ let releaseOrderProducts = []
450
+ draftOrder.orderProducts = draftOrder.orderProducts.map((itm, idx) => {
451
+ let foundProductInv = productInventory.items.find(
452
+ i =>
453
+ (i.productDetailId == itm?.productDetailId || i.productId == itm?.productBundle?.id) &&
454
+ !(i.remainQty === 0)
455
+ )
456
+ if (foundProductInv) {
457
+ releaseOrderProducts.push({
458
+ ...itm,
459
+ releaseUomValue:
460
+ itm.releaseQty > foundProductInv.remainQty
461
+ ? (foundProductInv.remainUomValue / foundProductInv.remainQty) * foundProductInv.remainQty
462
+ : (foundProductInv.remainUomValue / foundProductInv.remainQty) * itm.releaseQty,
463
+ status: itm.releaseQty <= foundProductInv.remainQty ? 'suffice' : 'partial-release',
464
+ releaseQty: itm.releaseQty > foundProductInv.remainQty ? foundProductInv.remainQty : itm.releaseQty, //it will take the remainQty instead of releaseQty when remainQty < releaseQty
465
+ newReleaseQty:
466
+ itm.releaseQty > foundProductInv.remainQty ? itm.releaseQty - foundProductInv.remainQty : 0
467
+ })
468
+ }
469
+ })
470
+
471
+ let sufficient = releaseOrderProducts.filter(op => op.status == 'suffice' || op.status == 'partial-release')
472
+
473
+ //create RO
474
+ if (sufficient.length > 0) {
475
+ let releaseGood = { ...draftOrder }
476
+ delete releaseGood.id
477
+ delete releaseGood.name
478
+ delete releaseGood.createdAt
479
+ delete releaseGood.createdBy
480
+ delete releaseGood.updatedAt
481
+ delete releaseGood.updatedBy
482
+
483
+ let orderInventories = []
484
+
485
+ for (let index = 0; index < releaseOrderProducts.length; index++) {
486
+ const itm: Partial<OrderProduct> = releaseOrderProducts[index]
487
+ let data = []
488
+ if (itm.productBundle) {
489
+ let bundle: ProductBundle = await tx.getRepository(ProductBundle).findOne({
490
+ where: { id: itm.productBundle.id },
491
+ relations: [
492
+ 'productBundleSettings',
493
+ 'productBundleSettings.productDetail',
494
+ 'productBundleSettings.product'
495
+ ]
496
+ })
497
+
498
+ for (let index2 = 0; index2 < bundle.productBundleSettings.length; index2++) {
499
+ const objProductBundleSetting = bundle.productBundleSettings[index2]
500
+ data.push({
501
+ sku: objProductBundleSetting.product.sku,
502
+ packingType: objProductBundleSetting.productDetail.packingType,
503
+ packingSize: objProductBundleSetting.productDetail.packingSize,
504
+ uom: objProductBundleSetting.productDetail.uom,
505
+ releaseQty: objProductBundleSetting.bundleQty * itm.releaseQty,
506
+ assignedQty: undefined,
507
+ assignedUomValue: undefined,
508
+ releaseUomValue: objProductBundleSetting.bundleQty * itm.releaseQty * itm.releaseUomValue
509
+ })
510
+ }
511
+ } else {
512
+ data = [
513
+ {
514
+ sku: itm.product.sku,
515
+ packingType: itm.packingType,
516
+ packingSize: itm.packingSize,
517
+ uom: itm.uom,
518
+ releaseQty: itm.releaseQty,
519
+ assignedQty: undefined,
520
+ assignedUomValue: undefined,
521
+ releaseUomValue: itm.releaseUomValue
522
+ }
523
+ ]
524
+ }
525
+
526
+ data.forEach(data => {
527
+ let existingOI = orderInventories.find(
528
+ itm =>
529
+ itm.sku == data.sku &&
530
+ itm.packingType == data.packingType &&
531
+ itm.packingSize == data.packingSize &&
532
+ itm.uom == data.uom
533
+ )
534
+
535
+ if (existingOI) {
536
+ existingOI.releaseQty = existingOI.releaseQty + data.releaseQty
537
+ existingOI.releaseUomValue = existingOI.releaseUomValue + data.uomValue
538
+ existingOI.uomValue = existingOI.uomValue + data.uomValue
539
+ } else {
540
+ orderInventories.push({ ...data, orderProduct: itm })
541
+ }
542
+ })
543
+ }
544
+ await getConnection().transaction(async (tx: EntityManager) => {
545
+ let availableItems: any[] = await bulkReleaseGoodsAvailableItemsFunction(
546
+ orderInventories,
547
+ draftOrder.bizplace.id,
548
+ context,
549
+ tx
550
+ )
551
+
552
+ // first condition for partial release (values use for generating release good)
553
+ if (draftOrder.id === value.id && value.releaseType === 'partial') {
554
+ releaseGood.orderInventories = availableItems.map(itm => {
555
+ return {
556
+ ...itm,
557
+ releaseQty: itm.assignedQty,
558
+ releaseUomValue: itm.releaseUomValue,
559
+ uomValue: itm.uomValue
560
+ }
561
+ })
562
+ } else if (availableItems.some(item => !item.releaseQty || item.releaseQty > item.assignedQty)) {
563
+ throw new ValidationError({
564
+ ...ValidationError.ERROR_CODES.INSUFFICIENT_STOCK,
565
+ detail: { data: JSON.stringify(availableItems) }
566
+ })
567
+ } else {
568
+ releaseGood.orderInventories = availableItems.map(itm => {
569
+ return {
570
+ ...itm,
571
+ releaseQty: itm.releaseQty,
572
+ releaseUomValue: itm.releaseUomValue,
573
+ uomValue: itm.uomValue
574
+ }
575
+ })
576
+ }
577
+
578
+ // update orderInventories if availableItems are valid
579
+ releaseGood.noOfItems = orderInventories.length
580
+
581
+ let createdReleaseGood: ReleaseGood = await bulkGenerateReleaseGood(
582
+ releaseGood,
583
+ releaseGood.bizplace.id,
584
+ roNoSetting,
585
+ domain,
586
+ user,
587
+ draftOrder,
588
+ tx
589
+ )
590
+
591
+ await tx
592
+ .getRepository(DraftReleaseGood)
593
+ .update({ id: draftOrder.id }, { status: DRAFT_RELEASE_ORDER_STATUS.PARTIAL_RELEASED })
594
+
595
+ const directReceiveSetting: Setting = await tx.getRepository(Setting).findOne({
596
+ where: { domain, category: 'id-rule', name: 'enable-direct-receive-release-order' }
597
+ })
598
+
599
+ const partnerDirectReceiveSetting: PartnerSetting = await tx.getRepository(PartnerSetting).findOne({
600
+ where: { setting: directReceiveSetting, domain, partnerDomain: draftOrder.bizplace?.domain }
601
+ })
602
+
603
+ let settingValue
604
+
605
+ if (
606
+ !isNaN(partnerDirectReceiveSetting?.value) &&
607
+ !isNaN(parseFloat(partnerDirectReceiveSetting?.value))
608
+ ) {
609
+ settingValue = parseFloat(partnerDirectReceiveSetting.value)
610
+ } else {
611
+ settingValue = parseFloat(directReceiveSetting.value)
612
+ }
613
+
614
+ createdReleaseGood = await confirmReleaseGood(createdReleaseGood.name, context, tx)
615
+
616
+ if (settingValue > 1) {
617
+ createdReleaseGood = await receiveReleaseGood(createdReleaseGood.name, context, tx)
618
+
619
+ for (let value = 0; value < releaseOrderProducts.length; value++) {
620
+ if (releaseOrderProducts[value].status == 'partial-release') {
621
+ let newOrderProduct = releaseOrderProducts.map(item => {
622
+ return {
623
+ ...item,
624
+ name: OrderNoGenerator.orderProduct(),
625
+ draftReleaseGood: draftOrder,
626
+ releaseQty: item.newReleaseQty,
627
+ bizplace: draftOrder.bizplace,
628
+ domain: draftOrder.domain,
629
+ creator: user,
630
+ updater: user,
631
+ productDetail: item.productDetail,
632
+ status: ORDER_STATUS.DRAFT
633
+ }
634
+ })
635
+
636
+ delete newOrderProduct[value].id
637
+ delete newOrderProduct[value].releaseUomValue
638
+
639
+ let generatedOrderProduct = await tx.getRepository(OrderProduct).save(newOrderProduct[value])
640
+
641
+ console.log(generatedOrderProduct)
642
+ }
643
+ }
644
+ }
645
+ })
646
+ }
647
+ } catch (e) {
648
+ logger.error(`draft-release-good-mutation[generateReleaseGoodsFromDraft:${loggerJson}]: ${e?.message}`)
649
+ } finally {
650
+ console.timeEnd(`creating_order:${loggerJson}`)
651
+ }
652
+ })
653
+ }
654
+ }
655
+ const checkDraftOrders = await tx.getRepository(DraftReleaseGood).find({
656
+ where: {
657
+ domain,
658
+ id: In(ids),
659
+ status: In([DRAFT_RELEASE_ORDER_STATUS.DRAFT, DRAFT_RELEASE_ORDER_STATUS.PARTIAL_RELEASED])
660
+ },
661
+ relations: ['bizplace', 'domain', 'orderProducts', 'orderProducts.product', 'orderProducts.productBundle']
662
+ })
663
+
664
+ let productBundleOrders = []
665
+ let failReleaseOrder = []
666
+ let releasedOrders = []
667
+
668
+ for (let index = 0; index < checkDraftOrders.length; index++) {
669
+ const allProductsAssignedOrPartialReleased = checkDraftOrders[index].orderProducts.every(itm =>
670
+ ['ASSIGNED', DRAFT_RELEASE_ORDER_STATUS.PARTIAL_RELEASED].includes(itm.status)
671
+ )
672
+ if (allProductsAssignedOrPartialReleased) {
673
+
674
+ let draftOrderId = checkDraftOrders[index].id
675
+ await tx
676
+ .getRepository(DraftReleaseGood)
677
+ .update({ id: draftOrderId }, { status: DRAFT_RELEASE_ORDER_STATUS.SUBMITTED })
678
+ }
679
+
680
+ const commonOrders = checkDraftOrders[index].orderProducts.every(checkOrder => checkOrder.status === 'DRAFT')
681
+ const hasPB = checkDraftOrders[index].orderProducts.some(itm => !itm.product)
682
+
683
+ if (commonOrders) {
684
+ failReleaseOrder.push(checkDraftOrders[index].name)
685
+ }
686
+
687
+ if (hasPB) {
688
+ productBundleOrders.push(checkDraftOrders[index].name)
689
+ }
690
+ }
691
+
692
+ if (failReleaseOrder.length > 0) {
693
+ releasedOrders = checkDraftOrders.filter(order => !failReleaseOrder.includes(order.name))
694
+ releasedOrders = releasedOrders.map(item => {
695
+ return {
696
+ draftName: item.name
697
+ }
698
+ })
699
+ }
700
+
701
+ if (productBundleOrders.length > 0) {
702
+ let productBundleOrder = productBundleOrders.map(item => {
703
+ return {
704
+ draftName: item,
705
+ isProductBundle: true
706
+ }
707
+ })
708
+ releasedOrders.push(...productBundleOrder)
709
+ }
710
+
711
+ return releasedOrders
712
+ } catch (e) {
713
+ logger.error(`draft-release-good-mutation[generateReleaseGoodsFromDraft]: ${e?.message}`)
714
+ }
715
+ }