@things-factory/worksheet-base 4.3.701 → 4.3.705

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/worksheet-base",
3
- "version": "4.3.701",
3
+ "version": "4.3.705",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -23,28 +23,28 @@
23
23
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
24
24
  },
25
25
  "dependencies": {
26
- "@things-factory/auth-base": "^4.3.695",
27
- "@things-factory/biz-base": "^4.3.701",
28
- "@things-factory/document-template-base": "^4.3.695",
29
- "@things-factory/id-rule-base": "^4.3.695",
30
- "@things-factory/integration-accounting": "^4.3.701",
31
- "@things-factory/integration-base": "^4.3.695",
32
- "@things-factory/integration-lmd": "^4.3.701",
33
- "@things-factory/integration-marketplace": "^4.3.701",
34
- "@things-factory/integration-powrup": "^4.3.701",
35
- "@things-factory/integration-sellercraft": "^4.3.701",
36
- "@things-factory/integration-sftp": "^4.3.701",
37
- "@things-factory/marketplace-base": "^4.3.701",
38
- "@things-factory/notification": "^4.3.695",
39
- "@things-factory/sales-base": "^4.3.701",
40
- "@things-factory/setting-base": "^4.3.695",
41
- "@things-factory/shell": "^4.3.695",
42
- "@things-factory/transport-base": "^4.3.701",
43
- "@things-factory/warehouse-base": "^4.3.701",
44
- "@things-factory/worksheet-ui": "^4.3.695",
26
+ "@things-factory/auth-base": "^4.3.705",
27
+ "@things-factory/biz-base": "^4.3.705",
28
+ "@things-factory/document-template-base": "^4.3.705",
29
+ "@things-factory/id-rule-base": "^4.3.705",
30
+ "@things-factory/integration-accounting": "^4.3.705",
31
+ "@things-factory/integration-base": "^4.3.705",
32
+ "@things-factory/integration-lmd": "^4.3.705",
33
+ "@things-factory/integration-marketplace": "^4.3.705",
34
+ "@things-factory/integration-powrup": "^4.3.705",
35
+ "@things-factory/integration-sellercraft": "^4.3.705",
36
+ "@things-factory/integration-sftp": "^4.3.705",
37
+ "@things-factory/marketplace-base": "^4.3.705",
38
+ "@things-factory/notification": "^4.3.705",
39
+ "@things-factory/sales-base": "^4.3.705",
40
+ "@things-factory/setting-base": "^4.3.705",
41
+ "@things-factory/shell": "^4.3.705",
42
+ "@things-factory/transport-base": "^4.3.705",
43
+ "@things-factory/warehouse-base": "^4.3.705",
44
+ "@things-factory/worksheet-ui": "^4.3.705",
45
45
  "jspdf": "2.5.1",
46
46
  "puppeteer": "21.0.3",
47
47
  "uuid": "^9.0.0"
48
48
  },
49
- "gitHead": "2cb46fe9d95770899e069846c590a3b24c847d9c"
49
+ "gitHead": "37ae3b066444a1094389a59b38414e5c2b75db20"
50
50
  }
@@ -140,9 +140,24 @@ export class PutawayWorksheetController extends VasWorksheetController {
140
140
  }
141
141
 
142
142
  // Allowed types (ranking is used for recommendation; validation enforces allowed set)
143
- const allowedTypes = [LOCATION_TYPE.STORAGE, LOCATION_TYPE.SHELF, LOCATION_TYPE.FLOOR]
143
+ // QUARANTINE and DAMAGE are allowed but skip stacking/homogeneity validation
144
+ const allowedTypes = [
145
+ LOCATION_TYPE.STORAGE,
146
+ LOCATION_TYPE.SHELF,
147
+ LOCATION_TYPE.FLOOR,
148
+ LOCATION_TYPE.QUARANTINE,
149
+ LOCATION_TYPE.DAMAGE
150
+ ]
144
151
  if (!allowedTypes.includes(location.type as any)) {
145
- throw new Error('Scanned location type is not allowed for putaway (allowed: STORAGE, SHELF, FLOOR)')
152
+ throw new Error(
153
+ 'Scanned location type is not allowed for putaway (allowed: STORAGE, SHELF, FLOOR, QUARANTINE, DAMAGE)'
154
+ )
155
+ }
156
+
157
+ // Skip stacking limit and homogeneity checks for QUARANTINE and DAMAGE locations
158
+ // Users can scan anything freely into these location types
159
+ if (location.type === LOCATION_TYPE.QUARANTINE || location.type === LOCATION_TYPE.DAMAGE) {
160
+ return
146
161
  }
