@things-factory/operato-wms 4.3.680 → 4.3.682
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/constants/worksheet.js +4 -0
- package/client/pages/inventory/inventory-adjustment.js +1 -8
- package/client/pages/outbound/packing-product.js +40 -29
- package/client/pages/outbound/picking-product.js +180 -5
- package/package.json +5 -5
- package/translations/en.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
|
@@ -115,6 +115,10 @@ export const WORKSHEET_STATUS = {
|
|
|
115
115
|
PARTIAL_PROCESSING: {
|
|
116
116
|
name: i18next.t('label.partial_processing'),
|
|
117
117
|
value: 'PARTIAL_PROCESSING'
|
|
118
|
+
},
|
|
119
|
+
PARTIAL_EXECUTING: {
|
|
120
|
+
name: i18next.t('label.partial_executing'),
|
|
121
|
+
value: 'PARTIAL_EXECUTING'
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
124
|
|
|
@@ -1166,13 +1166,6 @@ class InventoryAdjustment extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1166
1166
|
if (new Date(itm?.manufactureDate) > new Date()) {
|
|
1167
1167
|
throw new Error(i18next.t('text.invalid_manufacture_date'))
|
|
1168
1168
|
}
|
|
1169
|
-
if (itm.expirationDate != null) {
|
|
1170
|
-
if (new Date(itm.expirationDate) < new Date()) {
|
|
1171
|
-
this.showToast({
|
|
1172
|
-
message: `${i18next.t('text.expiration_date_will_be_earlier_than_today')}`
|
|
1173
|
-
})
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
1169
|
if (
|
|
1177
1170
|
itm?.adjustmentCode?.trim() == '' ||
|
|
1178
1171
|
(itm?.adjustmentCode?.trim() != ADJUSTMENT_CODE.AC01.value &&
|
|
@@ -1196,7 +1189,7 @@ class InventoryAdjustment extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1196
1189
|
throw new Error(i18next.t('text.sku_is_required_kindly_fill_in_the_sku_to_continue'))
|
|
1197
1190
|
}
|
|
1198
1191
|
|
|
1199
|
-
if (itm.qty <
|
|
1192
|
+
if (itm.qty < 0 || itm.unitCost < 0 || itm.uomValue < 0) {
|
|
1200
1193
|
throw new Error(i18next.t('text.invalid_value_in_list'))
|
|
1201
1194
|
}
|
|
1202
1195
|
|
|
@@ -805,13 +805,10 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
805
805
|
variables: { orderPackageId: id }
|
|
806
806
|
})
|
|
807
807
|
if (!response.errors) {
|
|
808
|
-
|
|
809
|
-
this.
|
|
810
|
-
|
|
811
|
-
return {
|
|
812
|
-
invoice: response.data.fetchSellercraftDocument.invoice,
|
|
813
|
-
airwayBill: response.data.fetchSellercraftDocument.airwayBill
|
|
814
|
-
}
|
|
808
|
+
const { invoice, airwayBill } = response.data.fetchSellercraftDocument
|
|
809
|
+
this.invoice = invoice
|
|
810
|
+
this.airwayBill = airwayBill
|
|
811
|
+
return { invoice, airwayBill }
|
|
815
812
|
}
|
|
816
813
|
}
|
|
817
814
|
|
|
@@ -823,6 +820,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
823
820
|
let document = await fetchOrder(this._orderPackageInformation.orderPackage.id)
|
|
824
821
|
invoice = document.invoice
|
|
825
822
|
}
|
|
823
|
+
if (!invoice || invoice.trim() === '') throw new Error('Document not available')
|
|
826
824
|
let url = new URL(window.location)
|
|
827
825
|
convertedPdfUrl = `${url.origin}/proxy?url=${invoice}`
|
|
828
826
|
} else if (type == 'awb') {
|
|
@@ -832,6 +830,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
832
830
|
let document = await fetchOrder(this._orderPackageInformation.orderPackage.id)
|
|
833
831
|
airwayBill = document.airwayBill
|
|
834
832
|
}
|
|
833
|
+
if (!airwayBill || airwayBill.trim() === '') throw new Error('Document not available')
|
|
835
834
|
if (airwayBill.includes('partner.shopeemobile.com')) {
|
|
836
835
|
convertedPdfUrl = `/pdf/merge?urls=${airwayBill}`
|
|
837
836
|
} else {
|
|
@@ -868,7 +867,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
868
867
|
|
|
869
868
|
if (type == 'invoice') {
|
|
870
869
|
let invoice = this.invoice
|
|
871
|
-
|
|
870
|
+
if (!invoice || String(invoice).trim() === '') throw new Error('Document not available')
|
|
872
871
|
if (isValidHttpUrl(invoice)) {
|
|
873
872
|
let url = new URL(window.location)
|
|
874
873
|
convertedPdfUrl = `${url.origin}/proxy?url=${invoice}`
|
|
@@ -877,7 +876,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
877
876
|
}
|
|
878
877
|
} else if (type == 'awb') {
|
|
879
878
|
let airwayBill = this.airwayBill
|
|
880
|
-
|
|
879
|
+
if (!airwayBill || String(airwayBill).trim() === '') throw new Error('Document not available')
|
|
881
880
|
if (airwayBill.includes('partner.shopeemobile.com')) {
|
|
882
881
|
convertedPdfUrl = `/pdf/merge?urls=${airwayBill}`
|
|
883
882
|
} else if (isValidHttpUrl(airwayBill)) {
|
|
@@ -923,6 +922,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
923
922
|
let document = await this.fetchPowrupOrderDocument(this._orderPackageInformation.orderPackage.id)
|
|
924
923
|
invoice = document.invoice
|
|
925
924
|
}
|
|
925
|
+
if (!invoice || invoice.trim() === '') throw new Error('Document not available')
|
|
926
926
|
let url = new URL(window.location)
|
|
927
927
|
convertedPdfUrl = `${url.origin}/proxy?url=${invoice}`
|
|
928
928
|
} else if (type == 'awb') {
|
|
@@ -932,6 +932,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
932
932
|
let document = await this.fetchPowrupOrderDocument(this._orderPackageInformation.orderPackage.id)
|
|
933
933
|
airwayBill = document.airwayBill
|
|
934
934
|
}
|
|
935
|
+
if (!airwayBill || airwayBill.trim() === '') throw new Error('Document not available')
|
|
935
936
|
if (airwayBill.includes('partner.shopeemobile.com')) {
|
|
936
937
|
convertedPdfUrl = `/pdf/merge?urls=${airwayBill}`
|
|
937
938
|
} else {
|
|
@@ -970,13 +971,10 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
970
971
|
variables: { orderPackageId: id }
|
|
971
972
|
})
|
|
972
973
|
if (!response.errors) {
|
|
973
|
-
|
|
974
|
-
this.
|
|
975
|
-
|
|
976
|
-
return {
|
|
977
|
-
invoice: response.data.fetchPowrupDocument.invoice,
|
|
978
|
-
airwayBill: response.data.fetchPowrupDocument.airwayBill
|
|
979
|
-
}
|
|
974
|
+
const { invoice, airwayBill } = response.data.fetchPowrupDocument
|
|
975
|
+
this.invoice = invoice
|
|
976
|
+
this.airwayBill = airwayBill
|
|
977
|
+
return { invoice, airwayBill }
|
|
980
978
|
}
|
|
981
979
|
}
|
|
982
980
|
|
|
@@ -999,6 +997,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
999
997
|
let document = await this.fetchWebspertOrderDocument(this._orderPackageInformation.orderPackage.id)
|
|
1000
998
|
invoice = document.invoice
|
|
1001
999
|
}
|
|
1000
|
+
if (!invoice || invoice.trim() === '') throw new Error('Document not available')
|
|
1002
1001
|
let url = new URL(window.location)
|
|
1003
1002
|
convertedPdfUrl = `${url.origin}/proxy?url=${invoice}`
|
|
1004
1003
|
} else if (type == 'awb') {
|
|
@@ -1008,6 +1007,7 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1008
1007
|
let document = await this.fetchWebspertOrderDocument(this._orderPackageInformation.orderPackage.id)
|
|
1009
1008
|
airwayBill = document.airwayBill
|
|
1010
1009
|
}
|
|
1010
|
+
if (!airwayBill || airwayBill.trim() === '') throw new Error('Document not available')
|
|
1011
1011
|
if (airwayBill.includes('partner.shopeemobile.com')) {
|
|
1012
1012
|
convertedPdfUrl = `/pdf/merge?urls=${airwayBill}`
|
|
1013
1013
|
} else {
|
|
@@ -1046,13 +1046,10 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1046
1046
|
variables: { orderPackageId: id }
|
|
1047
1047
|
})
|
|
1048
1048
|
if (!response.errors) {
|
|
1049
|
-
|
|
1050
|
-
this.
|
|
1051
|
-
|
|
1052
|
-
return {
|
|
1053
|
-
invoice: response.data.fetchWebspertDocument.invoice,
|
|
1054
|
-
airwayBill: response.data.fetchWebspertDocument.airwayBill
|
|
1055
|
-
}
|
|
1049
|
+
const { invoice, airwayBill } = response.data.fetchWebspertDocument
|
|
1050
|
+
this.invoice = invoice
|
|
1051
|
+
this.airwayBill = airwayBill
|
|
1052
|
+
return { invoice, airwayBill }
|
|
1056
1053
|
}
|
|
1057
1054
|
}
|
|
1058
1055
|
|
|
@@ -1103,12 +1100,13 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1103
1100
|
|
|
1104
1101
|
var orderDocInfo = await this.getOrderDocument(this.refNo, 'shippingLabel')
|
|
1105
1102
|
|
|
1106
|
-
if (orderDocInfo
|
|
1103
|
+
if (!orderDocInfo || orderDocInfo.length === 0) {
|
|
1107
1104
|
throw new Error('Document not available')
|
|
1108
1105
|
} else {
|
|
1109
1106
|
let content
|
|
1110
1107
|
if (this.platform == 'shopee' && !orderDocInfo[0]?.isShopeeV2) {
|
|
1111
|
-
const orderDocUrls = orderDocInfo.map(item => item.airwayBill)
|
|
1108
|
+
const orderDocUrls = orderDocInfo.map(item => item.airwayBill).filter(url => url && String(url).trim() !== '')
|
|
1109
|
+
if (orderDocUrls.length === 0) throw new Error('Document not available')
|
|
1112
1110
|
for (var i = 0; i < orderDocUrls.length; i++) {
|
|
1113
1111
|
orderDocUrls[i] = 'urls=' + orderDocUrls[i]
|
|
1114
1112
|
}
|
|
@@ -1120,7 +1118,9 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1120
1118
|
// }
|
|
1121
1119
|
else {
|
|
1122
1120
|
let url = new URL(window.location)
|
|
1123
|
-
|
|
1121
|
+
const awb = orderDocInfo[0]?.airwayBill
|
|
1122
|
+
if (!awb || String(awb).trim() === '') throw new Error('Document not available')
|
|
1123
|
+
content = `${url.origin}/proxy?url=${encodeURIComponent(awb)}`
|
|
1124
1124
|
}
|
|
1125
1125
|
this.callPrintDialog(content)
|
|
1126
1126
|
}
|
|
@@ -1176,6 +1176,14 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1176
1176
|
}
|
|
1177
1177
|
|
|
1178
1178
|
async callPrintDialog(contentSource) {
|
|
1179
|
+
if (
|
|
1180
|
+
!contentSource ||
|
|
1181
|
+
(typeof contentSource === 'string' && contentSource.trim() === '') ||
|
|
1182
|
+
contentSource === 'undefined'
|
|
1183
|
+
) {
|
|
1184
|
+
this.showToast({ type: 'warning', message: i18next.t('text.no_document_available') })
|
|
1185
|
+
return
|
|
1186
|
+
}
|
|
1179
1187
|
switch (this.platform) {
|
|
1180
1188
|
//this condition is to select based on the content type
|
|
1181
1189
|
//for html content will be using srcdoc
|
|
@@ -1775,12 +1783,15 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1775
1783
|
}
|
|
1776
1784
|
}
|
|
1777
1785
|
|
|
1778
|
-
showToast(
|
|
1786
|
+
showToast(payload) {
|
|
1787
|
+
const normalized = typeof payload === 'string' ? { message: payload } : payload || {}
|
|
1788
|
+
const notifyType = normalized.type || 'error'
|
|
1789
|
+
const notifyMessage = normalized.message || i18next.t('text.no_document_available')
|
|
1779
1790
|
document.dispatchEvent(
|
|
1780
1791
|
new CustomEvent('notify', {
|
|
1781
1792
|
detail: {
|
|
1782
|
-
type,
|
|
1783
|
-
message
|
|
1793
|
+
type: notifyType,
|
|
1794
|
+
message: notifyMessage
|
|
1784
1795
|
}
|
|
1785
1796
|
})
|
|
1786
1797
|
)
|
|
@@ -1267,8 +1267,59 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1267
1267
|
}
|
|
1268
1268
|
|
|
1269
1269
|
async validatePicking() {
|
|
1270
|
-
//
|
|
1271
|
-
|
|
1270
|
+
// Support random picking sequence: auto-select row by scanned identifiers (carton/pallet) and product barcode
|
|
1271
|
+
if (this._pageSettings?.enablePickingRandomSeq === true) {
|
|
1272
|
+
// 1) Carton-based (carton label flow)
|
|
1273
|
+
if (this.cartonInput?.value) {
|
|
1274
|
+
const scannedCartonId = this.cartonInput.value.trim()
|
|
1275
|
+
if (scannedCartonId) {
|
|
1276
|
+
let candidates = (this.data?.records || []).filter(
|
|
1277
|
+
rec => rec.cartonId === scannedCartonId && rec.status !== 'DONE' && rec.status !== 'MISSING'
|
|
1278
|
+
)
|
|
1279
|
+
candidates = this._filterCandidatesByInputQty(candidates)
|
|
1280
|
+
|
|
1281
|
+
// Validate carton id: must have at least one candidate
|
|
1282
|
+
if (!candidates || candidates.length === 0) {
|
|
1283
|
+
this._focusOnCartonNoInput()
|
|
1284
|
+
throw new Error(i18next.t('text.invalid_carton_id'))
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
if (this._enableProductScanning) {
|
|
1288
|
+
// Require product barcode when product scanning enabled
|
|
1289
|
+
if (!this.productBarcodeInput?.value) {
|
|
1290
|
+
this._focusOnProductBarcodeInput()
|
|
1291
|
+
throw new Error(i18next.t('text.empty_product_barcode'))
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
const matchedRecord = await this._selectRecordByGtinFromCandidates(
|
|
1295
|
+
this.productBarcodeInput.value.trim(),
|
|
1296
|
+
candidates
|
|
1297
|
+
)
|
|
1298
|
+
|
|
1299
|
+
if (!matchedRecord) {
|
|
1300
|
+
this._focusOnProductBarcodeInput()
|
|
1301
|
+
this.productBarcodeInput.value = ''
|
|
1302
|
+
throw new Error(i18next.t('text.incorrect_product_barcode'))
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
if (!this._selectedOrderInventory || this._selectedOrderInventory.name !== matchedRecord.name) {
|
|
1306
|
+
this.updateSelectedItemProp(matchedRecord)
|
|
1307
|
+
this.scannableField()
|
|
1308
|
+
}
|
|
1309
|
+
} else {
|
|
1310
|
+
// Product scanning disabled: pick a deterministic candidate
|
|
1311
|
+
const matchedRecord = this._pickBestCandidate(candidates)
|
|
1312
|
+
if (
|
|
1313
|
+
matchedRecord &&
|
|
1314
|
+
(!this._selectedOrderInventory || this._selectedOrderInventory.name !== matchedRecord.name)
|
|
1315
|
+
) {
|
|
1316
|
+
this.updateSelectedItemProp(matchedRecord)
|
|
1317
|
+
this.scannableField()
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1272
1323
|
|
|
1273
1324
|
if ((!this.palletInput?.value || !this.cartonInput?.value) && this._isRequireSerialNumberScanningOutbound) {
|
|
1274
1325
|
if (!this.serialInput?.value) {
|
|
@@ -1320,8 +1371,31 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1320
1371
|
// Auto Find matching carton for pick scanning row without forcing the user to choose
|
|
1321
1372
|
if (this._pageSettings.enablePickingRandomSeq == true) {
|
|
1322
1373
|
let cartonInputValue = this.cartonInput.value
|
|
1323
|
-
|
|
1324
|
-
|
|
1374
|
+
let candidates = this.data.records.filter(
|
|
1375
|
+
rec => rec.cartonId === cartonInputValue && rec.status !== 'DONE' && rec.status !== 'MISSING'
|
|
1376
|
+
)
|
|
1377
|
+
candidates = this._filterCandidatesByInputQty(candidates)
|
|
1378
|
+
if (this._enableProductScanning && this.productBarcodeInput?.value) {
|
|
1379
|
+
foundRecord = await this._selectRecordByGtinFromCandidates(
|
|
1380
|
+
this.productBarcodeInput.value.trim(),
|
|
1381
|
+
candidates
|
|
1382
|
+
)
|
|
1383
|
+
}
|
|
1384
|
+
// If product barcode is provided but no GTIN match, stop without fallback
|
|
1385
|
+
if (this._enableProductScanning && this.productBarcodeInput?.value && !foundRecord) {
|
|
1386
|
+
this._focusOnProductBarcodeInput()
|
|
1387
|
+
this.productBarcodeInput.value = ''
|
|
1388
|
+
throw new Error(i18next.t('text.incorrect_product_barcode'))
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// No product barcode: deterministically choose best candidate among duplicates
|
|
1392
|
+
if (!foundRecord && (!this._enableProductScanning || !this.productBarcodeInput?.value)) {
|
|
1393
|
+
foundRecord = this._pickBestCandidate(candidates)
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
if (foundRecord) {
|
|
1397
|
+
this.updateSelectedItemProp(foundRecord)
|
|
1398
|
+
}
|
|
1325
1399
|
} else {
|
|
1326
1400
|
foundRecord = null
|
|
1327
1401
|
}
|
|
@@ -1579,6 +1653,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1579
1653
|
}
|
|
1580
1654
|
bizplaceName
|
|
1581
1655
|
partnerDomainId
|
|
1656
|
+
customerCompanyDomainId
|
|
1582
1657
|
refNo
|
|
1583
1658
|
refNo2
|
|
1584
1659
|
refNo3
|
|
@@ -1757,6 +1832,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1757
1832
|
worksheetInfo {
|
|
1758
1833
|
bizplaceName
|
|
1759
1834
|
partnerDomainId
|
|
1835
|
+
customerCompanyDomainId
|
|
1760
1836
|
startedAt
|
|
1761
1837
|
}
|
|
1762
1838
|
worksheetDetailInfos {
|
|
@@ -2222,7 +2298,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
2222
2298
|
settings: {
|
|
2223
2299
|
name: 'name',
|
|
2224
2300
|
operator: 'in',
|
|
2225
|
-
value: ['enable-product-scanning', 'qr-code-scanning', 'enable-tote-scanning']
|
|
2301
|
+
value: ['enable-product-scanning', 'qr-code-scanning', 'enable-tote-scanning', 'enable-input-qty']
|
|
2226
2302
|
},
|
|
2227
2303
|
settingsDomain: this._worksheetInfo.partnerDomainId
|
|
2228
2304
|
})
|
|
@@ -2231,6 +2307,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
2231
2307
|
|
|
2232
2308
|
this._enableProductScanning = settingsMap.get('enable-product-scanning') === 'true'
|
|
2233
2309
|
this._enableToteScanning = settingsMap.get('enable-tote-scanning') === 'true'
|
|
2310
|
+
this._enableInputQty = settingsMap.get('enable-input-qty')
|
|
2234
2311
|
this._qrProcessing = settingsMap.get('qr-code-scanning')
|
|
2235
2312
|
|
|
2236
2313
|
this._selectedOrderInventory = this.data?.records[0] || undefined
|
|
@@ -2359,6 +2436,104 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
2359
2436
|
}
|
|
2360
2437
|
|
|
2361
2438
|
massageReleaseGood(response) {}
|
|
2439
|
+
|
|
2440
|
+
_getTypedQty() {
|
|
2441
|
+
if (!this.releaseQtyInput || !this.releaseQtyInput.value) return null
|
|
2442
|
+
const qty = parseFloat(this.releaseQtyInput.value)
|
|
2443
|
+
if (isNaN(qty) || qty <= 0) return null
|
|
2444
|
+
return qty
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
_filterCandidatesByInputQty(candidates) {
|
|
2448
|
+
const typedQty = this._getTypedQty()
|
|
2449
|
+
if (!typedQty || !Array.isArray(candidates) || !candidates.length) return candidates
|
|
2450
|
+
const matches = candidates.filter(rec => parseFloat(rec?.releaseQty) === typedQty)
|
|
2451
|
+
return matches.length ? matches : candidates
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
_pickBestCandidate(candidates) {
|
|
2455
|
+
if (!Array.isArray(candidates) || !candidates.length) return null
|
|
2456
|
+
|
|
2457
|
+
const sorted = [...candidates].sort((a, b) => {
|
|
2458
|
+
const aCompleted = !!a?.completed
|
|
2459
|
+
const bCompleted = !!b?.completed
|
|
2460
|
+
if (aCompleted !== bCompleted) return aCompleted - bCompleted // prefer incomplete
|
|
2461
|
+
|
|
2462
|
+
const aMissing = a?.status === 'MISSING'
|
|
2463
|
+
const bMissing = b?.status === 'MISSING'
|
|
2464
|
+
if (aMissing !== bMissing) return aMissing - bMissing // prefer not missing
|
|
2465
|
+
|
|
2466
|
+
const aPending = !!a?.hasMissingInventoryChanges
|
|
2467
|
+
const bPending = !!b?.hasMissingInventoryChanges
|
|
2468
|
+
if (aPending !== bPending) return aPending - bPending // prefer not pending
|
|
2469
|
+
|
|
2470
|
+
const aRemain = (a?.releaseQty || 0) - (a?.pickedQty || 0)
|
|
2471
|
+
const bRemain = (b?.releaseQty || 0) - (b?.pickedQty || 0)
|
|
2472
|
+
if (aRemain !== bRemain) return bRemain - aRemain // prefer greater remaining qty
|
|
2473
|
+
|
|
2474
|
+
if (a?.name && b?.name && a.name !== b.name) return a.name.localeCompare(b.name)
|
|
2475
|
+
return 0
|
|
2476
|
+
})
|
|
2477
|
+
|
|
2478
|
+
return sorted[0] || null
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
async _selectRecordByGtinFromCandidates(gtin, candidates) {
|
|
2482
|
+
try {
|
|
2483
|
+
if (!gtin || !candidates?.length) return null
|
|
2484
|
+
|
|
2485
|
+
// Apply qty-based narrowing first when duplicates exist
|
|
2486
|
+
candidates = this._filterCandidatesByInputQty(candidates)
|
|
2487
|
+
|
|
2488
|
+
// Use checkGtin to resolve product-packing info to match candidate rows
|
|
2489
|
+
const response = await client.query({
|
|
2490
|
+
query: gql`
|
|
2491
|
+
query checkGtin($gtin: String!, $customerCompanyDomainId: String!) {
|
|
2492
|
+
checkGtin(gtin: $gtin, customerCompanyDomainId: $customerCompanyDomainId) {
|
|
2493
|
+
items {
|
|
2494
|
+
id
|
|
2495
|
+
name
|
|
2496
|
+
packingType
|
|
2497
|
+
packingSize
|
|
2498
|
+
gtin
|
|
2499
|
+
product {
|
|
2500
|
+
id
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
total
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
`,
|
|
2507
|
+
variables: {
|
|
2508
|
+
gtin,
|
|
2509
|
+
customerCompanyDomainId: this._worksheetInfo?.customerCompanyDomainId
|
|
2510
|
+
}
|
|
2511
|
+
})
|
|
2512
|
+
|
|
2513
|
+
if (response?.errors) return null
|
|
2514
|
+
|
|
2515
|
+
const items = response?.data?.checkGtin?.items || []
|
|
2516
|
+
if (!items.length) return null
|
|
2517
|
+
|
|
2518
|
+
// First try exact product+packing match, then fall back to product-only match
|
|
2519
|
+
const exactMatches = candidates.filter(rec =>
|
|
2520
|
+
items.some(
|
|
2521
|
+
itm =>
|
|
2522
|
+
itm.product?.id === rec?.product?.id &&
|
|
2523
|
+
itm.packingType === rec.packingType &&
|
|
2524
|
+
itm.packingSize === rec.packingSize
|
|
2525
|
+
)
|
|
2526
|
+
)
|
|
2527
|
+
if (exactMatches.length) return this._pickBestCandidate(exactMatches)
|
|
2528
|
+
|
|
2529
|
+
const productOnlyMatches = candidates.filter(rec => items.some(itm => itm.product?.id === rec?.product?.id))
|
|
2530
|
+
if (productOnlyMatches.length) return this._pickBestCandidate(productOnlyMatches)
|
|
2531
|
+
|
|
2532
|
+
return null
|
|
2533
|
+
} catch (e) {
|
|
2534
|
+
return null
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2362
2537
|
}
|
|
2363
2538
|
|
|
2364
2539
|
window.customElements.define('picking-product', PickingProduct)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/operato-wms",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.682",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"@things-factory/print-ui": "^4.3.675",
|
|
92
92
|
"@things-factory/product-base": "^4.3.677",
|
|
93
93
|
"@things-factory/resource-ui": "^4.3.677",
|
|
94
|
-
"@things-factory/sales-ui": "^4.3.
|
|
94
|
+
"@things-factory/sales-ui": "^4.3.682",
|
|
95
95
|
"@things-factory/scene-data-transform": "^4.3.591",
|
|
96
96
|
"@things-factory/scene-excel": "^4.3.591",
|
|
97
97
|
"@things-factory/scene-firebase": "^4.3.591",
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"@things-factory/system-ui": "^4.3.675",
|
|
108
108
|
"@things-factory/transport-base": "^4.3.677",
|
|
109
109
|
"@things-factory/tutorial-ui": "^4.3.677",
|
|
110
|
-
"@things-factory/warehouse-base": "^4.3.
|
|
111
|
-
"@things-factory/worksheet-base": "^4.3.
|
|
110
|
+
"@things-factory/warehouse-base": "^4.3.682",
|
|
111
|
+
"@things-factory/worksheet-base": "^4.3.682"
|
|
112
112
|
},
|
|
113
113
|
"devDependencies": {
|
|
114
114
|
"@things-factory/builder": "^4.3.591",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"cypress-localstorage-commands": "^1.6.1",
|
|
118
118
|
"eslint-plugin-cypress": "^2.12.1"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "b2ad61e11288f94f4fc73b4f74c049e70a77079a"
|
|
121
121
|
}
|
package/translations/en.json
CHANGED
|
@@ -1049,6 +1049,7 @@
|
|
|
1049
1049
|
"label.order_status_loading": "loading",
|
|
1050
1050
|
"label.order_status_packing": "packing",
|
|
1051
1051
|
"label.order_status_partial_return": "partial return",
|
|
1052
|
+
"label.order_status_partial_processing": "partial processing",
|
|
1052
1053
|
"label.order_status_pending": "pending",
|
|
1053
1054
|
"label.order_status_pending_approval": "pending approval",
|
|
1054
1055
|
"label.order_status_pending_cancel": "pending cancel",
|
package/translations/ko.json
CHANGED
|
@@ -1041,6 +1041,7 @@
|
|
|
1041
1041
|
"label.order_status_loading": "상차중",
|
|
1042
1042
|
"label.order_status_packing": "[ko] packing",
|
|
1043
1043
|
"label.order_status_partial_return": "부분 반환",
|
|
1044
|
+
"label.order_status_partial_processing": "부분 처리중",
|
|
1044
1045
|
"label.order_status_pending_approval": "승인 대기",
|
|
1045
1046
|
"label.order_status_pending_cancel": "취소 대기",
|
|
1046
1047
|
"label.order_status_pending_receive": "미수집",
|
package/translations/ms.json
CHANGED
|
@@ -1059,6 +1059,7 @@
|
|
|
1059
1059
|
"label.order_status_in_transit": "dalam perjalanan",
|
|
1060
1060
|
"label.order_status_inspecting": "disemak",
|
|
1061
1061
|
"label.order_status_intransit": "dalam perjalanan",
|
|
1062
|
+
"label.order_status_partial_processing": "sebahagian diproses",
|
|
1062
1063
|
"label.order_status_pending": "dalam penyediaan",
|
|
1063
1064
|
"label.order_status_pending_cancel": "pending dibatalkan",
|
|
1064
1065
|
"label.order_status_pending_receive": "pending diterima",
|
package/translations/zh.json
CHANGED
|
@@ -1076,6 +1076,7 @@
|
|
|
1076
1076
|
"label.order_status_loading": "装载中",
|
|
1077
1077
|
"label.order_status_packing": "包装中",
|
|
1078
1078
|
"label.order_status_partial_return": "部分退货",
|
|
1079
|
+
"label.order_status_partial_processing": "部分处理中",
|
|
1079
1080
|
"label.order_status_pending": "待处理",
|
|
1080
1081
|
"label.order_status_pending_approval": "待批准",
|
|
1081
1082
|
"label.order_status_pending_cancel": "待取消",
|