@things-factory/worksheet-base 4.3.59 → 4.3.62

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 (55) hide show
  1. package/dist-server/controllers/outbound/picking-worksheet-controller.js +86 -88
  2. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/outbound/returning-worksheet-controller.js +16 -0
  4. package/dist-server/controllers/outbound/returning-worksheet-controller.js.map +1 -1
  5. package/dist-server/entities/worksheet-detail.js +2 -1
  6. package/dist-server/entities/worksheet-detail.js.map +1 -1
  7. package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js +1 -34
  8. package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js.map +1 -1
  9. package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js +70 -0
  10. package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js.map +1 -0
  11. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.js +4 -4
  12. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.js.map +1 -1
  13. package/dist-server/graphql/resolvers/worksheet/index.js +2 -1
  14. package/dist-server/graphql/resolvers/worksheet/index.js.map +1 -1
  15. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +18 -8
  16. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
  17. package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js +6 -2
  18. package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js.map +1 -1
  19. package/dist-server/graphql/resolvers/worksheet/picking/scan-product-batch-picking.js +4 -4
  20. package/dist-server/graphql/resolvers/worksheet/picking/scan-product-batch-picking.js.map +1 -1
  21. package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js +4 -4
  22. package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js.map +1 -1
  23. package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +1 -0
  24. package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
  25. package/dist-server/graphql/resolvers/worksheet/worksheet.js +11 -3
  26. package/dist-server/graphql/resolvers/worksheet/worksheet.js.map +1 -1
  27. package/dist-server/graphql/resolvers/worksheet-detail/index.js +2 -1
  28. package/dist-server/graphql/resolvers/worksheet-detail/index.js.map +1 -1
  29. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js +81 -0
  30. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js.map +1 -0
  31. package/dist-server/graphql/types/worksheet/batch-pick-worksheet-info.js +12 -0
  32. package/dist-server/graphql/types/worksheet/batch-pick-worksheet-info.js.map +1 -0
  33. package/dist-server/graphql/types/worksheet/index.js +9 -4
  34. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  35. package/dist-server/graphql/types/worksheet-detail/index.js +10 -0
  36. package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
  37. package/package.json +12 -12
  38. package/server/controllers/outbound/picking-worksheet-controller.ts +111 -109
  39. package/server/controllers/outbound/returning-worksheet-controller.ts +23 -0
  40. package/server/entities/worksheet-detail.ts +4 -0
  41. package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +2 -42
  42. package/server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.ts +80 -0
  43. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.ts +7 -8
  44. package/server/graphql/resolvers/worksheet/index.ts +2 -0
  45. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +32 -11
  46. package/server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.ts +4 -0
  47. package/server/graphql/resolvers/worksheet/picking/scan-product-batch-picking.ts +7 -4
  48. package/server/graphql/resolvers/worksheet/picking/scan-product-picking.ts +7 -4
  49. package/server/graphql/resolvers/worksheet/picking-worksheet.ts +5 -4
  50. package/server/graphql/resolvers/worksheet/worksheet.ts +16 -3
  51. package/server/graphql/resolvers/worksheet-detail/index.ts +3 -1
  52. package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +164 -0
  53. package/server/graphql/types/worksheet/batch-pick-worksheet-info.ts +9 -0
  54. package/server/graphql/types/worksheet/index.ts +10 -5
  55. package/server/graphql/types/worksheet-detail/index.ts +10 -0
@@ -1,54 +1,17 @@
1
1
  import { EntityManager, SelectQueryBuilder } from 'typeorm'
2
2
 
3
- import {
4
- ORDER_STATUS, ORDER_INVENTORY_STATUS,
5
- OrderInventory as OrderInventoryEntity,
6
- ReleaseGood as ReleaseGoodEntity
7
- } from '@things-factory/sales-base'
3
+ import { OrderInventory as OrderInventoryEntity, ReleaseGood as ReleaseGoodEntity } from '@things-factory/sales-base'
8
4
  import { Domain } from '@things-factory/shell'
9
- import { Location } from '@things-factory/warehouse-base'
10
5
 
11
- import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
12
6
  import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
13
7
 
