@things-factory/sales-base 4.3.695 → 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/dist-server/service/draft-release-good/draft-release-good-create.js +29 -5
- package/dist-server/service/draft-release-good/draft-release-good-create.js.map +1 -1
- package/dist-server/service/draft-release-good/draft-release-good-mutation.js +1 -1
- package/dist-server/service/draft-release-good/draft-release-good-mutation.js.map +1 -1
- package/dist-server/service/draft-release-good/draft-release-good-query.js +12 -1
- package/dist-server/service/draft-release-good/draft-release-good-query.js.map +1 -1
- package/dist-server/service/release-good/release-good-mutation.js +152 -10
- package/dist-server/service/release-good/release-good-mutation.js.map +1 -1
- package/dist-server/service/release-good/release-good-query.js +14 -1
- package/dist-server/service/release-good/release-good-query.js.map +1 -1
- package/dist-server/utils/inventory-util.js +29 -7
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +10 -10
- package/server/service/draft-release-good/draft-release-good-create.ts +28 -3
- package/server/service/draft-release-good/draft-release-good-mutation.ts +1 -1
- package/server/service/draft-release-good/draft-release-good-query.ts +13 -0
- package/server/service/release-good/release-good-mutation.ts +185 -4
- package/server/service/release-good/release-good-query.ts +16 -1
- package/server/utils/inventory-util.ts +30 -7
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
getOutletBizplace,
|
|
23
23
|
getPermittedBizplaces
|
|
24
24
|
} from '@things-factory/biz-base'
|
|
25
|
+
import { ContactPoint } from '@things-factory/biz-base'
|
|
25
26
|
import { GeoCountry } from '@things-factory/geography'
|
|
26
27
|
import { generateId } from '@things-factory/id-rule-base'
|
|
27
28
|
import { WebhookEventsEnum, webhookHandler } from '@things-factory/integration-base'
|
|
@@ -30,7 +31,7 @@ import { MarketplaceStore } from '@things-factory/integration-marketplace'
|
|
|
30
31
|
import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
|
|
31
32
|
import { MarketplaceOrder } from '@things-factory/marketplace-base'
|
|
32
33
|
// import { sendNotification } from '@things-factory/notification'
|
|
33
|
-
import { ProductBundleSetting, ProductDetail } from '@things-factory/product-base'
|
|
34
|
+
import { Product, ProductBundleSetting, ProductDetail } from '@things-factory/product-base'
|
|
34
35
|
import { PartnerSetting, Setting } from '@things-factory/setting-base'
|
|
35
36
|
import { Domain } from '@things-factory/shell'
|
|
36
37
|
import { Inventory, ProductDetailStock } from '@things-factory/warehouse-base'
|
|
@@ -620,6 +621,162 @@ export async function generateReleaseGoodFunction(
|
|
|
620
621
|
await InventoryUtil.validateWarehousePartnersProductsQuantity(domain, bizplace, orderInventories, context, tx)
|
|
621
622
|
/** End Validate Release Order Product Quantity Section */
|
|
622
623
|
|
|
624
|
+
/**
|
|
625
|
+
* Enforce outbound shelf-life at submission time using deliverTo.releaseShelfLife (if present).
|
|
626
|
+
* This guards scenarios where user selected inventories first and then set Contact Point,
|
|
627
|
+
* ensuring final validation rejects items that don't meet the shelf-life requirement.
|
|
628
|
+
*/
|
|
629
|
+
let outboundShelfLifeOverride: number | null = null
|
|
630
|
+
let contactPoint: ContactPoint = null
|
|
631
|
+
const deliverToId: string | null =
|
|
632
|
+
typeof releaseGood?.deliverTo === 'string' && releaseGood?.deliverTo ? String(releaseGood.deliverTo) : null
|
|
633
|
+
if (deliverToId) {
|
|
634
|
+
contactPoint = await tx.getRepository(ContactPoint).findOne({ where: { id: deliverToId } })
|
|
635
|
+
if (contactPoint?.releaseShelfLife != null && contactPoint.releaseShelfLife !== 0) {
|
|
636
|
+
outboundShelfLifeOverride = Number(contactPoint.releaseShelfLife)
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (orderInventories?.length) {
|
|
641
|
+
// Helper function to build inventory availability query with optional warehouse and batch filters
|
|
642
|
+
const buildInventoryAvailabilityQuery = (
|
|
643
|
+
productId: string,
|
|
644
|
+
packingType: string,
|
|
645
|
+
packingSize: number,
|
|
646
|
+
uom: string,
|
|
647
|
+
warehouseName: string | null,
|
|
648
|
+
batchId: string | null,
|
|
649
|
+
outboundShelfLifeOverride: number | null
|
|
650
|
+
) => {
|
|
651
|
+
const query = `
|
|
652
|
+
select
|
|
653
|
+
coalesce(sum(
|
|
654
|
+
case when (iv.qty - greatest(coalesce(iv.locked_qty,0),0) - greatest(coalesce(pds.unassigned_qty,0),0)) < 0
|
|
655
|
+
then 0
|
|
656
|
+
else (iv.qty - greatest(coalesce(iv.locked_qty,0),0) - greatest(coalesce(pds.unassigned_qty,0),0))
|
|
657
|
+
end
|
|
658
|
+
), 0) as total_available_qty,
|
|
659
|
+
coalesce(sum(
|
|
660
|
+
case when (iv.uom_value - greatest(coalesce(iv.locked_uom_value,0),0) - greatest(coalesce(pds.unassigned_uom_value,0),0)) < 0
|
|
661
|
+
then 0
|
|
662
|
+
else (iv.uom_value - greatest(coalesce(iv.locked_uom_value,0),0) - greatest(coalesce(pds.unassigned_uom_value,0),0))
|
|
663
|
+
end
|
|
664
|
+
), 0) as total_available_uom_value,
|
|
665
|
+
max(p.sku) as product_sku
|
|
666
|
+
from inventories iv
|
|
667
|
+
left join product_detail_stocks pds on pds.product_detail_id = iv.product_detail_id
|
|
668
|
+
inner join products p on p.id = iv.product_id
|
|
669
|
+
inner join locations loc on loc.id = iv.location_id
|
|
670
|
+
inner join warehouses w on w.id = loc.warehouse_id
|
|
671
|
+
where iv.domain_id = $1
|
|
672
|
+
and iv.bizplace_id = $2
|
|
673
|
+
and iv.product_id = $3
|
|
674
|
+
and iv.packing_type = $4
|
|
675
|
+
and iv.packing_size = $5
|
|
676
|
+
and iv.uom = $6
|
|
677
|
+
and iv.status = 'STORED'
|
|
678
|
+
and loc.type not in ('QUARANTINE','RESERVE','DAMAGE','STORAGE')
|
|
679
|
+
and iv.obsolete = false
|
|
680
|
+
and (
|
|
681
|
+
case
|
|
682
|
+
when iv.expiration_date is not null
|
|
683
|
+
then CURRENT_DATE < iv.expiration_date - (
|
|
684
|
+
case
|
|
685
|
+
when $9::integer is not null and $9::integer > 0
|
|
686
|
+
then $9::integer
|
|
687
|
+
when p.min_outbound_shelf_life is not null
|
|
688
|
+
then p.min_outbound_shelf_life
|
|
689
|
+
else 0
|
|
690
|
+
end
|
|
691
|
+
)
|
|
692
|
+
else true
|
|
693
|
+
end
|
|
694
|
+
)
|
|
695
|
+
and ($7::text is null or w.name = $7::text)
|
|
696
|
+
and ($8::text is null or iv.batch_id = $8::text)
|
|
697
|
+
`
|
|
698
|
+
|
|
699
|
+
const params = [
|
|
700
|
+
domain.id,
|
|
701
|
+
bizplace.id,
|
|
702
|
+
productId,
|
|
703
|
+
packingType,
|
|
704
|
+
packingSize,
|
|
705
|
+
uom,
|
|
706
|
+
warehouseName,
|
|
707
|
+
batchId,
|
|
708
|
+
outboundShelfLifeOverride
|
|
709
|
+
]
|
|
710
|
+
|
|
711
|
+
return { query, params }
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const insufficientItems: any[] = []
|
|
715
|
+
for (const item of orderInventories) {
|
|
716
|
+
// Only validate standard (non-bundle) rows that have product/productDetail context
|
|
717
|
+
if (!item?.productDetail?.id || !item?.uom) continue
|
|
718
|
+
|
|
719
|
+
const productDetailId = item.productDetail.id
|
|
720
|
+
const productId = item?.product?.id || item?.productDetail?.product?.id
|
|
721
|
+
const packingType = item.packingType
|
|
722
|
+
const packingSize = item.packingSize
|
|
723
|
+
const uom = item.uom
|
|
724
|
+
const warehouseName = (item as any)?.warehouseCode ? String((item as any).warehouseCode).trim() : null
|
|
725
|
+
const batchId = item?.batchId && item.batchId !== '-' ? String(item.batchId).trim() : null
|
|
726
|
+
|
|
727
|
+
// Validate availability with shelf-life predicate applied
|
|
728
|
+
const { query, params } = buildInventoryAvailabilityQuery(
|
|
729
|
+
productId,
|
|
730
|
+
packingType,
|
|
731
|
+
packingSize,
|
|
732
|
+
uom,
|
|
733
|
+
warehouseName,
|
|
734
|
+
batchId,
|
|
735
|
+
outboundShelfLifeOverride
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
const rows = await tx.query(query, params)
|
|
739
|
+
|
|
740
|
+
const totalQty = parseFloat(rows?.[0]?.total_available_qty || '0')
|
|
741
|
+
// Normalize release quantity for non-decimal products
|
|
742
|
+
let reqQty = item.releaseQty
|
|
743
|
+
if ((item as any)?.product?.isInventoryDecimal === false) {
|
|
744
|
+
reqQty = Math.round(reqQty)
|
|
745
|
+
} else {
|
|
746
|
+
reqQty = Math.round(reqQty * 1000) / 1000
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
let productSku: string = rows?.[0]?.product_sku || null
|
|
750
|
+
if (!productSku && productId) {
|
|
751
|
+
const prod: Product = await tx
|
|
752
|
+
.getRepository(Product)
|
|
753
|
+
.findOne({ where: { id: productId }, select: ['id', 'sku'] })
|
|
754
|
+
if (prod?.sku) {
|
|
755
|
+
productSku = prod.sku
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
if (totalQty + 1e-6 < reqQty) {
|
|
759
|
+
insufficientItems.push({
|
|
760
|
+
productId,
|
|
761
|
+
productDetailId,
|
|
762
|
+
productSku: productSku,
|
|
763
|
+
packingType,
|
|
764
|
+
packingSize,
|
|
765
|
+
uom,
|
|
766
|
+
batchId,
|
|
767
|
+
requiredQty: reqQty,
|
|
768
|
+
availableQty: totalQty
|
|
769
|
+
})
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (insufficientItems.length > 0) {
|
|
773
|
+
throw new ValidationError({
|
|
774
|
+
...ValidationError.ERROR_CODES.INSUFFICIENT_STOCK,
|
|
775
|
+
detail: { data: JSON.stringify(insufficientItems) }
|
|
776
|
+
})
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
623
780
|
const orderSource: string = releaseGood.source
|
|
624
781
|
switch (orderSource) {
|
|
625
782
|
case ApplicationType.SELLERCRAFT:
|
|
@@ -801,6 +958,7 @@ export async function generateReleaseGoodFunction(
|
|
|
801
958
|
lastMileDelivery: lmd || null,
|
|
802
959
|
codOption: releaseGood?.codOption || null,
|
|
803
960
|
paidAmount: releaseGood?.paidAmount || null,
|
|
961
|
+
deliverTo: contactPoint || null,
|
|
804
962
|
creator: user,
|
|
805
963
|
updater: user
|
|
806
964
|
}
|
|
@@ -948,7 +1106,13 @@ export async function generateReleaseGoodFunction(
|
|
|
948
1106
|
bizplace,
|
|
949
1107
|
warehouseDomain,
|
|
950
1108
|
tx,
|
|
951
|
-
newOrderInv.batchId
|
|
1109
|
+
newOrderInv.batchId,
|
|
1110
|
+
undefined,
|
|
1111
|
+
undefined,
|
|
1112
|
+
undefined,
|
|
1113
|
+
undefined,
|
|
1114
|
+
undefined,
|
|
1115
|
+
outboundShelfLifeOverride
|
|
952
1116
|
)
|
|
953
1117
|
|
|
954
1118
|
assignedOrderInventories = assignedOrderInventories.map(aoi => {
|
|
@@ -1681,6 +1845,21 @@ export async function bulkGenerateReleaseGood(
|
|
|
1681
1845
|
newReleaseGood.shippingOrder = createdSO
|
|
1682
1846
|
}
|
|
1683
1847
|
|
|
1848
|
+
/**
|
|
1849
|
+
* Enforce outbound shelf-life at submission time using deliverTo.releaseShelfLife (if present).
|
|
1850
|
+
* This guards scenarios where user selected inventories first and then set Contact Point,
|
|
1851
|
+
* ensuring final validation rejects items that don't meet the shelf-life requirement.
|
|
1852
|
+
*/
|
|
1853
|
+
let outboundShelfLifeOverride: number | null = null
|
|
1854
|
+
const deliverToId: string | null =
|
|
1855
|
+
typeof releaseGood?.deliverTo === 'string' && releaseGood?.deliverTo ? String(releaseGood.deliverTo) : null
|
|
1856
|
+
if (deliverToId) {
|
|
1857
|
+
const contactPoint: ContactPoint = await tx.getRepository(ContactPoint).findOne({ where: { id: deliverToId } })
|
|
1858
|
+
if (contactPoint?.releaseShelfLife != null && contactPoint.releaseShelfLife !== 0) {
|
|
1859
|
+
outboundShelfLifeOverride = Number(contactPoint.releaseShelfLife)
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1684
1863
|
let finalOrderInventories: Partial<OrderInventory>[] = []
|
|
1685
1864
|
|
|
1686
1865
|
// pre assign inventory to orderInventories
|
|
@@ -1717,7 +1896,9 @@ export async function bulkGenerateReleaseGood(
|
|
|
1717
1896
|
'',
|
|
1718
1897
|
null,
|
|
1719
1898
|
oi.cartonId,
|
|
1720
|
-
oi.expirationDate
|
|
1899
|
+
oi.expirationDate,
|
|
1900
|
+
undefined,
|
|
1901
|
+
outboundShelfLifeOverride
|
|
1721
1902
|
)
|
|
1722
1903
|
|
|
1723
1904
|
finalOrderInventories.push(
|
|
@@ -1976,7 +2157,7 @@ function extractRawReleaseGoods(rawReleaseGoods): Partial<ReleaseGood[]> {
|
|
|
1976
2157
|
packingSize: item.packingSize,
|
|
1977
2158
|
uom: item.uom,
|
|
1978
2159
|
releaseQty: Math.round(parseFloat(item.releaseQty) * 1000) / 1000,
|
|
1979
|
-
releaseUomValue: Math.round(parseFloat(item.releaseUomValue) * 1000) / 1000
|
|
2160
|
+
releaseUomValue: Math.round(parseFloat(item.releaseUomValue) * 1000) / 1000
|
|
1980
2161
|
})
|
|
1981
2162
|
}
|
|
1982
2163
|
} else {
|
|
@@ -952,6 +952,13 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
952
952
|
const companyBizplaceId: Bizplace = await getCompanyBizplace(null, null, bizplaceId)
|
|
953
953
|
|
|
954
954
|
if (!rawReleaseGoods) return
|
|
955
|
+
// derive optional release shelf life override (use the first non-null value if provided)
|
|
956
|
+
const releaseShelfLifeOverride: number | null = (() => {
|
|
957
|
+
const found = (rawReleaseGoods || []).find(
|
|
958
|
+
(r: any) => r?.releaseShelfLifeOverride !== undefined && r?.releaseShelfLifeOverride !== null
|
|
959
|
+
)
|
|
960
|
+
return found ? Number(found.releaseShelfLifeOverride) : null
|
|
961
|
+
})()
|
|
955
962
|
// derive optional filters
|
|
956
963
|
const uniqueWarehouseCodes: string[] = Array.from(
|
|
957
964
|
new Set(
|
|
@@ -1067,6 +1074,13 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1067
1074
|
AND i.transfer_uom_value <= 0
|
|
1068
1075
|
AND ( $5::text IS NULL OR w.name = $5 )
|
|
1069
1076
|
${`AND ( $6::text IS NULL OR i.batch_id = $6 )`}
|
|
1077
|
+
AND (
|
|
1078
|
+
CASE
|
|
1079
|
+
WHEN i.expiration_date IS NOT NULL AND COALESCE($7::integer, p.min_outbound_shelf_life) IS NOT NULL
|
|
1080
|
+
THEN CURRENT_DATE < i.expiration_date - COALESCE($7::integer, p.min_outbound_shelf_life)
|
|
1081
|
+
ELSE TRUE
|
|
1082
|
+
END
|
|
1083
|
+
)
|
|
1070
1084
|
GROUP BY i.product_id, foo.product_detail_id, foo.sku, foo.product_info, i.packing_type, i.packing_size, i.uom, p.is_inventory_decimal${
|
|
1071
1085
|
groupByWarehouse ? ', w.name' : ''
|
|
1072
1086
|
}
|
|
@@ -1080,7 +1094,8 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1080
1094
|
LOCATION_TYPE.QUARANTINE,
|
|
1081
1095
|
LOCATION_TYPE.RESERVE,
|
|
1082
1096
|
uniqueWarehouseCodes.length === 1 ? uniqueWarehouseCodes[0] : null,
|
|
1083
|
-
uniqueBatchIds.length === 1 ? uniqueBatchIds[0] : null
|
|
1097
|
+
uniqueBatchIds.length === 1 ? uniqueBatchIds[0] : null,
|
|
1098
|
+
releaseShelfLifeOverride
|
|
1084
1099
|
]
|
|
1085
1100
|
)
|
|
1086
1101
|
|
|
@@ -78,6 +78,8 @@ export const InventoryUtil = {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
// optional override for outbound shelf life (from ContactPoint deliverTo)
|
|
82
|
+
const releaseShelfLifeOverrideFilter = filters.find(f => f.name === 'releaseShelfLifeOverride')
|
|
81
83
|
let queryStrings = `
|
|
82
84
|
CREATE TEMP TABLE temp_inventory_product_group ON COMMIT DROP AS (
|
|
83
85
|
SELECT * FROM (
|
|
@@ -163,7 +165,19 @@ export const InventoryUtil = {
|
|
|
163
165
|
) bp on i.product_id = bp.product_id
|
|
164
166
|
WHERE i.bizplace_id IN (${bizplaceIds})
|
|
165
167
|
AND i.lock_inventory is not true
|
|
166
|
-
AND case
|
|
168
|
+
AND case
|
|
169
|
+
when i.expiration_date is not null
|
|
170
|
+
then CURRENT_DATE < i.expiration_date - (
|
|
171
|
+
case
|
|
172
|
+
when $2::integer is not null and $2::integer > 0
|
|
173
|
+
then $2::integer
|
|
174
|
+
when p.min_outbound_shelf_life is not null
|
|
175
|
+
then p.min_outbound_shelf_life
|
|
176
|
+
else 0
|
|
177
|
+
end
|
|
178
|
+
)
|
|
179
|
+
else true
|
|
180
|
+
end
|
|
167
181
|
${productDetailWhereClause}
|
|
168
182
|
${
|
|
169
183
|
productFilter
|
|
@@ -252,7 +266,10 @@ export const InventoryUtil = {
|
|
|
252
266
|
)
|
|
253
267
|
`
|
|
254
268
|
|
|
255
|
-
await trxMgr.query(queryStrings, [
|
|
269
|
+
await trxMgr.query(queryStrings, [
|
|
270
|
+
domain.id,
|
|
271
|
+
releaseShelfLifeOverrideFilter ? releaseShelfLifeOverrideFilter.value : null
|
|
272
|
+
])
|
|
256
273
|
|
|
257
274
|
const [{ total }]: any = await trxMgr.query(`select count(*) as total from temp_inventory_product_group`)
|
|
258
275
|
let items: any[] = []
|
|
@@ -295,6 +312,7 @@ export const InventoryUtil = {
|
|
|
295
312
|
let cycleCountFilter = filters.find(filter => filter.name == 'cycleCount')?.value
|
|
296
313
|
|
|
297
314
|
const _groupType = filters.find(res => res.name == 'groupType')
|
|
315
|
+
const releaseShelfLifeOverrideFilter = filters.find(filter => filter.name === 'releaseShelfLifeOverride')
|
|
298
316
|
let queryStrings = `
|
|
299
317
|
CREATE TEMP TABLE temp_inventory_product_group AS (
|
|
300
318
|
SELECT * FROM (
|
|
@@ -335,7 +353,7 @@ export const InventoryUtil = {
|
|
|
335
353
|
AND i.transfer_qty <= 0
|
|
336
354
|
AND i.transfer_uom_value <= 0
|
|
337
355
|
AND i.lock_inventory is not true
|
|
338
|
-
AND CASE WHEN i.expiration_date IS NOT NULL AND p.min_outbound_shelf_life IS NOT NULL THEN CURRENT_DATE < i.expiration_date - p.min_outbound_shelf_life ELSE true END
|
|
356
|
+
AND CASE WHEN i.expiration_date IS NOT NULL AND COALESCE($2::integer, p.min_outbound_shelf_life) IS NOT NULL THEN CURRENT_DATE < i.expiration_date - COALESCE($2::integer, p.min_outbound_shelf_life) ELSE true END
|
|
339
357
|
${
|
|
340
358
|
cycleCountFilter
|
|
341
359
|
? `AND i.id NOT IN (
|
|
@@ -425,7 +443,10 @@ export const InventoryUtil = {
|
|
|
425
443
|
})
|
|
426
444
|
}
|
|
427
445
|
|
|
428
|
-
await trxMgr.query(queryStrings, [
|
|
446
|
+
await trxMgr.query(queryStrings, [
|
|
447
|
+
domain.id,
|
|
448
|
+
releaseShelfLifeOverrideFilter ? releaseShelfLifeOverrideFilter.value : null
|
|
449
|
+
])
|
|
429
450
|
|
|
430
451
|
const [{ total }]: any = await trxMgr.query(
|
|
431
452
|
`select count(*) as total from temp_inventory_product_group ${filterGroupTypeQuery ? filterGroupTypeQuery : ''}`
|
|
@@ -873,7 +894,8 @@ export const InventoryUtil = {
|
|
|
873
894
|
recall: boolean = null,
|
|
874
895
|
cartonId?: string,
|
|
875
896
|
expirationDate?: Date,
|
|
876
|
-
warehouseName?: string
|
|
897
|
+
warehouseName?: string,
|
|
898
|
+
outboundShelfLifeOverride?: number
|
|
877
899
|
): Promise<OrderInventory[]> {
|
|
878
900
|
let strictProduct = 'false'
|
|
879
901
|
|
|
@@ -918,14 +940,15 @@ export const InventoryUtil = {
|
|
|
918
940
|
.andWhere('"iv"."transfer_uom_value" <= 0')
|
|
919
941
|
.andWhere('"iv"."product_id" = :productId')
|
|
920
942
|
.andWhere(
|
|
921
|
-
'case when "iv"."expiration_date" is not null
|
|
943
|
+
'case when "iv"."expiration_date" is not null then CURRENT_DATE < "iv"."expiration_date" - (case when :outboundShelfLifeOverride::integer is not null and :outboundShelfLifeOverride::integer > 0 then :outboundShelfLifeOverride::integer when "p"."min_outbound_shelf_life" is not null then "p"."min_outbound_shelf_life" else 0 end) else true end'
|
|
922
944
|
)
|
|
923
945
|
.setParameters({
|
|
924
946
|
domainId: domain.id,
|
|
925
947
|
bizplaceId: customerBizplace.id,
|
|
926
948
|
productId: product.id,
|
|
927
949
|
status: INVENTORY_STATUS.STORED,
|
|
928
|
-
locationTypes
|
|
950
|
+
locationTypes,
|
|
951
|
+
outboundShelfLifeOverride: outboundShelfLifeOverride ?? null
|
|
929
952
|
})
|
|
930
953
|
|
|
931
954
|
if (batchId) {
|