@things-factory/worksheet-base 4.3.697 → 4.3.700

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.697",
3
+ "version": "4.3.700",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,27 +24,27 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@things-factory/auth-base": "^4.3.695",
27
- "@things-factory/biz-base": "^4.3.695",
27
+ "@things-factory/biz-base": "^4.3.700",
28
28
  "@things-factory/document-template-base": "^4.3.695",
29
29
  "@things-factory/id-rule-base": "^4.3.695",
30
- "@things-factory/integration-accounting": "^4.3.695",
30
+ "@things-factory/integration-accounting": "^4.3.700",
31
31
  "@things-factory/integration-base": "^4.3.695",
32
- "@things-factory/integration-lmd": "^4.3.695",
33
- "@things-factory/integration-marketplace": "^4.3.695",
34
- "@things-factory/integration-powrup": "^4.3.695",
35
- "@things-factory/integration-sellercraft": "^4.3.695",
36
- "@things-factory/integration-sftp": "^4.3.695",
37
- "@things-factory/marketplace-base": "^4.3.695",
32
+ "@things-factory/integration-lmd": "^4.3.700",
33
+ "@things-factory/integration-marketplace": "^4.3.700",
34
+ "@things-factory/integration-powrup": "^4.3.700",
35
+ "@things-factory/integration-sellercraft": "^4.3.700",
36
+ "@things-factory/integration-sftp": "^4.3.700",
37
+ "@things-factory/marketplace-base": "^4.3.700",
38
38
  "@things-factory/notification": "^4.3.695",
39
- "@things-factory/sales-base": "^4.3.697",
39
+ "@things-factory/sales-base": "^4.3.700",
40
40
  "@things-factory/setting-base": "^4.3.695",
41
41
  "@things-factory/shell": "^4.3.695",
42
- "@things-factory/transport-base": "^4.3.695",
43
- "@things-factory/warehouse-base": "^4.3.695",
42
+ "@things-factory/transport-base": "^4.3.700",
43
+ "@things-factory/warehouse-base": "^4.3.700",
44
44
  "@things-factory/worksheet-ui": "^4.3.695",
45
45
  "jspdf": "2.5.1",
46
46
  "puppeteer": "21.0.3",
47
47
  "uuid": "^9.0.0"
48
48
  },
49
- "gitHead": "6ceb3dfb7cd0068636370f501e5043d41d82cdf8"
49
+ "gitHead": "f1b712fc8f3a7b7b5136204e4c4fd6bfad0e766e"
50
50
  }
@@ -81,8 +81,10 @@ export class PutawayReturningWorksheetController extends VasWorksheetController
81
81
  targetInventory.product = inventory.product
82
82
  targetInventory.packingType = inventory.productDetail.packingType
83
83
  targetInventory.productDetail = inventory.productDetail
84
+ targetInventory.refItemId = inventory.otherRef
84
85
  targetInventory.creator = this.user
85
86
  targetInventory.updater = this.user
87
+ targetInventory.actualPackQty = inventory.qty
86
88
  targetInventory = await this.trxMgr.getRepository(OrderInventory).save(targetInventory)
87
89
 
88
90
  worksheet.worksheetDetails = await this.createWorksheetDetails(
@@ -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
@@ -246,7 +246,8 @@ export class UnloadingWorksheetController extends VasWorksheetController {
246
246
  uomValue: uomValue,
247
247
  unitCost: targetOrderInventory.unitCost,
248
248
  orderInventoryId: targetOrderInventory?.id,
249
- refInventory: targetOrderInventory?.inventory
249
+ refInventory: targetOrderInventory?.inventory,
250
+ otherRef: targetOrderInventory.refItemId
250
251
  }
251
252
 
252
253
  const updateOI = {
@@ -401,6 +402,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
401
402
  }
402
403
  newInventory.orderProductId = Boolean(arrivalNotice) ? targetProduct.id : null
403
404
  newInventory.orderInventoryId = Boolean(returnOrder) ? targetInventory.id : null
405
+ newInventory.otherRef = Boolean(returnOrder) ? targetInventory.refItemId : null
404
406
  newInventory.warehouse = warehouse
405
407
  newInventory.location = location
406
408
  newInventory.zone = zone
@@ -629,6 +631,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
629
631
  }
630
632
  newInventory.orderProductId = Boolean(arrivalNotice) ? targetProduct.id : null
631
633
  newInventory.orderInventoryId = Boolean(returnOrder) ? targetInventory.id : null
634
+ newInventory.otherRef = Boolean(returnOrder) ? targetInventory.refItemId : null
632
635
  newInventory.warehouse = warehouse
633
636
  newInventory.location = location
634
637
  newInventory.zone = zone
@@ -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 !== '') {