@things-factory/sales-base 4.3.184 → 4.3.187

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 (52) hide show
  1. package/dist-server/constants/order.js +10 -5
  2. package/dist-server/constants/order.js.map +1 -1
  3. package/dist-server/service/draft-release-good/draft-release-good-query.js +24 -2
  4. package/dist-server/service/draft-release-good/draft-release-good-query.js.map +1 -1
  5. package/dist-server/service/draft-release-good/draft-release-good.js +5 -0
  6. package/dist-server/service/draft-release-good/draft-release-good.js.map +1 -1
  7. package/dist-server/service/index.js +7 -0
  8. package/dist-server/service/index.js.map +1 -1
  9. package/dist-server/service/manifest/manifest.js +1 -1
  10. package/dist-server/service/manifest/manifest.js.map +1 -1
  11. package/dist-server/service/order-inventory/order-inventory.js +14 -0
  12. package/dist-server/service/order-inventory/order-inventory.js.map +1 -1
  13. package/dist-server/service/order-package/order-package.js +5 -0
  14. package/dist-server/service/order-package/order-package.js.map +1 -1
  15. package/dist-server/service/order-product/order-product.js +10 -0
  16. package/dist-server/service/order-product/order-product.js.map +1 -1
  17. package/dist-server/service/release-good/release-good-query.js +3 -0
  18. package/dist-server/service/release-good/release-good-query.js.map +1 -1
  19. package/dist-server/service/release-good/release-good.js +21 -1
  20. package/dist-server/service/release-good/release-good.js.map +1 -1
  21. package/dist-server/service/replenishment/index.js +9 -0
  22. package/dist-server/service/replenishment/index.js.map +1 -0
  23. package/dist-server/service/replenishment/replenishment-mutation.js +226 -0
  24. package/dist-server/service/replenishment/replenishment-mutation.js.map +1 -0
  25. package/dist-server/service/replenishment/replenishment-query.js +114 -0
  26. package/dist-server/service/replenishment/replenishment-query.js.map +1 -0
  27. package/dist-server/service/replenishment/replenishment-type.js +119 -0
  28. package/dist-server/service/replenishment/replenishment-type.js.map +1 -0
  29. package/dist-server/service/replenishment/replenishment.js +104 -0
  30. package/dist-server/service/replenishment/replenishment.js.map +1 -0
  31. package/dist-server/utils/inventory-util.js +17 -2
  32. package/dist-server/utils/inventory-util.js.map +1 -1
  33. package/dist-server/utils/order-no-generator.js +4 -0
  34. package/dist-server/utils/order-no-generator.js.map +1 -1
  35. package/package.json +8 -8
  36. package/server/constants/order.ts +10 -5
  37. package/server/service/draft-release-good/draft-release-good-query.ts +29 -2
  38. package/server/service/draft-release-good/draft-release-good.ts +4 -0
  39. package/server/service/index.ts +7 -0
  40. package/server/service/manifest/manifest.ts +3 -3
  41. package/server/service/order-inventory/order-inventory.ts +12 -1
  42. package/server/service/order-package/order-package.ts +4 -0
  43. package/server/service/order-product/order-product.ts +8 -0
  44. package/server/service/release-good/release-good-query.ts +3 -0
  45. package/server/service/release-good/release-good.ts +16 -0
  46. package/server/service/replenishment/index.ts +6 -0
  47. package/server/service/replenishment/replenishment-mutation.ts +309 -0
  48. package/server/service/replenishment/replenishment-query.ts +76 -0
  49. package/server/service/replenishment/replenishment-type.ts +78 -0
  50. package/server/service/replenishment/replenishment.ts +87 -0
  51. package/server/utils/inventory-util.ts +19 -2
  52. package/server/utils/order-no-generator.ts +7 -0
