@things-factory/worksheet-base 4.1.33 → 4.1.34

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 (51) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +235 -0
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/outbound/picking-worksheet-controller.js +318 -39
  4. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/render-invoices.js +17 -20
  6. package/dist-server/controllers/render-invoices.js.map +1 -1
  7. package/dist-server/controllers/worksheet-controller.js +14 -0
  8. package/dist-server/controllers/worksheet-controller.js.map +1 -1
  9. package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js +16 -2
  10. package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js.map +1 -1
  11. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +0 -17
  12. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
  13. package/dist-server/graphql/resolvers/worksheet/picking/index.js +2 -1
  14. package/dist-server/graphql/resolvers/worksheet/picking/index.js.map +1 -1
  15. package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js +15 -0
  16. package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js.map +1 -0
  17. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +3 -2
  18. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
  19. package/dist-server/graphql/resolvers/worksheet/unloading/index.js +3 -1
  20. package/dist-server/graphql/resolvers/worksheet/unloading/index.js.map +1 -1
  21. package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js +15 -0
  22. package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js.map +1 -0
  23. package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js +15 -0
  24. package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js.map +1 -0
  25. package/dist-server/graphql/resolvers/worksheet/unloading/unload.js.map +1 -1
  26. package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js +3 -1
  27. package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js.map +1 -1
  28. package/dist-server/graphql/types/worksheet/index.js +16 -0
  29. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  30. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +1 -0
  31. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
  32. package/dist-server/graphql/types/worksheet/worksheet-info.js +1 -0
  33. package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
  34. package/package.json +5 -5
  35. package/server/controllers/inbound/unloading-worksheet-controller.ts +277 -1
  36. package/server/controllers/outbound/picking-worksheet-controller.ts +424 -52
  37. package/server/controllers/render-invoices.ts +26 -29
  38. package/server/controllers/worksheet-controller.ts +17 -2
  39. package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +25 -6
  40. package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +0 -18
  41. package/server/graphql/resolvers/worksheet/picking/index.ts +3 -1
  42. package/server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.ts +24 -0
  43. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +6 -2
  44. package/server/graphql/resolvers/worksheet/unloading/index.ts +4 -0
  45. package/server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.ts +26 -0
  46. package/server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.ts +24 -0
  47. package/server/graphql/resolvers/worksheet/unloading/unload.ts +3 -1
  48. package/server/graphql/resolvers/worksheet/unloading-worksheet.ts +3 -1
  49. package/server/graphql/types/worksheet/index.ts +16 -0
  50. package/server/graphql/types/worksheet/worksheet-detail-info.ts +1 -0
  51. package/server/graphql/types/worksheet/worksheet-info.ts +1 -0
@@ -1,4 +1,4 @@
1
- import { In } from 'typeorm'
1
+ import { Equal, In, Not } from 'typeorm'
2
2
 
3
3
  import { Bizplace } from '@things-factory/biz-base'
4
4
  import { generateId } from '@things-factory/id-rule-base'
@@ -14,8 +14,11 @@ import {
14
14
  import { Setting } from '@things-factory/setting-base'
15
15
  import {
16
16
  Inventory,
17
+ INVENTORY_ITEM_SOURCE,
17
18
  INVENTORY_STATUS,
18
19
  INVENTORY_TRANSACTION_TYPE,
20
+ InventoryItem,
21
+ InventoryNoGenerator,
19
22
  Location,
20
23
  LOCATION_TYPE
21
24
  } from '@things-factory/warehouse-base'
@@ -190,7 +193,7 @@ export class PickingWorksheetController extends VasWorksheetController {
190
193
  if (vasWorksheet) {
191
194
  await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
192
195
  }
193
- } catch (e) { }
196
+ } catch (e) {}
194
197
 
