@things-factory/warehouse-base 4.1.41 → 4.2.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 (49) hide show
  1. package/dist-server/constants/inventory.js +9 -2
  2. package/dist-server/constants/inventory.js.map +1 -1
  3. package/dist-server/service/index.js +6 -0
  4. package/dist-server/service/index.js.map +1 -1
  5. package/dist-server/service/inventory/inventory-query.js +37 -14
  6. package/dist-server/service/inventory/inventory-query.js.map +1 -1
  7. package/dist-server/service/inventory/inventory-types.js +12 -0
  8. package/dist-server/service/inventory/inventory-types.js.map +1 -1
  9. package/dist-server/service/inventory/inventory.js +22 -0
  10. package/dist-server/service/inventory/inventory.js.map +1 -1
  11. package/dist-server/service/inventory-change/inventory-change-mutation.js +134 -5
  12. package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -1
  13. package/dist-server/service/inventory-change/inventory-change-query.js +1 -0
  14. package/dist-server/service/inventory-change/inventory-change-query.js.map +1 -1
  15. package/dist-server/service/inventory-change/inventory-change.js +10 -0
  16. package/dist-server/service/inventory-change/inventory-change.js.map +1 -1
  17. package/dist-server/service/inventory-item/inventory-item-query.js +82 -4
  18. package/dist-server/service/inventory-item/inventory-item-query.js.map +1 -1
  19. package/dist-server/service/inventory-item/inventory-item.js +8 -0
  20. package/dist-server/service/inventory-item/inventory-item.js.map +1 -1
  21. package/dist-server/service/inventory-item-change/index.js +9 -0
  22. package/dist-server/service/inventory-item-change/index.js.map +1 -0
  23. package/dist-server/service/inventory-item-change/inventory-item-change-mutation.js +121 -0
  24. package/dist-server/service/inventory-item-change/inventory-item-change-mutation.js.map +1 -0
  25. package/dist-server/service/inventory-item-change/inventory-item-change-query.js +87 -0
  26. package/dist-server/service/inventory-item-change/inventory-item-change-query.js.map +1 -0
  27. package/dist-server/service/inventory-item-change/inventory-item-change-type.js +107 -0
  28. package/dist-server/service/inventory-item-change/inventory-item-change-type.js.map +1 -0
  29. package/dist-server/service/inventory-item-change/inventory-item-change.js +110 -0
  30. package/dist-server/service/inventory-item-change/inventory-item-change.js.map +1 -0
  31. package/dist-server/utils/inventory-util.js +23 -40
  32. package/dist-server/utils/inventory-util.js.map +1 -1
  33. package/package.json +6 -6
  34. package/server/constants/inventory.ts +9 -1
  35. package/server/service/index.ts +9 -0
  36. package/server/service/inventory/inventory-query.ts +53 -14
  37. package/server/service/inventory/inventory-types.ts +9 -0
  38. package/server/service/inventory/inventory.ts +17 -0
  39. package/server/service/inventory-change/inventory-change-mutation.ts +177 -6
  40. package/server/service/inventory-change/inventory-change-query.ts +1 -0
  41. package/server/service/inventory-change/inventory-change.ts +5 -0
  42. package/server/service/inventory-item/inventory-item-query.ts +98 -3
  43. package/server/service/inventory-item/inventory-item.ts +6 -0
  44. package/server/service/inventory-item-change/index.ts +6 -0
  45. package/server/service/inventory-item-change/inventory-item-change-mutation.ts +116 -0
  46. package/server/service/inventory-item-change/inventory-item-change-query.ts +43 -0
  47. package/server/service/inventory-item-change/inventory-item-change-type.ts +68 -0
  48. package/server/service/inventory-item-change/inventory-item-change.ts +92 -0
  49. package/server/utils/inventory-util.ts +21 -43
@@ -96,4 +96,10 @@ export class InventoryItem {
96
96
 
97
97
  @RelationId((inventoryItem: InventoryItem) => inventoryItem.creator)
98
98
  updaterId?: string
99
+
100
+ @Field({ nullable: true })
101
+ type?: string
102
+
103
+ @Field({ nullable: true })
104
+ transactionType?: string
99
105
  }
