@things-factory/operato-wms 4.3.824 → 4.3.825
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/client/pages/adjustment/transfer-inventory.js +24 -64
- package/client/pages/components/select-product-popup.js +20 -0
- package/client/pages/constants/location.js +4 -0
- package/client/pages/master/location-list.js +140 -18
- package/client/pages/order/arrival-notice/create-arrival-notice.js +18 -0
- package/client/pages/order/draft-release-good/draft-release-good-list.js +1 -0
- package/config.development.js +71 -141
- package/dist-server/graphql/resolvers/index.js +2 -0
- package/dist-server/graphql/resolvers/index.js.map +1 -1
- package/dist-server/graphql/resolvers/transfer-location/check-transfer-location-recommendation.js +108 -0
- package/dist-server/graphql/resolvers/transfer-location/check-transfer-location-recommendation.js.map +1 -0
- package/dist-server/graphql/resolvers/transfer-location/index.js +7 -0
- package/dist-server/graphql/resolvers/transfer-location/index.js.map +1 -0
- package/dist-server/graphql/types/index.js +3 -0
- package/dist-server/graphql/types/index.js.map +1 -1
- package/dist-server/graphql/types/transfer-location/index.js +14 -0
- package/dist-server/graphql/types/transfer-location/index.js.map +1 -0
- package/dist-server/graphql/types/transfer-location/transfer-location-recommendation.js +13 -0
- package/dist-server/graphql/types/transfer-location/transfer-location-recommendation.js.map +1 -0
- package/package.json +5 -5
- package/server/graphql/resolvers/index.ts +2 -0
- package/server/graphql/resolvers/transfer-location/check-transfer-location-recommendation.ts +123 -0
- package/server/graphql/resolvers/transfer-location/index.ts +7 -0
- package/server/graphql/types/index.ts +3 -0
- package/server/graphql/types/transfer-location/index.ts +13 -0
- package/server/graphql/types/transfer-location/transfer-location-recommendation.ts +7 -0
- package/translations/en.json +12 -0
- package/translations/ko.json +12 -0
- package/translations/ms.json +12 -0
- package/translations/zh.json +12 -0
|
@@ -857,17 +857,8 @@ class TransferInventory extends connect(store)(localize(i18next)(PageView)) {
|
|
|
857
857
|
async pageInitialized() {
|
|
858
858
|
this._transferCodes = await getCodeByName('TRANSFER_CODES')
|
|
859
859
|
|
|
860
|
-
const
|
|
861
|
-
fetchSettingRule('location-recommendation-level'),
|
|
862
|
-
fetchSettingRule('stacking-option-limit')
|
|
863
|
-
])
|
|
860
|
+
const locationRecommendationLevel = await fetchSettingRule('location-recommendation-level')
|
|
864
861
|
this._locationRecommendationLevel = (locationRecommendationLevel || '').toUpperCase().trim()
|
|
865
|
-
try {
|
|
866
|
-
const parsed = JSON.parse(stackingOptionLimitStr || '{}')
|
|
867
|
-
this._stackingOptionLimit = { min: Number(parsed.Min) || 1, max: Number(parsed.Max) || 1 }
|
|
868
|
-
} catch {
|
|
869
|
-
this._stackingOptionLimit = { min: 1, max: 1 }
|
|
870
|
-
}
|
|
871
862
|
|
|
872
863
|
await this._fetchLocations()
|
|
873
864
|
this.refInventoryType = INVENTORY_TYPES.LOT.value
|
|
@@ -1340,73 +1331,42 @@ class TransferInventory extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1340
1331
|
const level = this._locationRecommendationLevel
|
|
1341
1332
|
if (!level) return true
|
|
1342
1333
|
|
|
1343
|
-
const
|
|
1334
|
+
const originPalletId = this._selectedInventory?.palletId
|
|
1335
|
+
const qty = parseFloat(this.qtyInput?.value) || 0
|
|
1336
|
+
|
|
1337
|
+
// RECOMMENDATION LEVEL 4 -> QTY IS REQUIRED FOR CHECKING
|
|
1338
|
+
if (level === 'LEVEL 4' && qty <= 0) {
|
|
1339
|
+
throw new Error(i18next.t('text.please_enter_transfer_qty'))
|
|
1340
|
+
}
|
|
1344
1341
|
|
|
1345
1342
|
const response = await client.query({
|
|
1346
1343
|
query: gql`
|
|
1347
|
-
query
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
product { sku }
|
|
1351
|
-
}
|
|
1352
|
-
total
|
|
1344
|
+
query checkTransferLocationRecommendation($originPalletId: String!, $toLocationName: String!, $qty: Float!) {
|
|
1345
|
+
checkTransferLocationRecommendation(originPalletId: $originPalletId, toLocationName: $toLocationName, qty: $qty) {
|
|
1346
|
+
warningMessage
|
|
1353
1347
|
}
|
|
1354
1348
|
}
|
|
1355
1349
|
`,
|
|
1356
|
-
variables: {
|
|
1357
|
-
filters: [
|
|
1358
|
-
{ name: 'locationName', operator: 'eq', value: toLocationName },
|
|
1359
|
-
{ name: 'status', operator: 'eq', value: 'STORED' }
|
|
1360
|
-
]
|
|
1361
|
-
}
|
|
1350
|
+
variables: { originPalletId, toLocationName, qty }
|
|
1362
1351
|
})
|
|
1363
1352
|
|
|
1364
|
-
if (response.errors)
|
|
1353
|
+
if (!response.errors) {
|
|
1354
|
+
const warningKey = response.data?.checkTransferLocationRecommendation?.warningMessage
|
|
1355
|
+
if (!warningKey) return true
|
|
1365
1356
|
|
|
1366
|
-
|
|
1357
|
+
const warningMsg = i18next.t(`text.${warningKey}`)
|
|
1367
1358
|
|
|
1368
|
-
|
|
1359
|
+
const result = await CustomAlert({
|
|
1360
|
+
title: i18next.t('title.reminder'),
|
|
1361
|
+
text: level === 'LEVEL 4' ? `${warningMsg}\n\n${i18next.t('text.may_proceed_without_level_4_recommendation')}` : warningMsg,
|
|
1362
|
+
confirmButton: { text: i18next.t('button.proceed') },
|
|
1363
|
+
cancelButton: { text: i18next.t('button.cancel') }
|
|
1364
|
+
})
|
|
1369
1365
|
|
|
1370
|
-
|
|
1371
|
-
case 'LEVEL 1': {
|
|
1372
|
-
await this._fetchLocations(); // REFRESH TO GET LATEST
|
|
1373
|
-
const toLocation = (this._locations || []).find(l => l.name === toLocationName)
|
|
1374
|
-
if (toLocation?.status?.toUpperCase() !== 'EMPTY') {
|
|
1375
|
-
warningMsg = i18next.t('text.reminder_location_assigned_to_another_sku')
|
|
1376
|
-
}
|
|
1377
|
-
break
|
|
1378
|
-
}
|
|
1379
|
-
case 'LEVEL 2': {
|
|
1380
|
-
const hasDifferentSku = inventoriesAtLocation.some(inv => inv.product?.sku !== fromSku)
|
|
1381
|
-
if (hasDifferentSku) {
|
|
1382
|
-
warningMsg = i18next.t('text.reminder_location_assigned_to_another_sku')
|
|
1383
|
-
}
|
|
1384
|
-
break
|
|
1385
|
-
}
|
|
1386
|
-
case 'LEVEL 3': {
|
|
1387
|
-
const hasDifferentSku = inventoriesAtLocation.some(inv => inv.product?.sku !== fromSku)
|
|
1388
|
-
const allowStacking = this._selectedInventory?.product?.allowStackingOption
|
|
1389
|
-
const stackingLimit = allowStacking ? this._stackingOptionLimit?.max : null
|
|
1390
|
-
const hitStackingLimit = stackingLimit != null && countAtLocation >= stackingLimit
|
|
1391
|
-
if (hasDifferentSku || hitStackingLimit) {
|
|
1392
|
-
warningMsg = i18next.t('text.reminder_location_occupied_by_different_sku_or_stacking_capacity')
|
|
1393
|
-
}
|
|
1394
|
-
break
|
|
1395
|
-
}
|
|
1396
|
-
default:
|
|
1397
|
-
|
|
1366
|
+
return result.value
|
|
1398
1367
|
}
|
|
1399
1368
|
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
const result = await CustomAlert({
|
|
1403
|
-
title: i18next.t('title.reminder'),
|
|
1404
|
-
text: warningMsg,
|
|
1405
|
-
confirmButton: { text: i18next.t('button.confirm') },
|
|
1406
|
-
cancelButton: { text: i18next.t('button.cancel') }
|
|
1407
|
-
})
|
|
1408
|
-
|
|
1409
|
-
return result.value
|
|
1369
|
+
return false
|
|
1410
1370
|
}
|
|
1411
1371
|
|
|
1412
1372
|
_isSpecialLocationType(type) {
|
|
@@ -215,6 +215,11 @@ class SelectProductPopup extends localize(i18next)(LitElement) {
|
|
|
215
215
|
uom
|
|
216
216
|
uomValue
|
|
217
217
|
costPrice
|
|
218
|
+
lengthUnit
|
|
219
|
+
width
|
|
220
|
+
depth
|
|
221
|
+
height
|
|
222
|
+
volume
|
|
218
223
|
product {
|
|
219
224
|
id
|
|
220
225
|
name
|
|
@@ -269,6 +274,11 @@ class SelectProductPopup extends localize(i18next)(LitElement) {
|
|
|
269
274
|
isError: false,
|
|
270
275
|
productBrand: record.brand,
|
|
271
276
|
unitPrice: parseFloat(record.costPrice).toFixed(2),
|
|
277
|
+
lengthUnit: record.lengthUnit || null,
|
|
278
|
+
width: record.width || null,
|
|
279
|
+
depth: record.depth || null,
|
|
280
|
+
height: record.height || null,
|
|
281
|
+
volume: record.volume || null,
|
|
272
282
|
product: {
|
|
273
283
|
id: record.productId,
|
|
274
284
|
name: record.name,
|
|
@@ -302,6 +312,11 @@ class SelectProductPopup extends localize(i18next)(LitElement) {
|
|
|
302
312
|
isError: false,
|
|
303
313
|
productBrand: selectedProduct.brand,
|
|
304
314
|
unitPrice: parseFloat(selectedProduct.costPrice).toFixed(2),
|
|
315
|
+
lengthUnit: selectedProduct.lengthUnit || null,
|
|
316
|
+
width: selectedProduct.width || null,
|
|
317
|
+
depth: selectedProduct.depth || null,
|
|
318
|
+
height: selectedProduct.height || null,
|
|
319
|
+
volume: selectedProduct.volume || null,
|
|
305
320
|
product: {
|
|
306
321
|
id: selectedProduct.productId,
|
|
307
322
|
name: selectedProduct.name,
|
|
@@ -336,6 +351,11 @@ class SelectProductPopup extends localize(i18next)(LitElement) {
|
|
|
336
351
|
isError: false,
|
|
337
352
|
unitPrice: parseFloat(itm.costPrice).toFixed(2),
|
|
338
353
|
productBrand: itm.brand,
|
|
354
|
+
lengthUnit: itm.lengthUnit || null,
|
|
355
|
+
width: itm.width || null,
|
|
356
|
+
depth: itm.depth || null,
|
|
357
|
+
height: itm.height || null,
|
|
358
|
+
volume: itm.volume || null,
|
|
339
359
|
product: {
|
|
340
360
|
id: itm.productId,
|
|
341
361
|
name: itm.name,
|
|
@@ -70,7 +70,7 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
70
70
|
.config=${this.config}
|
|
71
71
|
.fetchHandler="${this.fetchHandler.bind(this)}"
|
|
72
72
|
@select-record-change=${e => (this._selectedRecords = e.detail.selectedRecords)}
|
|
73
|
-
}
|
|
73
|
+
@record-change=${this._onRecordChange.bind(this)}
|
|
74
74
|
></data-grist>
|
|
75
75
|
`
|
|
76
76
|
}
|
|
@@ -275,6 +275,41 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
275
275
|
sortable: true,
|
|
276
276
|
width: 80
|
|
277
277
|
},
|
|
278
|
+
{
|
|
279
|
+
type: 'float',
|
|
280
|
+
name: 'length',
|
|
281
|
+
header: i18next.t('field.length_m'),
|
|
282
|
+
record: { editable: true },
|
|
283
|
+
imex: { header: i18next.t('field.length_m'), key: 'length', width: 25, type: 'float' },
|
|
284
|
+
sortable: true,
|
|
285
|
+
width: 80
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
type: 'float',
|
|
289
|
+
name: 'width',
|
|
290
|
+
header: i18next.t('field.width_m'),
|
|
291
|
+
record: { editable: true },
|
|
292
|
+
imex: { header: i18next.t('field.width_m'), key: 'width', width: 25, type: 'float' },
|
|
293
|
+
sortable: true,
|
|
294
|
+
width: 80
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
type: 'float',
|
|
298
|
+
name: 'height',
|
|
299
|
+
header: i18next.t('field.height_m'),
|
|
300
|
+
record: { editable: true },
|
|
301
|
+
imex: { header: i18next.t('field.height_m'), key: 'height', width: 25, type: 'float' },
|
|
302
|
+
sortable: true,
|
|
303
|
+
width: 80
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
type: 'float',
|
|
307
|
+
name: 'volume',
|
|
308
|
+
header: i18next.t('field.volume_m3'),
|
|
309
|
+
record: { editable: false },
|
|
310
|
+
sortable: true,
|
|
311
|
+
width: 80
|
|
312
|
+
},
|
|
278
313
|
{
|
|
279
314
|
type: 'select',
|
|
280
315
|
name: 'status',
|
|
@@ -302,6 +337,15 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
302
337
|
sortable: true,
|
|
303
338
|
width: 80
|
|
304
339
|
},
|
|
340
|
+
{
|
|
341
|
+
type: 'string',
|
|
342
|
+
name: 'locationClass',
|
|
343
|
+
header: i18next.t('field.class'),
|
|
344
|
+
record: { editable: true },
|
|
345
|
+
imex: { header: i18next.t('field.class'), key: 'locationClass', width: 50, type: 'string' },
|
|
346
|
+
sortable: true,
|
|
347
|
+
width: 120
|
|
348
|
+
},
|
|
305
349
|
{
|
|
306
350
|
type: 'datetime',
|
|
307
351
|
name: 'updatedAt',
|
|
@@ -336,8 +380,18 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
336
380
|
.records=${records}
|
|
337
381
|
.config=${{
|
|
338
382
|
rows: this.config.rows,
|
|
339
|
-
columns: [
|
|
383
|
+
columns: [
|
|
384
|
+
...this.config.columns.filter(column => column.imex !== undefined),
|
|
385
|
+
{
|
|
386
|
+
type: 'string',
|
|
387
|
+
name: 'errMsg',
|
|
388
|
+
header: i18next.t('field.error_message'),
|
|
389
|
+
record: { editable: false },
|
|
390
|
+
width: 300
|
|
391
|
+
}
|
|
392
|
+
]
|
|
340
393
|
}}
|
|
394
|
+
.enableRowErrors=${true}
|
|
341
395
|
.importHandler="${this.importHandler.bind(this)}"
|
|
342
396
|
></import-pop-up>
|
|
343
397
|
`,
|
|
@@ -373,6 +427,11 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
373
427
|
column
|
|
374
428
|
shelf
|
|
375
429
|
status
|
|
430
|
+
length
|
|
431
|
+
width
|
|
432
|
+
height
|
|
433
|
+
volume
|
|
434
|
+
locationClass
|
|
376
435
|
updatedAt
|
|
377
436
|
updater {
|
|
378
437
|
id
|
|
@@ -394,16 +453,10 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
394
453
|
if (!response.errors) {
|
|
395
454
|
var responseItems = response.data.locations.items || []
|
|
396
455
|
var total = response.data.locations.total || 0
|
|
397
|
-
|
|
398
|
-
if (this._locationList.length > 0) {
|
|
399
|
-
let generatedItems = this._locationList
|
|
400
|
-
var records = [...responseItems, ...generatedItems]
|
|
401
|
-
total += generatedItems.length
|
|
402
|
-
}
|
|
403
456
|
}
|
|
404
457
|
|
|
405
458
|
return {
|
|
406
|
-
records:
|
|
459
|
+
records: responseItems || [],
|
|
407
460
|
total: total || 0
|
|
408
461
|
}
|
|
409
462
|
}
|
|
@@ -419,7 +472,10 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
419
472
|
const locationType = Object.keys(LOCATION_TYPE)
|
|
420
473
|
const locationStatus = Object.keys(LOCATION_STATUS)
|
|
421
474
|
|
|
475
|
+
let hasError = false
|
|
422
476
|
patches = patches.map(itm => {
|
|
477
|
+
itm.errMsg = ''
|
|
478
|
+
|
|
423
479
|
// Error if there is an empty value
|
|
424
480
|
if (
|
|
425
481
|
isEmpty(itm.name) ||
|
|
@@ -430,30 +486,56 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
430
486
|
isEmpty(itm.status) ||
|
|
431
487
|
''
|
|
432
488
|
) {
|
|
433
|
-
|
|
489
|
+
itm.errMsg = i18next.t('text.empty_value_in_list')
|
|
490
|
+
hasError = true
|
|
491
|
+
return itm
|
|
434
492
|
}
|
|
435
493
|
// Error if location name is already existed
|
|
436
494
|
if (records.find(exist => exist.name == itm.name)) {
|
|
437
|
-
|
|
495
|
+
itm.errMsg = i18next.t('text.location_name(s)_already_existed')
|
|
496
|
+
hasError = true
|
|
497
|
+
return itm
|
|
438
498
|
}
|
|
439
499
|
|
|
440
|
-
// Error if location
|
|
500
|
+
// Error if location type does not exist
|
|
441
501
|
let foundLocationType = locationType.find(exist => exist == itm.type)
|
|
442
502
|
if (!foundLocationType) {
|
|
443
|
-
|
|
503
|
+
itm.errMsg = i18next.t('text.location_type_does_not_exist')
|
|
504
|
+
hasError = true
|
|
505
|
+
return itm
|
|
444
506
|
}
|
|
445
|
-
|
|
507
|
+
|
|
508
|
+
// Error if Class has data for Quarantine or Damage location type
|
|
509
|
+
const isRestricted = [LOCATION_TYPE.QUARANTINE.value, LOCATION_TYPE.DAMAGE.value].includes(itm.type)
|
|
510
|
+
if (isRestricted && itm.locationClass) {
|
|
511
|
+
itm.errMsg = i18next.t('text.cannot_update_class_for_quarantine_or_damage_location')
|
|
512
|
+
hasError = true
|
|
513
|
+
return itm
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Error if location status does not exist
|
|
446
517
|
let foundLocationStatus = locationStatus.find(exist => exist == itm.status)
|
|
447
518
|
if (!foundLocationStatus) {
|
|
448
|
-
|
|
519
|
+
itm.errMsg = i18next.t('text.location_status_does_not_exist')
|
|
520
|
+
hasError = true
|
|
521
|
+
return itm
|
|
449
522
|
}
|
|
523
|
+
|
|
450
524
|
return itm
|
|
451
525
|
})
|
|
526
|
+
|
|
527
|
+
if (hasError) return patches
|
|
528
|
+
|
|
452
529
|
if (patches && patches.length) {
|
|
453
530
|
patches = patches.map(patch => {
|
|
454
531
|
if (this._warehouseId) {
|
|
455
532
|
patch.warehouse = { id: this._warehouseId }
|
|
456
533
|
}
|
|
534
|
+
delete patch.errMsg
|
|
535
|
+
delete patch.volume
|
|
536
|
+
patch.length = patch.length || null
|
|
537
|
+
patch.width = patch.width || null
|
|
538
|
+
patch.height = patch.height || null
|
|
457
539
|
return patch
|
|
458
540
|
})
|
|
459
541
|
const response = await client.mutate({
|
|
@@ -502,6 +584,7 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
502
584
|
if (this._warehouseId && !patch.warehouse) {
|
|
503
585
|
patch.warehouse = { id: this._warehouseId }
|
|
504
586
|
}
|
|
587
|
+
delete patch.volume
|
|
505
588
|
return patch
|
|
506
589
|
})
|
|
507
590
|
|
|
@@ -650,9 +733,11 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
650
733
|
openPopup(
|
|
651
734
|
html`
|
|
652
735
|
<generate-location-list
|
|
653
|
-
@generated="${e => {
|
|
654
|
-
this.
|
|
655
|
-
this.dataGrist.
|
|
736
|
+
@generated="${async e => {
|
|
737
|
+
await this.dataGrist.fetch()
|
|
738
|
+
this.dataGrist._data.records.push(...e.detail)
|
|
739
|
+
this.dataGrist._data.total += e.detail.length
|
|
740
|
+
this.dataGrist.refresh()
|
|
656
741
|
}}"
|
|
657
742
|
></generate-location-list>
|
|
658
743
|
`,
|
|
@@ -783,6 +868,43 @@ class LocationList extends connect(store)(localize(i18next)(PageView)) {
|
|
|
783
868
|
}
|
|
784
869
|
}
|
|
785
870
|
|
|
871
|
+
_onRecordChange(e) {
|
|
872
|
+
const { column, after } = e.detail
|
|
873
|
+
|
|
874
|
+
if (column.name === 'type') {
|
|
875
|
+
const isRestricted = [LOCATION_TYPE.QUARANTINE.value, LOCATION_TYPE.DAMAGE.value].includes(after.type)
|
|
876
|
+
if (isRestricted) after.locationClass = null
|
|
877
|
+
return
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
if (column.name === 'locationClass') {
|
|
881
|
+
const isRestricted = [LOCATION_TYPE.QUARANTINE.value, LOCATION_TYPE.DAMAGE.value].includes(after.type)
|
|
882
|
+
if (isRestricted) {
|
|
883
|
+
after.locationClass = null
|
|
884
|
+
showToast(new Error(i18next.t('text.cannot_update_class_for_quarantine_or_damage_location')))
|
|
885
|
+
}
|
|
886
|
+
return
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
if (!['length', 'width', 'height'].includes(column.name)) return
|
|
890
|
+
|
|
891
|
+
const value = parseFloat(after[column.name])
|
|
892
|
+
if (!isNaN(value) && value <= 0) {
|
|
893
|
+
showToast(new Error(i18next.t('text.value_must_be_greater_than_zero')))
|
|
894
|
+
after[column.name] = null
|
|
895
|
+
} else if (!isNaN(value)) {
|
|
896
|
+
after[column.name] = parseFloat(value.toFixed(2))
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const length = after.length
|
|
900
|
+
const width = after.width
|
|
901
|
+
const height = after.height
|
|
902
|
+
|
|
903
|
+
after.volume = length > 0 && width > 0 && height > 0
|
|
904
|
+
? parseFloat((parseFloat(length) * parseFloat(width) * parseFloat(height)).toFixed(2))
|
|
905
|
+
: null
|
|
906
|
+
}
|
|
907
|
+
|
|
786
908
|
stateChanged(state) {
|
|
787
909
|
var locationLabelSetting = state.dashboard[LOCATION_LABEL_SETTING_KEY]
|
|
788
910
|
this._locationLabel = (locationLabelSetting && locationLabelSetting.board) || {}
|
|
@@ -46,6 +46,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
|
|
|
46
46
|
_disableCrossDockingSetting: Boolean,
|
|
47
47
|
_hideCrossDockingSetting: Boolean,
|
|
48
48
|
_strictProductSelection: Boolean,
|
|
49
|
+
_locationRecommendationLevel: String,
|
|
49
50
|
containerSizes: Array,
|
|
50
51
|
productGristConfig: Object,
|
|
51
52
|
vasGristConfig: Object,
|
|
@@ -477,6 +478,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
|
|
|
477
478
|
this._hideCrossDockingSetting = await fetchSettingRule('hide-cross-dock')
|
|
478
479
|
this._bizplaces = await this.fetchBizplaces()
|
|
479
480
|
this.enableDirectInbound = await fetchSettingRule('enable-direct-gan-order')
|
|
481
|
+
this._locationRecommendationLevel = (await fetchSettingRule('location-recommendation-level') || '').toUpperCase().trim()
|
|
480
482
|
|
|
481
483
|
this._validateTransport()
|
|
482
484
|
|
|
@@ -1223,6 +1225,22 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
|
|
|
1223
1225
|
this._validateProducts()
|
|
1224
1226
|
this._validateVas()
|
|
1225
1227
|
|
|
1228
|
+
if (this._locationRecommendationLevel === 'LEVEL 4') {
|
|
1229
|
+
const records = this.productGrist.dirtyData.records
|
|
1230
|
+
const invalidProduct = records.find(record =>
|
|
1231
|
+
!record.lengthUnit || (record.volume == null && (!record.width || !record.depth || !record.height))
|
|
1232
|
+
)
|
|
1233
|
+
if (invalidProduct) {
|
|
1234
|
+
const result = await CustomAlert({
|
|
1235
|
+
title: i18next.t('title.reminder'),
|
|
1236
|
+
text: i18next.t('text.missing_product_dimensions_for_level_4'),
|
|
1237
|
+
confirmButton: { text: i18next.t('button.proceed') },
|
|
1238
|
+
cancelButton: { text: i18next.t('button.cancel') }
|
|
1239
|
+
})
|
|
1240
|
+
if (!result.value) return
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1226
1244
|
const result = await CustomAlert({
|
|
1227
1245
|
title: i18next.t('title.are_you_sure'),
|
|
1228
1246
|
text: i18next.t('text.create_arrival_notice'),
|
|
@@ -241,6 +241,7 @@ class DraftReleaseGoodList extends localize(i18next)(PageView) {
|
|
|
241
241
|
{ name: 'Shopify', value: 'SPF' },
|
|
242
242
|
{ name: 'Tiktok', value: 'TTK' },
|
|
243
243
|
{ name: 'Magento', value: 'MGT' },
|
|
244
|
+
{ name: 'Xilnex', value: 'XILNEX' },
|
|
244
245
|
{ name: 'Generic', value: 'GENERIC' }
|
|
245
246
|
]
|
|
246
247
|
}
|