195
198
  const pendingSplitOIs: OrderInventory[] = await this.trxMgr.getRepository(OrderInventory).find({
196
199
  where: { domain: this.domain, releaseGood, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
@@ -443,7 +446,7 @@ export class PickingWorksheetController extends VasWorksheetController {
443
446
  detail.product?.id === product.id
444
447
  )
445
448
 
446
- if (!foundProductDetail) {
449
+ if (!foundProductDetail && !product?.isRequireSerialNumberScanningOutbound) {
447
450
  const roProductDetail: ProductDetail = productDetails.find(
448
451
  (parentDetail: ProductDetail) =>
449
452
  parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
@@ -453,26 +456,56 @@ export class PickingWorksheetController extends VasWorksheetController {
453
456
  if (pickedQty > releaseQty) {
454
457
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
455
458
  }
459
+ } else if (!foundProductDetail) {
460
+ throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
456
461
  }
457
462
 
458
- if (product?.isRequireSerialNumberScanning) {
459
- if (!serialNumber || serialNumber == '')
463
+ if (product?.isRequireSerialNumberScanningOutbound) {
464
+ if (!serialNumber || serialNumber == '') {
460
465
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
461
-
462
- if (serialNumber) {
463
- targetInventory.serialNumber = JSON.stringify(
464
- targetInventory.serialNumber ? [...JSON.parse(targetInventory.serialNumber), serialNumber] : [serialNumber]
465
- )
466
466
  }
467
- }
468
467
 
469
- targetInventory.pickedAt = new Date()
470
- targetInventory.pickedByUser = this.user
468
+ let totalInventoryItems = await this.trxMgr.getRepository(InventoryItem).count({
469
+ where: {
470
+ inventory
471
+ }
472
+ })
473
+
474
+ let foundSerialNumber: InventoryItem = await this.trxMgr
475
+ .getRepository(InventoryItem)
476
+ .findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
477
+
478
+ if (foundSerialNumber) {
479
+ if (foundSerialNumber.inventoryId !== inventory.id) {
480
+ throw new Error('Serial Number scanned is in another inventory')
481
+ }
482
+
483
+ if (foundSerialNumber.status !== INVENTORY_STATUS.STORED || foundSerialNumber.outboundOrderId) {
484
+ throw new Error('Inventory Item is not available')
485
+ }
486
+
487
+ foundSerialNumber.status = INVENTORY_STATUS.PICKED
488
+ foundSerialNumber.updater = this.user
489
+ foundSerialNumber.outboundOrderId = releaseGood.id
490
+
491
+ await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
492
+ } else {
493
+ if (totalInventoryItems >= inventory.qty) {
494
+ throw new Error('Insufficient inventory quantity to scan new serial number')
495
+ }
471
496
 
472
- let pickedBy: string[] = targetInventory.pickedBy ? (targetInventory.pickedBy).split(',') : []
473
- if (!pickedBy.find(x => x == this.user.name)) {
474
- pickedBy.push(this.user.name)
475
- targetInventory.pickedBy = pickedBy.join(',')
497
+ let inventoryItem: InventoryItem = new InventoryItem()
498
+ inventoryItem.name = InventoryNoGenerator.inventoryItemName()
499
+ inventoryItem.serialNumber = serialNumber
500
+ inventoryItem.status = INVENTORY_STATUS.PICKED
501
+ inventoryItem.outboundOrderId = releaseGood.id
502
+ inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
503
+ inventoryItem.product = product
504
+ inventoryItem.inventory = inventory
505
+ inventoryItem.domain = this.domain
506
+
507
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
508
+ }
476
509
  }
477
510
 
478
511
  await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
@@ -518,32 +551,103 @@ export class PickingWorksheetController extends VasWorksheetController {
518
551
  //validation to prevent over release
519
552
  if (inventory.qty <= 0) throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
520
553
 
521
- if (inventory.palletId !== palletId)
554
+ if (inventory.palletId !== palletId /*&& !product?.isRequireSerialNumberScanningOutbound*/)
555
+ //to be changed
522
556
  throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
523
557
 
524
- if (product?.isRequireSerialNumberScanning) {
525
- if (!serialNumber || serialNumber == '')
558
+ if (product?.isRequireSerialNumberScanningOutbound) {
559
+ if (!serialNumber || serialNumber == '') {
526
560
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
561
+ }
527
562
 
528
- if (serialNumber) {
529
- targetInventory.serialNumber = JSON.stringify(
530
- targetInventory.serialNumber ? [...JSON.parse(targetInventory.serialNumber), serialNumber] : [serialNumber]
531
- )
563
+ let totalInventoryItems = await this.trxMgr.getRepository(InventoryItem).count({
564
+ where: {
565
+ inventory
566
+ }
567
+ })
568
+
569
+ let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
570
+ where: { domain: this.domain, serialNumber: serialNumber, product },
571
+ relations: ['product', 'inventory']
572
+ })
573
+
574
+ let scannedPalletIdInventory: Inventory = await this.trxMgr
575
+ .getRepository(Inventory)
576
+ .findOne({ where: { domain: this.domain, palletId }, relations: ['product'] })
577
+
578
+ if (foundSerialNumber) {
579
+ if (
580
+ foundSerialNumber.status !== INVENTORY_STATUS.STORED ||
581
+ foundSerialNumber.outboundOrderId ||
582
+ foundSerialNumber.inventory !== inventory
583
+ /*to be changed for replacement && inventory.palletId == palletId*/
584
+ ) {
585
+ throw new Error('Inventory Item is not available')
586
+ }
587
+
588
+ foundSerialNumber.status = INVENTORY_STATUS.PICKED
589
+ foundSerialNumber.updater = this.user
590
+ foundSerialNumber.outboundOrderId = releaseGood.id
591
+
592
+ await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
593
+ } else {
594
+ if (totalInventoryItems >= inventory.qty) {
595
+ throw new Error('Insufficient inventory quantity to scan new serial number')
596
+ }
597
+
598
+ let inventoryItem: InventoryItem = new InventoryItem()
599
+ inventoryItem.name = InventoryNoGenerator.inventoryItemName()
600
+ inventoryItem.serialNumber = serialNumber
601
+ inventoryItem.status = INVENTORY_STATUS.PICKED
602
+ inventoryItem.outboundOrderId = releaseGood.id
603
+ inventoryItem.product = product
604
+ inventoryItem.inventory = scannedPalletIdInventory
605
+ inventoryItem.domain = this.domain
606
+
607
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
532
608
  }
533
- }
534
- targetInventory.pickedAt = new Date()
535
- targetInventory.pickedByUser = this.user;
536
609
 
537
- let pickedBy: string[] = targetInventory.pickedBy ? (targetInventory.pickedBy).split(',') : []
538
- if (!pickedBy.find(x => x == this.user.name)) {
539
- pickedBy.push(this.user.name)
540
- targetInventory.pickedBy = pickedBy.join(',')
541
- }
610
+ if (inventory.palletId !== palletId) {
611
+ let existingOrderInv = await this.trxMgr.getRepository(OrderInventory).findOne({
612
+ where: {
613
+ domain: this.domain,
614
+ inventory: scannedPalletIdInventory,
615
+ releaseGood: releaseGood
616
+ }
617
+ })
542
618
 
543
- targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
619
+ if (existingOrderInv) {
620
+ //if replacement order inventory already existed in worksheet detail
621
+ await this.serialNumberReplacementForExistingOrderInv(
622
+ existingOrderInv,
623
+ targetInventory,
624
+ worksheetDetail,
625
+ foundSerialNumber
626
+ )
627
+ } else if (
628
+ scannedPalletIdInventory.batchId == inventory.batchId &&
629
+ scannedPalletIdInventory.product.id == product.id &&
630
+ scannedPalletIdInventory.product.packingType == product.packingType
631
+ ) {
632
+ //if replacement order inventory does not exist
633
+ await this.serialNumberReplacement(
634
+ targetInventory,
635
+ scannedPalletIdInventory,
636
+ releaseGood,
637
+ product,
638
+ worksheetDetail,
639
+ foundSerialNumber
640
+ )
641
+ } else {
642
+ throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
643
+ }
644
+ }
645
+ }
544
646
 
545
647
  await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
546
648
 
649
+ targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
650
+
547
651
  const fromLocation: Location = targetInventory.inventory.location
548
652
  if (locationName) {
549
653
  const toLocation: Location = await this.trxMgr.getRepository(Location).findOne({
@@ -638,16 +742,6 @@ export class PickingWorksheetController extends VasWorksheetController {
638
742
 
639
743
  targetInventory.pickedQty = targetInventory.releaseQty
640
744
  targetInventory.status = ORDER_INVENTORY_STATUS.PICKED
641
-
642
- targetInventory.pickedAt = new Date()
643
- targetInventory.pickedByUser = this.user;
644
-
645
- let pickedBy: string[] = targetInventory.pickedBy ? (targetInventory.pickedBy).split(',') : []
646
- if (!pickedBy.find(x => x == this.user.name)) {
647
- pickedBy.push(this.user.name)
648
- targetInventory.pickedBy = pickedBy.join(',')
649
- }
650
-
651
745
  await this.updateOrderTargets([targetInventory])
652
746
 
653
747
  inventory.qty -= targetInventory.releaseQty
@@ -802,15 +896,6 @@ export class PickingWorksheetController extends VasWorksheetController {
802
896
  targetInventory.pickedQty += pickedQty > gapQtyRemaining ? gapQtyRemaining : pickedQty
803
897
  remainingAssignedQty = remainingAssignedQty < 0 ? 0 : remainingAssignedQty
804
898
 
805
- targetInventory.pickedAt = new Date()
806
- targetInventory.pickedByUser = this.user;
807
-
808
- let pickedBy: string[] = targetInventory.pickedBy ? (targetInventory.pickedBy).split(',') : []
809
- if (!pickedBy.find(x => x == this.user.name)) {
810
- pickedBy.push(this.user.name)
811
- targetInventory.pickedBy = pickedBy.join(',')
812
- }
813
-
814
899
  if (targetInventory.pickedQty == targetReleaseQty) {
815
900
  const leftQty: number = inventory.qty - targetInventory.releaseQty
816
901
  if (leftQty < 0) {
@@ -865,6 +950,28 @@ export class PickingWorksheetController extends VasWorksheetController {
865
950
  ])
866
951
  await this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
867
952
 
953
+ let InventoryItems: InventoryItem = await this.trxMgr
954
+ .getRepository(InventoryItem)
955
+ .find({ where: { outboundOrderId: releaseGood.id } })
956
+
957
+ if (InventoryItems.length > 0) {
958
+ InventoryItems.forEach((itm: InventoryItem) => {
959
+ itm.status = INVENTORY_STATUS.TERMINATED
960
+ itm.updater = this.user
961
+ })
962
+
963
+ // let inventoryLists = InventoryItems.filter(
964
+ // (value, index, self) => index === self.findIndex(itm => itm.inventory.id === value.inventory.id)
965
+ // )
966
+
967
+ // inventoryLists.forEach((itm: Inventory) => {
968
+ // if (itm.inventory.qty - itm.releaseQty == 0)
969
+ // this.transactionInventory(itm, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
970
+ // })
971
+
972
+ await this.trxMgr.getRepository(InventoryItem).save(InventoryItems)
973
+ }
974
+
868
975
  let orderStatus: string
869
976
  if (releaseGood?.packingOption) {
870
977
  orderStatus = ORDER_STATUS.READY_TO_PACK
@@ -1025,4 +1132,269 @@ export class PickingWorksheetController extends VasWorksheetController {
1025
1132
 
1026
1133
  return orderInventory
1027
1134
  }
1135
+
1136
+ private async serialNumberReplacementForExistingOrderInv(
1137
+ existingOrderInv,
1138
+ targetInventory,
1139
+ worksheetDetail,
1140
+ foundSerialNumber
1141
+ ) {
1142
+ try {
1143
+ //1. update replacement inventory, order inventory, old inventory, old order inventory quantity
1144
+ let newInventory: Inventory = await this.trxMgr
1145
+ .getRepository(Inventory)
1146
+ .findOne({ where: { domain: this.domain, id: existingOrderInv?.inventoryId } })
1147
+
1148
+ let newOrderInventory: OrderInventory = await this.trxMgr
1149
+ .getRepository(OrderInventory)
1150
+ .findOne({ where: { domain: this.domain, id: existingOrderInv?.id } })
1151
+
1152
+ let oldInventory: Inventory = await this.trxMgr
1153
+ .getRepository(Inventory)
1154
+ .findOne({ where: { domain: this.domain, id: targetInventory?.inventory.id } })
1155
+
1156
+ let oldOrderInventory: OrderInventory = await this.trxMgr
1157
+ .getRepository(OrderInventory)
1158
+ .findOne({ where: { domain: this.domain, id: targetInventory?.id } })
1159
+
1160
+ //if replacement inventory quantity insufficient
1161
+ if (newInventory.qty - newInventory.lockedQty < targetInventory.releaseQty - targetInventory.pickedQty) {
1162
+ newOrderInventory.releaseQty += newInventory.qty - newInventory.lockedQty
1163
+ newOrderInventory.releaseUomValue += newInventory.uomValue - newInventory.lockedUomValue
1164
+
1165
+ oldOrderInventory.releaseQty -= newOrderInventory.releaseQty
1166
+ oldOrderInventory.releaseUomValue -= newOrderInventory.releaseUomValue
1167
+
1168
+ oldInventory.lockedQty -= newOrderInventory.releaseQty
1169
+ oldInventory.lockedUomValue -= newOrderInventory.releaseUomValue
1170
+
1171
+ newInventory.lockedQty = newInventory.qty
1172
+ newInventory.lockedUomValue = newInventory.uomValue
1173
+ } else {
1174
+ newOrderInventory.releaseQty += targetInventory.releaseQty - targetInventory.pickedQty
1175
+ newOrderInventory.releaseUomValue +=
1176
+ newOrderInventory.releaseQty * (targetInventory.releaseUomValue / targetInventory.releaseQty)
1177
+
1178
+ oldOrderInventory.releaseQty = targetInventory.pickedQty
1179
+ oldOrderInventory.status = INVENTORY_STATUS.PICKED
1180
+ oldOrderInventory.releaseUomValue =
1181
+ (targetInventory.releaseUomValue / targetInventory.releaseQty) * oldOrderInventory.releaseQty
1182
+
1183
+ oldInventory.lockedQty -= targetInventory.releaseQty - targetInventory.pickedQty
1184
+ oldInventory.lockedUomValue =
1185
+ oldInventory.lockedQty * (targetInventory.releaseUomValue / targetInventory.releaseQty)
1186
+
1187
+ newInventory.lockedQty = newInventory.lockedQty + (targetInventory.releaseQty - targetInventory.pickedQty)
1188
+ newInventory.lockedUomValue =
1189
+ (targetInventory.releaseUomValue / targetInventory.releaseQty) * newInventory.lockedQty
1190
+ }
1191
+
1192
+ newInventory = await this.trxMgr.getRepository(Inventory).save({ ...newInventory, updater: this.user })
1193
+
1194
+ newOrderInventory = await this.trxMgr.getRepository(OrderInventory).save({
1195
+ ...newOrderInventory,
1196
+ status: INVENTORY_STATUS.PICKING,
1197
+ pickedQty: existingOrderInv.pickedQty++,
1198
+ updater: this.user
1199
+ })
1200
+
1201
+ oldInventory = await this.trxMgr.getRepository(Inventory).save({ ...oldInventory, updater: this.user })
1202
+
1203
+ foundSerialNumber = await this.trxMgr
1204
+ .getRepository(InventoryItem)
1205
+ .save({ ...foundSerialNumber, inventory: newInventory })
1206
+
1207
+ //2. update replacement worksheet detail
1208
+ await this.trxMgr.getRepository(WorksheetDetail).update(
1209
+ {
1210
+ targetInventory: existingOrderInv
1211
+ },
1212
+ {
1213
+ status: WORKSHEET_STATUS.EXECUTING,
1214
+ updater: this.user
1215
+ }
1216
+ )
1217
+
1218
+ if (oldOrderInventory.releaseQty !== 0) {
1219
+ oldOrderInventory = await this.trxMgr
1220
+ .getRepository(OrderInventory)
1221
+ .save({ ...oldOrderInventory, updater: this.user })
1222
+
1223
+ await this.trxMgr.getRepository(WorksheetDetail).update(
1224
+ {
1225
+ name: worksheetDetail.name
1226
+ },
1227
+ {
1228
+ status: WORKSHEET_STATUS.DONE,
1229
+ updater: this.user
1230
+ }
1231
+ )
1232
+ } else {
1233
+ await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
1234
+ await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
1235
+ }
1236
+ } catch (e) {}
1237
+ }
1238
+
1239
+ private async serialNumberReplacement(
1240
+ targetInventory,
1241
+ scannedPalletIdInventory,
1242
+ releaseGood,
1243
+ product,
1244
+ worksheetDetail,
1245
+ foundSerialNumber
1246
+ ) {
1247
+ try {
1248
+ //1. create new inventory, new order inventory, update old inventory, old order inventory quantity
1249
+ let newInventory: Inventory = await this.trxMgr
1250
+ .getRepository(Inventory)
1251
+ .findOne({ where: { id: scannedPalletIdInventory?.id } })
1252
+
1253
+ let oldInventory: Inventory = await this.trxMgr
1254
+ .getRepository(Inventory)
1255
+ .findOne({ where: { domain: this.domain, id: targetInventory?.inventory.id } })
1256
+
1257
+ let oldOrderInventory: OrderInventory = await this.trxMgr
1258
+ .getRepository(OrderInventory)
1259
+ .findOne({ where: { domain: this.domain, id: targetInventory?.id } })
1260
+
1261
+ let newOrderInventoryReleaseQty = 0
1262
+ let newOrderInventoryReleaseUomValue = 0
1263
+
1264
+ //if replacement inventory quantity insufficient
1265
+ if (newInventory.qty - newInventory.lockedQty < targetInventory.releaseQty - targetInventory.pickedQty) {
1266
+ newOrderInventoryReleaseQty = newInventory.qty - newInventory.lockedQty
1267
+ newOrderInventoryReleaseUomValue = newInventory.uomValue - newInventory.lockedUomValue
1268
+
1269
+ oldOrderInventory.releaseQty -= newOrderInventoryReleaseQty
1270
+ oldOrderInventory.releaseUomValue -= newOrderInventoryReleaseUomValue
1271
+
1272
+ oldInventory.lockedQty -= newOrderInventoryReleaseQty
1273
+ oldInventory.lockedUomValue -= newOrderInventoryReleaseUomValue
1274
+
1275
+ newInventory.lockedQty = newInventory.qty
1276
+ newInventory.lockedUomValue = newInventory.uomValue
1277
+ } else {
1278
+ newOrderInventoryReleaseQty = targetInventory.releaseQty - targetInventory.pickedQty
1279
+ newOrderInventoryReleaseUomValue =
1280
+ newOrderInventoryReleaseQty * (targetInventory.releaseUomValue / targetInventory.releaseQty)
1281
+
1282
+ oldOrderInventory.releaseQty = targetInventory.pickedQty
1283
+ oldOrderInventory.status = INVENTORY_STATUS.PICKED
1284
+ oldOrderInventory.releaseUomValue =
1285
+ (targetInventory.releaseUomValue / targetInventory.releaseQty) * oldOrderInventory.releaseQty
1286
+
1287
+ oldInventory.lockedQty -= newOrderInventoryReleaseQty
1288
+ oldInventory.lockedUomValue -= newOrderInventoryReleaseUomValue
1289
+
1290
+ newInventory.lockedQty = newInventory.lockedQty + (targetInventory.releaseQty - targetInventory.pickedQty)
1291
+ newInventory.lockedUomValue =
1292
+ (targetInventory.releaseUomValue / targetInventory.releaseQty) * newInventory.lockedQty
1293
+ }
1294
+
1295
+ newInventory = await this.trxMgr.getRepository(Inventory).save({ ...newInventory, updater: this.user })
1296
+
1297
+ let newTargetInventory = (({ id, ...targetInventory }) => targetInventory)(targetInventory)
1298
+
1299
+ let newOrderInventory = await this.trxMgr.getRepository(OrderInventory).save({
1300
+ ...newTargetInventory,
1301
+ domain: this.domain,
1302
+ name: OrderNoGenerator.orderInventory(),
1303
+ releaseGood,
1304
+ releaseQty: newOrderInventoryReleaseQty,
1305
+ releaseUomValue: newOrderInventoryReleaseUomValue,
1306
+ pickedQty: 1,
1307
+ product,
1308
+ inventory: scannedPalletIdInventory,
1309
+ creator: this.user,
1310
+ updater: this.user
1311
+ })
1312
+
1313
+ oldInventory = await this.trxMgr.getRepository(Inventory).save({ ...oldInventory, updater: this.user })
1314
+
1315
+ foundSerialNumber = await this.trxMgr
1316
+ .getRepository(InventoryItem)
1317
+ .save({ ...foundSerialNumber, inventory: newInventory })
1318
+
1319
+ //3. create new worksheet detail
1320
+ let NewWorksheetDetail = (({ id, ...worksheetDetail }) => worksheetDetail)(worksheetDetail)
1321
+ await this.trxMgr.getRepository(WorksheetDetail).save({
1322
+ ...NewWorksheetDetail,
1323
+ domain: this.domain,
1324
+ name: WorksheetNoGenerator.pickingDetail(),
1325
+ targetInventory: newOrderInventory,
1326
+ status: WORKSHEET_STATUS.EXECUTING,
1327
+ creator: this.user,
1328
+ updater: this.user
1329
+ })
1330
+
1331
+ //if old order inventory release quantity is 0 then delete
1332
+ if (oldOrderInventory.releaseQty !== 0) {
1333
+ oldOrderInventory = await this.trxMgr
1334
+ .getRepository(OrderInventory)
1335
+ .save({ ...oldOrderInventory, updater: this.user })
1336
+
1337
+ //4. update old worksheet detail
1338
+ worksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).update(
1339
+ {
1340
+ name: worksheetDetail.name
1341
+ },
1342
+ {
1343
+ status: WORKSHEET_STATUS.DONE,
1344
+ updater: this.user
1345
+ }
1346
+ )
1347
+ } else {
1348
+ await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
1349
+ await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
1350
+ }
1351
+ } catch (e) {}
1352
+ }
1353
+
1354
+ async undoSerialNumberPicking(worksheetDetailName: string, inventoryItemId: string): Promise<void> {
1355
+ const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
1356
+ where: { name: worksheetDetailName, domain: this.domain, status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED)) },
1357
+ relations: [
1358
+ 'worksheet',
1359
+ 'worksheet.releaseGood',
1360
+ 'targetInventory',
1361
+ 'targetInventory.product',
1362
+ 'targetInventory.inventory'
1363
+ ]
1364
+ })
1365
+
1366
+ let targetInventory: OrderInventory = worksheetDetail.targetInventory
1367
+
1368
+ if (targetInventory.releaseQty == targetInventory.pickedQty && targetInventory.status == INVENTORY_STATUS.PICKED) {
1369
+ targetInventory.status = INVENTORY_STATUS.PICKING
1370
+
1371
+ await this.trxMgr
1372
+ .getRepository(WorksheetDetail)
1373
+ .update({ id: worksheetDetail.id }, { status: WORKSHEET_STATUS.EXECUTING })
1374
+
1375
+ targetInventory.inventory.qty += targetInventory.releaseQty
1376
+ targetInventory.inventory.uomValue =
1377
+ Math.round((targetInventory.inventory.uomValue + targetInventory.releaseUomValue) * 100) / 100
1378
+ targetInventory.inventory.lockedQty = targetInventory.inventory.lockedQty + targetInventory.releaseQty
1379
+ targetInventory.inventory.lockedUomValue =
1380
+ Math.round((targetInventory.inventory.lockedUomValue + targetInventory.releaseUomValue) * 100) / 100
1381
+
1382
+ await this.trxMgr.getRepository(Inventory).save(targetInventory.inventory)
1383
+ }
1384
+
1385
+ await this.trxMgr.getRepository(InventoryItem).update(
1386
+ {
1387
+ id: inventoryItemId
1388
+ },
1389
+ {
1390
+ status: INVENTORY_STATUS.STORED,
1391
+ outboundOrderId: null,
1392
+ updater: this.user
1393
+ }
1394
+ )
1395
+
1396
+ targetInventory.pickedQty--
1397
+ targetInventory.updater = this.user
1398
+ await this.updateOrderTargets([targetInventory])
1399
+ }
1028
1400
  }
@@ -1,17 +1,9 @@
1
- import FormData from 'form-data'
2
- import fetch from 'node-fetch'
3
- import {
4
- getRepository,
5
- SelectQueryBuilder
6
- } from 'typeorm'
7
-
8
- import {
9
- Attachment,
10
- STORAGE
11
- } from '@things-factory/attachment-base'
1
+ import { getRepository, SelectQueryBuilder } from 'typeorm'
2
+
3
+ import { Attachment, STORAGE } from '@things-factory/attachment-base'
12
4
  import { Bizplace } from '@things-factory/biz-base'
13
5
  import { config } from '@things-factory/env'
14
- import { ReleaseGood } from '@things-factory/sales-base'
6
+ import { InvoiceProduct, ReleaseGood } from '@things-factory/sales-base'
15
7
  import { Domain } from '@things-factory/shell'
16
8
 
17
9
  import { TEMPLATE_TYPE } from '../constants'
@@ -28,31 +20,24 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
28
20
  let result = await Promise.all(
29
21
  req.roIds.map(async roId => {
30
22
  try {
31
- const qb: SelectQueryBuilder<ReleaseGood> = getRepository(ReleaseGood)
23
+ const qb: SelectQueryBuilder<ReleaseGood> = await getRepository(ReleaseGood)
32
24
  .createQueryBuilder('rg')
33
25
  .innerJoinAndSelect('rg.domain', 'domain')
34
26
  .innerJoinAndSelect('rg.bizplace', 'bizplace')
35
27
  .innerJoinAndSelect('bizplace.domain', 'bizplace_domain')
36
28
  .innerJoinAndSelect('bizplace.company', 'company')
37
29
  .innerJoinAndSelect('company.domain', 'company_domain')
38
- .innerJoinAndSelect('invoices', 'iv', 'rg.id = iv.release_good_id')
39
- .innerJoinAndSelect('iv.invoiceProducts', 'ip')
30
+ .innerJoinAndSelect('invoices', 'iv', 'rg.ref_no = iv.ref_no_1')
40
31
  .leftJoinAndSelect('marketplace_orders', 'mo', 'rg.id = mo.release_order_id::uuid')
41
- .leftJoinAndSelect('mo.marketplaceOrderItems', 'moi')
42
- .leftJoinAndSelect('marketplace_product_variations', 'mpv', 'moi.marketplace_product_variation_id = mpv.id')
43
- .leftJoinAndSelect('products', 'p', 'mpv.sku = p.sku and p.domain_id = company.domain_id')
44
32
  .leftJoinAndSelect('marketplace_order_shippings', 'mos', 'rg.id = mos.release_order_id::uuid')
45
33
  .leftJoinAndSelect('mo.fulfillmentCenter', 'fc')
46
34
  .where('rg.id = :roId')
47
- .andWhere('ip.sku = p.sku')
48
35
  .andWhere('rg.domain = :domainId')
49
36
  .setParameters({ roId, domainId: domain.id })
50
37
 
51
- let items: any[] = await qb.getRawMany()
52
-
53
- if (items.length) {
54
- let record: any = items[0]
38
+ let record: any = await qb.getRawOne()
55
39
 
40
+ if (record) {
56
41
  const partnerBiz: Partial<Bizplace> = {
57
42
  id: record.bizplace_id,
58
43
  name: record.bizplace_name,
@@ -86,6 +71,16 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
86
71
  record.iv_delivery_address_5
87
72
  ]
88
73
 
74
+ const qb: SelectQueryBuilder<InvoiceProduct> = await getRepository(InvoiceProduct)
75
+ .createQueryBuilder('ip')
76
+ .innerJoin('invoices', 'iv', 'iv.id = ip.invoice_id')
77
+ .leftJoin('release_goods', 'rg', 'rg.ref_no = iv.ref_no_1')
78
+ .where('rg.id = :roId')
79
+ .andWhere('rg.domain = :domainId')
80
+ .setParameters({ roId, domainId: domain.id })
81
+
82
+ let items: any[] = await qb.getRawMany()
83
+
89
84
  const product_list = items.map((item, idx) => {
90
85
  return {
91
86
  list_no: idx + 1,
@@ -100,9 +95,9 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
100
95
  (item.ip_paid_price || item.ip_unit_price) * parseInt(item.ip_qty || 0)
101
96
  ),
102
97
  product_total_unit_price: getRoundedValue(item.ip_unit_price * parseInt(item.ip_qty || 0)),
103
- original_price: getRoundedValue(parseFloat(item.moi_original_price || 0)),
104
- product_discount: getRoundedValue(parseFloat(item.moi_discount || 0)),
105
- shipping_fee_paid_by_customer: getRoundedValue(parseFloat(item.moi_shipping_fee_paid_by_customer || 0))
98
+ original_price: getRoundedValue(parseFloat(item.ip_unit_price || 0)),
99
+ product_discount: getRoundedValue(parseFloat(item.ip_discount || 0)),
100
+ shipping_fee_paid_by_customer: getRoundedValue(parseFloat(item.ip_shipping_fee_paid_by_customer || 0))
106
101
  }
107
102
  })
108
103
 
@@ -161,12 +156,14 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
161
156
  .join(' '),
162
157
  fulfillment_center: record.fc_name,
163
158
  voucher_amount: getRoundedValue(parseFloat(record.mo_voucher_amount || 0)),
164
- actual_shipping_fee: getRoundedValue(parseFloat(record.mos_actual_shipping_fee || record.mos_shipping_fee || 0)),
159
+ actual_shipping_fee: getRoundedValue(
160
+ parseFloat(record.mos_actual_shipping_fee || record.mos_shipping_fee || 0)
161
+ ),
165
162
  sub_total: sumProductTotalPaidPrice,
166
163
  grand_total: getRoundedValue(
167
164
  sumProductTotalPaidPrice -
168
- parseFloat(record.mo_voucher_amount || 0) +
169
- parseFloat(record.mos_actual_shipping_fee || 0)
165
+ parseFloat(record.mo_voucher_amount || 0) +
166
+ parseFloat(record.mos_actual_shipping_fee || 0)
170
167
  ),
171
168
  product_list
172
169
  }