14
8
  export const findReleaseOrdersByTaskNoResolver = {
15
9
  async findReleaseOrdersByTaskNo(_: any, { taskNo }, context: any) {
16
10
  const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
17
11
  let task = await tx.getRepository(WorksheetEntity).findOne({
18
- where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
12
+ where: { taskNo }
19
13
  })
20
14
 
21
- // Find Task based on Bin
22
- if (!task) {
23
- const binLocation: Location = await tx.getRepository(Location).findOne({
24
- where: { domain, name: taskNo }
25
- })
26
-
27
- const qb: SelectQueryBuilder<OrderInventoryEntity> = tx.getRepository(OrderInventoryEntity).createQueryBuilder('orderInventory')
28
-
29
- qb.innerJoinAndSelect('orderInventory.releaseGood', 'releaseGood')
30
- .innerJoinAndSelect('worksheets', 'ws', `orderInventory.ref_worksheet_id = ws.id AND ws.type = 'BATCH_PICKING'`)
31
- .innerJoinAndSelect('worksheets', 'ws2', `ws2.task_no = ws.task_no AND ws2.type = 'SORTING'`)
32
- .innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
33
- .innerJoinAndSelect('bizplace.domain', 'domain')
34
- .where('orderInventory.domain_id = :domainId', { domainId: domain.id })
35
- .andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
36
- orderInventoryStatus: [ORDER_INVENTORY_STATUS.SORTING]
37
- })
38
- .andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
39
- .andWhere('releaseGood.status = :status', { status: ORDER_STATUS.SORTING })
40
-
41
- const orderInventoryByBin = await qb.getRawOne()
42
- if (orderInventoryByBin?.releaseGood_id) {
43
- taskNo = orderInventoryByBin.ws_task_no
44
- task = await tx.getRepository(WorksheetEntity).findOne({
45
- where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
46
- })
47
- } else {
48
- throw new Error(`Bin do not have any batch picking order.`)
49
- }
50
- }
51
-
52
15
  if (!task) throw new Error('Unable to find task no.')
53
16
 
54
17
  const qb: SelectQueryBuilder<WorksheetEntity> = tx
@@ -63,9 +26,6 @@ export const findReleaseOrdersByTaskNoResolver = {
63
26
  .innerJoin(ReleaseGoodEntity, 'rg', 'rg.id = oi.release_good_id')
64
27
  .where('domain.id = :domainId', { domainId: domain.id })
65
28
  .andWhere('ws.taskNo = :taskNo', { taskNo: taskNo })
66
- .andWhere('ws.type = :worksheetType', { worksheetType: WORKSHEET_TYPE.SORTING })
67
- .andWhere('ws.status = :worksheetStatus', { worksheetStatus: WORKSHEET_STATUS.EXECUTING })
68
- .andWhere('rg.status = :roStatus', { roStatus: ORDER_STATUS.SORTING })
69
29
  .groupBy('rg.id')
70
30
  .addGroupBy('rg.name')
71
31
  .addGroupBy('rg.status')
@@ -0,0 +1,80 @@
1
+ import { EntityManager, SelectQueryBuilder } from 'typeorm'
2
+
3
+ import {
4
+ ORDER_INVENTORY_STATUS,
5
+ ORDER_STATUS,
6
+ OrderInventory as OrderInventoryEntity,
7
+ ReleaseGood as ReleaseGoodEntity
8
+ } from '@things-factory/sales-base'
9
+ import { Domain } from '@things-factory/shell'
10
+ import { Location } from '@things-factory/warehouse-base'
11
+
12
+ import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
13
+ import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
14
+
15
+ export const findSortingReleaseOrdersByTaskNoResolver = {
16
+ async findSortingReleaseOrdersByTaskNo(_: any, { taskNo }, context: any) {
17
+ const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
18
+ let task = await tx.getRepository(WorksheetEntity).findOne({
19
+ where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
20
+ })
21
+
22
+ // Find Task based on Bin
23
+ if (!task) {
24
+ const binLocation: Location = await tx.getRepository(Location).findOne({
25
+ where: { domain, name: taskNo }
26
+ })
27
+
28
+ const qb: SelectQueryBuilder<OrderInventoryEntity> = tx
29
+ .getRepository(OrderInventoryEntity)
30
+ .createQueryBuilder('orderInventory')
31
+
32
+ qb.innerJoinAndSelect('orderInventory.releaseGood', 'releaseGood')
33
+ .innerJoinAndSelect('worksheets', 'ws', `orderInventory.ref_worksheet_id = ws.id AND ws.type = 'BATCH_PICKING'`)
34
+ .innerJoinAndSelect('worksheets', 'ws2', `ws2.task_no = ws.task_no AND ws2.type = 'SORTING'`)
35
+ .innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
36
+ .innerJoinAndSelect('bizplace.domain', 'domain')
37
+ .where('orderInventory.domain_id = :domainId', { domainId: domain.id })
38
+ .andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
39
+ orderInventoryStatus: [ORDER_INVENTORY_STATUS.SORTING]
40
+ })
41
+ .andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
42
+ .andWhere('releaseGood.status = :status', { status: ORDER_STATUS.SORTING })
43
+
44
+ const orderInventoryByBin = await qb.getRawOne()
45
+ if (orderInventoryByBin?.releaseGood_id) {
46
+ taskNo = orderInventoryByBin.ws_task_no
47
+ task = await tx.getRepository(WorksheetEntity).findOne({
48
+ where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
49
+ })
50
+ } else {
51
+ throw new Error(`Bin do not have any batch picking order.`)
52
+ }
53
+ }
54
+
55
+ if (!task) throw new Error('Unable to find task no.')
56
+
57
+ const qb: SelectQueryBuilder<WorksheetEntity> = tx
58
+ .getRepository(WorksheetEntity)
59
+ .createQueryBuilder('ws')
60
+ .select('rg.id as id')
61
+ .addSelect('rg.name as name')
62
+ .addSelect('rg.status as status')
63
+ .innerJoin(Domain, 'domain', 'ws.domain_id = domain.id')
64
+ .innerJoin(WorksheetDetailEntity, 'wsd', 'ws.id = wsd.worksheet_id')
65
+ .innerJoin(OrderInventoryEntity, 'oi', 'oi.id = wsd.target_inventory_id')
66
+ .innerJoin(ReleaseGoodEntity, 'rg', 'rg.id = oi.release_good_id')
67
+ .where('domain.id = :domainId', { domainId: domain.id })
68
+ .andWhere('ws.taskNo = :taskNo', { taskNo: taskNo })
69
+ .andWhere('ws.type = :worksheetType', { worksheetType: WORKSHEET_TYPE.SORTING })
70
+ .andWhere('ws.status = :worksheetStatus', { worksheetStatus: WORKSHEET_STATUS.EXECUTING })
71
+ .andWhere('rg.status = :roStatus', { roStatus: ORDER_STATUS.SORTING })
72
+ .groupBy('rg.id')
73
+ .addGroupBy('rg.name')
74
+ .addGroupBy('rg.status')
75
+ .orderBy('rg.createdAt', 'ASC')
76
+
77
+ const releaseGoods: ReleaseGoodEntity[] = await qb.getRawMany()
78
+ return { releaseGoods, taskNo }
79
+ }
80
+ }
@@ -1,14 +1,14 @@
1
1
  import { User } from '@things-factory/auth-base'
