@things-factory/sales-base 4.3.248 → 4.3.250

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.
@@ -1,28 +1,26 @@
1
1
  import { FileUpload, GraphQLUpload } from 'graphql-upload'
2
2
  import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
3
3
  import { EntityManager, getConnection, getRepository, In, Not, Repository } from 'typeorm'
4
- import { logger } from '@things-factory/env'
5
4
 
6
5
  import { Attachment, createAttachments } from '@things-factory/attachment-base'
7
6
  import { Application, ApplicationType, Partner, Role, User } from '@things-factory/auth-base'
8
7
  import {
9
8
  Bizplace,
9
+ getCompanyBizplace,
10
10
  getDomainUsers,
11
11
  getMyBizplace,
12
12
  getOutletBizplace,
13
- getPermittedBizplaces,
14
- getCompanyBizplace
13
+ getPermittedBizplaces
15
14
  } from '@things-factory/biz-base'
16
15
  import { generateId } from '@things-factory/id-rule-base'
17
16
  import { MarketplaceStore } from '@things-factory/integration-marketplace'
18
17
  import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
19
- import { Powrup } from '@things-factory/integration-powrup'
20
- import { MarketplaceOrder, MarketplaceProductVariation } from '@things-factory/marketplace-base'
18
+ import { MarketplaceOrder } from '@things-factory/marketplace-base'
21
19
  // import { sendNotification } from '@things-factory/notification'
22
20
  import { Product, ProductBundleSetting, ProductDetail } from '@things-factory/product-base'
23
21
  import { PartnerSetting, Setting } from '@things-factory/setting-base'
24
22
  import { Domain } from '@things-factory/shell'
25
- import { Inventory } from '@things-factory/warehouse-base'
23
+ import { Inventory, ProductDetailStock } from '@things-factory/warehouse-base'
26
24
 
27
25
  // import { NewOrderProduct } from '../order-product/order-product-types'
