@things-factory/operato-wms 4.3.767 → 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/bulk-operation/validate-gan-popup.js +2 -2
- 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 +77 -44
- 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/arrival-notice/create-arrival-notice.js +209 -206
- package/client/pages/order/arrival-notice/duplicate-arrival-notice.js +132 -129
- package/client/pages/order/arrival-notice/edit-product-popup.js +97 -92
- 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
|
@@ -2,6 +2,7 @@ import '@things-factory/form-ui'
|
|
|
2
2
|
import '@things-factory/grist-ui'
|
|
3
3
|
import '@things-factory/worksheet-ui'
|
|
4
4
|
import '../batch-picking-popup'
|
|
5
|
+
import '../packing-label-history-popup'
|
|
5
6
|
import '../../../outbound/generate-worksheet-popup'
|
|
6
7
|
import '../../../outbound/select-operator-popup'
|
|
7
8
|
|
|
@@ -58,6 +59,11 @@ class B2bOrderList extends localize(i18next)(PageView) {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
constructor() {
|
|
63
|
+
super()
|
|
64
|
+
this._hasSelectionListener = false
|
|
65
|
+
}
|
|
66
|
+
|
|
61
67
|
render() {
|
|
62
68
|
return html`
|
|
63
69
|
<search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.dataGrist.fetch()}></search-form>
|
|
@@ -73,6 +79,32 @@ class B2bOrderList extends localize(i18next)(PageView) {
|
|
|
73
79
|
get context() {
|
|
74
80
|
var actions = []
|
|
75
81
|
|
|
82
|
+
actions.push({
|
|
83
|
+
title: i18next.t('title.packing_label_history'),
|
|
84
|
+
action: this._openPackingLabelHistory.bind(this),
|
|
85
|
+
icon: 'history',
|
|
86
|
+
emphasis: {
|
|
87
|
+
raised: false,
|
|
88
|
+
outlined: true,
|
|
89
|
+
dense: false,
|
|
90
|
+
danger: false
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
if (this._shouldShowButtonForSelection()) {
|
|
95
|
+
actions.push({
|
|
96
|
+
title: i18next.t('title.print_packing_label'),
|
|
97
|
+
action: this._openPrintPackingList.bind(this),
|
|
98
|
+
icon: 'print',
|
|
99
|
+
emphasis: {
|
|
100
|
+
raised: false,
|
|
101
|
+
outlined: true,
|
|
102
|
+
dense: false,
|
|
103
|
+
danger: false
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
76
108
|
if (this.isUserBelongsDomain) {
|
|
77
109
|
if (this._betaSetting) {
|
|
78
110
|
actions.push({
|
|
@@ -96,6 +128,7 @@ class B2bOrderList extends localize(i18next)(PageView) {
|
|
|
96
128
|
...CommonButtonStyles.add
|
|
97
129
|
})
|
|
98
130
|
}
|
|
131
|
+
|
|
99
132
|
return {
|
|
100
133
|
title: i18next.t('title.release_orders'),
|
|
101
134
|
actions,
|
|
@@ -501,6 +534,13 @@ class B2bOrderList extends localize(i18next)(PageView) {
|
|
|
501
534
|
}
|
|
502
535
|
]
|
|
503
536
|
}
|
|
537
|
+
|
|
538
|
+
await this.updateComplete
|
|
539
|
+
if (this.dataGrist && !this._hasSelectionListener) {
|
|
540
|
+
this.dataGrist.addEventListener('select-record-change', () => this.updateContext())
|
|
541
|
+
this.dataGrist.addEventListener('select-all-change', () => this.updateContext())
|
|
542
|
+
this._hasSelectionListener = true
|
|
543
|
+
}
|
|
504
544
|
}
|
|
505
545
|
|
|
506
546
|
get searchForm() {
|
|
@@ -588,6 +628,10 @@ class B2bOrderList extends localize(i18next)(PageView) {
|
|
|
588
628
|
id
|
|
589
629
|
name
|
|
590
630
|
}
|
|
631
|
+
activeWorksheet {
|
|
632
|
+
type
|
|
633
|
+
status
|
|
634
|
+
}
|
|
591
635
|
}
|
|
592
636
|
total
|
|
593
637
|
}
|
|
@@ -812,6 +856,61 @@ class B2bOrderList extends localize(i18next)(PageView) {
|
|
|
812
856
|
return { header: headerSetting, data: data }
|
|
813
857
|
}
|
|
814
858
|
|
|
859
|
+
_shouldShowButtonForSelection() {
|
|
860
|
+
if (!this.dataGrist) return false
|
|
861
|
+
|
|
862
|
+
const selected = this.dataGrist.selected || []
|
|
863
|
+
if (selected.length === 0) return false
|
|
864
|
+
|
|
865
|
+
const allowedWorksheetTypes = ['LOADING', 'PROCESSING', 'PARTIAL_PROCESSING']
|
|
866
|
+
const allowedWorksheetStatuses = ['EXECUTING', 'PARTIAL_EXECUTING']
|
|
867
|
+
|
|
868
|
+
return selected.every(order => {
|
|
869
|
+
// Check if activeWorksheet exists
|
|
870
|
+
if (!order.activeWorksheet) return false
|
|
871
|
+
|
|
872
|
+
// Check if activeWorksheet.type is one of the allowed types
|
|
873
|
+
if (!allowedWorksheetTypes.includes(order.activeWorksheet.type)) return false
|
|
874
|
+
|
|
875
|
+
// Check if activeWorksheet.status is EXECUTING or PARTIAL_EXECUTING
|
|
876
|
+
return allowedWorksheetStatuses.includes(order.activeWorksheet.status)
|
|
877
|
+
})
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
_openPrintPackingList() {
|
|
881
|
+
try {
|
|
882
|
+
if (!this.dataGrist || !this.dataGrist.selected || this.dataGrist.selected.length === 0) {
|
|
883
|
+
throw new Error(i18next.t('text.please_select_one_or_more_order') || 'Please select one or more orders')
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
const selectedOrderNames = this.dataGrist.selected.map(order => order.name).filter(Boolean)
|
|
887
|
+
if (selectedOrderNames.length === 0) {
|
|
888
|
+
throw new Error(i18next.t('text.no_valid_orders_selected') || 'No valid orders selected')
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
const orderNoParam = selectedOrderNames.join(',')
|
|
892
|
+
navigate(`preview_print_packing_list?orderNo=${encodeURIComponent(orderNoParam)}`)
|
|
893
|
+
} catch (e) {
|
|
894
|
+
this._showToast({ type: 'error', message: e.message || i18next.t('text.failed_to_open_print_packing_label') })
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
_openPackingLabelHistory() {
|
|
899
|
+
try {
|
|
900
|
+
openPopup(
|
|
901
|
+
html` <packing-label-history-popup></packing-label-history-popup> `,
|
|
902
|
+
{
|
|
903
|
+
backdrop: true,
|
|
904
|
+
size: 'large',
|
|
905
|
+
title: i18next.t('title.packing_label_history'),
|
|
906
|
+
escapable: false
|
|
907
|
+
}
|
|
908
|
+
)
|
|
909
|
+
} catch (e) {
|
|
910
|
+
this._showToast({ type: 'error', message: e.message || i18next.t('text.failed_to_open_packing_label_history') })
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
815
914
|
_showToast({ type, message }) {
|
|
816
915
|
document.dispatchEvent(
|
|
817
916
|
new CustomEvent('notify', {
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import '@things-factory/form-ui'
|
|
2
|
+
import '@things-factory/grist-ui'
|
|
3
|
+
import './print-quantity-popup'
|
|
4
|
+
|
|
5
|
+
import gql from 'graphql-tag'
|
|
6
|
+
import { css, html, LitElement } from 'lit-element'
|
|
7
|
+
|
|
8
|
+
import { i18next, localize } from '@things-factory/i18n-base'
|
|
9
|
+
import { openPopup } from '@things-factory/layout-base'
|
|
10
|
+
import { client } from '@things-factory/shell'
|
|
11
|
+
import { ScrollbarStyles } from '@things-factory/styles'
|
|
12
|
+
import { isMobileDevice } from '@things-factory/utils'
|
|
13
|
+
|
|
14
|
+
import { showToast } from '../../../util'
|
|
15
|
+
|
|
16
|
+
class PackingLabelHistoryPopup extends localize(i18next)(LitElement) {
|
|
17
|
+
static get properties() {
|
|
18
|
+
return {
|
|
19
|
+
_searchFields: Array,
|
|
20
|
+
config: Object,
|
|
21
|
+
data: Object,
|
|
22
|
+
_packingLabelOptions: Array
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static get styles() {
|
|
27
|
+
return [
|
|
28
|
+
ScrollbarStyles,
|
|
29
|
+
css`
|
|
30
|
+
:host {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
background-color: white;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
search-form {
|
|
38
|
+
overflow: visible;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.grist {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
flex: 1;
|
|
45
|
+
overflow-y: auto;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.grist-container {
|
|
49
|
+
overflow-y: hidden;
|
|
50
|
+
display: flex;
|
|
51
|
+
flex: 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
data-grist {
|
|
55
|
+
overflow-y: hidden;
|
|
56
|
+
flex: 1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.button-container {
|
|
60
|
+
padding: var(--button-container-padding);
|
|
61
|
+
margin: var(--button-container-margin);
|
|
62
|
+
text-align: var(--button-container-align);
|
|
63
|
+
background-color: var(--button-container-background);
|
|
64
|
+
height: var(--button-container-height);
|
|
65
|
+
}
|
|
66
|
+
`
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
constructor() {
|
|
71
|
+
super()
|
|
72
|
+
this._packingLabelOptions = []
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
get searchForm() {
|
|
76
|
+
return this.shadowRoot.querySelector('search-form')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get dataGrist() {
|
|
80
|
+
return this.shadowRoot.querySelector('data-grist')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_initSearchFields() {
|
|
84
|
+
this._searchFields = [
|
|
85
|
+
{
|
|
86
|
+
label: i18next.t('field.order_no') || 'Order No.',
|
|
87
|
+
name: 'releaseGood.name',
|
|
88
|
+
type: 'text',
|
|
89
|
+
props: { searchOper: 'i_like' }
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
label: i18next.t('field.packing_label_no'),
|
|
93
|
+
name: 'displayNumber',
|
|
94
|
+
type: 'select',
|
|
95
|
+
options: this._packingLabelOptions,
|
|
96
|
+
props: { searchOper: 'eq' }
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_initConfig() {
|
|
102
|
+
this.config = {
|
|
103
|
+
rows: { selectable: { multiple: true }, appendable: false },
|
|
104
|
+
list: { fields: ['releaseGood', 'refNo', 'displayNumber', 'printedAt'] },
|
|
105
|
+
pagination: { limit: 50, pages: [20, 50, 100, 200] },
|
|
106
|
+
columns: [
|
|
107
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
108
|
+
{ type: 'gutter', gutterName: 'row-selector', multiple: true },
|
|
109
|
+
{
|
|
110
|
+
type: 'gutter',
|
|
111
|
+
gutterName: 'button',
|
|
112
|
+
icon: 'reorder',
|
|
113
|
+
handlers: {
|
|
114
|
+
click: (_columns, _data, _column, record) => {}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: 'object',
|
|
119
|
+
name: 'releaseGood',
|
|
120
|
+
header: i18next.t('field.order_no') || 'Release Orders',
|
|
121
|
+
sortable: true,
|
|
122
|
+
width: 180
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: 'string',
|
|
126
|
+
name: 'refNo',
|
|
127
|
+
header: i18next.t('field.ref_no') || 'Ref No.',
|
|
128
|
+
sortable: true,
|
|
129
|
+
width: 150
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'number',
|
|
133
|
+
name: 'displayNumber',
|
|
134
|
+
header: i18next.t('field.packing_label_no') || 'Packing Label No.',
|
|
135
|
+
sortable: true,
|
|
136
|
+
width: 120
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'datetime',
|
|
140
|
+
name: 'printedAt',
|
|
141
|
+
header: i18next.t('field.printed_at') || 'Printed At',
|
|
142
|
+
sortable: true,
|
|
143
|
+
width: 160
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: 'object',
|
|
147
|
+
name: 'printedBy',
|
|
148
|
+
header: i18next.t('field.printed_by') || 'Printed By',
|
|
149
|
+
sortable: true,
|
|
150
|
+
width: 160
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async firstUpdated() {
|
|
157
|
+
await this._fetchPackingLabelOptions()
|
|
158
|
+
this._initSearchFields()
|
|
159
|
+
this._initConfig()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async _fetchPackingLabelOptions() {
|
|
163
|
+
try {
|
|
164
|
+
const response = await client.query({
|
|
165
|
+
query: gql`
|
|
166
|
+
query {
|
|
167
|
+
maxPackingLabelCount
|
|
168
|
+
}
|
|
169
|
+
`
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
if (!response.errors) {
|
|
173
|
+
const maxCount = response.data.maxPackingLabelCount || 0
|
|
174
|
+
this._packingLabelOptions = [
|
|
175
|
+
{ value: '', name: '' },
|
|
176
|
+
...Array.from({ length: maxCount }, (_, i) => ({
|
|
177
|
+
value: String(i + 1),
|
|
178
|
+
name: String(i + 1)
|
|
179
|
+
}))
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error('Failed to fetch packing label options:', e)
|
|
184
|
+
this._packingLabelOptions = [{ value: '', name: '' }]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async fetchHandler({ page, limit, sorters = [] }) {
|
|
189
|
+
const filters = this.searchForm.queryFilters
|
|
190
|
+
|
|
191
|
+
const response = await client.query({
|
|
192
|
+
query: gql`
|
|
193
|
+
query printedLoadingPackagesHistory($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
194
|
+
printedLoadingPackagesHistory(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
195
|
+
items {
|
|
196
|
+
id
|
|
197
|
+
name
|
|
198
|
+
displayNumber
|
|
199
|
+
releaseGood {
|
|
200
|
+
id
|
|
201
|
+
name
|
|
202
|
+
refNo
|
|
203
|
+
}
|
|
204
|
+
printedAt
|
|
205
|
+
printedBy {
|
|
206
|
+
id
|
|
207
|
+
name
|
|
208
|
+
description
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
total
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
`,
|
|
215
|
+
variables: {
|
|
216
|
+
filters,
|
|
217
|
+
pagination: { page, limit },
|
|
218
|
+
sortings: sorters
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
if (!response.errors) {
|
|
223
|
+
return {
|
|
224
|
+
total: response.data.printedLoadingPackagesHistory.total || 0,
|
|
225
|
+
records:
|
|
226
|
+
response.data.printedLoadingPackagesHistory.items.map(item => ({
|
|
227
|
+
...item,
|
|
228
|
+
refNo: item.releaseGood?.refNo || ''
|
|
229
|
+
})) || []
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return { total: 0, records: [] }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
_handlePrint() {
|
|
237
|
+
try {
|
|
238
|
+
const selected = this.dataGrist.selected || []
|
|
239
|
+
if (selected.length === 0) {
|
|
240
|
+
showToast({
|
|
241
|
+
type: 'warning',
|
|
242
|
+
message: i18next.t('text.please_select_at_least_one_record') || 'Please select at least one record'
|
|
243
|
+
})
|
|
244
|
+
return
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
openPopup(
|
|
248
|
+
html`
|
|
249
|
+
<print-quantity-popup
|
|
250
|
+
@print="${e => {
|
|
251
|
+
const printQuantity = e.detail.printQuantity
|
|
252
|
+
|
|
253
|
+
// Validate print quantity
|
|
254
|
+
if (!printQuantity || printQuantity <= 0) {
|
|
255
|
+
showToast({
|
|
256
|
+
type: 'error',
|
|
257
|
+
message: i18next.t('text.print_qty_must_be_at_least_one') || 'Print quantity must be at least 1'
|
|
258
|
+
})
|
|
259
|
+
return
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Close popup and execute print
|
|
263
|
+
history.back()
|
|
264
|
+
this._executePrint(selected, printQuantity)
|
|
265
|
+
}}"
|
|
266
|
+
></print-quantity-popup>
|
|
267
|
+
`,
|
|
268
|
+
{
|
|
269
|
+
backdrop: true,
|
|
270
|
+
size: 'small',
|
|
271
|
+
title: i18next.t('title.print_packing_label') || 'Print Packing Label'
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
} catch (e) {
|
|
275
|
+
showToast({ type: 'error', message: e.message || i18next.t('text.failed_to_print') })
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async _executePrint(selected, printQuantity) {
|
|
280
|
+
const loadingPackageIds = selected.map(item => item.id).filter(Boolean)
|
|
281
|
+
|
|
282
|
+
if (loadingPackageIds.length === 0) {
|
|
283
|
+
showToast({ type: 'error', message: i18next.t('text.no_valid_packages_selected') || 'No valid packages selected' })
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
const response = await fetch('/render_packing_label', {
|
|
289
|
+
method: 'POST',
|
|
290
|
+
credentials: 'include',
|
|
291
|
+
headers: { 'Content-Type': 'application/json' },
|
|
292
|
+
body: JSON.stringify({
|
|
293
|
+
loadingPackageIds,
|
|
294
|
+
printQuantity: Math.max(1, parseInt(printQuantity) || 1)
|
|
295
|
+
})
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
if (!response.ok) {
|
|
299
|
+
const errorText = await response.text()
|
|
300
|
+
throw new Error(errorText || `Failed to render packing label: ${response.statusText}`)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const renderedHtml = await response.text()
|
|
304
|
+
if (!renderedHtml) {
|
|
305
|
+
showToast({ type: 'error', message: i18next.t('text.failed_to_render_template') || 'Failed to render template' })
|
|
306
|
+
return
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
await this._printViaIframe(renderedHtml)
|
|
310
|
+
this.dataGrist.fetch()
|
|
311
|
+
} catch (error) {
|
|
312
|
+
console.error('Print error:', error)
|
|
313
|
+
showToast({ type: 'error', message: error.message || i18next.t('text.failed_to_print') || 'Failed to print' })
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async _printViaIframe(htmlContent) {
|
|
318
|
+
return new Promise((resolve, reject) => {
|
|
319
|
+
const iframe = this._printIframe
|
|
320
|
+
if (!iframe) {
|
|
321
|
+
reject(new Error('Print iframe not found'))
|
|
322
|
+
return
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
iframe.onload = () => {
|
|
326
|
+
try {
|
|
327
|
+
iframe.contentWindow.focus()
|
|
328
|
+
iframe.contentWindow.print()
|
|
329
|
+
resolve()
|
|
330
|
+
} catch (e) {
|
|
331
|
+
reject(e)
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document
|
|
336
|
+
iframeDoc.open()
|
|
337
|
+
iframeDoc.write(htmlContent)
|
|
338
|
+
iframeDoc.close()
|
|
339
|
+
})
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
get _printIframe() {
|
|
343
|
+
return this.shadowRoot?.querySelector('#print-iframe')
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
_closePopup() {
|
|
347
|
+
history.back()
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
render() {
|
|
351
|
+
return html`
|
|
352
|
+
<search-form
|
|
353
|
+
id="search-form"
|
|
354
|
+
.fields=${this._searchFields}
|
|
355
|
+
@submit=${() => this.dataGrist.fetch()}
|
|
356
|
+
></search-form>
|
|
357
|
+
|
|
358
|
+
<div class="grist-container">
|
|
359
|
+
<div class="grist">
|
|
360
|
+
<data-grist
|
|
361
|
+
.mode=${isMobileDevice() ? 'LIST' : 'GRID'}
|
|
362
|
+
.config=${this.config}
|
|
363
|
+
.fetchHandler=${this.fetchHandler.bind(this)}
|
|
364
|
+
></data-grist>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
|
|
368
|
+
<div class="button-container">
|
|
369
|
+
<mwc-button @click=${this._closePopup}>${i18next.t('button.close')}</mwc-button>
|
|
370
|
+
<mwc-button raised @click=${this._handlePrint}>${i18next.t('button.print')}</mwc-button>
|
|
371
|
+
</div>
|
|
372
|
+
|
|
373
|
+
<iframe id="print-iframe" style="display: none;"></iframe>
|
|
374
|
+
`
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
window.customElements.define('packing-label-history-popup', PackingLabelHistoryPopup)
|