@things-factory/operato-wms 4.3.769 → 4.3.770
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/components/list-view/product-list-view.js +28 -3
- package/client/pages/components/mobile-condition-of-goods-listing.js +342 -0
- package/client/pages/components/unloading-worksheet-information-popup.js +299 -0
- package/client/pages/constants/order.js +7 -0
- package/client/pages/inbound/condition-of-goods-popup.js +646 -0
- package/client/pages/inbound/putaway/putaway-product.js +35 -6
- package/client/pages/inbound/unload-product-landing-page.js +282 -0
- package/client/pages/inbound/unload-product.js +707 -175
- package/client/pages/inbound/unloaded-inventories-popup.js +3 -0
- package/client/pages/inventory/inventory-adjustment-approval.js +28 -1
- package/client/pages/inventory/inventory-adjustment.js +31 -1
- package/client/pages/inventory/inventory-by-product-detail.js +15 -0
- package/client/pages/inventory/inventory-history.js +18 -0
- package/client/pages/inventory/onhand-inventory.js +14 -0
- package/client/pages/order/release-order/b2b/b2b-order-list.js +99 -0
- package/client/pages/order/release-order/packing-label-history-popup.js +378 -0
- package/client/pages/order/release-order/preview-print-packing-list.js +533 -0
- package/client/pages/order/release-order/print-quantity-popup.js +118 -0
- package/client/pages/outbound/loading-v2/loading-execution-base.js +29 -0
- package/client/pages/outbound/loading-v2/loading-execution.js +579 -2
- package/client/pages/outbound/loading-v2/loading-package-info-popup.js +182 -0
- package/client/pages/outbound/loading-v2/loading.js +18 -0
- package/client/pages/report/inbound-order-details-report.js +26 -1
- package/client/route.js +17 -0
- package/dist-server/graphql/resolvers/outbound/find-loadable-release-good-by-bin.js +9 -1
- package/dist-server/graphql/resolvers/outbound/find-loadable-release-good-by-bin.js.map +1 -1
- package/dist-server/graphql/resolvers/outbound/loading-worksheet-v2.js +11 -5
- package/dist-server/graphql/resolvers/outbound/loading-worksheet-v2.js.map +1 -1
- package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js +2 -1
- package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js.map +1 -1
- package/dist-server/graphql/types/reports/inbound-order-details-report.js +1 -0
- package/dist-server/graphql/types/reports/inbound-order-details-report.js.map +1 -1
- package/package.json +15 -15
- package/server/graphql/resolvers/outbound/find-loadable-release-good-by-bin.ts +9 -1
- package/server/graphql/resolvers/outbound/loading-worksheet-v2.ts +13 -1
- package/server/graphql/resolvers/reports/inbound-order-details-report.ts +2 -1
- package/server/graphql/types/reports/inbound-order-details-report.ts +1 -0
- package/things-factory.config.js +8 -0
- package/translations/en.json +45 -1
- package/translations/ko.json +40 -0
- package/translations/ms.json +40 -0
- package/translations/zh.json +40 -0
|
@@ -121,14 +121,20 @@ const FIND_LOADABLE_RELEASE_GOOD_BY_BIN = gql`
|
|
|
121
121
|
batchId
|
|
122
122
|
packingType
|
|
123
123
|
refWorksheetId
|
|
124
|
+
packedQty
|
|
125
|
+
releaseQty
|
|
124
126
|
product {
|
|
125
127
|
id
|
|
126
128
|
sku
|
|
127
129
|
name
|
|
130
|
+
isInventoryDecimal
|
|
128
131
|
}
|
|
129
132
|
productDetail {
|
|
130
133
|
id
|
|
131
134
|
}
|
|
135
|
+
orderProduct {
|
|
136
|
+
id
|
|
137
|
+
}
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
}
|
|
@@ -182,14 +188,20 @@ const LOADING_WORKSHEET_V2 = gql`
|
|
|
182
188
|
batchId
|
|
183
189
|
packingType
|
|
184
190
|
refWorksheetId
|
|
191
|
+
packedQty
|
|
192
|
+
releaseQty
|
|
185
193
|
product {
|
|
186
194
|
id
|
|
187
195
|
sku
|
|
188
196
|
name
|
|
197
|
+
isInventoryDecimal
|
|
189
198
|
}
|
|
190
199
|
productDetail {
|
|
191
200
|
id
|
|
192
201
|
}
|
|
202
|
+
orderProduct {
|
|
203
|
+
id
|
|
204
|
+
}
|
|
193
205
|
}
|
|
194
206
|
}
|
|
195
207
|
}
|
|
@@ -519,6 +531,18 @@ export class LoadingExecutionBase extends LitElement {
|
|
|
519
531
|
}
|
|
520
532
|
}
|
|
521
533
|
|
|
534
|
+
get groupPackingListButton() {
|
|
535
|
+
// Only return button when active tab is LOADING
|
|
536
|
+
if (this.state?.activeTab !== TAB_TYPES.LOADING) {
|
|
537
|
+
return null
|
|
538
|
+
}
|
|
539
|
+
return {
|
|
540
|
+
title: i18next.t('button.group_packing_list'),
|
|
541
|
+
action: async () => {},
|
|
542
|
+
...CommonButtonStyles.inspect
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
522
546
|
// Input Getters
|
|
523
547
|
get productBarcodeInput() {
|
|
524
548
|
return this.shadowRoot
|
|
@@ -1152,6 +1176,11 @@ export class LoadingExecutionBase extends LitElement {
|
|
|
1152
1176
|
if (this._useQcSku) {
|
|
1153
1177
|
buttons.unshift(this.orderListButton)
|
|
1154
1178
|
}
|
|
1179
|
+
// Only add button if getter returns a valid button (checks activeTab internally)
|
|
1180
|
+
const groupPackingButton = this.groupPackingListButton
|
|
1181
|
+
if (groupPackingButton) {
|
|
1182
|
+
buttons.unshift(groupPackingButton)
|
|
1183
|
+
}
|
|
1155
1184
|
buttons.unshift(this.warehouseReturnButton)
|
|
1156
1185
|
buttons.unshift(this.loadButton)
|
|
1157
1186
|
}
|
|
@@ -9,7 +9,11 @@ import { isMobileDevice } from '@things-factory/utils'
|
|
|
9
9
|
import { LoadingExecutionBase } from './loading-execution-base'
|
|
10
10
|
import '../../components/list-view/product-list-view'
|
|
11
11
|
import { fetchSettingRule } from '../../../fetch-setting-value'
|
|
12
|
-
import {
|
|
12
|
+
import { CommonButtonStyles } from '@things-factory/styles'
|
|
13
|
+
import { client, CustomAlert, gqlContext } from '@things-factory/shell'
|
|
14
|
+
import { openPopup } from '@things-factory/layout-base'
|
|
15
|
+
import { showToast } from '../../../util'
|
|
16
|
+
import './loading-package-info-popup'
|
|
13
17
|
|
|
14
18
|
// Constants
|
|
15
19
|
const SETTINGS = {
|
|
@@ -37,6 +41,61 @@ const VALIDATE_QC_SEALS = gql`
|
|
|
37
41
|
}
|
|
38
42
|
`
|
|
39
43
|
|
|
44
|
+
const GROUP_PACKING_TAB_TYPES = {
|
|
45
|
+
SKU: 'SKU',
|
|
46
|
+
PACKING_LIST: 'Packing Label'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const GROUP_PACKING_TABS = [GROUP_PACKING_TAB_TYPES.SKU, GROUP_PACKING_TAB_TYPES.PACKING_LIST]
|
|
50
|
+
|
|
51
|
+
const CREATE_GROUP_LOADING_PACKAGES = gql`
|
|
52
|
+
mutation createGroupLoadingPackages($releaseGoodNo: String!, $groupedItems: [GroupLoadingPackageItem!]!) {
|
|
53
|
+
createGroupLoadingPackages(releaseGoodNo: $releaseGoodNo, groupedItems: $groupedItems) {
|
|
54
|
+
id
|
|
55
|
+
name
|
|
56
|
+
status
|
|
57
|
+
loadingPackageItems {
|
|
58
|
+
id
|
|
59
|
+
name
|
|
60
|
+
releaseQty
|
|
61
|
+
orderProduct {
|
|
62
|
+
id
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
`
|
|
68
|
+
|
|
69
|
+
const GET_LOADING_PACKAGES = gql`
|
|
70
|
+
query loadingPackagesByReleaseGoodNo($releaseGoodNo: String!) {
|
|
71
|
+
loadingPackagesByReleaseGoodNo(releaseGoodNo: $releaseGoodNo) {
|
|
72
|
+
id
|
|
73
|
+
name
|
|
74
|
+
status
|
|
75
|
+
createdAt
|
|
76
|
+
loadingPackageItems {
|
|
77
|
+
id
|
|
78
|
+
name
|
|
79
|
+
packedQty
|
|
80
|
+
orderProduct {
|
|
81
|
+
id
|
|
82
|
+
name
|
|
83
|
+
packingType
|
|
84
|
+
product {
|
|
85
|
+
id
|
|
86
|
+
name
|
|
87
|
+
sku
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
productDetail {
|
|
91
|
+
id
|
|
92
|
+
packingType
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
`
|
|
98
|
+
|
|
40
99
|
// List View Configurations
|
|
41
100
|
const QC_LIST_CONFIG = {
|
|
42
101
|
selectable: true,
|
|
@@ -134,6 +193,65 @@ const LOADING_LIST_CONFIG = {
|
|
|
134
193
|
}
|
|
135
194
|
}
|
|
136
195
|
|
|
196
|
+
const SKU_LIST_CONFIG = {
|
|
197
|
+
selectable: true,
|
|
198
|
+
columnLeft: {
|
|
199
|
+
size: 8,
|
|
200
|
+
fields: [
|
|
201
|
+
{
|
|
202
|
+
type: 'row',
|
|
203
|
+
content: [
|
|
204
|
+
{
|
|
205
|
+
header: 'SKU No.',
|
|
206
|
+
field: 'relatedOrderInv.product.sku',
|
|
207
|
+
type: 'string'
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
type: 'row',
|
|
213
|
+
content: [
|
|
214
|
+
{
|
|
215
|
+
header: 'Product Name',
|
|
216
|
+
field: 'relatedOrderInv.product.name',
|
|
217
|
+
type: 'string',
|
|
218
|
+
style: '-webkit-line-clamp: 2;'
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: 'row',
|
|
224
|
+
content: [
|
|
225
|
+
{
|
|
226
|
+
header: 'Packing Type',
|
|
227
|
+
field: 'relatedOrderInv.packingType',
|
|
228
|
+
type: 'string'
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
columnRight: {
|
|
235
|
+
size: 4,
|
|
236
|
+
fields: [
|
|
237
|
+
{
|
|
238
|
+
type: 'row',
|
|
239
|
+
content: [
|
|
240
|
+
{
|
|
241
|
+
header: 'Total Qty.',
|
|
242
|
+
field: 'remainingQty',
|
|
243
|
+
type: 'string'
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
type: 'editableValueBox',
|
|
249
|
+
content: { header: 'Group Qty.', field: 'groupQty', type: 'number', placeholder: 'e.g. 10', defaultValue: '' }
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
137
255
|
export class LoadingExecution extends LoadingExecutionBase {
|
|
138
256
|
static get properties() {
|
|
139
257
|
return {
|
|
@@ -141,7 +259,11 @@ export class LoadingExecution extends LoadingExecutionBase {
|
|
|
141
259
|
_useQcSku: { type: Boolean },
|
|
142
260
|
_currentReleaseGood: { type: Object },
|
|
143
261
|
_tabCounts: { type: Object },
|
|
144
|
-
_qcBannerState: { type: Object }
|
|
262
|
+
_qcBannerState: { type: Object },
|
|
263
|
+
_isGroupPackingMode: { type: Boolean },
|
|
264
|
+
_groupPackingActiveTab: { type: String },
|
|
265
|
+
_loadingPackages: { type: Array },
|
|
266
|
+
_combinedSkuData: { type: Array }
|
|
145
267
|
}
|
|
146
268
|
}
|
|
147
269
|
|
|
@@ -325,6 +447,9 @@ export class LoadingExecution extends LoadingExecutionBase {
|
|
|
325
447
|
this._useQcSku = false
|
|
326
448
|
this._currentReleaseGood = null
|
|
327
449
|
this._qcBannerState = { show: false, needsSealing: false, minimumSealNumber: 0 }
|
|
450
|
+
this._isGroupPackingMode = false
|
|
451
|
+
this._loadingPackages = []
|
|
452
|
+
this._combinedSkuData = []
|
|
328
453
|
this._deliveryOrderConfig = {
|
|
329
454
|
columnLeft: {
|
|
330
455
|
size: 8,
|
|
@@ -367,6 +492,7 @@ export class LoadingExecution extends LoadingExecutionBase {
|
|
|
367
492
|
startedAt: this.worksheet?.startedAt
|
|
368
493
|
}
|
|
369
494
|
}
|
|
495
|
+
|
|
370
496
|
// Update banner state when QC or loading data changes
|
|
371
497
|
if (changedProperties.has('qcData') || changedProperties.has('loadingData')) {
|
|
372
498
|
if (this._updateQcBannerState) {
|
|
@@ -375,6 +501,66 @@ export class LoadingExecution extends LoadingExecutionBase {
|
|
|
375
501
|
}
|
|
376
502
|
}
|
|
377
503
|
|
|
504
|
+
get groupPackingListButton() {
|
|
505
|
+
return {
|
|
506
|
+
title: i18next.t('button.group_packing_label'),
|
|
507
|
+
action: async () => {
|
|
508
|
+
if (this.state?.activeTab !== TAB_TYPES.LOADING) {
|
|
509
|
+
showToast({ message: i18next.t('text.only_available_on_loading_tab'), type: 'error' })
|
|
510
|
+
return
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
await this._fetchLoadingPackages()
|
|
514
|
+
this._calculateAndCombineSkuData()
|
|
515
|
+
this._isGroupPackingMode = true
|
|
516
|
+
this.getButton()
|
|
517
|
+
},
|
|
518
|
+
...CommonButtonStyles.inspect
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
//===== OVERWRITE PARENT CLASS, FOR GROUP PACKING MODE =====
|
|
523
|
+
getButton() {
|
|
524
|
+
if (this._isGroupPackingMode) {
|
|
525
|
+
const actions = [
|
|
526
|
+
{
|
|
527
|
+
title: i18next.t('button.back'),
|
|
528
|
+
action: () => {
|
|
529
|
+
this._isGroupPackingMode = false
|
|
530
|
+
this.getButton()
|
|
531
|
+
},
|
|
532
|
+
...CommonButtonStyles.back
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
title: i18next.t('button.group'),
|
|
536
|
+
action: async () => {
|
|
537
|
+
await this.handleGroupPackages()
|
|
538
|
+
},
|
|
539
|
+
...CommonButtonStyles.submit
|
|
540
|
+
}
|
|
541
|
+
]
|
|
542
|
+
|
|
543
|
+
this.parent.configContext(actions)
|
|
544
|
+
} else {
|
|
545
|
+
super.getButton()
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
get backButton() {
|
|
550
|
+
const base = super.backButton
|
|
551
|
+
return {
|
|
552
|
+
...base,
|
|
553
|
+
action: () => {
|
|
554
|
+
if (this._isGroupPackingMode) {
|
|
555
|
+
this._groupPackingActiveTab = GROUP_PACKING_TAB_TYPES.SKU
|
|
556
|
+
this._isGroupPackingMode = false
|
|
557
|
+
} else {
|
|
558
|
+
base.action()
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
378
564
|
combineSameProducts(data) {
|
|
379
565
|
const combinedMap = new Map()
|
|
380
566
|
|
|
@@ -453,10 +639,137 @@ export class LoadingExecution extends LoadingExecutionBase {
|
|
|
453
639
|
return LOADING_LIST_CONFIG
|
|
454
640
|
}
|
|
455
641
|
|
|
642
|
+
get skuListItemConfig() {
|
|
643
|
+
return SKU_LIST_CONFIG
|
|
644
|
+
}
|
|
645
|
+
|
|
456
646
|
get deliveryOrderConfig() {
|
|
457
647
|
return this._deliveryOrderConfig
|
|
458
648
|
}
|
|
459
649
|
|
|
650
|
+
_calculateAndCombineSkuData() {
|
|
651
|
+
if (!this.loadingData || this.loadingData.length === 0) {
|
|
652
|
+
this._combinedSkuData = []
|
|
653
|
+
return
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Step 1: Group loadingData by orderProductId and sum their releaseQty
|
|
657
|
+
const releaseQtyByOrderProductId = new Map()
|
|
658
|
+
this.loadingData.forEach(item => {
|
|
659
|
+
const orderProductId = item.relatedOrderInv?.orderProduct?.id
|
|
660
|
+
if (orderProductId) {
|
|
661
|
+
const currentReleaseQty = parseFloat(item.relatedOrderInv?.releaseQty || item.releaseQty) || 0
|
|
662
|
+
const existing = releaseQtyByOrderProductId.get(orderProductId) || 0
|
|
663
|
+
releaseQtyByOrderProductId.set(orderProductId, existing + currentReleaseQty)
|
|
664
|
+
}
|
|
665
|
+
})
|
|
666
|
+
|
|
667
|
+
// Step 2: Group loadingPackageItems by orderProductId and sum their packedQty
|
|
668
|
+
const packedQtyByOrderProductId = new Map()
|
|
669
|
+
if (this._loadingPackages && this._loadingPackages.length > 0) {
|
|
670
|
+
this._loadingPackages.forEach(pkg => {
|
|
671
|
+
if (pkg.loadingPackageItems && pkg.loadingPackageItems.length > 0) {
|
|
672
|
+
pkg.loadingPackageItems.forEach(item => {
|
|
673
|
+
const orderProductId = item.orderProduct?.id
|
|
674
|
+
if (orderProductId) {
|
|
675
|
+
const packedQty = parseFloat(item.packedQty) || 0
|
|
676
|
+
const existing = packedQtyByOrderProductId.get(orderProductId) || 0
|
|
677
|
+
packedQtyByOrderProductId.set(orderProductId, existing + packedQty)
|
|
678
|
+
}
|
|
679
|
+
})
|
|
680
|
+
}
|
|
681
|
+
})
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Step 3: Combine items by orderProductId and create simple array
|
|
685
|
+
const combinedMap = new Map()
|
|
686
|
+
|
|
687
|
+
this.loadingData.forEach(item => {
|
|
688
|
+
const orderProductId = item.relatedOrderInv?.orderProduct?.id
|
|
689
|
+
if (!orderProductId) return
|
|
690
|
+
|
|
691
|
+
if (!combinedMap.has(orderProductId)) {
|
|
692
|
+
const totalReleaseQty = releaseQtyByOrderProductId.get(orderProductId) || 0
|
|
693
|
+
const totalPackedQty = packedQtyByOrderProductId.get(orderProductId) || 0
|
|
694
|
+
const remainingQty = Math.max(0, totalReleaseQty - totalPackedQty)
|
|
695
|
+
|
|
696
|
+
// Create simple object with only needed fields
|
|
697
|
+
combinedMap.set(orderProductId, {
|
|
698
|
+
id: item.id, // Keep first item's id for selection
|
|
699
|
+
orderProductId: orderProductId,
|
|
700
|
+
remainingQty: remainingQty.toString(),
|
|
701
|
+
packedQty: totalPackedQty,
|
|
702
|
+
sku: item.relatedOrderInv?.product?.sku || '',
|
|
703
|
+
productName: item.relatedOrderInv?.product?.name || '',
|
|
704
|
+
packingType: item.relatedOrderInv?.packingType || '',
|
|
705
|
+
isInventoryDecimal: item.relatedOrderInv?.product?.isInventoryDecimal || false,
|
|
706
|
+
groupQty: null, // Reset to null (empty field, will use full availableQty)
|
|
707
|
+
relatedOrderInv: {
|
|
708
|
+
...item.relatedOrderInv,
|
|
709
|
+
orderProduct: {
|
|
710
|
+
id: orderProductId
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
})
|
|
714
|
+
}
|
|
715
|
+
})
|
|
716
|
+
|
|
717
|
+
// Step 4: Filter out items with remainingQty === 0
|
|
718
|
+
this._combinedSkuData = Array.from(combinedMap.values()).filter(item => {
|
|
719
|
+
const remainingQty = parseFloat(item.remainingQty || 0)
|
|
720
|
+
return remainingQty > 0
|
|
721
|
+
})
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
get filteredSkuData() {
|
|
725
|
+
return this._combinedSkuData || []
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
get packingListConfig() {
|
|
729
|
+
return {
|
|
730
|
+
selectable: false,
|
|
731
|
+
columnLeft: {
|
|
732
|
+
size: 8,
|
|
733
|
+
fields: [
|
|
734
|
+
{
|
|
735
|
+
type: 'row',
|
|
736
|
+
content: [
|
|
737
|
+
{
|
|
738
|
+
header: 'Packing Label No.',
|
|
739
|
+
field: 'displayNumber',
|
|
740
|
+
type: 'number',
|
|
741
|
+
style: 'font-weight: bold;'
|
|
742
|
+
}
|
|
743
|
+
]
|
|
744
|
+
}
|
|
745
|
+
]
|
|
746
|
+
},
|
|
747
|
+
columnRight: {
|
|
748
|
+
size: 4,
|
|
749
|
+
fields: [
|
|
750
|
+
{
|
|
751
|
+
type: 'actionBox',
|
|
752
|
+
content: [
|
|
753
|
+
{
|
|
754
|
+
header: 'View Info',
|
|
755
|
+
btnClass: 'btn-common',
|
|
756
|
+
callback: rowData => {
|
|
757
|
+
const originalPackage = this._loadingPackages.find(pkg => pkg.id === rowData.id)
|
|
758
|
+
if (originalPackage) {
|
|
759
|
+
this.openLoadingPackageInfoPopup(originalPackage)
|
|
760
|
+
} else {
|
|
761
|
+
console.error('Loading package not found:', rowData.id)
|
|
762
|
+
showToast({ message: i18next.t('text.error_occurred') || 'Error loading package details', type: 'error' })
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
]
|
|
767
|
+
}
|
|
768
|
+
]
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
460
773
|
/**
|
|
461
774
|
* Determines if the "Go to LOADED" banner should be shown.
|
|
462
775
|
* Banner appears when:
|
|
@@ -557,7 +870,271 @@ export class LoadingExecution extends LoadingExecutionBase {
|
|
|
557
870
|
return this._qcBannerState?.show || false
|
|
558
871
|
}
|
|
559
872
|
|
|
873
|
+
async openGroupPackingTab(e, tabName) {
|
|
874
|
+
if (this.state?.activeTab !== TAB_TYPES.LOADING) {
|
|
875
|
+
showToast({ message: i18next.t('text.only_available_on_loading_tab'), type: 'error' })
|
|
876
|
+
return
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
this._groupPackingActiveTab = tabName
|
|
880
|
+
await this.updateComplete
|
|
881
|
+
|
|
882
|
+
await this._fetchLoadingPackages()
|
|
883
|
+
if (tabName === GROUP_PACKING_TAB_TYPES.SKU) {
|
|
884
|
+
this._calculateAndCombineSkuData()
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
async _fetchLoadingPackages() {
|
|
889
|
+
const releaseGoodNo = this._currentReleaseGood?.releaseGood?.name || this.worksheet?.releaseGood?.name
|
|
890
|
+
if (!releaseGoodNo) {
|
|
891
|
+
console.warn('No release good number available to fetch loading packages')
|
|
892
|
+
this._loadingPackages = []
|
|
893
|
+
return
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
try {
|
|
897
|
+
const response = await client.query({
|
|
898
|
+
query: GET_LOADING_PACKAGES,
|
|
899
|
+
variables: { releaseGoodNo },
|
|
900
|
+
})
|
|
901
|
+
|
|
902
|
+
if (response.errors) {
|
|
903
|
+
throw new Error(response.errors[0]?.message || i18next.t('text.error_occurred'))
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
const packages = response.data.loadingPackagesByReleaseGoodNo || []
|
|
907
|
+
this._loadingPackages = packages.map((pkg, index) => ({
|
|
908
|
+
...pkg,
|
|
909
|
+
displayNumber: index + 1
|
|
910
|
+
}))
|
|
911
|
+
this.requestUpdate()
|
|
912
|
+
} catch (error) {
|
|
913
|
+
console.error('Error fetching loading packages:', error)
|
|
914
|
+
showToast({ message: error.message || i18next.t('text.error_occurred'), type: 'error' })
|
|
915
|
+
this._loadingPackages = []
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
async openLoadingPackageInfoPopup(loadingPackage) {
|
|
921
|
+
if (!loadingPackage || !loadingPackage.loadingPackageItems || loadingPackage.loadingPackageItems.length === 0) {
|
|
922
|
+
showToast({ message: i18next.t('text.no_items_found') || 'No items found in this package', type: 'info' })
|
|
923
|
+
return
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
const items = loadingPackage.loadingPackageItems.map(item => ({
|
|
927
|
+
id: item.id,
|
|
928
|
+
sku: item.orderProduct?.product?.sku || '',
|
|
929
|
+
productName: item.orderProduct?.product?.name || item.orderProduct?.name || '',
|
|
930
|
+
packingType: item.productDetail?.packingType || item.orderProduct?.packingType || '',
|
|
931
|
+
qty: item.packedQty
|
|
932
|
+
}))
|
|
933
|
+
|
|
934
|
+
await openPopup(
|
|
935
|
+
html`
|
|
936
|
+
<loading-package-info-popup
|
|
937
|
+
._data=${items}
|
|
938
|
+
._packageName=${loadingPackage.name}
|
|
939
|
+
._packageNumber=${loadingPackage.displayNumber}
|
|
940
|
+
._packageId=${loadingPackage.id}
|
|
941
|
+
@undo=${async e => {
|
|
942
|
+
await this._fetchLoadingPackages()
|
|
943
|
+
this._calculateAndCombineSkuData()
|
|
944
|
+
this.requestUpdate()
|
|
945
|
+
}}
|
|
946
|
+
></loading-package-info-popup>
|
|
947
|
+
`,
|
|
948
|
+
{
|
|
949
|
+
backdrop: true,
|
|
950
|
+
size: 'large',
|
|
951
|
+
title: `${i18next.t('text.packing_list_info') || 'Packing List Info'}: ${loadingPackage.name}`
|
|
952
|
+
}
|
|
953
|
+
)
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
async handleGroupPackages() {
|
|
957
|
+
try {
|
|
958
|
+
const skuListView = this.shadowRoot.querySelector('#sku')
|
|
959
|
+
if (!skuListView) {
|
|
960
|
+
showToast({ message: i18next.t('text.sku_list_view_not_found') })
|
|
961
|
+
return
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const selectedItemIds = skuListView.selectedItems || []
|
|
965
|
+
if (selectedItemIds.length === 0) {
|
|
966
|
+
showToast({ message: i18next.t('text.no_sku_selected') })
|
|
967
|
+
return
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
const viewData = skuListView.data || []
|
|
971
|
+
const selectedItems = viewData.filter(item => selectedItemIds.includes(item.id))
|
|
972
|
+
|
|
973
|
+
if (selectedItems.length === 0) {
|
|
974
|
+
showToast({ message: i18next.t('text.selected_items_not_found') })
|
|
975
|
+
return
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
const groupedItems = selectedItems.map(item => {
|
|
979
|
+
const availableQty = parseFloat(item.remainingQty) || 0
|
|
980
|
+
// Check direct property first (from combined SKU data), then fallback to nested path
|
|
981
|
+
const isInventoryDecimal = item.isInventoryDecimal === true || item.relatedOrderInv?.product?.isInventoryDecimal === true
|
|
982
|
+
const productSku = item.sku || item.relatedOrderInv?.product?.sku || 'Unknown'
|
|
983
|
+
|
|
984
|
+
let groupQty
|
|
985
|
+
|
|
986
|
+
if (item.groupQty == null) {
|
|
987
|
+
groupQty = availableQty
|
|
988
|
+
} else {
|
|
989
|
+
const enteredQty = parseFloat(item.groupQty)
|
|
990
|
+
|
|
991
|
+
if (isNaN(enteredQty)) {
|
|
992
|
+
throw new Error(i18next.t('text.invalid_quantity_input') || 'Invalid quantity input')
|
|
993
|
+
} else if (enteredQty === 0) {
|
|
994
|
+
throw new Error(i18next.t('text.group_quantity_cannot_be_zero') || 'Group quantity cannot be zero')
|
|
995
|
+
} else if (enteredQty < 0) {
|
|
996
|
+
throw new Error(i18next.t('text.group_quantity_cannot_be_negative') || 'Group quantity cannot be negative')
|
|
997
|
+
} else {
|
|
998
|
+
groupQty = enteredQty
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Validate decimal values - only allow decimals if isInventoryDecimal is true
|
|
1003
|
+
if (!isInventoryDecimal && !Number.isInteger(groupQty)) {
|
|
1004
|
+
throw new Error(
|
|
1005
|
+
i18next.t('text.decimal_not_allowed_for_product', { sku: productSku }) ||
|
|
1006
|
+
`Decimal quantity is not allowed for product ${productSku}`
|
|
1007
|
+
)
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Validate groupQty doesn't exceed available quantity
|
|
1011
|
+
if (groupQty > availableQty) {
|
|
1012
|
+
throw new Error(i18next.t('text.group_quantity_exceeds_total'))
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
return {
|
|
1016
|
+
orderProductId: item.orderProductId,
|
|
1017
|
+
groupQty: groupQty
|
|
1018
|
+
}
|
|
1019
|
+
})
|
|
1020
|
+
|
|
1021
|
+
const releaseGoodNo = this._currentReleaseGood?.releaseGood?.name
|
|
1022
|
+
if (!releaseGoodNo) {
|
|
1023
|
+
showToast({ message: i18next.t('text.release_good_number_not_found') })
|
|
1024
|
+
return
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
const response = await client.mutate({
|
|
1028
|
+
mutation: CREATE_GROUP_LOADING_PACKAGES,
|
|
1029
|
+
variables: {
|
|
1030
|
+
releaseGoodNo: releaseGoodNo,
|
|
1031
|
+
groupedItems: groupedItems
|
|
1032
|
+
},
|
|
1033
|
+
context: gqlContext()
|
|
1034
|
+
})
|
|
1035
|
+
|
|
1036
|
+
if (response.errors) {
|
|
1037
|
+
throw new Error(response.errors[0]?.message || i18next.t('text.failed_to_create_group_loading_packages'))
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
const loadingPackage = response.data.createGroupLoadingPackages
|
|
1041
|
+
showToast({
|
|
1042
|
+
message: i18next.t('text.new_packing_label_created'),
|
|
1043
|
+
type: 'success'
|
|
1044
|
+
})
|
|
1045
|
+
|
|
1046
|
+
if (this._isGroupPackingMode) {
|
|
1047
|
+
await this._fetchLoadingPackages()
|
|
1048
|
+
await this.updateComplete
|
|
1049
|
+
if (this._groupPackingActiveTab === GROUP_PACKING_TAB_TYPES.SKU) {
|
|
1050
|
+
this._calculateAndCombineSkuData()
|
|
1051
|
+
await this.updateComplete
|
|
1052
|
+
const skuListView = this.shadowRoot.querySelector('#sku')
|
|
1053
|
+
if (skuListView) {
|
|
1054
|
+
skuListView.selectedItems = []
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
this.getButton()
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
console.error('Error creating group loading packages:', error)
|
|
1062
|
+
showToast({ message: error.message || i18next.t('text.failed_to_create_group_loading_packages'), type: 'error' })
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
560
1066
|
render() {
|
|
1067
|
+
if (this._isGroupPackingMode) {
|
|
1068
|
+
if (!this._groupPackingActiveTab) this._groupPackingActiveTab = GROUP_PACKING_TAB_TYPES.SKU
|
|
1069
|
+
|
|
1070
|
+
return html`
|
|
1071
|
+
<button
|
|
1072
|
+
class="order-info text-center"
|
|
1073
|
+
?disabled=${!Boolean(this._currentReleaseGood?.releaseGood?.name)}
|
|
1074
|
+
@click=${e => {
|
|
1075
|
+
if (this._currentReleaseGood?.releaseGood?.name) {
|
|
1076
|
+
this.showOrderInfo()
|
|
1077
|
+
}
|
|
1078
|
+
}}
|
|
1079
|
+
>
|
|
1080
|
+
<label class="text-14 font-bold order-no"
|
|
1081
|
+
>${i18next.t('label.order_no')}: ${this._currentReleaseGood?.releaseGood?.name || this.worksheet?.binLocationName || ''}</label
|
|
1082
|
+
>
|
|
1083
|
+
<mwc-icon style="color:#007E7F;">info</mwc-icon>
|
|
1084
|
+
</button>
|
|
1085
|
+
|
|
1086
|
+
<div class="tabs">
|
|
1087
|
+
${GROUP_PACKING_TABS.map(
|
|
1088
|
+
tab => html`
|
|
1089
|
+
<button
|
|
1090
|
+
class="font-bold tab-button ${this._groupPackingActiveTab === tab ? 'active' : ''}"
|
|
1091
|
+
@click=${async e => {
|
|
1092
|
+
await this.openGroupPackingTab(e, tab)
|
|
1093
|
+
}}
|
|
1094
|
+
>
|
|
1095
|
+
${tab === GROUP_PACKING_TAB_TYPES.SKU ? i18next.t('label.sku') : i18next.t('label.packing_label')}
|
|
1096
|
+
</button>
|
|
1097
|
+
`
|
|
1098
|
+
)}
|
|
1099
|
+
</div>
|
|
1100
|
+
|
|
1101
|
+
${this._groupPackingActiveTab === GROUP_PACKING_TAB_TYPES.SKU
|
|
1102
|
+
? html`
|
|
1103
|
+
<div class="tab-info text-center">
|
|
1104
|
+
<label class="text-14 font-bold">${i18next.t('label.total_sku')}: ${this.filteredSkuData.length}</label>
|
|
1105
|
+
</div>
|
|
1106
|
+
`
|
|
1107
|
+
: ''}
|
|
1108
|
+
|
|
1109
|
+
${this._groupPackingActiveTab === GROUP_PACKING_TAB_TYPES.PACKING_LIST
|
|
1110
|
+
? html`
|
|
1111
|
+
<div class="tab-info text-center">
|
|
1112
|
+
<label class="text-14 font-bold">${i18next.t('label.total_packing_label')}: ${(this._loadingPackages || []).length}</label>
|
|
1113
|
+
</div>
|
|
1114
|
+
`
|
|
1115
|
+
: ''}
|
|
1116
|
+
|
|
1117
|
+
<div class="tab-content ${this._groupPackingActiveTab === GROUP_PACKING_TAB_TYPES.SKU ? 'active' : ''}">
|
|
1118
|
+
<product-list-view
|
|
1119
|
+
id="sku"
|
|
1120
|
+
.config=${this.skuListItemConfig}
|
|
1121
|
+
.data=${this.filteredSkuData}
|
|
1122
|
+
></product-list-view>
|
|
1123
|
+
</div>
|
|
1124
|
+
|
|
1125
|
+
<div class="tab-content ${this._groupPackingActiveTab === GROUP_PACKING_TAB_TYPES.PACKING_LIST ? 'active' : ''}">
|
|
1126
|
+
${this._loadingPackages && this._loadingPackages.length > 0
|
|
1127
|
+
? html`
|
|
1128
|
+
<product-list-view
|
|
1129
|
+
.config=${this.packingListConfig}
|
|
1130
|
+
.data=${this._loadingPackages}
|
|
1131
|
+
></product-list-view>
|
|
1132
|
+
`
|
|
1133
|
+
: ''}
|
|
1134
|
+
</div>
|
|
1135
|
+
`
|
|
1136
|
+
}
|
|
1137
|
+
|
|
561
1138
|
if (!this.state) {
|
|
562
1139
|
this.resetView()
|
|
563
1140
|
}
|