28
26
  import {
@@ -37,13 +35,14 @@ import {
37
35
  ORDER_VAS_STATUS,
38
36
  PRODUCT_GROUP_TYPE
39
37
  } from '../../constants'
40
- import { EcommerceController, SellercraftController, PowrupController } from '../../controllers'
38
+ import { EcommerceController, PowrupController, SellercraftController } from '../../controllers'
41
39
  import { ValidationError } from '../../errors'
42
40
  import { InventoryUtil, OrderNoGenerator } from '../../utils'
43
41
  import { ArrivalNotice } from '../arrival-notice/arrival-notice'
44
42
  import { confirmArrivalNoticeFunction, deleteArrivalNotice } from '../arrival-notice/arrival-notice-mutation'
45
43
  import { OrderInventory } from '../order-inventory/order-inventory'
46
44
  import { OrderProduct } from '../order-product/order-product'
45
+ import { OrderVasItem } from '../order-vas-item/order-vas-item'
47
46
  import { OrderVas } from '../order-vas/order-vas'
48
47
  import { NewReleaseGood, ReleaseGoodPatch, ShippingOrderInfoPatch } from '../release-good/release-good-types'
49
48
  import { ShippingOrder } from '../shipping-order/shipping-order'
@@ -51,7 +50,6 @@ import { ShippingOrderPatch } from '../shipping-order/shipping-order-types'
51
50
  import { Vas } from '../vas/vas'
52
51
  import { ReleaseGood } from './release-good'
53
52
  import { bulkReleaseGoodsAvailableItemsFunction } from './release-good-query'
54
- import { OrderVasItem } from '../order-vas-item/order-vas-item'
55
53
 
56
54
  @Resolver(ReleaseGood)
57
55
  export class ReleaseGoodMutation {
@@ -371,6 +369,8 @@ export async function deleteReleaseGood(tx: EntityManager, name: string, user: U
371
369
  where: { domain, name },
372
370
  relations: [
373
371
  'arrivalNotice',
372
+ 'orderProducts',
373
+ 'orderProducts.productDetail',
374
374
  'orderInventories',
375
375
  'orderInventories.orderProduct',
376
376
  'orderInventories.inventory',
@@ -385,6 +385,7 @@ export async function deleteReleaseGood(tx: EntityManager, name: string, user: U
385
385
  const foundOIs: OrderInventory[] = foundReleaseOrder.orderInventories
386
386
  const foundOVs: OrderVas[] = foundReleaseOrder.orderVass
387
387
  const foundSO: ShippingOrder = foundReleaseOrder.shippingOrder
388
+ const foundOPs: OrderProduct[] = foundReleaseOrder.orderProducts
388
389
 
389
390
  let foundAttachment: Attachment
390
391
  if (foundReleaseOrder?.ownTransport) {
@@ -421,6 +422,28 @@ export async function deleteReleaseGood(tx: EntityManager, name: string, user: U
421
422
  })
422
423
  )
423
424
 
425
+ // Deduct unassigned qty if ro is unassigned
426
+ if (foundReleaseOrder.assignedInventory == false) {
427
+ await Promise.all(
428
+ foundOPs.map(async (op: OrderProduct) => {
429
+ await tx
430
+ .getRepository(ProductDetailStock)
431
+ .createQueryBuilder()
432
+ .update(ProductDetailStock)
433
+ .set({
434
+ unassignedQty: () => `"unassigned_qty" - ${op.releaseQty}`,
435
+ unassignedUomValue: () => `"unassigned_uom_value" - ${op.releaseUomValue}`
436
+ })
437
+ .where({ productDetail: op.productDetail.id })
438
+ .execute()
439
+
440
+ await tx.getRepository(OrderProduct).delete({ id: op.id })
441
+
442
+ return op
443
+ })
444
+ )
445
+ }
446
+
424
447
  // 2. delete order vass
425
448
  const vasIds = foundOVs.map((vas: OrderVas) => vas.id)
426
449
  if (vasIds.length) {
@@ -449,6 +472,7 @@ export async function deleteReleaseGood(tx: EntityManager, name: string, user: U
449
472
  if (foundSO) {
450
473
  await tx.getRepository(ShippingOrder).delete({ domain, id: foundSO.id })
451
474
  }
475
+
452
476
  return true
453
477
  }
454
478
 
@@ -736,6 +760,18 @@ export async function generateReleaseGoodFunction(
736
760
  newReleaseGood.noOfItems = orderInventories.length
737
761
  newReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
738
762
 
763
+ const worksheetPickingAssignment: Setting = await tx.getRepository(Setting).findOne({
764
+ where: { domain, category: 'id-rule', name: 'enable-worksheet-picking-activation-assignment' }
765
+ })
766
+
767
+ newReleaseGood.assignedInventory =
768
+ worksheetPickingAssignment?.value == 'true'
769
+ ? newReleaseGood.orderMethod == ORDER_METHOD.SELECT_BY_PALLET
770
+ ? true
771
+ : false
772
+ : true
773
+ newReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
774
+
739
775
  for (let oi of orderInventories) {
740
776
  let productDetail: any = await tx
741
777
  .getRepository(ProductDetail)
@@ -747,7 +783,6 @@ export async function generateReleaseGoodFunction(
747
783
  domain: warehouseDomain,
748
784
  bizplace: bizplace,
749
785
  status: ORDER_INVENTORY_STATUS.PENDING,
750
- name: OrderNoGenerator.orderInventory(),
751
786
  releaseGood: newReleaseGood,
752
787
  product: productDetail.product,
753
788
  productDetail,
@@ -758,6 +793,7 @@ export async function generateReleaseGoodFunction(
758
793
  let newOrderProduct: OrderProduct = Object.assign(new OrderProduct(), newOrderInv)
759
794
  newOrderProduct = {
760
795
  ...newOrderProduct,
796
+ name: OrderNoGenerator.orderProduct(),
761
797
  packQty: 0,
762
798
  actualPackQty: 0,
763
799
  palletQty: 0,
@@ -774,62 +810,67 @@ export async function generateReleaseGoodFunction(
774
810
 
775
811
  finalOrderInventories.push(newOrderInv)
776
812
  } else {
777
- // Preassign Inventories
778
- const inventoryAssignmentSetting: Setting = await tx.getRepository(Setting).findOne({
779
- where: { domain, name: 'rule-for-inventory-assignment' }
780
- })
813
+ if (worksheetPickingAssignment?.value !== 'true') {
814
+ // Preassign Inventories
815
+ const inventoryAssignmentSetting: Setting = await tx.getRepository(Setting).findOne({
816
+ where: { domain, name: 'rule-for-inventory-assignment' }
817
+ })
781
818
 
782
- let locationSortingRules = []
783
- if (inventoryAssignmentSetting) {
784
- let locationSetting = JSON.parse(inventoryAssignmentSetting.value)
785
- for (const key in locationSetting) {
786
- locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
819
+ let locationSortingRules = []
820
+ if (inventoryAssignmentSetting) {
821
+ let locationSetting = JSON.parse(inventoryAssignmentSetting.value)
822
+ for (const key in locationSetting) {
823
+ locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
824
+ }
787
825
  }
788
- }
789
826
 
790
- let assignedOrderInventories: OrderInventory[] = await InventoryUtil.autoAssignInventoryForRelease(
791
- oi,
792
- productDetail.product,
793
- productDetail,
794
- locationSortingRules,
795
- bizplace,
796
- warehouseDomain,
797
- tx,
798
- oi.batchId
799
- )
827
+ let assignedOrderInventories: OrderInventory[] = await InventoryUtil.autoAssignInventoryForRelease(
828
+ newOrderInv,
829
+ productDetail.product,
830
+ productDetail,
831
+ locationSortingRules,
832
+ bizplace,
833
+ warehouseDomain,
834
+ tx,
835
+ newOrderInv.batchId
836
+ )
800
837
 
801
- assignedOrderInventories = assignedOrderInventories.map(aoi => {
802
- return {
803
- ...aoi,
804
- orderProduct: newOrderProduct
805
- }
806
- })
838
+ assignedOrderInventories = assignedOrderInventories.map(aoi => {
839
+ return {
840
+ ...aoi,
841
+ orderProduct: newOrderProduct
842
+ }
843
+ })
807
844
 
808
- finalOrderInventories.push(...assignedOrderInventories)
845
+ finalOrderInventories.push(...assignedOrderInventories)
846
+ } else {
847
+ finalOrderInventories.push(newOrderInv)
848
+ }
809
849
  }
810
850
  }
811
851
 
812
852
  for (let oi of finalOrderInventories) {
813
- let generatedOI: OrderInventory = Object.assign(new OrderInventory(), oi)
814
- generatedOI = {
815
- ...generatedOI,
816
- domain: warehouseDomain,
817
- bizplace,
818
- status: ORDER_INVENTORY_STATUS.PENDING,
819
- name: OrderNoGenerator.orderInventory(),
820
- releaseGood: newReleaseGood,
821
- creator: user,
822
- updater: user
823
- }
824
-
825
- await tx.getRepository(OrderInventory).save({ ...generatedOI })
826
-
827
853
  // update inventory locked qty and uom value
828
- await tx.getRepository(Inventory).update(oi.inventory.id, {
829
- lockedQty: (oi.inventory?.lockedQty || 0) + generatedOI.releaseQty,
830
- lockedUomValue: (oi.inventory?.lockedUomValue || 0) + generatedOI.releaseUomValue,
831
- updater: user
832
- })
854
+ if (worksheetPickingAssignment?.value !== 'true' || oi.inventory?.id) {
855
+ await tx.getRepository(OrderInventory).save({ ...oi, name: OrderNoGenerator.orderInventory() })
856
+
857
+ await tx.getRepository(Inventory).update(oi.inventory.id, {
858
+ lockedQty: (oi.inventory?.lockedQty || 0) + oi.releaseQty,
859
+ lockedUomValue: (oi.inventory?.lockedUomValue || 0) + oi.releaseUomValue,
860
+ updater: user
861
+ })
862
+ } else {
863
+ await tx
864
+ .getRepository(ProductDetailStock)
865
+ .createQueryBuilder()
866
+ .update(ProductDetailStock)
867
+ .set({
868
+ unassignedQty: () => `"unassigned_qty" + ${oi.releaseQty}`,
869
+ unassignedUomValue: () => `"unassigned_uom_value" + ${oi.releaseUomValue}`
870
+ })
871
+ .where({ productDetail: oi.productDetail.id })
872
+ .execute()
873
+ }
833
874
  }
834
875
 
835
876
  // VAS
@@ -1367,6 +1408,10 @@ export async function bulkGenerateReleaseGood(
1367
1408
  tx?: EntityManager
1368
1409
  ): Promise<ReleaseGood> {
1369
1410
  try {
1411
+ const worksheetPickingAssignment: Setting = await tx.getRepository(Setting).findOne({
1412
+ where: { domain, category: 'id-rule', name: 'enable-worksheet-picking-activation-assignment' }
1413
+ })
1414
+
1370
1415
  let warehouseDomain: Domain = domain
1371
1416
  let { orderInventories, shippingOrder } = releaseGood
1372
1417
 
@@ -1402,7 +1447,8 @@ export async function bulkGenerateReleaseGood(
1402
1447
  orderMethod: ORDER_METHOD.SELECT_BY_PRODUCT,
1403
1448
  status: ORDER_STATUS.PENDING,
1404
1449
  creator: releaseGood?.creator || user,
1405
- updater: releaseGood?.updater || user
1450
+ updater: releaseGood?.updater || user,
1451
+ assignedInventory: worksheetPickingAssignment?.value == 'true' ? false : true
1406
1452
  }
1407
1453
 
1408
1454
  newReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
@@ -1432,43 +1478,47 @@ export async function bulkGenerateReleaseGood(
1432
1478
 
1433
1479
  // pre assign inventory to orderInventories
1434
1480
  for (let oi of orderInventories) {
1435
- const pickingProductSetting: Setting = await tx.getRepository(Setting).findOne({
1436
- where: { domain, name: 'rule-for-picking-product' }
1437
- })
1481
+ if (worksheetPickingAssignment?.value !== 'true') {
1482
+ const pickingProductSetting: Setting = await tx.getRepository(Setting).findOne({
1483
+ where: { domain, name: 'rule-for-picking-product' }
1484
+ })
1438
1485
 
1439
- let locationSortingRules = []
1440
- if (pickingProductSetting) {
1441
- let locationSetting = JSON.parse(pickingProductSetting.value)
1442
- for (const key in locationSetting) {
1443
- locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
1486
+ let locationSortingRules = []
1487
+ if (pickingProductSetting) {
1488
+ let locationSetting = JSON.parse(pickingProductSetting.value)
1489
+ for (const key in locationSetting) {
1490
+ locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
1491
+ }
1444
1492
  }
1445
- }
1446
1493
 
1447
- let productDetail = oi.orderProduct?.productDetail
1448
- let product = oi.orderProduct?.product
1449
- if (!productDetail) {
1450
- productDetail = await tx.getRepository(ProductDetail).findOne(oi.productDetailId, { relations: ['product'] })
1451
- product = productDetail.product
1452
- }
1494
+ let productDetail = oi.orderProduct?.productDetail
1495
+ let product = oi.orderProduct?.product
1496
+ if (!productDetail) {
1497
+ productDetail = await tx.getRepository(ProductDetail).findOne(oi.productDetailId, { relations: ['product'] })
1498
+ product = productDetail.product
1499
+ }
1453
1500
 
1454
- let assignedResult = await InventoryUtil.autoAssignInventoryForRelease(
1455
- oi,
1456
- product,
1457
- productDetail,
1458
- locationSortingRules,
1459
- bizplace,
1460
- warehouseDomain,
1461
- tx
1462
- )
1501
+ let assignedResult = await InventoryUtil.autoAssignInventoryForRelease(
1502
+ oi,
1503
+ product,
1504
+ productDetail,
1505
+ locationSortingRules,
1506
+ bizplace,
1507
+ warehouseDomain,
1508
+ tx
1509
+ )
1463
1510
 
1464
- finalOrderInventories.push(
1465
- ...assignedResult.map(itm => {
1466
- return {
1467
- ...itm,
1468
- orderProduct: oi?.orderProduct
1469
- }
1470
- })
1471
- )
1511
+ finalOrderInventories.push(
1512
+ ...assignedResult.map(itm => {
1513
+ return {
1514
+ ...itm,
1515
+ orderProduct: oi?.orderProduct
1516
+ }
1517
+ })
1518
+ )
1519
+ } else {
1520
+ finalOrderInventories.push(oi)
1521
+ }
1472
1522
  }
1473
1523
 
1474
1524
  for (let oi of finalOrderInventories) {
@@ -1517,14 +1567,27 @@ export async function bulkGenerateReleaseGood(
1517
1567
  })
1518
1568
  }
1519
1569
 
1520
- await tx.getRepository(OrderInventory).save({ ...generatedOI, orderProduct: newOrderProduct })
1521
-
1522
1570
  // update inventory locked qty and uom value
1523
- await tx.getRepository(Inventory).update(oi.inventory.id, {
1524
- lockedQty: (oi.inventory?.lockedQty || 0) + generatedOI.releaseQty,
1525
- lockedUomValue: (oi.inventory?.lockedUomValue || 0) + generatedOI.releaseUomValue,
1526
- updater: user
1527
- })
1571
+ if (worksheetPickingAssignment?.value !== 'true') {
1572
+ await tx.getRepository(OrderInventory).save({ ...generatedOI, orderProduct: newOrderProduct })
1573
+
1574
+ await tx.getRepository(Inventory).update(oi.inventory.id, {
1575
+ lockedQty: (oi.inventory?.lockedQty || 0) + generatedOI.releaseQty,
1576
+ lockedUomValue: (oi.inventory?.lockedUomValue || 0) + generatedOI.releaseUomValue,
1577
+ updater: user
1578
+ })
1579
+ } else {
1580
+ await tx
1581
+ .getRepository(ProductDetailStock)
1582
+ .createQueryBuilder()
1583
+ .update(ProductDetailStock)
1584
+ .set({
1585
+ unassignedQty: () => `"unassigned_qty" + ${generatedOI.releaseQty}`,
1586
+ unassignedUomValue: () => `"unassigned_uom_value" + ${generatedOI.releaseUomValue}`
1587
+ })
1588
+ .where({ productDetail: oi.productDetail ? oi.productDetail.id : oi.productDetailId })
1589
+ .execute()
1590
+ }
1528
1591
  }
1529
1592
 
1530
1593
  return newReleaseGood
@@ -516,6 +516,10 @@ export class ReleaseGood {
516
516
  @Field({ nullable: true })
517
517
  lastMarketPackCall: Date
518
518
 
519
+ @Column({ nullable: true, default: true })
520
+ @Field({ nullable: true })
521
+ assignedInventory: Boolean
522
+
519
523
  @ManyToOne(type => User)
520
524
  @Field(type => User, { nullable: true })
521
525
  manifestedBy: User
@@ -1,29 +1,10 @@
1
- import {
2
- EntityManager,
3
- Equal,
4
- getRepository,
5
- In,
6
- Not,
7
- Raw,
8
- Repository,
9
- SelectQueryBuilder
10
- } from 'typeorm'
1
+ import { EntityManager, Equal, getRepository, In, Not, Raw, Repository, SelectQueryBuilder } from 'typeorm'
11
2
 
12
3
  import { User } from '@things-factory/auth-base'
13
4
  import { Bizplace } from '@things-factory/biz-base'
14
- import {
15
- Product,
16
- ProductBundle,
17
- ProductDetail
18
- } from '@things-factory/product-base'
19
- import {
20
- PartnerSetting,
21
- Setting
22
- } from '@things-factory/setting-base'
23
- import {
24
- Domain,
25
- ListParam
26
- } from '@things-factory/shell'
5
+ import { Product, ProductBundle, ProductDetail } from '@things-factory/product-base'
6
+ import { PartnerSetting, Setting } from '@things-factory/setting-base'
7
+ import { Domain, ListParam } from '@things-factory/shell'
27
8
  import {
28
9
  generateInventoryHistory,
29
10
  Inventory,
@@ -122,14 +103,15 @@ export const InventoryUtil = {
122
103
  coalesce(p.brand, '') AS "productBrand",
123
104
  p.id AS "productId",
124
105
  pd.id AS "productDetailId",
125
- COALESCE(SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0)) - MAX(COALESCE(bp.bundle_product_release_qty, 0)),0) AS "remainQty",
126
- COALESCE(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)),0) AS "remainUomValue",
127
- concat(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)), ' ', pd.uom) AS "remainUomValueWithUom",
106
+ COALESCE(SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - SUM(COALESCE(pds.unassigned_qty, 0)) - MAX(COALESCE(oi.release_qty, 0)) - MAX(COALESCE(bp.bundle_product_release_qty, 0)),0) AS "remainQty",
107
+ COALESCE(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - SUM(COALESCE(pds.unassigned_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)),0) AS "remainUomValue",
108
+ concat(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - SUM(COALESCE(pds.unassigned_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)), ' ', pd.uom) AS "remainUomValueWithUom",
128
109
  COALESCE(SUM(COALESCE(i.transfer_qty, 0)), 0) AS "transferQty",
129
110
  COALESCE(SUM(COALESCE(i.transfer_uom_value, 0)), 0) AS "transferUomValue",
130
111
  'SINGLE' AS "groupType"
131
112
  FROM products p
132
113
  INNER join product_details pd on pd.product_id = p.id
114
+ LEFT JOIN product_detail_stocks pds on pds.product_detail_id = pd.id
133
115
  LEFT JOIN (
134
116
  SELECT i.* FROM inventories i
135
117
  INNER JOIN locations l2 ON i.location_id = l2.id AND i.domain_id = l2.domain_id
@@ -175,13 +157,14 @@ export const InventoryUtil = {
175
157
  FROM product_bundles pb
176
158
  LEFT JOIN (
177
159
  SELECT pbs.product_id, pbs.product_bundle_id, min(pbs.bundle_qty),
178
- (SUM(COALESCE(i2.qty, 0)) - SUM(COALESCE(i2.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) / min(pbs.bundle_qty) AS "availableQty",
179
- (SUM(COALESCE(i2.uom_value, 0)) - SUM(COALESCE(i2.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0))) / min(pbs.bundle_qty) AS "availableUomValue",
160
+ (SUM(COALESCE(i2.qty, 0)) - SUM(COALESCE(i2.locked_qty, 0)) - SUM(COALESCE(pds2.unassigned_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) / min(pbs.bundle_qty) AS "availableQty",
161
+ (SUM(COALESCE(i2.uom_value, 0)) - SUM(COALESCE(i2.locked_uom_value, 0)) - SUM(COALESCE(pds2.unassigned_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0))) / min(pbs.bundle_qty) AS "availableUomValue",
180
162
  (SUM(COALESCE(i2.transfer_qty, 0)) / min(pbs.bundle_qty)) AS "transferQty",
181
163
  (SUM(COALESCE(i2.transfer_uom_value, 0)) / min(pbs.bundle_qty)) AS "transferUomValue",
182
164
  pbs.product_detail_id
183
165
  FROM product_bundle_settings pbs
184
166
  LEFT JOIN inventories i2 ON i2.product_id = pbs.product_id AND i2.domain_id = $1 AND i2.status = 'STORED'
167
+ LEFT JOIN product_detail_stocks pds2 ON pds2.product_detail_id = pbs.product_detail_id
185
168
  INNER JOIN locations l2 ON i2.location_id = l2.id
186
169
  LEFT JOIN oi ON oi.product_id = i2.product_id
187
170
  WHERE l2.type NOT IN ('${LOCATION_TYPE.QUARANTINE}', '${LOCATION_TYPE.RESERVE}')
@@ -305,13 +288,14 @@ export const InventoryUtil = {
305
288
  coalesce(p.brand, '') AS "productBrand",
306
289
  p.id AS "productId",
307
290
  i.product_detail_id AS "productDetailId",
308
- SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0)) - MAX(COALESCE(bp.bundle_product_release_qty, 0)) AS "remainQty",
309
- SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)) AS "remainUomValue",
310
- concat(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)), ' ', i.uom) AS "remainUomValueWithUom",
291
+ SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0)) - MAX(COALESCE(bp.bundle_product_release_qty, 0)) - SUM(COALESCE(pds.unassigned_qty, 0)) AS "remainQty",
292
+ SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)) - SUM(COALESCE(pds.unassigned_uom_value)) AS "remainUomValue",
293
+ concat(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)) - SUM(COALESCE(pds.unassigned_uom_value)), ' ', i.uom) AS "remainUomValueWithUom",
311
294
  'SINGLE' AS "groupType"
312
295
  FROM
313
296
  inventories i
314
297
  LEFT JOIN products p ON i.product_id = p.id
298
+ LEFT JOIN product_detail_stocks pds ON pds.product_detail_id = i.product_detail_id
315
299
  LEFT JOIN oi ON i.batch_id = oi.batch_id AND p.name = oi.product_name AND i.packing_type = oi.packing_type AND i.packing_size = oi.packing_size AND i.uom = oi.uom
316
300
  LEFT JOIN locations l2 ON i.location_id = l2.id AND i.domain_id = l2.domain_id
317
301
  LEFT JOIN (
@@ -535,7 +519,7 @@ export const InventoryUtil = {
535
519
  validOrderInventories.map(x => {
536
520
  return {
537
521
  product_detail_id: x.productDetail.id,
538
- batch_id: x.batchId.replace(`'`,`''`),
522
+ batch_id: x.batchId.replace(`'`, `''`),
539
523
  release_qty: x.releaseQty,
540
524
  uom: x.uom
541
525
  }
@@ -652,11 +636,10 @@ export const InventoryUtil = {
652
636
  })
653
637
 
654
638
  if (partnerStrictProductSelectionSetting) strictProduct = partnerStrictProductSelectionSetting.value
655
-
656
-
639
+
657
640
  let locationTypes = [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE]
658
641
 
659
- if(recall === false){
642
+ if (recall === false) {
660
643
  locationTypes.push(LOCATION_TYPE.DAMAGE)
661
644
  }
662
645
 
@@ -812,7 +795,7 @@ async function getConditions(
812
795
  WHERE pb.status = 'ACTIVATED'
813
796
  `
814
797
 
815
- let whereClause = hasRemainingQty ? ` WHERE "remainQty" > 0` : ` WHERE 1 = 1`
798
+ let whereClause = hasRemainingQty ? ` WHERE "remainQty" > 0 ` : ` WHERE 1 = 1 `
816
799
 
817
800
  let productDetailWhereClause = ``
818
801
 
@@ -845,7 +828,7 @@ async function getConditions(
845
828
 
846
829
  case 'batchId':
847
830
  let batchId = `${value}`
848
- whereClause += `AND LOWER("batchId") LIKE '${batchId.replace(`'`,`''`).toLowerCase()}'`
831
+ whereClause += `AND LOWER("batchId") LIKE '${batchId.replace(`'`, `''`).toLowerCase()}'`
849
832
  break
850
833
 
851
834
  case 'batchIdRef':
@@ -949,7 +932,7 @@ async function getConditions(
949
932
  AND (i.batch_id, p.id, i.packing_type, i.packing_size) ${operator === 'in' ? 'IN' : 'NOT IN'} (${value
950
933
  .map(
951
934
  (v: { batchId: string; productId: string; packingType: string; packingSize: string }) =>
952
- `('${v.batchId.replace(`'`,`''`)}', '${v.productId}', '${v.packingType}', '${v.packingSize}')`
935
+ `('${v.batchId.replace(`'`, `''`)}', '${v.productId}', '${v.packingType}', '${v.packingSize}')`
953
936
  )
954
937
  .join()})
955
938
  `
@@ -1117,6 +1100,7 @@ export function _composeTargetInventories(
1117
1100
  }
1118
1101
 
1119
1102
  orderInventories.push({
1103
+ ...record,
1120
1104
  ...orderInventory,
1121
1105
  inventory,
1122
1106
  packingType,