@things-factory/warehouse-base 4.1.38 → 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 +8 -8
  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
@@ -1,7 +1,8 @@
1
- import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
- import { Brackets, getRepository, SelectQueryBuilder } from 'typeorm'
1
+ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { Brackets, EntityManager, getRepository, In, Not, SelectQueryBuilder } from 'typeorm'
3
3
 
4
4
  import { User } from '@things-factory/auth-base'
5
+ import { Product } from '@things-factory/product-base'
5
6
  import { convertListParams, Domain, ListParam } from '@things-factory/shell'
6
7
 
7
8
  import { INVENTORY_STATUS } from '../../constants'
@@ -25,11 +26,81 @@ export class InventoryItemQuery {
25
26
  const { domain } = context.state
26
27
 
27
28
  const convertedParams = convertListParams(params, domain.id)
28
- const [items, total] = await getRepository(InventoryItem).findAndCount(convertedParams)
29
+ const [items, total] = await getRepository(InventoryItem).findAndCount({
30
+ ...convertedParams,
31
+ relations: ['inventory', 'product']
32
+ })
29
33
 
30
34
  return { items, total }
31
35
  }
32
36
 
37
+ @Directive('@transaction')
38
+ @Query(returns => InventoryItemList, { description: 'To fetch multiple InventoryItems with InventoryItemChanges' })
39
+ async inventoryItemsWithChanges(@Args() params: ListParam, @Ctx() context: any): Promise<InventoryItemList> {
40
+ const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
41
+
42
+ const page = params?.pagination?.page
43
+ const limit = params?.pagination?.limit
44
+
45
+ let inventoryFilter = params.filters.find(filter => filter.name == 'inventoryId')
46
+
47
+ let items: any = []
48
+ let total: any = 0
49
+ if (inventoryFilter) {
50
+ await tx.query(
51
+ `
52
+ create temp table temp_inventory_items on commit drop as (
53
+ select * from (
54
+ select ii.id, ii.name, ii.serial_number, '' as "type", 'ORIGINAL' as "transaction_type", i2.id as inventory_id, i2.name as inventory_name, i2.pallet_id as pallet_id, i2.carton_id as carton_id, p2.id as product_id, p2.name as product_name, p2.sku as product_sku from inventory_items ii
55
+ inner join inventories i2 on i2.id = ii.inventory_id
56
+ inner join products p2 on p2.id = i2.product_id
57
+ where ii.domain_id = $1 and ii.inventory_id = $2 and ii.status = $3
58
+ ) src
59
+ )
60
+ `,
61
+ [domain.id, inventoryFilter.value, INVENTORY_STATUS.STORED]
62
+ )
63
+
64
+ const offsetQuery: string = params?.pagination ? `OFFSET ${(page - 1) * limit} LIMIT ${limit}` : ''
65
+
66
+ items = await tx.query(`
67
+ select * from temp_inventory_items ${offsetQuery}
68
+ `)
69
+
70
+ total = await tx.query(`
71
+ select count(*) from temp_inventory_items
72
+ `)
73
+
74
+ items = items.map(item => {
75
+ return {
76
+ id: item.id,
77
+ name: item.name,
78
+ serialNumber: item.serial_number,
79
+ type: item.type,
80
+ transactionType: item.transaction_type,
81
+ inventory: {
82
+ id: item.inventory_id,
83
+ name: item.inventory_name,
84
+ palletId: item.pallet_id,
85
+ cartonId: item.carton_id
86
+ },
87
+ product: {
88
+ id: item.product_id,
89
+ name: item.product_name,
90
+ sku: item.product_sku
91
+ }
92
+ }
93
+ })
94
+
95
+ total = total[0].count
96
+ }
97
+
98
+ return {
99
+ items,
100
+ total
101
+ }
102
+ }
103
+
33
104
  @Query(returns => InventoryItemList, { description: 'To fetch multiple InventoryItems by inventory' })
34
105
  async inventoryItemsByInventory(@Args() params: ListParam, @Ctx() context: any): Promise<InventoryItemList> {
35
106
  const { domain } = context.state
@@ -47,6 +118,7 @@ export class InventoryItemQuery {
47
118
  qb.leftJoinAndSelect('ivi.product', 'product').leftJoinAndSelect('ivi.inventory', 'inventory')
48
119
  qb.where('ivi.product_id=:productId', { productId: productIdFilter.value })
49
120
  qb.andWhere('inventory.status!=:inventoryStatus', { inventoryStatus: INVENTORY_STATUS.PARTIALLY_UNLOADED })
121
+ qb.andWhere('inventory.domain_id=:domainId', { domainId: domain.id })
50
122
 
51
123
  if (orderTypeFilter.value == 'inbound') {
52
124
  qb.andWhere('ivi.inbound_order_id=:orderId', { orderId: orderIdFilter.value })
@@ -116,3 +188,26 @@ export class InventoryItemQuery {
116
188
  return await getRepository(User).findOne(inventoryItem.creatorId)
117
189
  }
118
190
  }
191
+
192
+ export async function checkExistingSerialNumber(
193
+ serialNumber: string,
194
+ product: Product,
195
+ context: any,
196
+ inventory?: Inventory,
197
+ tx?: EntityManager
198
+ ) {
199
+ const { domain }: { domain: Domain } = context.state
200
+
201
+ let countCondition: any = {
202
+ domain,
203
+ product,
204
+ serialNumber,
205
+ status: Not(In([INVENTORY_STATUS.DELETED, INVENTORY_STATUS.TERMINATED]))
206
+ }
207
+
208
+ if (inventory) countCondition = { ...countCondition, inventory }
209
+
210
+ const duplicatedSerialNumberCnt: number = await tx.getRepository(InventoryItem).count(countCondition)
211
+
212
+ if (duplicatedSerialNumberCnt) return true
213
+ }
@@ -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
  )