147
162
 
148
163
  // Stacking limits
@@ -356,7 +356,11 @@ export class UnloadingWorksheetController extends VasWorksheetController {
356
356
 
357
357
  let foundInventory: Inventory = await invQb.getOne()
358
358
 
359
- const batchIdRef: string = Boolean(arrivalNotice) ? targetProduct.batchIdRef : null
359
+ const batchIdRef: string = Boolean(arrivalNotice)
360
+ ? targetProduct.batchIdRef
361
+ : Boolean(returnOrder)
362
+ ? targetInventory.batchId
363
+ : null
360
364
  const remark: string = Boolean(arrivalNotice) ? targetProduct.remark : targetInventory.remark
361
365
  const manufactureDate: number = Boolean(arrivalNotice) ? targetProduct.manufactureDate : null
362
366
  const location: Location = worksheet.bufferLocation
@@ -585,7 +589,11 @@ export class UnloadingWorksheetController extends VasWorksheetController {
585
589
 
586
590
  let foundInventory: Inventory = await invQb.getOne()
587
591
 
588
- const batchIdRef: string = Boolean(arrivalNotice) ? targetProduct.batchIdRef : null
592
+ const batchIdRef: string = Boolean(arrivalNotice)
593
+ ? targetProduct.batchIdRef
594
+ : Boolean(returnOrder)
595
+ ? targetInventory.batchId
596
+ : null
589
597
  const remark: string = Boolean(arrivalNotice) ? targetProduct.remark : targetInventory.remark
590
598
  const manufactureDate: number = Boolean(arrivalNotice) ? targetProduct.manufactureDate : null
591
599
  const location: Location = worksheet.bufferLocation
@@ -239,6 +239,7 @@ export class PickingWorksheetController extends VasWorksheetController {
239
239
  'releaseGood',
240
240
  'releaseGood.bizplace',
241
241
  'releaseGood.domain',
242
+ 'releaseGood.deliverTo',
242
243
  'releaseGood.lastMileDelivery',
243
244
  'releaseGood.bizplace.domain',
244
245
  'domain',
@@ -517,6 +518,7 @@ export class PickingWorksheetController extends VasWorksheetController {
517
518
  'worksheetDetails.targetProduct.product',
518
519
  'worksheetDetails.targetProduct.productDetail',
519
520
  'worksheetDetails.targetProduct.releaseGood',
521
+ 'worksheetDetails.targetProduct.releaseGood.deliverTo',
520
522
  'worksheetDetails.targetInventory',
521
523
  'worksheetDetails.targetInventory.releaseGood',
522
524
  'worksheetDetails.targetInventory.releaseGood.domain',
@@ -2423,6 +2425,11 @@ export class PickingWorksheetController extends VasWorksheetController {
2423
2425
  }
2424
2426
  }
2425
2427
 
2428
+ // if deliverTo contact point exists and has releaseShelfLife, use it as override for outbound shelf life
2429
+ const releaseShelfLife = (releaseGood?.deliverTo as any)?.releaseShelfLife
2430
+ const outboundShelfLifeOverride =
2431
+ releaseGood?.deliverTo && releaseShelfLife != null && releaseShelfLife !== 0 ? Number(releaseShelfLife) : null
2432
+
2426
2433
  let assignedOrderInventories: OrderInventory[] = await InventoryUtil.autoAssignInventoryForRelease(
2427
2434
  op,
2428
2435
  op.productDetail.product,
@@ -2436,7 +2443,8 @@ export class PickingWorksheetController extends VasWorksheetController {
2436
2443
  undefined,
2437
2444
  undefined,
2438
2445
  undefined,
2439
- (op as any)?.warehouseCode
2446
+ (op as any)?.warehouseCode,
2447
+ outboundShelfLifeOverride
2440
2448
  )
2441
2449
 
2442
2450
  assignedOrderInventories = assignedOrderInventories.map(aoi => {
@@ -2522,7 +2530,11 @@ export class PickingWorksheetController extends VasWorksheetController {
2522
2530
  locationSortingRules: inventoryAssignmentSetting ? JSON.parse(inventoryAssignmentSetting.value) : false,
2523
2531
  pickingStrategy: orderProducts[i].product.pickingStrategy,
2524
2532
  warehouseName:
2525
- (orderProducts[i] as any)?.warehouseCode || (orderProducts[i] as any)?.warehouse?.name || undefined
2533
+ (orderProducts[i] as any)?.warehouseCode || (orderProducts[i] as any)?.warehouse?.name || undefined,
2534
+ releaseShelfLifeOverride: (() => {
2535
+ const releaseShelfLife = (orderProducts[i]?.releaseGood as any)?.deliverTo?.releaseShelfLife
2536
+ return releaseShelfLife != null && releaseShelfLife !== 0 ? Number(releaseShelfLife) : null
2537
+ })()
2526
2538
  },
2527
2539
  this.domain,
2528
2540
  this.trxMgr
@@ -10,23 +10,29 @@ export const inventoriesByPalletResolver = {
10
10
  const { domain, user }: { domain: Domain; user: User } = context.state
11
11
  const params = { filters, pagination }
12
12
  try {
13
- const bizplaceId = params.filters.find(x => x.name == 'bizplace_id')
14
- const productFilters = params.filters.filter(x => x.name == 'productName')
15
- const inventoriesFilters = params.filters.find(x => x.name == 'invFilter')
16
- const recallFilters = params.filters.find(x => x.name === 'recall')
17
- const skipLockCheckFilters = params.filters.find(x => x.name === 'skipLockCheck')
18
- let skipLockCheck: Boolean =
19
- skipLockCheckFilters && skipLockCheckFilters?.value ? skipLockCheckFilters?.value : false
20
- const productFilterColumns = ['sku', 'brandSku', 'name', 'description', 'brand', 'subBrand']
21
- params.filters = params.filters.filter(x => x.name != 'productName' && x.name != 'invFilter')
22
- const batchIdFilters = params.filters.find(x => x.name == 'batchId')
23
-
24
- if (!params.filters.find((filter: any) => filter.name === 'bizplace_id')) {
25
- throw new Error('No Bizplace found')
26
- }
13
+ const bizplaceId = params.filters.find(x => x.name == 'bizplace_id')
14
+ const releaseShelfLifeOverrideFilter = params.filters.find(x => x.name == 'releaseShelfLifeOverride')
15
+ const releaseShelfLifeOverride =
16
+ releaseShelfLifeOverrideFilter && releaseShelfLifeOverrideFilter.value != null
17
+ ? Number(releaseShelfLifeOverrideFilter.value)
18
+ : null
19
+ params.filters = params.filters.filter(x => x.name != 'releaseShelfLifeOverride')
20
+ const productFilters = params.filters.filter(x => x.name == 'productName')
21
+ const inventoriesFilters = params.filters.find(x => x.name == 'invFilter')
22
+ const recallFilters = params.filters.find(x => x.name === 'recall')
23
+ const skipLockCheckFilters = params.filters.find(x => x.name === 'skipLockCheck')
24
+ let skipLockCheck: Boolean =
25
+ skipLockCheckFilters && skipLockCheckFilters?.value ? skipLockCheckFilters?.value : false
26
+ const productFilterColumns = ['sku', 'brandSku', 'name', 'description', 'brand', 'subBrand']
27
+ params.filters = params.filters.filter(x => x.name != 'productName' && x.name != 'invFilter')
28
+ const batchIdFilters = params.filters.find(x => x.name == 'batchId')
29
+
30
+ if (!params.filters.find((filter: any) => filter.name === 'bizplace_id')) {
31
+ throw new Error('No Bizplace found')
32
+ }
27
33
 
28
- const locationFilters = params.filters.find(x => x.name == 'locationName')
29
- params.filters = params.filters.filter(x => x.name != 'locationName')
34
+ const locationFilters = params.filters.find(x => x.name == 'locationName')
35
+ params.filters = params.filters.filter(x => x.name != 'locationName')
30
36
 
31
37
  const qb: SelectQueryBuilder<Inventory> = getRepository(Inventory).createQueryBuilder('iv')
32
38
  buildQuery(qb, params, context)
@@ -43,7 +49,7 @@ export const inventoriesByPalletResolver = {
43
49
  .andWhere('iv.qty > 0')
44
50
  .andWhere('iv.transfer_qty <= 0')
45
51
  .andWhere('iv.transfer_uom_value <= 0')
46
- .andWhere('iv.lock_inventory is not true')
52
+ .andWhere('iv.lock_inventory is not true')
47
53
  .andWhere(
48
54
  `location.type ${recallFilters?.value === true ? '' : 'NOT'} IN ('${LOCATION_TYPE.QUARANTINE}', '${
49
55
  LOCATION_TYPE.RESERVE
@@ -72,10 +78,8 @@ export const inventoriesByPalletResolver = {
72
78
  }
73
79
 
74
80
  if (inventoriesFilters?.value?.length > 0) {
75
-
76
81
  qb.andWhere('iv.id NOT IN (:...inventoriesIds)', {
77
82
  inventoriesIds: inventoriesFilters.value
78
-
79
83
  })
80
84
  }
81
85
 
@@ -132,12 +136,14 @@ export const inventoriesByPalletResolver = {
132
136
  qb.andWhere(`iv.batch_id ilike '${batchIdFilters.value}'`)
133
137
  }
134
138
  qb.andWhere(
135
- 'iv.obsolete = true and case when iv.expiration_date is not null and product.min_outbound_shelf_life is not null then CURRENT_DATE > iv.expiration_date - product.min_outbound_shelf_life else true end)'
139
+ 'iv.obsolete = true and case when iv.expiration_date is not null then CURRENT_DATE > iv.expiration_date - (case when :releaseOverride::integer is not null and :releaseOverride::integer > 0 then :releaseOverride::integer when product.min_outbound_shelf_life is not null then product.min_outbound_shelf_life else 0 end) else true end)',
140
+ { releaseOverride: releaseShelfLifeOverride ?? null }
136
141
  )
137
142
  } else {
138
143
  qb.andWhere('iv.obsolete = false')
139
144
  qb.andWhere(
140
- 'case when iv.expiration_date is not null and product.min_outbound_shelf_life is not null then CURRENT_DATE < iv.expiration_date - product.min_outbound_shelf_life else true end'
145
+ 'case when iv.expiration_date is not null then CURRENT_DATE < iv.expiration_date - (case when :releaseOverride::integer is not null and :releaseOverride::integer > 0 then :releaseOverride::integer when product.min_outbound_shelf_life is not null then product.min_outbound_shelf_life else 0 end) else true end',
146
+ { releaseOverride: releaseShelfLifeOverride ?? null }
141
147
  )
142
148
  }
143
149
 
@@ -181,7 +187,7 @@ export const inventoriesByPalletResolver = {
181
187
  productBrand: item.product.brand,
182
188
  productId: item.product.id,
183
189
  productDetailId: item.productDetail.id,
184
- isInventoryDecimal: item.product.isInventoryDecimal,
190
+ isInventoryDecimal: item.product.isInventoryDecimal
185
191
  }
186
192
  })
187
193
  )
@@ -121,7 +121,8 @@ export async function inventoriesByStrategy(
121
121
  uom,
122
122
  pickingStrategy,
123
123
  locationSortingRules,
124
- warehouseName
124
+ warehouseName,
125
+ releaseShelfLifeOverride
125
126
  },
126
127
  domain: Domain,
127
128
  trxMgr: EntityManager
@@ -158,14 +159,15 @@ export async function inventoriesByStrategy(
158
159
  })
159
160
  .andWhere('"INV"."obsolete" = false')
160
161
  .andWhere(
161
- 'case when "INV"."expiration_date" is not null and "PROD"."min_outbound_shelf_life" is not null then CURRENT_DATE < "INV"."expiration_date" - "PROD"."min_outbound_shelf_life" else true end'
162
+ 'case when "INV"."expiration_date" is not null then CURRENT_DATE < "INV"."expiration_date" - (case when :releaseShelfLifeOverride::integer is not null and :releaseShelfLifeOverride::integer > 0 then :releaseShelfLifeOverride::integer when "PROD"."min_outbound_shelf_life" is not null then "PROD"."min_outbound_shelf_life" else 0 end) else true end'
162
163
  )
163
164
  .setParameters({
164
165
  domainId: domain.id,
165
166
  productId,
166
167
  packingType,
167
168
  packingSize,
168
- uom
169
+ uom,
170
+ releaseShelfLifeOverride: releaseShelfLifeOverride ?? null
169
171
  })
170
172
 
171
173
  if (batchId !== '') {