@@ -0,0 +1,87 @@
1
+ import {
2
+ CreateDateColumn,
3
+ UpdateDateColumn,
4
+ Entity,
5
+ Index,
6
+ Column,
7
+ RelationId,
8
+ ManyToOne,
9
+ PrimaryGeneratedColumn,
10
+ OneToMany
11
+ } from 'typeorm'
12
+ import { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'
13
+
14
+ import { Domain } from '@things-factory/shell'
15
+ import { User } from '@things-factory/auth-base'
16
+ import { Bizplace } from '@things-factory/biz-base'
17
+ import { OrderInventory, OrderProduct } from '../'
18
+
19
+ export enum ReplenishmentStatus {
20
+ STATUS_A = 'STATUS_A',
21
+ STATUS_B = 'STATUS_B'
22
+ }
23
+
24
+ registerEnumType(ReplenishmentStatus, {
25
+ name: 'ReplenishmentStatus',
26
+ description: 'state enumeration of a replenishment'
27
+ })
28
+
29
+ @Entity()
30
+ @Index('ix_replenishment_0', (replenishment: Replenishment) => [replenishment.domain, replenishment.name], {
31
+ unique: true
32
+ })
33
+ @ObjectType({ description: 'Entity for Replenishment' })
34
+ export class Replenishment {
35
+ @PrimaryGeneratedColumn('uuid')
36
+ @Field(type => ID)
37
+ readonly id: string
38
+
39
+ @Column()
40
+ @Field({ nullable: true })
41
+ name: string
42
+
43
+ @Column()
44
+ @Field({ nullable: true })
45
+ status: string
46
+
47
+ @ManyToOne(type => Domain)
48
+ @Field(type => Domain, { nullable: true })
49
+ domain: Domain
50
+
51
+ @RelationId((replenishment: Replenishment) => replenishment.domain)
52
+ domainId: string
53
+
54
+ @OneToMany(type => OrderInventory, orderInventory => orderInventory.replenishment)
55
+ @Field(type => [OrderInventory], { nullable: true })
56
+ orderInventories: OrderInventory[]
57
+
58
+ @OneToMany(type => OrderProduct, orderProduct => orderProduct.replenishment)
59
+ @Field(type => [OrderProduct], { nullable: true })
60
+ orderProducts: OrderProduct[]
61
+
62
+ @CreateDateColumn()
63
+ @Field({ nullable: true })
64
+ createdAt?: Date
65
+
66
+ @UpdateDateColumn()
67
+ @Field({ nullable: true })
68
+ updatedAt?: Date
69
+
70
+ @ManyToOne(type => User, {
71
+ nullable: true
72
+ })
73
+ @Field({ nullable: true })
74
+ creator?: User
75
+
76
+ @RelationId((replenishment: Replenishment) => replenishment.creator)
77
+ creatorId?: string
78
+
79
+ @ManyToOne(type => User, {
80
+ nullable: true
81
+ })
82
+ @Field({ nullable: true })
83
+ updater?: User
84
+
85
+ @RelationId((replenishment: Replenishment) => replenishment.creator)
86
+ updaterId?: string
87
+ }
@@ -106,6 +106,8 @@ export const InventoryUtil = {
106
106
  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",
107
107
  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",
108
108
  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",
109
+ COALESCE(SUM(COALESCE(i.transfer_qty, 0)), 0) AS "transferQty",
110
+ COALESCE(SUM(COALESCE(i.transfer_uom_value, 0)), 0) AS "transferUomValue",
109
111
  'SINGLE' AS "groupType"
110
112
  FROM products p
111
113
  INNER join product_details pd on pd.product_id = p.id
@@ -148,12 +150,16 @@ export const InventoryUtil = {
148
150
  COALESCE(MIN(FLOOR(pbs."availableQty")),0) AS "remainQty",
149
151
  COALESCE(MIN(FLOOR(pbs."availableUomValue")),0) AS "remainUomValue",
150
152
  CONCAT(COALESCE(MIN(FLOOR(pbs."availableUomValue")),0),' UNIT') AS "remainUomValueWithUom",
153
+ COALESCE(MIN(FLOOR(pbs."transferQty")),0) AS "transferQty",
154
+ COALESCE(MIN(FLOOR(pbs."transferUomValue")),0) AS "transferUomValue",
151
155
  'BUNDLE' AS "groupType"
152
156
  FROM product_bundles pb
153
157
  LEFT JOIN (
154
158
  SELECT pbs.product_id, pbs.product_bundle_id, min(pbs.bundle_qty),
155
159
  (SUM(COALESCE(i2.qty, 0)) - SUM(COALESCE(i2.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) / min(pbs.bundle_qty) AS "availableQty",
156
160
  (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",
161
+ (SUM(COALESCE(i2.transfer_qty, 0)) / min(pbs.bundle_qty)) AS "transferQty",
162
+ (SUM(COALESCE(i2.transfer_uom_value, 0)) / min(pbs.bundle_qty)) AS "transferUomValue",
157
163
  pbs.product_detail_id
158
164
  FROM product_bundle_settings pbs
159
165
  LEFT JOIN inventories i2 ON i2.product_id = pbs.product_id AND i2.domain_id = $1 AND i2.status = 'STORED'
@@ -299,6 +305,8 @@ export const InventoryUtil = {
299
305
  WHERE i.domain_id = $1
300
306
  AND l2.type NOT IN ('${LOCATION_TYPE.QUARANTINE}', '${LOCATION_TYPE.RESERVE}')
301
307
  AND i.obsolete = false
308
+ AND i.transfer_qty <= 0
309
+ AND i.transfer_uom_value <= 0
302
310
  AND case when i.expiration_date is not null and p.shelf_life is not null then CURRENT_DATE < i.expiration_date - p.shelf_life else true end
303
311
  ${productWhereClause}
304
312
  GROUP BY
@@ -601,7 +609,8 @@ export const InventoryUtil = {
601
609
  customerBizplace: Bizplace,
602
610
  domain: Domain,
603
611
  trxMgr: EntityManager,
604
- batchId?: string
612
+ batchId?: string,
613
+ preferLocation: string = null
605
614
  ): Promise<OrderInventory[]> {
606
615
  let strictProduct = 'false'
607
616
 
@@ -627,6 +636,7 @@ export const InventoryUtil = {
627
636
 
628
637
  let qb: SelectQueryBuilder<Inventory> = trxMgr.getRepository(Inventory).createQueryBuilder('iv')
629
638
  qb.innerJoinAndSelect('iv.location', 'loc')
639
+ .innerJoin('warehouse_inventory_assignment_rankings', 'wiar', '"wiar"."location_type" = "loc"."type"')
630
640
  .innerJoin('iv.product', 'p')
631
641
  .andWhere('"iv"."domain_id" = :domainId')
632
642
  .andWhere('"iv"."bizplace_id" = :bizplaceId')
@@ -634,6 +644,8 @@ export const InventoryUtil = {
634
644
  .andWhere('"iv"."qty" - COALESCE("iv"."locked_qty", 0) > 0')
635
645
  .andWhere('"loc"."type" NOT IN (:...locationTypes)')
636
646
  .andWhere('"iv"."obsolete" = false')
647
+ .andWhere('"iv"."transfer_qty" <= 0')
648
+ .andWhere('"iv"."transfer_uom_value" <= 0')
637
649
  .andWhere('"iv"."product_id" = :productId')
638
650
  .andWhere(
639
651
  'case when "iv"."expiration_date" is not null and "p"."shelf_life" is not null then CURRENT_DATE < "iv"."expiration_date" - "p"."shelf_life" else true end'
@@ -650,7 +662,10 @@ export const InventoryUtil = {
650
662
  qb.andWhere('"iv"."batch_id" = :batchId', { batchId: batchId })
651
663
  }
652
664
 
653
- if (strictProduct == 'true') {
665
+ if (preferLocation) {
666
+ qb.andWhere('"loc"."type" = :preferLocation', { preferLocation })
667
+ }
668
+ if (strictProduct == 'true' || preferLocation == 'STORAGE') {
654
669
  qb.andWhere('"iv"."product_detail_id" = :productDetailId', { productDetailId: productDetail.id })
655
670
  } else {
656
671
  qb.andWhere('"iv"."packing_type" = :packingType', { packingType: orderInventory.packingType })
@@ -672,6 +687,8 @@ export const InventoryUtil = {
672
687
  return qb
673
688
  }
674
689
 
690
+ qb.addOrderBy('"wiar"."rank"', 'ASC')
691
+
675
692
  switch (product?.pickingStrategy) {
676
693
  case 'FIFO':
677
694
  qb.addOrderBy('"iv"."created_at"', 'ASC')
@@ -78,6 +78,13 @@ export class OrderNoGenerator {
78
78
  return `OTI-${uuidv4()}`
79
79
  }
80
80
 
81
+ static replenishment() {
82
+ const currentDate = new Date()
83
+ return `RP-${currentDate.getFullYear()}${
84
+ currentDate.getMonth() + 1
85
+ }${currentDate.getDate()}${currentDate.getHours()}${currentDate.getMinutes()}${currentDate.getSeconds()}${currentDate.getMilliseconds()}`
86
+ }
87
+
81
88
  static purchaseOrder() {
82
89
  const currentDate = new Date()
83
90
  return `PO-${currentDate.getFullYear()}${