@@ -0,0 +1,6 @@
1
+ import { InventoryItemChange } from './inventory-item-change'
2
+ import { InventoryItemChangeQuery } from './inventory-item-change-query'
3
+ import { InventoryItemChangeMutation } from './inventory-item-change-mutation'
4
+
5
+ export const entities = [InventoryItemChange]
6
+ export const resolvers = [InventoryItemChangeQuery, InventoryItemChangeMutation]
@@ -0,0 +1,116 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+
4
+ import { InventoryNoGenerator } from '../../utils'
5
+ import { InventoryItemChange } from './inventory-item-change'
6
+ import { InventoryItemChangePatch, NewInventoryItemChange } from './inventory-item-change-type'
7
+
8
+ @Resolver(InventoryItemChange)
9
+ export class InventoryItemChangeMutation {
10
+ @Directive('@transaction')
11
+ @Mutation(returns => InventoryItemChange, { description: 'To create new InventoryItemChange' })
12
+ async createInventoryItemChange(
13
+ @Arg('inventoryItemChange') inventoryItemChange: NewInventoryItemChange,
14
+ @Ctx() context: any
15
+ ): Promise<InventoryItemChange> {
16
+ const { domain, user, tx } = context.state
17
+
18
+ return await tx.getRepository(InventoryItemChange).save({
19
+ ...inventoryItemChange,
20
+ name: InventoryNoGenerator.inventoryName(),
21
+ status: 'PENDING_SUBMISSION',
22
+ domain,
23
+ creator: user,
24
+ updater: user
25
+ })
26
+ }
27
+
28
+ @Directive('@transaction')
29
+ @Mutation(returns => InventoryItemChange, { description: 'To modify InventoryItemChange information' })
30
+ async updateInventoryItemChange(
31
+ @Arg('id') id: string,
32
+ @Arg('patch') patch: InventoryItemChangePatch,
33
+ @Ctx() context: any
34
+ ): Promise<InventoryItemChange> {
35
+ const { domain, user, tx } = context.state
36
+
37
+ const repository = tx.getRepository(InventoryItemChange)
38
+ const inventoryItemChange = await repository.findOne({
39
+ where: { domain, id }
40
+ })
41
+
42
+ return await repository.save({
43
+ ...inventoryItemChange,
44
+ ...patch,
45
+ updater: user
46
+ })
47
+ }
48
+
49
+ @Directive('@transaction')
50
+ @Mutation(returns => [InventoryItemChange], { description: "To modify multiple InventoryItemChanges' information" })
51
+ async updateMultipleInventoryItemChange(
52
+ @Arg('patches', type => [InventoryItemChangePatch]) patches: InventoryItemChangePatch[],
53
+ @Ctx() context: any
54
+ ): Promise<InventoryItemChange[]> {
55
+ const { domain, user, tx } = context.state
56
+
57
+ let results = []
58
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
59
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
60
+ const inventoryItemChangeRepo = tx.getRepository(InventoryItemChange)
61
+
62
+ if (_createRecords.length > 0) {
63
+ for (let i = 0; i < _createRecords.length; i++) {
64
+ const newRecord = _createRecords[i]
65
+
66
+ const result = await inventoryItemChangeRepo.save({
67
+ ...newRecord,
68
+ domain,
69
+ creator: user,
70
+ updater: user
71
+ })
72
+
73
+ results.push({ ...result, cuFlag: '+' })
74
+ }
75
+ }
76
+
77
+ if (_updateRecords.length > 0) {
78
+ for (let i = 0; i < _updateRecords.length; i++) {
79
+ const newRecord = _updateRecords[i]
80
+ const inventoryItemChange = await inventoryItemChangeRepo.findOne(newRecord.id)
81
+
82
+ const result = await inventoryItemChangeRepo.save({
83
+ ...inventoryItemChange,
84
+ ...newRecord,
85
+ updater: user
86
+ })
87
+
88
+ results.push({ ...result, cuFlag: 'M' })
89
+ }
90
+ }
91
+
92
+ return results
93
+ }
94
+
95
+ @Directive('@transaction')
96
+ @Mutation(returns => Boolean, { description: 'To delete InventoryItemChange' })
97
+ async deleteInventoryItemChange(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
98
+ const { domain, tx } = context.state
99
+
100
+ await tx.getRepository(InventoryItemChange).delete({ domain, id })
101
+ return true
102
+ }
103
+
104
+ @Directive('@transaction')
105
+ @Mutation(returns => Boolean, { description: 'To delete multiple inventoryItemChanges' })
106
+ async deleteInventoryItemChanges(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<boolean> {
107
+ const { domain, tx } = context.state
108
+
109
+ await tx.getRepository(InventoryItemChange).delete({
110
+ domain,
111
+ id: In(ids)
112
+ })
113
+
114
+ return true
115
+ }
116
+ }
@@ -0,0 +1,43 @@
1
+ import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
2
+ import { getRepository } from 'typeorm'
3
+ import { Domain, ListParam, convertListParams } from '@things-factory/shell'
4
+ import { User } from '@things-factory/auth-base'
5
+ import { InventoryItemChange } from './inventory-item-change'
6
+ import { InventoryItemChangeList } from './inventory-item-change-type'
7
+
8
+ @Resolver(InventoryItemChange)
9
+ export class InventoryItemChangeQuery {
10
+ @Query(returns => InventoryItemChange, { description: 'To fetch a InventoryItemChange' })
11
+ async inventoryItemChange(@Arg('id') id: string, @Ctx() context: any): Promise<InventoryItemChange> {
12
+ const { domain } = context.state
13
+
14
+ return await getRepository(InventoryItemChange).findOne({
15
+ where: { domain, id }
16
+ })
17
+ }
18
+
19
+ @Query(returns => InventoryItemChangeList, { description: 'To fetch multiple InventoryItemChanges' })
20
+ async inventoryItemChanges(@Args() params: ListParam, @Ctx() context: any): Promise<InventoryItemChangeList> {
21
+ const { domain } = context.state
22
+
23
+ const convertedParams = convertListParams(params, domain.id)
24
+ const [items, total] = await getRepository(InventoryItemChange).findAndCount(convertedParams)
25
+
26
+ return { items, total }
27
+ }
28
+
29
+ @FieldResolver(type => Domain)
30
+ async domain(@Root() inventoryItemChange: InventoryItemChange): Promise<Domain> {
31
+ return await getRepository(Domain).findOne(inventoryItemChange.domainId)
32
+ }
33
+
34
+ @FieldResolver(type => User)
35
+ async updater(@Root() inventoryItemChange: InventoryItemChange): Promise<User> {
36
+ return await getRepository(User).findOne(inventoryItemChange.updaterId)
37
+ }
38
+
39
+ @FieldResolver(type => User)
40
+ async creator(@Root() inventoryItemChange: InventoryItemChange): Promise<User> {
41
+ return await getRepository(User).findOne(inventoryItemChange.creatorId)
42
+ }
43
+ }
@@ -0,0 +1,68 @@
1
+ import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
2
+
3
+ import { ObjectRef } from '@things-factory/shell'
4
+
5
+ import { InventoryItemChange } from './inventory-item-change'
6
+
7
+ @InputType()
8
+ export class NewInventoryItemChange {
9
+ @Field({ nullable: true })
10
+ name: string
11
+
12
+ @Field({ nullable: true })
13
+ serialNumber?: string
14
+
15
+ @Field({ nullable: true })
16
+ type?: string
17
+
18
+ @Field({ nullable: true })
19
+ status?: string
20
+
21
+ @Field(type => ObjectRef, { nullable: true })
22
+ inventory?: ObjectRef
23
+
24
+ @Field(type => ObjectRef, { nullable: true })
25
+ inventoryItem?: ObjectRef
26
+
27
+ @Field(type => ObjectRef, { nullable: true })
28
+ inventoryChange?: ObjectRef
29
+ }
30
+
31
+ @InputType()
32
+ export class InventoryItemChangePatch {
33
+ @Field(type => ID, { nullable: true })
34
+ id?: string
35
+
36
+ @Field({ nullable: true })
37
+ name?: string
38
+
39
+ @Field({ nullable: true })
40
+ serialNumber?: string
41
+
42
+ @Field({ nullable: true })
43
+ type?: string
44
+
45
+ @Field({ nullable: true })
46
+ status?: string
47
+
48
+ @Field(type => ObjectRef, { nullable: true })
49
+ inventory?: ObjectRef
50
+
51
+ @Field(type => ObjectRef, { nullable: true })
52
+ inventoryItem?: ObjectRef
53
+
54
+ @Field(type => ObjectRef, { nullable: true })
55
+ inventoryChange?: ObjectRef
56
+
57
+ @Field({ nullable: true })
58
+ cuFlag: string
59
+ }
60
+
61
+ @ObjectType()
62
+ export class InventoryItemChangeList {
63
+ @Field(type => [InventoryItemChange])
64
+ items: InventoryItemChange[]
65
+
66
+ @Field(type => Int)
67
+ total: number
68
+ }
@@ -0,0 +1,92 @@
1
+ import { Field, ID, ObjectType } from 'type-graphql'
2
+ import {
3
+ Column,
4
+ CreateDateColumn,
5
+ Entity,
6
+ Index,
7
+ ManyToOne,
8
+ PrimaryGeneratedColumn,
9
+ RelationId,
10
+ UpdateDateColumn
11
+ } from 'typeorm'
12
+
13
+ import { User } from '@things-factory/auth-base'
14
+ import { Domain } from '@things-factory/shell'
15
+
16
+ import { InventoryChange } from '../inventory-change/inventory-change'
17
+ import { InventoryItem } from '../inventory-item/inventory-item'
18
+ import { Inventory } from '../inventory/inventory'
19
+
20
+ @Entity()
21
+ @Index(
22
+ 'ix_inventory_item_change_0',
23
+ (inventoryItemChange: InventoryItemChange) => [inventoryItemChange.domain, inventoryItemChange.name],
24
+ { unique: true }
25
+ )
26
+ @ObjectType({ description: 'Entity for InventoryItemChange' })
27
+ export class InventoryItemChange {
28
+ @PrimaryGeneratedColumn('uuid')
29
+ @Field(type => ID)
30
+ readonly id: string
31
+
32
+ @ManyToOne(type => Domain)
33
+ @Field({ nullable: true })
34
+ domain?: Domain
35
+
36
+ @RelationId((inventoryItemChange: InventoryItemChange) => inventoryItemChange.domain)
37
+ domainId?: string
38
+
39
+ @ManyToOne(type => InventoryItem, { nullable: true })
40
+ @Field(type => InventoryItem, { nullable: true })
41
+ inventoryItem: InventoryItem
42
+
43
+ @ManyToOne(type => Inventory, { nullable: true })
44
+ @Field(type => Inventory, { nullable: true })
45
+ inventory: Inventory
46
+
47
+ @ManyToOne(type => InventoryChange, { nullable: true })
48
+ @Field(type => InventoryChange, { nullable: true })
49
+ inventoryChange: InventoryChange
50
+
51
+ @Column()
52
+ @Field()
53
+ name: string
54
+
55
+ @Column({ nullable: true })
56
+ @Field({ nullable: true })
57
+ serialNumber?: string
58
+
59
+ @Column({ nullable: true })
60
+ @Field({ nullable: true })
61
+ type?: string
62
+
63
+ @Column({ nullable: true })
64
+ @Field({ nullable: true })
65
+ status?: string
66
+
67
+ @CreateDateColumn()
68
+ @Field({ nullable: true })
69
+ createdAt?: Date
70
+
71
+ @UpdateDateColumn()
72
+ @Field({ nullable: true })
73
+ updatedAt?: Date
74
+
75
+ @ManyToOne(type => User, {
76
+ nullable: true
77
+ })
78
+ @Field({ nullable: true })
79
+ creator?: User
80
+
81
+ @RelationId((inventoryItemChange: InventoryItemChange) => inventoryItemChange.creator)
82
+ creatorId?: string
83
+
84
+ @ManyToOne(type => User, {
85
+ nullable: true
86
+ })
87
+ @Field({ nullable: true })
88
+ updater?: User
89
+
90
+ @RelationId((inventoryItemChange: InventoryItemChange) => inventoryItemChange.creator)
91
+ updaterId?: string
92
+ }
@@ -383,49 +383,17 @@ export async function getInventoriesByStrategy(
383
383
  bizplaceId: string,
384
384
  worksheetId: string,
385
385
  orderProducts: any[],
386
- pickingStrategy: string,
387
386
  locationSortingRules: any[],
388
387
  trxMgr: EntityManager
389
388
  ): Promise<Inventory[]> {
390
389
  let orderProductsJSON: string = JSON.stringify(orderProducts)
391
- let orderBy: string = 'ORDER BY op."productId"'
392
-
393
- let locationSortings: string[] = (locationSortingRules || []).map((rule: { name: string; descOrder: boolean }) => {
394
- return `, l.${rule.name} ${rule.descOrder ? 'DESC' : ''}`
395
- })
396
-
397
- switch (pickingStrategy.toUpperCase()) {
398
- case 'FIFO':
399
- orderBy += ', i.created_at'
400
- if (locationSortingRules?.length) {
401
- orderBy += locationSortings.join('')
402
- }
403
- break
404
-
405
- case 'LIFO':
406
- orderBy += ', i.created_at DESC'
407
- if (locationSortingRules?.length) {
408
- orderBy += locationSortings.join('')
409
- }
410
- break
411
-
412
- case 'FEFO':
413
- orderBy += ', i.expiration_date'
414
- if (locationSortingRules?.length) {
415
- orderBy += locationSortings.join('')
416
- }
417
- break
418
-
419
- case 'LOCATION':
420
- if (locationSortingRules?.length) {
421
- orderBy += locationSortings.join('')
422
- } else orderBy += ', l.name DESC'
423
- break
390
+ let locationSorting: string = (locationSortingRules || [])
391
+ .map((rule: { name: string; descOrder: boolean }) => {
392
+ return `l.${rule.name}${rule.descOrder ? 'DESC' : ''}`
393
+ })
394
+ .join(', ')
424
395
 
425
- default:
426
- orderBy += ', i.created_at'
427
- break
428
- }
396
+ if (locationSorting === '') locationSorting = 'l.name'
429
397
 
430
398
  await trxMgr.query(
431
399
  `
@@ -435,7 +403,8 @@ export async function getInventoriesByStrategy(
435
403
  "packingType" VARCHAR(50),
436
404
  "packingSize" INT,
437
405
  "uom" VARCHAR(10),
438
- "releaseQty" INT
406
+ "releaseQty" INT,
407
+ "pickingStrategy" VARCHAR(25)
439
408
  );
440
409
  `
441
410
  )
@@ -443,7 +412,7 @@ export async function getInventoriesByStrategy(
443
412
  await trxMgr.query(
444
413
  `
445
414
  INSERT INTO temp_op2
446
- SELECT "productId", "batchId", "packingType", "packingSize", "uom", "releaseQty"
415
+ SELECT "productId", "batchId", "packingType", "packingSize", "uom", "releaseQty", "pickingStrategy"
447
416
  FROM JSON_POPULATE_RECORDSET(NULL::temp_op2, $1) js
448
417
  `,
449
418
  [orderProductsJSON]
@@ -456,7 +425,7 @@ export async function getInventoriesByStrategy(
456
425
  FROM order_inventories oi
457
426
  WHERE oi.status IN ('PENDING','PENDING_RECEIVE','PENDING_WORKSHEET','PENDING_SPLIT')
458
427
  AND oi.bizplace_id = $1
459
- AND oi.inventory_id NOTNULL
428
+ AND oi.inventory_id NOTNULL
460
429
  AND oi.ref_worksheet_id != $2
461
430
  GROUP BY oi.inventory_id
462
431
  )
@@ -475,7 +444,16 @@ export async function getInventoriesByStrategy(
475
444
  i.uom_value - COALESCE(i.locked_uom_value,0) - COALESCE(foo.total_release_uom_value,0) AS "remainUomValue",
476
445
  op."packingType",
477
446
  op."packingSize",
478
- op."uom"
447
+ op."uom",
448
+ ROW_NUMBER() OVER (
449
+ PARTITION BY op."productId", op."batchId", op."packingType", op."packingSize", op."uom"
450
+ ORDER BY
451
+ CASE WHEN op."pickingStrategy" = 'FIFO' THEN i.created_at END,
452
+ CASE WHEN op."pickingStrategy" = 'FEFO' THEN i.expiration_date END,
453
+ CASE WHEN op."pickingStrategy" = 'LIFO' THEN i.created_at END DESC,
454
+ CASE WHEN op."pickingStrategy" = 'FMFO' THEN i.manufacture_date END,
455
+ ${locationSorting}
456
+ ) AS rn
479
457
  FROM inventories i
480
458
  INNER JOIN locations l ON i.location_id = l.id
481
459
  AND l.TYPE NOT IN ($1, $2)
@@ -487,7 +465,7 @@ export async function getInventoriesByStrategy(
487
465
  WHERE i.domain_id = $3
488
466
  AND i.bizplace_id = $4
489
467
  AND i.status = $5
490
- ${orderBy}
468
+ ORDER BY op."productId", rn
491
469
  `,
492
470
  [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE, domainId, bizplaceId, INVENTORY_STATUS.STORED]
493
471
  )