2
- import { OrderInventory } from '@things-factory/sales-base'
3
- import { Domain } from '@things-factory/shell'
2
+ import { OrderInventory, GenerateBatchPickInfo } from '@things-factory/sales-base'
3
+ import { Domain, ObjectRef } from '@things-factory/shell'
4
4
  import { EntityManager } from 'typeorm'
5
5
  import { PickingWorksheetController } from '../../../../controllers/'
6
6
  import { Worksheet, WorksheetDetail } from '../../../../entities'
7
7
 
8
8
  export const generateBatchPickingWorksheetResolver = {
9
- async generateBatchPickingWorksheet(_: any, { releaseGoodNos, partnerBizplaceId }, context: any) {
9
+ async generateBatchPickingWorksheet(_: any, { releaseGoodWithBiz }, context: any) {
10
10
  const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
11
- return await generateBatchPickingWorksheet(tx, domain, user, releaseGoodNos, partnerBizplaceId)
11
+ return await generateBatchPickingWorksheet(tx, domain, user, releaseGoodWithBiz)
12
12
  }
13
13
  }
14
14
 
@@ -16,9 +16,8 @@ export async function generateBatchPickingWorksheet(
16
16
  tx: EntityManager,
17
17
  domain: Domain,
18
18
  user: User,
19
- releaseGoodNos: [string],
20
- partnerBizplaceId: string
21
- ): Promise<Worksheet> {
19
+ releaseGoodWithBiz: [[GenerateBatchPickInfo]]
20
+ ): Promise<Worksheet[]> {
22
21
  const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
23
- return await worksheetController.generateBatchPickingWorksheet(releaseGoodNos, partnerBizplaceId)
22
+ return await worksheetController.generateBatchPickingWorksheet(releaseGoodWithBiz)
24
23
  }
@@ -11,6 +11,7 @@ import { deliveryOrderByWorksheetResolver } from './delivery-order-by-worksheet'
11
11
  import { fetchDeliveryOrderROResolver } from './fetch-delivery-order-ro'
12
12
  import { fetchSellercraftAirwayBillResolver } from './fetch-sellercraft-airway-bill'
13
13
  import { findReleaseOrdersByTaskNoResolver } from './find-release-orders-by-task-no'
14
+ import { findSortingReleaseOrdersByTaskNoResolver } from './find-sorting-release-orders-by-task-no'
14
15
  import { Mutations as GenerateWorksheetMutations } from './generate-worksheet'
15
16
  import { havingVasResolver } from './having-vas'
16
17
  import { Mutations as InspectMutations } from './inspecting'
@@ -99,6 +100,7 @@ export const Query = {
99
100
  ...myPickingAssignmentStatusResolver,
100
101
  ...recommendPutawayLocationResolver,
101
102
  ...sortingWorksheetResolver,
103
+ ...findSortingReleaseOrdersByTaskNoResolver,
102
104
  ...findReleaseOrdersByTaskNoResolver,
103
105
  ...fetchDeliveryOrderROResolver
104
106
  }
@@ -11,8 +11,11 @@ export const inventoriesByPalletResolver = {
11
11
  const { domain, user }: { domain: Domain; user: User } = context.state
12
12
  const params = { filters, pagination }
13
13
  let permittedBizplaceIds: string[] = await getPermittedBizplaceIds(domain, user)
14
-
15
14
  const productFilters = params.filters.filter(x => x.name == 'productName')
15
+ const recallFilters = params.filters.find(x => x.name === 'recall')
16
+ const skipLockCheckFilters = params.filters.find(x => x.name === 'skipLockCheck')
17
+ let skipLockCheck: Boolean =
18
+ skipLockCheckFilters && skipLockCheckFilters?.value ? skipLockCheckFilters?.value : false
16
19
  const productFilterColumns = ['sku', 'brandSku', 'name', 'description', 'brand', 'subBrand']
17
20
  params.filters = params.filters.filter(x => x.name != 'productName')
18
21
 
@@ -28,6 +31,12 @@ export const inventoriesByPalletResolver = {
28
31
  params.filters.find(filter => filter.name === 'bizplace').relation = true
29
32
  }
30
33
 
34
+ const locationFilters = params.filters.find(x => x.name == 'location')
35
+
36
+ const removeLocationIndex = params.filters.findIndex(x => x.name == 'location')
37
+
38
+ params.filters.splice(removeLocationIndex, 1)
39
+
31
40
  const qb: SelectQueryBuilder<Inventory> = getRepository(Inventory).createQueryBuilder('iv')
32
41
  buildQuery(qb, params, context)
33
42
 
@@ -39,9 +48,11 @@ export const inventoriesByPalletResolver = {
39
48
  .leftJoinAndSelect('iv.creator', 'creator')
40
49
  .leftJoinAndSelect('iv.updater', 'updater')
41
50
  .andWhere('iv.qty > 0')
42
- .andWhere('CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END >= 0')
43
- .andWhere('iv.qty - CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END > 0')
44
- .andWhere(`location.type NOT IN ('${LOCATION_TYPE.QUARANTINE}', '${LOCATION_TYPE.RESERVE}')`)
51
+ .andWhere(
52
+ `location.type ${recallFilters?.value === true ? '' : 'NOT'} IN ('${LOCATION_TYPE.QUARANTINE}', '${
53
+ LOCATION_TYPE.RESERVE
54
+ }')`
55
+ )
45
56
  .andWhere(
46
57
  `(iv.batch_id, product.name, iv.packing_type, product.brand) NOT IN (
47
58
  SELECT
@@ -60,14 +71,24 @@ export const inventoriesByPalletResolver = {
60
71
  { permittedBizplaceIds, domainId: domain.id }
61
72
  )
62
73
 
74
+ if (!skipLockCheck) {
75
+ qb.andWhere('CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END >= 0')
76
+ qb.andWhere('iv.qty - CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END > 0')
77
+ }
78
+
79
+ if (locationFilters) {
80
+ qb.andWhere(`location.name ilike '${locationFilters.value}'`)
81
+ }
82
+
63
83
  if (sortings?.length !== 0) {
64
- const arrChildSortData = ['bizplace', 'product', 'location', 'warehouse', 'zone']
84
+ const arrChildSortData = ['productName', 'productSKU']
85
+
86
+ const remapChildSortData = ['name', 'sku']
65
87
  const sort = (sortings || []).reduce(
66
- (acc, sort) => ({
88
+ (acc, sort, idx) => ({
67
89
  ...acc,
68
- [arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'iv.' + sort.name]: sort.desc
69
- ? 'DESC'
70
- : 'ASC'
90
+ [arrChildSortData.indexOf(sort.name) >= 0 ? 'product' + '.' + remapChildSortData[idx] : 'iv.' + sort.name]:
91
+ sort.desc ? 'DESC' : 'ASC'
71
92
  }),
72
93
  {}
73
94
  )
@@ -101,7 +122,6 @@ export const inventoriesByPalletResolver = {
101
122
  })
102
123
  )
103
124
  }
104
-
105
125
  let [items, total] = await qb.getManyAndCount()
106
126
 
107
127
  items = await Promise.all(
@@ -116,7 +136,8 @@ export const inventoriesByPalletResolver = {
116
136
  // product: item.product,
117
137
  productName: item.product.name,
118
138
  productSKU: item.product.sku,
119
- productBrand: item.product.brand
139
+ productBrand: item.product.brand,
140
+ productId: item.product.id
120
141
  }
121
142
  })
122
143
  )
@@ -28,6 +28,7 @@ export const fetchAndAssignPickingTaskResolver = {
28
28
  .addSelect('ws.name')
29
29
  .addSelect('ws.status')
30
30
  .addSelect('ws.release_good_id')
31
+ .innerJoin('ws.releaseGood', 'rg')
31
32
  .where(
32
33
  '(ws.domain_id = :domain_id AND ws.type = :type AND ws.assignee_id =:assignee AND (ws.status = :status1 OR ws.status = :status2))',
33
34
  {
@@ -50,6 +51,7 @@ export const fetchAndAssignPickingTaskResolver = {
50
51
  .getQuery()
51
52
  return 'NOT EXISTS ' + subQuery
52
53
  })
54
+ .orderBy('"rg"."created_at"', 'ASC')
53
55
 
54
56
  worksheet = await worksheetQb.getRawOne()
55
57
 
@@ -61,6 +63,7 @@ export const fetchAndAssignPickingTaskResolver = {
61
63
  .addSelect('ws.name')
62
64
  .addSelect('ws.status')
63
65
  .addSelect('ws.release_good_id')
66
+ .innerJoin('ws.releaseGood', 'rg')
64
67
  .where(
65
68
  '(ws.domain_id = :domain_id AND ws.type = :type AND ws.assignee_id IS NULL AND (ws.status = :status1 OR ws.status = :status2))',
66
69
  {
@@ -82,6 +85,7 @@ export const fetchAndAssignPickingTaskResolver = {
82
85
  .getQuery()
83
86
  return 'NOT EXISTS ' + subQuery
84
87
  })
88
+ .orderBy('"rg"."created_at"', 'ASC')
85
89
 
86
90
  worksheet = await worksheetQb.getRawOne()
87
91
 
@@ -6,7 +6,7 @@ import { PickingWorksheetController } from '../../../../controllers'
6
6
  export const scanProductBatchPickingResolver = {
7
7
  async scanProductBatchPicking(
8
8
  _: any,
9
- { taskNo, worksheetType, cartonId, productBarcode, inventory, binLocationName },
9
+ { taskNo, worksheetType, cartonId, productBarcode, inventory, binLocationName, pickingQty },
10
10
  context: any
11
11
  ) {
12
12
  const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
@@ -19,7 +19,8 @@ export const scanProductBatchPickingResolver = {
19
19
  cartonId,
20
20
  productBarcode,
21
21
  inventory,
22
- binLocationName
22
+ binLocationName,
23
+ pickingQty
23
24
  )
24
25
  }
25
26
  }
@@ -33,7 +34,8 @@ export async function scanProductBatchPicking(
33
34
  cartonId: string,
34
35
  productBarcode: string,
35
36
  inventory: any,
36
- binLocationName?: string
37
+ binLocationName?: string,
38
+ pickingQty?: number
37
39
  ) {
38
40
  const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
39
41
  await worksheetController.scanProductBatchPicking(
@@ -42,6 +44,7 @@ export async function scanProductBatchPicking(
42
44
  cartonId,
43
45
  productBarcode,
44
46
  inventory,
45
- binLocationName
47
+ binLocationName,
48
+ pickingQty
46
49
  )
47
50
  }
@@ -6,7 +6,7 @@ import { PickingWorksheetController } from '../../../../controllers'
6
6
  export const scanProductPickingResolver = {
7
7
  async scanProductPicking(
8
8
  _: any,
9
- { worksheetDetailName, worksheetType, productBarcode, cartonId, binLocation, serialNumber, toteNo },
9
+ { worksheetDetailName, worksheetType, productBarcode, cartonId, binLocation, serialNumber, toteNo, pickingQty },
10
10
  context: any
11
11
  ) {
12
12
  const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
@@ -20,7 +20,8 @@ export const scanProductPickingResolver = {
20
20
  cartonId,
21
21
  binLocation,
22
22
  serialNumber,
23
- toteNo
23
+ toteNo,
24
+ pickingQty
24
25
  )
25
26
  }
26
27
  }
@@ -35,7 +36,8 @@ export async function scanProductPicking(
35
36
  cartonId: string,
36
37
  binLocation?: string,
37
38
  serialNumber?: string,
38
- toteNo?: string
39
+ toteNo?: string,
40
+ pickingQty?: number
39
41
  ) {
40
42
  const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
41
43
  await worksheetController.scanProductPicking(
@@ -45,6 +47,7 @@ export async function scanProductPicking(
45
47
  cartonId,
46
48
  binLocation,
47
49
  serialNumber,
48
- toteNo
50
+ toteNo,
51
+ pickingQty
49
52
  )
50
53
  }
@@ -100,6 +100,7 @@ export async function pickingWorksheet(
100
100
  refNo: releaseGood.refNo,
101
101
  refNo2: releaseGood.refNo2,
102
102
  refNo3: releaseGood.refNo3,
103
+ type: releaseGood.type,
103
104
  containerNo: shippingOrder?.containerNo,
104
105
  marketplaceStatus: releaseGood.marketplaceOrderStatus,
105
106
  shippingProvider: releaseGood.transporter,
@@ -113,10 +114,10 @@ export async function pickingWorksheet(
113
114
  const inventoryChangesCount: number = await tx.getRepository(InventoryChange).count({
114
115
  where: {
115
116
  inventory: inventory.id,
116
- status:"PENDING",
117
- transactionType:"MISSING"
117
+ status: "PENDING",
118
+ transactionType: "MISSING"
118
119
  },
119
- relations:['inventory','product']
120
+ relations: ['inventory', 'product']
120
121
  })
121
122
 
122
123
  return {
@@ -138,7 +139,7 @@ export async function pickingWorksheet(
138
139
  expirationDate: inventory?.expirationDate,
139
140
  location: inventory?.location,
140
141
  relatedOrderInv: targetInventory,
141
- hasMissingInventoryChanges:inventoryChangesCount > 0 ? true:false
142
+ hasMissingInventoryChanges: inventoryChangesCount > 0 ? true : false
142
143
  }
143
144
  })
144
145
  }
@@ -91,7 +91,7 @@ export const worksheetResolver = {
91
91
  }
92
92
 
93
93
  let pWorksheetPickingItemSorting = getRepository(Setting).findOne({
94
- where: { domain, category: 'location', name: 'rule-for-worksheet-release-goods-item' }
94
+ where: { domain, category: 'location', name: 'rule-for-picking-product' }
95
95
  })
96
96
 
97
97
  if (worksheet?.arrivalNotice?.id) {
@@ -172,10 +172,12 @@ export const worksheetResolver = {
172
172
  if (sortingSetting?.value) {
173
173
  let settingValue = JSON.parse(sortingSetting.value)
174
174
  for (const key in settingValue) {
175
- qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] ? 'ASC' : 'DESC')
175
+ qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] == 'ASC' ? 'ASC' : 'DESC')
176
176
  }
177
177
  }
178
178
 
179
+ qbOrderInventories.addOrderBy(`product.name`, 'ASC')
180
+
179
181
  let orderInventories: OrderInventory[] = await qbOrderInventories.getMany()
180
182
  worksheet.orderInventories = orderInventories
181
183
  }
@@ -204,10 +206,12 @@ export const worksheetResolver = {
204
206
  if (sortingSetting?.value) {
205
207
  let settingValue = JSON.parse(sortingSetting.value)
206
208
  for (const key in settingValue) {
207
- qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] ? 'ASC' : 'DESC')
209
+ qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] == 'ASC' ? 'ASC' : 'DESC')
208
210
  }
209
211
  }
210
212
 
213
+ qbOrderInventories.addOrderBy(`product.name`, 'ASC')
214
+
211
215
  let orderInventories: OrderInventory[] = await qbOrderInventories.getMany()
212
216
  worksheet.orderInventories = orderInventories
213
217
 
@@ -248,6 +252,15 @@ export const worksheetResolver = {
248
252
  })
249
253
  }
250
254
 
255
+ if (worksheet.orderInventories) {
256
+ worksheet.worksheetDetails.sort(function (a, b) {
257
+ return (
258
+ worksheet.orderInventories.map(oi => oi.id).indexOf(a.targetInventory.id) -
259
+ worksheet.orderInventories.map(oi => oi.id).indexOf(b.targetInventory.id)
260
+ )
261
+ })
262
+ }
263
+
251
264
  if (worksheet?.returnOrder?.id) {
252
265
  worksheet.orderInventories = await getRepository(OrderInventory).find({
253
266
  where: {
@@ -7,6 +7,7 @@ import { generateCartonIdResolver } from './generate-carton-id'
7
7
  import { generatePalletIdResolver } from './generate-pallet-id'
8
8
  import { generatePickingWorksheetDetailsResolver } from './generate-picking-worksheet-details'
9
9
  import { generateReleaseGoodWorksheetDetailsResolver } from './generate-release-good-worksheet-details'
10
+ import { regenerateReleaseGoodWorksheetDetailsResolver } from './regenerate-release-good-worksheet-details'
10
11
  import { updateWorksheetDetail } from './update-worksheet-detail'
11
12
  import { worksheetDetailResolver } from './worksheet-detail'
12
13
  import { worksheetDetailsResolver } from './worksheet-details'
@@ -28,5 +29,6 @@ export const Mutation = {
28
29
  ...generateBatchPickingWorksheetDetailsResolver,
29
30
  ...generateBatchPickingWorksheetDetailsByBulkResolver,
30
31
  ...generatePickingWorksheetDetailsResolver,
31
- ...generateReleaseGoodWorksheetDetailsResolver
32
+ ...generateReleaseGoodWorksheetDetailsResolver,
33
+ ...regenerateReleaseGoodWorksheetDetailsResolver
32
34
  }
@@ -0,0 +1,164 @@
1
+ import { EntityManager } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { Product } from '@things-factory/product-base'
5
+ import {
6
+ ORDER_INVENTORY_STATUS,
7
+ ORDER_PRODUCT_STATUS,
8
+ OrderInventory,
9
+ OrderNoGenerator,
10
+ OrderProduct
11
+ } from '@things-factory/sales-base'
12
+ import { Domain } from '@things-factory/shell'
13
+ import { Inventory } from '@things-factory/warehouse-base'
14
+
15
+ import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
16
+ import { Worksheet, WorksheetDetail } from '../../../entities'
17
+ import { WorksheetNoGenerator } from '../../../utils'
18
+
19
+ export const regenerateReleaseGoodWorksheetDetailsResolver = {
20
+ async regenerateReleaseGoodWorksheetDetails(
21
+ _: any,
22
+ { worksheetNo, batchId, productId, packingType, packingSize, orderProductId, worksheetDetails },
23
+ context: any
24
+ ): Promise<void> {
25
+ const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
26
+ return await regenerateReleaseGoodWorksheetDetails(
27
+ tx,
28
+ domain,
29
+ user,
30
+ worksheetNo,
31
+ batchId,
32
+ productId,
33
+ packingType,
34
+ packingSize,
35
+ orderProductId,
36
+ worksheetDetails
37
+ )
38
+ }
39
+ }
40
+
41
+ export async function regenerateReleaseGoodWorksheetDetails(
42
+ tx: EntityManager,
43
+ domain: Domain,
44
+ user: User,
45
+ worksheetNo: string,
46
+ batchId: string,
47
+ productId: string,
48
+ packingType: string,
49
+ packingSize: number,
50
+ orderProductId: string,
51
+ worksheetDetails: Partial<WorksheetDetail>[]
52
+ ): Promise<void> {
53
+ // 1. Remove prev worksheet details if it's exists
54
+ const worksheet: Worksheet = await tx.getRepository(Worksheet).findOne({
55
+ where: { name: worksheetNo, domain },
56
+ relations: [
57
+ 'bizplace',
58
+ 'releaseGood',
59
+ 'worksheetDetails',
60
+ 'worksheetDetails.targetInventory',
61
+ 'worksheetDetails.targetInventory.inventory',
62
+ 'worksheetDetails.targetInventory.product',
63
+ 'worksheetDetails.targetInventory.releaseGood',
64
+ 'worksheetDetails.targetInventory.orderProduct',
65
+ 'worksheetDetails.targetInventory.bizplace'
66
+ ]
67
+ })
68
+
69
+ const prevWSDs: WorksheetDetail[] = worksheet.worksheetDetails.filter((wsd: WorksheetDetail) => {
70
+ const targetInv: OrderInventory = wsd.targetInventory
71
+ if (targetInv.orderProductId === orderProductId) return wsd.id
72
+ })
73
+
74
+ // TODO: Update prev inventory locked qty and delete order inventories
75
+ if (prevWSDs?.length) {
76
+ const wsdIds: string[] = prevWSDs.map((wsd: WorksheetDetail) => wsd.id)
77
+ const prevOrderInvIds: string[] = prevWSDs.map((wsd: WorksheetDetail) => wsd.targetInventory.id)
78
+ const prevOrderInventories: OrderInventory[] = prevWSDs.map((wsd: WorksheetDetail) => wsd.targetInventory)
79
+ await Promise.all(
80
+ prevOrderInventories.map(async prevOI => {
81
+ if (prevOI?.inventory) {
82
+ await tx.getRepository(Inventory).update(
83
+ { id: prevOI.inventory.id },
84
+ {
85
+ lockedQty: prevOI.inventory.lockedQty - prevOI.releaseQty,
86
+ lockedUomValue: prevOI.inventory.lockedUomValue - prevOI.releaseUomValue
87
+ }
88
+ )
89
+ }
90
+ })
91
+ )
92
+
93
+ await tx.getRepository(WorksheetDetail).delete(wsdIds)
94
+ await tx.getRepository(OrderInventory).delete(prevOrderInvIds)
95
+ }
96
+
97
+ await Promise.all(
98
+ worksheetDetails.map(async (wsd: WorksheetDetail) => {
99
+ // 2. Create order inventory
100
+ let targetInventory: OrderInventory = wsd.targetInventory
101
+ const inventory: Inventory = await tx.getRepository(Inventory).findOne(targetInventory.inventory.id)
102
+
103
+ let targetProduct: OrderProduct = await tx
104
+ .getRepository(OrderProduct)
105
+ .findOne({ where: { id: wsd.targetProduct.id }, relations: ['releaseGood'] })
106
+
107
+ targetInventory = await tx.getRepository(OrderInventory).save({
108
+ ...targetInventory,
109
+ domain,
110
+ bizplace: worksheet.bizplace,
111
+ name: OrderNoGenerator.orderInventory(),
112
+ releaseGood: worksheet.type == WORKSHEET_TYPE.BATCH_PICKING ? targetProduct.releaseGood : worksheet.releaseGood,
113
+ inventory,
114
+ batchId: inventory.batchId,
115
+ batchIdRef: inventory.batchIdRef,
116
+ status: ORDER_INVENTORY_STATUS.READY_TO_PICK,
117
+ product: await tx.getRepository(Product).findOne(productId),
118
+ packingType,
119
+ packingSize,
120
+ orderProduct: targetProduct,
121
+ refWorksheetId: worksheet.type == WORKSHEET_TYPE.BATCH_PICKING ? worksheet.id : null,
122
+ creator: user,
123
+ updater: user
124
+ })
125
+
126
+ const currentLockedQty: any = inventory.lockedQty
127
+ const currentLockedUomValue: any = inventory.lockedUomValue
128
+
129
+ await tx.getRepository(Inventory).save({
130
+ ...targetInventory.inventory,
131
+ lockedQty: Boolean(currentLockedQty)
132
+ ? targetInventory.releaseQty + currentLockedQty
133
+ : targetInventory.releaseQty,
134
+ lockedUomValue: Boolean(currentLockedUomValue)
135
+ ? targetInventory.releaseUomValue + currentLockedUomValue
136
+ : targetInventory.releaseUomValue,
137
+ updater: user
138
+ })
139
+
140
+ // update order product status to ASSIGNED
141
+ await tx
142
+ .getRepository(OrderProduct)
143
+ .update({ id: targetProduct.id }, { status: ORDER_PRODUCT_STATUS.ASSIGNED, updater: user })
144
+
145
+ // 3. Create worksheet details
146
+ await tx.getRepository(WorksheetDetail).save({
147
+ ...wsd,
148
+ domain,
149
+ bizplace: worksheet.bizplace,
150
+ worksheet,
151
+ name:
152
+ worksheet.type == WORKSHEET_TYPE.BATCH_PICKING
153
+ ? WorksheetNoGenerator.batchPickingDetail()
154
+ : WorksheetNoGenerator.pickingDetail(),
155
+ targetProduct,
156
+ targetInventory,
157
+ type: worksheet.type == WORKSHEET_TYPE.BATCH_PICKING ? WORKSHEET_TYPE.BATCH_PICKING : WORKSHEET_TYPE.PICKING,
158
+ status: WORKSHEET_STATUS.DEACTIVATED,
159
+ creator: user,
160
+ updater: user
161
+ })
162
+ })
163
+ )
164
+ }
@@ -0,0 +1,9 @@
1
+ import { gql } from 'apollo-server-koa'
2
+
3
+ export const GenerateBatchPickInfo = gql`
4
+ input GenerateBatchPickInfo {
5
+ releaseGoodNo: String
6
+ bizplaceId: String
7
+ bizplaceName: String
8
+ }
9
+ `