@things-factory/sales-base 4.3.102 → 4.3.105-alpha.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 (70) hide show
  1. package/dist-server/service/arrival-notice/arrival-notice-mutation.js +6 -5
  2. package/dist-server/service/arrival-notice/arrival-notice-mutation.js.map +1 -1
  3. package/dist-server/service/arrival-notice/arrival-notice-query.js +1 -0
  4. package/dist-server/service/arrival-notice/arrival-notice-query.js.map +1 -1
  5. package/dist-server/service/draft-release-good/draft-release-good-mutation.js +3 -4
  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 +11 -15
  8. package/dist-server/service/draft-release-good/draft-release-good-query.js.map +1 -1
  9. package/dist-server/service/invoice-product/invoice-product.js +8 -3
  10. package/dist-server/service/invoice-product/invoice-product.js.map +1 -1
  11. package/dist-server/service/order-inventory/order-inventory-query.js +2 -1
  12. package/dist-server/service/order-inventory/order-inventory-query.js.map +1 -1
  13. package/dist-server/service/order-inventory/order-inventory-types.js +18 -10
  14. package/dist-server/service/order-inventory/order-inventory-types.js.map +1 -1
  15. package/dist-server/service/order-inventory/order-inventory.js +12 -3
  16. package/dist-server/service/order-inventory/order-inventory.js.map +1 -1
  17. package/dist-server/service/order-product/order-product-query.js +1 -0
  18. package/dist-server/service/order-product/order-product-query.js.map +1 -1
  19. package/dist-server/service/order-product/order-product-types.js +18 -10
  20. package/dist-server/service/order-product/order-product-types.js.map +1 -1
  21. package/dist-server/service/order-vas/order-vas.js +8 -3
  22. package/dist-server/service/order-vas/order-vas.js.map +1 -1
  23. package/dist-server/service/others/other-query.js +188 -176
  24. package/dist-server/service/others/other-query.js.map +1 -1
  25. package/dist-server/service/others/other-types.js +9 -1
  26. package/dist-server/service/others/other-types.js.map +1 -1
  27. package/dist-server/service/purchase-order/purchase-order-mutation.js +10 -2
  28. package/dist-server/service/purchase-order/purchase-order-mutation.js.map +1 -1
  29. package/dist-server/service/purchase-order/purchase-order-query.js +1 -0
  30. package/dist-server/service/purchase-order/purchase-order-query.js.map +1 -1
  31. package/dist-server/service/release-good/release-good-mutation.js +18 -8
  32. package/dist-server/service/release-good/release-good-mutation.js.map +1 -1
  33. package/dist-server/service/release-good/release-good-query.js +4 -6
  34. package/dist-server/service/release-good/release-good-query.js.map +1 -1
  35. package/dist-server/service/release-good/release-good-types.js +8 -4
  36. package/dist-server/service/release-good/release-good-types.js.map +1 -1
  37. package/dist-server/service/return-order/return-order-mutation.js +2 -0
  38. package/dist-server/service/return-order/return-order-mutation.js.map +1 -1
  39. package/dist-server/service/return-order/return-order-types.js.map +1 -1
  40. package/dist-server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory.js +8 -3
  41. package/dist-server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory.js.map +1 -1
  42. package/dist-server/utils/inventory-util.js +33 -102
  43. package/dist-server/utils/inventory-util.js.map +1 -1
  44. package/package.json +13 -13
  45. package/server/service/arrival-notice/arrival-notice-mutation.ts +6 -3
  46. package/server/service/arrival-notice/arrival-notice-query.ts +1 -0
  47. package/server/service/draft-release-good/draft-release-good-mutation.ts +3 -4
  48. package/server/service/draft-release-good/draft-release-good-query.ts +17 -21
  49. package/server/service/invoice-product/invoice-product.ts +5 -1
  50. package/server/service/order-inventory/order-inventory-query.ts +2 -0
  51. package/server/service/order-inventory/order-inventory-types.ts +6 -0
  52. package/server/service/order-inventory/order-inventory.ts +8 -1
  53. package/server/service/order-product/order-product-query.ts +1 -0
  54. package/server/service/order-product/order-product-types.ts +6 -0
  55. package/server/service/order-vas/order-vas.ts +6 -1
  56. package/server/service/others/other-query.ts +224 -218
  57. package/server/service/others/other-types.ts +7 -1
  58. package/server/service/purchase-order/purchase-order-mutation.ts +10 -1
  59. package/server/service/purchase-order/purchase-order-query.ts +1 -0
  60. package/server/service/release-good/release-good-mutation.ts +21 -8
  61. package/server/service/release-good/release-good-query.ts +4 -7
  62. package/server/service/release-good/release-good-types.ts +4 -3
  63. package/server/service/return-order/return-order-mutation.ts +3 -1
  64. package/server/service/return-order/return-order-types.ts +1 -0
  65. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory.ts +5 -1
  66. package/server/utils/inventory-util.ts +67 -147
  67. package/translations/en.json +1 -0
  68. package/translations/ko.json +2 -1
  69. package/translations/ms.json +2 -1
  70. package/translations/zh.json +25 -0
@@ -17,7 +17,7 @@ import { MarketplaceStore } from '@things-factory/integration-marketplace'
17
17
  import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
18
18
  import { MarketplaceOrder, MarketplaceProductVariation } from '@things-factory/marketplace-base'
19
19
  // import { sendNotification } from '@things-factory/notification'
20
- import { Product, ProductBundleSetting } from '@things-factory/product-base'
20
+ import { Product, ProductBundleSetting, ProductDetail } from '@things-factory/product-base'
21
21
  import { PartnerSetting, Setting } from '@things-factory/setting-base'
22
22
  import { Domain } from '@things-factory/shell'
23
23
  import { Inventory } from '@things-factory/warehouse-base'
@@ -676,7 +676,7 @@ export async function generateReleaseGoodFunction(
676
676
 
677
677
  const pbSettings: ProductBundleSetting[] = await tx.getRepository(ProductBundleSetting).find({
678
678
  where: { productBundle: oi.product.id },
679
- relations: ['product', 'productBundle']
679
+ relations: ['product', 'productBundle', 'productDetail']
680
680
  })
681
681
 
682
682
  pbSettings.forEach(pbs => {
@@ -690,6 +690,9 @@ export async function generateReleaseGoodFunction(
690
690
  id: pbs.product.id,
691
691
  name: pbs.product.name,
692
692
  groupType: PRODUCT_GROUP_TYPE.SINGLE
693
+ },
694
+ productDetail: {
695
+ id: pbs.productDetail.id
693
696
  }
694
697
  }
695
698
  splitBundleOIs.push(splitOI)
@@ -704,6 +707,10 @@ export async function generateReleaseGoodFunction(
704
707
  newReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
705
708
 
706
709
  for (let oi of orderInventories) {
710
+ let productDetail: any = await tx
711
+ .getRepository(ProductDetail)
712
+ .findOne(oi.productDetail.id, { relations: ['product'] })
713
+
707
714
  let newOrderInv: OrderInventory = Object.assign({}, oi)
708
715
  newOrderInv = {
709
716
  ...newOrderInv,
@@ -712,7 +719,8 @@ export async function generateReleaseGoodFunction(
712
719
  status: ORDER_INVENTORY_STATUS.PENDING,
713
720
  name: OrderNoGenerator.orderInventory(),
714
721
  releaseGood: newReleaseGood,
715
- product: await tx.getRepository(Product).findOne(oi.product.id),
722
+ product: productDetail.product,
723
+ productDetail,
716
724
  creator: user,
717
725
  updater: user
718
726
  }
@@ -750,9 +758,9 @@ export async function generateReleaseGoodFunction(
750
758
  }
751
759
 
752
760
  let assignedOrderInventories: OrderInventory[] = await InventoryUtil.autoAssignInventoryForRelease(
753
- newOrderInv.product,
754
761
  oi,
755
- oi.packingType,
762
+ productDetail.product,
763
+ productDetail,
756
764
  locationSortingRules,
757
765
  bizplace,
758
766
  warehouseDomain,
@@ -1379,12 +1387,17 @@ export async function bulkGenerateReleaseGood(
1379
1387
  }
1380
1388
  }
1381
1389
 
1382
- const product: Product = await tx.getRepository(Product).findOne(oi.productId)
1390
+ let productDetail = oi.orderProduct?.productDetail
1391
+ let product = oi.orderProduct?.product
1392
+ if (!productDetail) {
1393
+ productDetail = await tx.getRepository(ProductDetail).findOne(oi.productDetailId, { relations: ['product'] })
1394
+ product = productDetail.product
1395
+ }
1383
1396
 
1384
1397
  let assignedResult = await InventoryUtil.autoAssignInventoryForRelease(
1385
- product,
1386
1398
  oi,
1387
- oi.packingType,
1399
+ product,
1400
+ productDetail,
1388
1401
  locationSortingRules,
1389
1402
  bizplace,
1390
1403
  warehouseDomain,
@@ -196,6 +196,7 @@ export class ReleaseGoodQuery {
196
196
  .createQueryBuilder('oi')
197
197
  .leftJoinAndSelect('oi.inventory', 'inventory')
198
198
  .leftJoinAndSelect('oi.product', 'product')
199
+ .leftJoinAndSelect('oi.productDetail', 'productDetail')
199
200
  .leftJoinAndSelect('inventory.location', 'location')
200
201
  .where('oi.domain_id = :domainId', { domainId: domain.id })
201
202
  .andWhere('oi.release_good_id = :releaseGoodId', { releaseGoodId: releaseGood.id })
@@ -226,6 +227,7 @@ export class ReleaseGoodQuery {
226
227
  batchIdRef: inventory.batchIdRef,
227
228
  palletId: inventory.palletId,
228
229
  product: orderInv.product,
230
+ productDetail: orderInv.productDetail,
229
231
  productIdRef: orderInv.product.id,
230
232
  productName: `${orderInv.product.name} (${orderInv.product.description})`,
231
233
  packingType: orderInv.packingType,
@@ -375,10 +377,7 @@ export class ReleaseGoodQuery {
375
377
  params.filters.push({
376
378
  name: typeFilter == 'b2c' ? 'releaseDate' : 'createdAt',
377
379
  operator: 'gte',
378
- value:
379
- typeFilter == 'b2c'
380
- ? releaseDateFrom
381
- : fromDateVal.toISOString(),
380
+ value: typeFilter == 'b2c' ? releaseDateFrom : fromDateVal.toISOString(),
382
381
  relation: false
383
382
  })
384
383
  }
@@ -393,9 +392,7 @@ export class ReleaseGoodQuery {
393
392
  name: typeFilter == 'b2c' ? 'releaseDate' : 'createdAt',
394
393
  operator: typeFilter == 'b2c' ? 'lte' : 'lt',
395
394
  value:
396
- typeFilter == 'b2c'
397
- ? releaseDateTo
398
- : new Date(toDateVal.setDate(toDateVal.getDate() + 1)).toISOString(),
395
+ typeFilter == 'b2c' ? releaseDateTo : new Date(toDateVal.setDate(toDateVal.getDate() + 1)).toISOString(),
399
396
  relation: false
400
397
  })
401
398
  }
@@ -1,6 +1,6 @@
1
1
  import { Field, Float, InputType, Int, ObjectType } from 'type-graphql'
2
2
 
3
- import { Product } from '@things-factory/product-base'
3
+ import { Product, ProductDetail } from '@things-factory/product-base'
4
4
  import { ObjectRef } from '@things-factory/shell'
5
5
  import { Location } from '@things-factory/warehouse-base'
6
6
 
@@ -77,6 +77,9 @@ export class InventoryInfos {
77
77
  @Field(type => Product, { nullable: true })
78
78
  product?: Product
79
79
 
80
+ @Field(type => ProductDetail, { nullable: true })
81
+ productDetail?: ProductDetail
82
+
80
83
  @Field({ nullable: true })
81
84
  packingType?: string
82
85
 
@@ -185,8 +188,6 @@ export class NewReleaseGood {
185
188
  @Field({ nullable: true })
186
189
  orderMethod: string
187
190
 
188
-
189
-
190
191
  @Field({ nullable: true })
191
192
  collectionOrderNo: string
192
193
 
@@ -6,7 +6,7 @@ import { Attachment, createAttachments } from '@things-factory/attachment-base'
6
6
  import { Role, User } from '@things-factory/auth-base'
7
7
  import { Bizplace, getDomainUsers } from '@things-factory/biz-base'
8
8
  import { sendNotification } from '@things-factory/notification'
9
- import { Product } from '@things-factory/product-base'
9
+ import { Product, ProductDetail } from '@things-factory/product-base'
10
10
  import { Domain } from '@things-factory/shell'
11
11
  import { Inventory } from '@things-factory/warehouse-base'
12
12
 
@@ -59,6 +59,7 @@ export class ReturnOrderMutation {
59
59
  itm =>
60
60
  itm.product.id === curr.product.id &&
61
61
  itm.packingType === curr.packingType &&
62
+ itm.productDetailId === curr.product.productDetailId &&
62
63
  itm.batchId === curr.batchId &&
63
64
  itm.packingSize === curr.packingSize
64
65
  )
@@ -99,6 +100,7 @@ export class ReturnOrderMutation {
99
100
  newOrderInv.name = OrderNoGenerator.orderInventory()
100
101
  newOrderInv.returnOrder = createdReturnOrder
101
102
  newOrderInv.product = await tx.getRepository(Product).findOne(moi.product.id)
103
+ newOrderInv.productDetail = await tx.getRepository(ProductDetail).findOne(moi.productDetail.id)
102
104
  newOrderInv.creator = user
103
105
  newOrderInv.updater = user
104
106
 
@@ -115,6 +115,7 @@ export class NewReturnOrder {
115
115
  @Field({ nullable: true })
116
116
  truckNo: string
117
117
 
118
+
118
119
  @Field({ nullable: true })
119
120
  deliveryOrderNo: string
120
121
 
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  import { User } from '@things-factory/auth-base'
14
14
  import { Bizplace } from '@things-factory/biz-base'
15
- import { Product } from '@things-factory/product-base'
15
+ import { Product, ProductDetail } from '@things-factory/product-base'
16
16
  import { Domain } from '@things-factory/shell'
17
17
  import { Inventory } from '@things-factory/warehouse-base'
18
18
 
@@ -127,6 +127,10 @@ export class ReverseKittingOrderInventory {
127
127
  @Field({ nullable: true })
128
128
  updatedAt?: Date
129
129
 
130
+ @ManyToOne(type => ProductDetail, { nullable: true })
131
+ @Field({ nullable: true })
132
+ productDetail: ProductDetail
133
+
130
134
  @ManyToOne(type => User, { nullable: true })
131
135
  @Field({ nullable: true })
132
136
  creator?: User
@@ -2,7 +2,7 @@ import { EntityManager, Equal, getRepository, In, Not, Raw, Repository, SelectQu
2
2
 
3
3
  import { User } from '@things-factory/auth-base'
4
4
  import { Bizplace } from '@things-factory/biz-base'
5
- import { Product, ProductBundle } from '@things-factory/product-base'
5
+ import { Product, ProductBundle, ProductDetail } from '@things-factory/product-base'
6
6
  import { Domain, ListParam } from '@things-factory/shell'
7
7
  import {
8
8
  Inventory,
@@ -12,7 +12,8 @@ import {
12
12
  Location,
13
13
  LOCATION_STATUS,
14
14
  LOCATION_TYPE,
15
- Pallet
15
+ Pallet,
16
+ generateInventoryHistory
16
17
  } from '@things-factory/warehouse-base'
17
18
 
18
19
  import { ORDER_TYPES } from '../constants'
@@ -102,6 +103,7 @@ export const InventoryUtil = {
102
103
  coalesce(p.sku, '') AS "productSKU",
103
104
  coalesce(p.brand, '') AS "productBrand",
104
105
  p.id AS "productId",
106
+ pd.id AS "productDetailId",
105
107
  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",
106
108
  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",
107
109
  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",
@@ -114,10 +116,7 @@ export const InventoryUtil = {
114
116
  WHERE l2.type NOT IN ('${LOCATION_TYPE.QUARANTINE}', '${LOCATION_TYPE.RESERVE}')
115
117
  AND i.domain_id = $1 AND i.status = 'STORED'
116
118
  ${inventoryBizplaceFilter ? `AND i.bizplace_id = '${inventoryBizplaceFilter.value}'` : ``}
117
- ) i ON i.product_id = pd.product_id
118
- AND i.packing_type = pd.packing_type
119
- and i.packing_size = pd.packing_size
120
- and i.uom = pd.uom
119
+ ) i ON i.product_detail_id = pd.id
121
120
  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
122
121
  LEFT JOIN (
123
122
  SELECT pbs.product_id, SUM(pbs.bundle_qty * src.release_qty) AS bundle_product_release_qty, SUM(pbs.bundle_qty * src.release_uom_value) AS bundle_product_release_uom_value
@@ -127,22 +126,24 @@ export const InventoryUtil = {
127
126
  ) bp on i.product_id = bp.product_id
128
127
  WHERE p.bizplace_id IN (${bizplaceIds})
129
128
  ${productDetailWhereClause}
130
- ${productFilter
131
- ? `AND (
129
+ ${
130
+ productFilter
131
+ ? `AND (
132
132
  lower(p.sku) ilike '${productFilter.value}'
133
133
  OR lower(p.name) ilike '${productFilter.value}'
134
134
  OR lower(p.description) ilike '${productFilter.value}'
135
135
  )
136
136
  `
137
- : ``
138
- }
137
+ : ``
138
+ }
139
139
  GROUP BY
140
140
  p.id,
141
+ pd.id,
141
142
  pd.packing_type,
142
143
  pd.packing_size,
143
144
  pd.uom
144
145
  UNION
145
- SELECT packing_type, packing_size,'UNIT' AS "uom", name AS "productName", sku AS "productSKU", '-' AS "productBrand", id AS "productId",
146
+ SELECT packing_type, packing_size,'UNIT' AS "uom", name AS "productName", sku AS "productSKU", '-' AS "productBrand", id AS "productId", pbs.product_detail_id AS "productDetailId",
146
147
  COALESCE(MIN(FLOOR(pbs."availableQty")),0) AS "remainQty",
147
148
  COALESCE(MIN(FLOOR(pbs."availableUomValue")),0) AS "remainUomValue",
148
149
  CONCAT(COALESCE(MIN(FLOOR(pbs."availableUomValue")),0),' UNIT') AS "remainUomValueWithUom",
@@ -151,7 +152,8 @@ export const InventoryUtil = {
151
152
  LEFT JOIN (
152
153
  SELECT pbs.product_id, pbs.product_bundle_id, min(pbs.bundle_qty),
153
154
  (SUM(COALESCE(i2.qty, 0)) - SUM(COALESCE(i2.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) / min(pbs.bundle_qty) AS "availableQty",
154
- (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"
155
+ (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",
156
+ pbs.product_detail_id
155
157
  FROM product_bundle_settings pbs
156
158
  LEFT JOIN inventories i2 ON i2.product_id = pbs.product_id AND i2.domain_id = $1 AND i2.status = 'STORED'
157
159
  INNER JOIN locations l2 ON i2.location_id = l2.id
@@ -160,25 +162,28 @@ export const InventoryUtil = {
160
162
  ${inventoryBizplaceFilter ? `AND i2.bizplace_id = '${inventoryBizplaceFilter.value}'` : ``}
161
163
  GROUP BY
162
164
  pbs.product_id,
163
- pbs.product_bundle_id
165
+ pbs.product_bundle_id,
166
+ pbs.product_detail_id
164
167
  ) pbs ON pbs.product_bundle_id = pb.id
165
168
  ${bundleWhereClause}
166
169
  AND pb.bizplace_id IN (${bizplaceIds})
167
- ${productFilter
168
- ? `AND (
170
+ ${
171
+ productFilter
172
+ ? `AND (
169
173
  lower(pb.sku) ilike '${productFilter.value}'
170
174
  OR lower(pb.name) ilike '${productFilter.value}'
171
175
  OR lower(pb.description) ilike '${productFilter.value}'
172
176
  )
173
177
  `
174
- : ``
175
- }
178
+ : ``
179
+ }
176
180
  GROUP BY
177
181
  pb.packing_type,
178
182
  pb.packing_size,
179
183
  pb.name,
180
184
  pb.sku,
181
- pb.id
185
+ pb.id,
186
+ pbs.product_detail_id
182
187
  )
183
188
  AS inv_prod_grp
184
189
  ${whereClause}
@@ -273,6 +278,7 @@ export const InventoryUtil = {
273
278
  coalesce(p.sku, '') AS "productSKU",
274
279
  coalesce(p.brand, '') AS "productBrand",
275
280
  p.id AS "productId",
281
+ i.product_detail_id AS "productDetailId",
276
282
  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",
277
283
  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",
278
284
  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",
@@ -292,6 +298,7 @@ export const InventoryUtil = {
292
298
  AND l2.type NOT IN ('${LOCATION_TYPE.QUARANTINE}', '${LOCATION_TYPE.RESERVE}')
293
299
  ${productWhereClause}
294
300
  GROUP BY
301
+ i.product_detail_id,
295
302
  i.batch_id,
296
303
  i.batch_id_ref,
297
304
  p.id,
@@ -299,7 +306,7 @@ export const InventoryUtil = {
299
306
  i.packing_size,
300
307
  i.uom
301
308
  UNION
302
- SELECT 'BUNDLE' AS "batchId", null as "batchIdRef", packing_type, packing_size,'UNIT' AS "uom", name AS "productName", sku AS "productSKU", 'brand' AS "productBrand", id AS "productId",
309
+ SELECT 'BUNDLE' AS "batchId", null as "batchIdRef", packing_type, packing_size,'UNIT' AS "uom", name AS "productName", sku AS "productSKU", 'brand' AS "productBrand", id AS "productId", pbs.product_detail_id AS "productDetailId",
303
310
  MIN(FLOOR(pbs."availableQty")) AS "remainQty",
304
311
  MIN(FLOOR(pbs."availableUomValue")) AS "remainUomValue",
305
312
  CONCAT(MIN(FLOOR(pbs."availableUomValue")),' UNIT') AS "remainUomValueWithUom",
@@ -308,16 +315,17 @@ export const InventoryUtil = {
308
315
  INNER JOIN (
309
316
  SELECT pbs.product_id, pbs.product_bundle_id, min(pbs.bundle_qty),
310
317
  (SUM(COALESCE(i2.qty, 0)) - SUM(COALESCE(i2.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) / min(pbs.bundle_qty) AS "availableQty",
311
- (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"
318
+ (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",
319
+ pbs.product_detail_id
312
320
  FROM product_bundle_settings pbs
313
321
  LEFT JOIN inventories i2 ON i2.product_id = pbs.product_id AND i2.domain_id = $1
314
322
  AND i2.bizplace_id IN (${bizplaceIds})
315
323
  AND i2.status = 'STORED'
316
324
  LEFT JOIN oi ON oi.product_id = i2.product_id
317
- GROUP BY pbs.product_id, pbs.product_bundle_id
325
+ GROUP BY pbs.product_id, pbs.product_bundle_id, pbs.product_detail_id
318
326
  ) pbs ON pbs.product_bundle_id = pb.id
319
327
  ${bundleWhereClause}
320
- GROUP BY pb.packing_type, pb.packing_size, pb.name, pb.sku, pb.id
328
+ GROUP BY pb.packing_type, pb.packing_size, pb.name, pb.sku, pb.id, pbs.product_detail_id
321
329
  )
322
330
  AS inv_prod_grp
323
331
  ${whereClause}
@@ -357,13 +365,15 @@ export const InventoryUtil = {
357
365
 
358
366
  if (params?.pagination) {
359
367
  items = await trxMgr.query(
360
- `select * from temp_inventory_product_group ${filterGroupTypeQuery ? filterGroupTypeQuery : ''} ${sortingArr.length > 0 ? ' Order by ' + sortedBy.toString() : ''
368
+ `select * from temp_inventory_product_group ${filterGroupTypeQuery ? filterGroupTypeQuery : ''} ${
369
+ sortingArr.length > 0 ? ' Order by ' + sortedBy.toString() : ''
361
370
  } OFFSET $1 LIMIT $2`,
362
371
  [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]
363
372
  )
364
373
  } else {
365
374
  items = await trxMgr.query(
366
- `select * from temp_inventory_product_group ${filterGroupTypeQuery ? filterGroupTypeQuery : ''} ${sortingArr.length > 0 ? ' Order by ' + sortedBy.toString() : ''
375
+ `select * from temp_inventory_product_group ${filterGroupTypeQuery ? filterGroupTypeQuery : ''} ${
376
+ sortingArr.length > 0 ? ' Order by ' + sortedBy.toString() : ''
367
377
  }`
368
378
  )
369
379
  }
@@ -486,9 +496,8 @@ export const InventoryUtil = {
486
496
  let json_oi = JSON.stringify(
487
497
  orderInventories.map(x => {
488
498
  return {
489
- product_id: x.product.id,
499
+ product_detail_id: x.productDetail.id,
490
500
  batch_id: x.batchId,
491
- packing_type: x.packingType,
492
501
  release_qty: x.releaseQty,
493
502
  uom: x.uom
494
503
  }
@@ -497,15 +506,14 @@ export const InventoryUtil = {
497
506
 
498
507
  let resultQb = await trxMgr.query(
499
508
  `
500
- select joi.product_id as "productId", joi.batch_id as "batchId", joi.packing_type as "packingType", joi.uom as "uom", joi.release_qty as "releaseQty",
509
+ select joi.product_detail_id as "productDetailId", joi.batch_id as "batchId", joi.uom as "uom", joi.release_qty as "releaseQty",
501
510
  sum(i.qty - coalesce(i.locked_qty,0)) - coalesce(
502
511
  (
503
512
  select sum(oi.release_qty) from order_inventories oi
504
513
  where (oi.status = 'PENDING' or oi.status = 'PENDING_RECEIVE' or oi.status = 'PENDING_WORKSHEET' or oi.status = 'PENDING_SPLIT')
505
514
  and oi.inventory_id IS null
506
- and oi.product_id = joi.product_id
515
+ and oi.product_detail_id = joi.product_detail_id
507
516
  and oi.batch_id = joi.batch_id
508
- and oi.packing_type = joi.packing_type
509
517
  and oi.uom = joi.uom
510
518
  and oi.domain_id = $1
511
519
  and oi.bizplace_id = $2
@@ -515,21 +523,20 @@ export const InventoryUtil = {
515
523
  select sum(oi.release_uom_value) from order_inventories oi
516
524
  where (oi.status = 'PENDING' or oi.status = 'PENDING_RECEIVE' or oi.status = 'PENDING_WORKSHEET' or oi.status = 'PENDING_SPLIT')
517
525
  and oi.inventory_id IS null
518
- and oi.product_id = joi.product_id
526
+ and oi.product_detail_id = joi.product_detail_id
519
527
  and oi.batch_id = joi.batch_id
520
- and oi.packing_type = joi.packing_type
521
528
  and oi.uom = joi.uom
522
529
  and oi.domain_id = $1
523
530
  and oi.bizplace_id = $2
524
531
  ),0) as "availableUomValue"
525
532
  from json_populate_recordset(NULL::order_inventories,'${json_oi}') joi
526
- left join inventories i on joi.product_id = i.product_id
533
+ left join inventories i on joi.product_detail_id = i.product_detail_id
527
534
  and joi.batch_id = i.batch_id
528
- and joi.packing_type = i.packing_type and i.status ='STORED'
535
+ and i.status ='STORED'
529
536
  and joi.uom = i.uom
530
537
  and i.domain_id = $1
531
538
  and i.bizplace_id = $2
532
- group by joi.product_id, joi.batch_id, joi.packing_type, joi.release_qty, joi.uom
539
+ group by joi.product_detail_id, joi.batch_id, joi.packing_type, joi.release_qty, joi.uom
533
540
  `,
534
541
  [warehouseDomain.id, partnerBizplace.id]
535
542
  )
@@ -575,9 +582,9 @@ export const InventoryUtil = {
575
582
  * @returns orderInventories
576
583
  */
577
584
  async autoAssignInventoryForRelease(
578
- product: Product,
579
585
  orderInventory: OrderInventory,
580
- packingType: string,
586
+ product: Product,
587
+ productDetail: ProductDetail,
581
588
  locationSortingRules: any = [],
582
589
  customerBizplace: Bizplace,
583
590
  domain: Domain,
@@ -588,16 +595,14 @@ export const InventoryUtil = {
588
595
  qb.leftJoinAndSelect('iv.location', 'loc')
589
596
  .andWhere('"iv"."domain_id" = :domainId')
590
597
  .andWhere('"iv"."bizplace_id" = :bizplaceId')
591
- .andWhere('"iv"."packing_type" = :packingType')
592
- .andWhere('"iv"."product_id" = :productId')
598
+ .andWhere('"iv"."product_detail_id" = :productDetailId')
593
599
  .andWhere('"iv"."status" = :status')
594
600
  .andWhere('"iv"."qty" - COALESCE("iv"."locked_qty", 0) > 0')
595
601
  .andWhere('"loc"."type" NOT IN (:...locationTypes)')
596
602
  .setParameters({
597
603
  domainId: domain.id,
598
604
  bizplaceId: customerBizplace.id,
599
- packingType: packingType,
600
- productId: product.id,
605
+ productDetailId: productDetail.id,
601
606
  status: INVENTORY_STATUS.STORED,
602
607
  locationTypes: [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE]
603
608
  })
@@ -659,7 +664,7 @@ export const InventoryUtil = {
659
664
  }
660
665
  })
661
666
 
662
- return _composeTargetInventories(product, orderInventory, inventories)
667
+ return _composeTargetInventories(productDetail, orderInventory, inventories)
663
668
  },
664
669
 
665
670
  /**
@@ -851,31 +856,32 @@ async function getConditions(
851
856
  case 'batch_product':
852
857
  productWhereClause += `
853
858
  AND (i.batch_id, p.id, i.packing_type, i.packing_size) ${operator === 'in' ? 'IN' : 'NOT IN'} (${value
854
- .map(
855
- (v: { batchId: string; productId: string; packingType: string; packingSize: string }) =>
856
- `('${v.batchId}', '${v.productId}', '${v.packingType}', '${v.packingSize}')`
857
- )
858
- .join()})
859
+ .map(
860
+ (v: { batchId: string; productId: string; packingType: string; packingSize: string }) =>
861
+ `('${v.batchId}', '${v.productId}', '${v.packingType}', '${v.packingSize}')`
862
+ )
863
+ .join()})
859
864
  `
860
865
  break
861
866
 
862
867
  case 'batch_bundle':
863
868
  bundleWhereClause += `
864
869
  ${bundleWhereClause == '' ? 'WHERE' : 'AND'} pb.id ${operator === 'in' ? 'IN' : 'NOT IN'} (${value
865
- .map((v: { productId: string }) => `('${v.productId}')`)
866
- .join()})
870
+ .map((v: { productId: string }) => `('${v.productId}')`)
871
+ .join()})
867
872
  `
868
873
  break
869
874
 
870
875
  case 'product':
871
876
  productDetailWhereClause += `
872
- AND (pd.product_id, pd.packing_type, pd.packing_size, pd.uom) ${operator === 'in' ? 'IN' : 'NOT IN'
877
+ AND (pd.product_id, pd.packing_type, pd.packing_size, pd.uom) ${
878
+ operator === 'in' ? 'IN' : 'NOT IN'
873
879
  } (${value
874
- .map(
875
- (v: { productId: string; packingType: string; packingSize: string; uom: string }) =>
876
- `('${v.productId}', '${v.packingType}', '${v.packingSize}', '${v.uom}')`
877
- )
878
- .join()})
880
+ .map(
881
+ (v: { productId: string; packingType: string; packingSize: string; uom: string }) =>
882
+ `('${v.productId}', '${v.packingType}', '${v.packingSize}', '${v.uom}')`
883
+ )
884
+ .join()})
879
885
  `
880
886
  break
881
887
  }
@@ -927,98 +933,6 @@ async function updateInventory(
927
933
  return await trxMgr.getRepository(Inventory).save(inventory)
928
934
  }
929
935
 
930
- async function generateInventoryHistory(
931
- inventory: Inventory,
932
- refOrder: any,
933
- transactionType: string,
934
- qty: number,
935
- uomValue: number,
936
- user: User,
937
- trxMgr?: EntityManager
938
- ): Promise<InventoryHistory> {
939
- const invHistoryRepo: Repository<InventoryHistory> =
940
- trxMgr?.getRepository(InventoryHistory) || getRepository(InventoryHistory)
941
- const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)
942
-
943
- if (!inventory?.id) throw new Error(`Can't find out ID of inventory.`)
944
- if (!refOrder?.id || !refOrder.name) throw new Error(`Can't find out ID or Name of Reference Order`)
945
- if (
946
- !inventory?.domain ||
947
- !inventory?.bizplace ||
948
- !inventory?.product?.id ||
949
- !inventory?.warehouse?.id ||
950
- !inventory?.location?.id
951
- ) {
952
- inventory = await invRepo.findOne({
953
- where: { id: inventory.id },
954
- relations: ['domain', 'bizplace', 'product', 'warehouse', 'location']
955
- })
956
- }
957
-
958
- const domain: Domain = inventory.domain
959
- const location: Location = inventory.location
960
-
961
- const seq: number = await invHistoryRepo.count({ domain: inventory.domain, palletId: inventory.palletId })
962
- let openingQty: number = 0
963
- let openingUomValue: number = 0
964
-
965
- if (seq) {
966
- const lastInvHistory: InventoryHistory = await invHistoryRepo.findOne({
967
- domain: inventory.domain,
968
- palletId: inventory.palletId,
969
- seq: seq - 1
970
- })
971
- openingQty = lastInvHistory.openingQty + lastInvHistory.qty
972
- openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue
973
- }
974
-
975
- let inventoryHistory: InventoryHistory = new InventoryHistory()
976
- inventoryHistory.name = InventoryNoGenerator.inventoryHistoryName()
977
- inventoryHistory.description = inventory.description
978
- inventoryHistory.seq = seq
979
- inventoryHistory.palletId = inventory.palletId
980
- inventoryHistory.cartonId = inventory.cartonId
981
- inventoryHistory.batchId = inventory.batchId
982
- inventoryHistory.batchIdRef = inventory.batchIdRef
983
- inventoryHistory.status = inventory.status
984
- inventoryHistory.transactionType = transactionType
985
- inventoryHistory.refOrderId = refOrder?.id || null
986
- inventoryHistory.orderNo = refOrder?.name || null
987
- inventoryHistory.orderRefNo = refOrder?.refNo || null
988
- inventoryHistory.inventory = inventory
989
- inventoryHistory.product = inventory.product
990
- inventoryHistory.reusablePallet = inventory.reusablePallet
991
- inventoryHistory.zone = inventory.zone
992
- inventoryHistory.warehouse = inventory.warehouse
993
- inventoryHistory.location = inventory.location
994
- inventoryHistory.expirationDate = inventory.expirationDate
995
- inventoryHistory.packingType = inventory.packingType
996
- inventoryHistory.packingSize = inventory.packingSize
997
- inventoryHistory.uom = inventory.uom
998
- inventoryHistory.qty = qty
999
- inventoryHistory.openingQty = openingQty
1000
- inventoryHistory.uomValue = uomValue
1001
- inventoryHistory.openingUomValue = openingUomValue
1002
- inventoryHistory.unitCost = inventory.unitCost
1003
- inventoryHistory.domain = inventory.domain
1004
- inventoryHistory.bizplace = inventory.bizplace
1005
- inventoryHistory.creator = user
1006
- inventoryHistory.updater = user
1007
-
1008
- inventoryHistory = await invHistoryRepo.save(inventoryHistory)
1009
-
1010
- if (inventory.lastSeq !== seq) {
1011
- await invRepo.save({
1012
- ...inventory,
1013
- lastSeq: inventoryHistory.seq,
1014
- updater: user
1015
- })
1016
- }
1017
-
1018
- await switchLocationStatus(domain, location, user, trxMgr)
1019
- return inventoryHistory
1020
- }
1021
-
1022
936
  /**
1023
937
  * @description: Check location emptiness and update status of location
1024
938
  * @param domain
@@ -1057,12 +971,17 @@ export async function switchLocationStatus(
1057
971
  return location
1058
972
  }
1059
973
 
1060
- export function _composeTargetInventories(product: Product, record: any, inventories: Inventory[]): OrderInventory[] {
974
+ export function _composeTargetInventories(
975
+ productDetail: ProductDetail,
976
+ record: any,
977
+ inventories: Inventory[]
978
+ ): OrderInventory[] {
1061
979
  let leftReleaseQty: number = record.releaseQty
1062
980
  let leftReleaseUomValue: number = record.releaseUomValue
1063
981
  let compReleaseQty: number = 0
1064
982
  let compReleaseUomValue: number = 0
1065
983
  let totalInventoryQty: number = inventories.reduce((total, inventory) => total + inventory.remainQty, 0)
984
+ let product = productDetail.product
1066
985
 
1067
986
  if (totalInventoryQty < record.releaseQty) {
1068
987
  throw new Error(`invalid release qty for ${product?.sku}`)
@@ -1115,6 +1034,7 @@ export function _composeTargetInventories(product: Product, record: any, invento
1115
1034
  batchIdRef,
1116
1035
  uom,
1117
1036
  product,
1037
+ productDetail,
1118
1038
  type: ORDER_TYPES.RELEASE_OF_GOODS
1119
1039
  })
1120
1040
 
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "error.Manifest(s) (x) already in open status": "Manifest(s) ({x}) already in open status",
3
+ "error.product_not_found": "product not found",
3
4
  "error.release_order_not_found": "release order not found",
4
5
  "error.tracking_no_already_scanned_before": "tracking no already scanned before",
5
6
  "error.tracking_no_belongs_to_x": "tracking no belongs to {x}",
@@ -20,5 +20,6 @@
20
20
  "error.Manifest(s) (x) already in open status": "[ko] Manifest(s) ({x}) already in open status",
21
21
  "error.release_order_not_found": "[ko] release order not found",
22
22
  "error.tracking_no_belongs_to_x": "[ko] tracking no belongs to {x}",
23
- "error.tracking_no_already_scanned_before": "[ko] tracking no already scanned before"
23
+ "error.tracking_no_already_scanned_before": "[ko] tracking no already scanned before",
24
+ "error.product_not_found": "[ko] product not found"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "error.Manifest(s) (x) already in open status": "[ms] Manifest(s) ({x}) already in open status",
21
21
  "error.release_order_not_found": "[ms] release order not found",
22
22
  "error.tracking_no_belongs_to_x": "[ms] tracking no belongs to {x}",
23
- "error.tracking_no_already_scanned_before": "[ms] tracking no already scanned before"
23
+ "error.tracking_no_already_scanned_before": "[ms] tracking no already scanned before",
24
+ "error.product_not_found": "[ms] product not found"
24
25
  }