@things-factory/operato-wms 5.0.0-alpha.38 → 5.0.0-alpha.39
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/inbound/unload-product.js +11 -7
- package/client/pages/inventory/inventory-adjustment.js +8 -8
- package/client/pages/inventory-check/inspecting-product.js +13 -7
- package/client/pages/order/goods-received-note/customer-received-note.js +3 -0
- package/client/pages/order/goods-received-note/received-note-detail.js +3 -0
- package/client/pages/order/release-order/release-extra-product-popup.js +15 -10
- package/client/pages/outbound/merged-outbound-worksheet.js +7 -1
- package/client/pages/outbound/picking-product.js +1 -1
- package/client/pages/outbound/select-operator-popup.js +86 -14
- package/client/pages/outbound/single-outbound-worksheet.js +22 -14
- package/client/pages/outbound/worksheet-batch-picking.js +1 -1
- package/client/pages/outbound/worksheet-picking.js +1 -1
- package/client/pages/report/costing-report.js +453 -0
- package/client/pages/report/inbound-order-details-report.js +14 -0
- package/client/pages/report/outbound-order-details-report.js +12 -0
- package/client/pages/vas/print-product-label.js +15 -6
- package/client/route.js +4 -0
- package/dist-server/graphql/resolvers/reports/costing-report.js +172 -0
- package/dist-server/graphql/resolvers/reports/costing-report.js.map +1 -0
- package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js +2 -0
- package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js.map +1 -1
- package/dist-server/graphql/resolvers/reports/index.js +2 -1
- package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
- package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js +10 -3
- package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js.map +1 -1
- package/dist-server/graphql/types/reports/costing-report-list.js +14 -0
- package/dist-server/graphql/types/reports/costing-report-list.js.map +1 -0
- package/dist-server/graphql/types/reports/costing-report.js +19 -0
- package/dist-server/graphql/types/reports/costing-report.js.map +1 -0
- 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/dist-server/graphql/types/reports/index.js +6 -1
- package/dist-server/graphql/types/reports/index.js.map +1 -1
- package/dist-server/graphql/types/reports/outbound-order-details-report.js +1 -0
- package/dist-server/graphql/types/reports/outbound-order-details-report.js.map +1 -1
- package/helps/release-note.ko.md +22 -19
- package/helps/release-note.md +22 -19
- package/helps/release-note.ms.md +22 -19
- package/helps/release-note.zh.md +22 -19
- package/package.json +43 -43
- package/server/graphql/resolvers/reports/costing-report.ts +196 -0
- package/server/graphql/resolvers/reports/inbound-order-details-report.ts +2 -0
- package/server/graphql/resolvers/reports/index.ts +2 -0
- package/server/graphql/resolvers/reports/outbound-order-details-report.ts +10 -3
- package/server/graphql/types/reports/costing-report-list.ts +8 -0
- package/server/graphql/types/reports/costing-report.ts +13 -0
- package/server/graphql/types/reports/inbound-order-details-report.ts +1 -0
- package/server/graphql/types/reports/index.ts +7 -1
- package/server/graphql/types/reports/outbound-order-details-report.ts +1 -0
- package/things-factory.config.js +4 -0
- package/translations/en.json +8 -2
- package/translations/ko.json +2 -0
- package/translations/ms.json +2 -0
- package/translations/zh.json +2 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import '@things-factory/form-ui'
|
|
2
|
+
import '@things-factory/grist-ui'
|
|
3
|
+
import '../inventory/inventory-by-product-detail'
|
|
4
|
+
|
|
5
|
+
import gql from 'graphql-tag'
|
|
6
|
+
import { css, html } from 'lit-element'
|
|
7
|
+
import { connect } from 'pwa-helpers/connect-mixin'
|
|
8
|
+
|
|
9
|
+
import { getCodeByName } from '@things-factory/code-base'
|
|
10
|
+
import { i18next, localize } from '@things-factory/i18n-base'
|
|
11
|
+
import { client, gqlContext, PageView, store } from '@things-factory/shell'
|
|
12
|
+
import { flattenObject, isMobileDevice } from '@things-factory/utils'
|
|
13
|
+
|
|
14
|
+
class CostingReport extends connect(store)(localize(i18next)(PageView)) {
|
|
15
|
+
static get styles() {
|
|
16
|
+
return css`
|
|
17
|
+
:host {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
width: 100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
data-grist {
|
|
24
|
+
overflow-y: auto;
|
|
25
|
+
flex: 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.summary {
|
|
29
|
+
background-color: var(--main-section-background-color);
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
overflow-y: auto;
|
|
33
|
+
align-items: flex-end;
|
|
34
|
+
padding: var(--data-list-item-padding);
|
|
35
|
+
display: grid;
|
|
36
|
+
font-size: 14px;
|
|
37
|
+
color: #394e64;
|
|
38
|
+
grid-template-columns: repeat(2, 1fr);
|
|
39
|
+
grid-auto-rows: minmax(24px, auto);
|
|
40
|
+
}
|
|
41
|
+
`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static get properties() {
|
|
45
|
+
return {
|
|
46
|
+
_searchFields: Object,
|
|
47
|
+
_config: Object,
|
|
48
|
+
_partners: Object,
|
|
49
|
+
_gristData: Object,
|
|
50
|
+
data: Object
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get context() {
|
|
55
|
+
return {
|
|
56
|
+
title: 'Costing Report',
|
|
57
|
+
exportable: {
|
|
58
|
+
name: i18next.t('title.costing_report'),
|
|
59
|
+
data: this._exportableData.bind(this)
|
|
60
|
+
},
|
|
61
|
+
help: 'operato-wms/report/costing-report'
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get dataGrist() {
|
|
66
|
+
return this.shadowRoot.querySelector('data-grist')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get searchForm() {
|
|
70
|
+
return this.shadowRoot.querySelector('search-form')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get _bizplaceSelector() {
|
|
74
|
+
return this.searchForm.shadowRoot.querySelector('select[name=bizplace]')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get _fromDateInput() {
|
|
78
|
+
return this.searchForm.shadowRoot.querySelector('input[name=fromDate]')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get _toDateInput() {
|
|
82
|
+
return this.searchForm.shadowRoot.querySelector('input[name=toDate]')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get searchFields() {
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
label: i18next.t('field.company'),
|
|
89
|
+
name: 'bizplace',
|
|
90
|
+
type: 'select',
|
|
91
|
+
options: [
|
|
92
|
+
{ value: '' },
|
|
93
|
+
...this._partners
|
|
94
|
+
.map(partner => {
|
|
95
|
+
return {
|
|
96
|
+
name: `${partner.name} ${partner.description ? `(${partner.description})` : ''}`,
|
|
97
|
+
value: partner.id
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
.sort(this._compareValues('name', 'asc'))
|
|
101
|
+
],
|
|
102
|
+
props: { searchOper: 'eq' }
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
label: i18next.t('field.from_date'),
|
|
106
|
+
name: 'fromDate',
|
|
107
|
+
type: 'date',
|
|
108
|
+
props: {
|
|
109
|
+
searchOper: 'eq',
|
|
110
|
+
max: new Date().toISOString().split('T')[0]
|
|
111
|
+
},
|
|
112
|
+
value: (() => {
|
|
113
|
+
let date = new Date()
|
|
114
|
+
date.setMonth(date.getMonth() - 1)
|
|
115
|
+
return date.toISOString().split('T')[0]
|
|
116
|
+
})(),
|
|
117
|
+
handlers: { change: this._modifyDateRange.bind(this) }
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
label: i18next.t('field.to_date'),
|
|
121
|
+
name: 'toDate',
|
|
122
|
+
type: 'date',
|
|
123
|
+
props: {
|
|
124
|
+
searchOper: 'eq',
|
|
125
|
+
min: (() => {
|
|
126
|
+
let date = new Date()
|
|
127
|
+
date.setMonth(date.getMonth() - 1)
|
|
128
|
+
return date.toISOString().split('T')[0]
|
|
129
|
+
})(),
|
|
130
|
+
max: (() => {
|
|
131
|
+
var max = new Date()
|
|
132
|
+
max.setMonth(max.getMonth() + 1)
|
|
133
|
+
return max.toISOString().split('T')[0]
|
|
134
|
+
})()
|
|
135
|
+
},
|
|
136
|
+
value: new Date().toISOString().split('T')[0]
|
|
137
|
+
// handlers: { change: this._submit.bind(this) }
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get reportConfig() {
|
|
143
|
+
let columns = [
|
|
144
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
145
|
+
{
|
|
146
|
+
type: 'string',
|
|
147
|
+
name: 'bizplace|name',
|
|
148
|
+
header: i18next.t('field.company'),
|
|
149
|
+
width: 200
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'string',
|
|
153
|
+
name: 'product|sku',
|
|
154
|
+
header: i18next.t('field.sku'),
|
|
155
|
+
width: 150
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
type: 'string',
|
|
159
|
+
name: 'product|name',
|
|
160
|
+
header: i18next.t('field.product_name'),
|
|
161
|
+
width: 200
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
type: 'string',
|
|
165
|
+
name: 'product|description',
|
|
166
|
+
header: i18next.t('field.product_description'),
|
|
167
|
+
width: 300
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'string',
|
|
171
|
+
name: 'product|type',
|
|
172
|
+
header: i18next.t('field.product_type'),
|
|
173
|
+
width: 150
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
type: 'float',
|
|
177
|
+
name: 'qty',
|
|
178
|
+
header: i18next.t('field.qty'),
|
|
179
|
+
width: 120
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
type: 'float',
|
|
183
|
+
name: 'uomValue',
|
|
184
|
+
header: i18next.t('field.uom_value'),
|
|
185
|
+
width: 120
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
type: 'string',
|
|
189
|
+
name: 'uom',
|
|
190
|
+
header: i18next.t('field.uom'),
|
|
191
|
+
width: 100
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
type: 'string',
|
|
195
|
+
name: 'weightedAvgUnitCost',
|
|
196
|
+
header: 'Weighted Avg Unit Cost',
|
|
197
|
+
width: 100
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: 'string',
|
|
201
|
+
name: 'totalCost',
|
|
202
|
+
header: i18next.t('field.total_cost'),
|
|
203
|
+
width: 100
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
let list = {
|
|
207
|
+
fields: [
|
|
208
|
+
'bizplace|name',
|
|
209
|
+
'product|sku',
|
|
210
|
+
'product|name',
|
|
211
|
+
'product|description',
|
|
212
|
+
'product|type',
|
|
213
|
+
'qty',
|
|
214
|
+
'uomValue',
|
|
215
|
+
'uom',
|
|
216
|
+
'weightedAvgUnitCost',
|
|
217
|
+
'totalCost'
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
columns: columns,
|
|
223
|
+
list,
|
|
224
|
+
pagination: { limit: 100, pages: [100, 200, 500, 1000] },
|
|
225
|
+
rows: {
|
|
226
|
+
selectable: false,
|
|
227
|
+
insertable: false,
|
|
228
|
+
appendable: false
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
render() {
|
|
234
|
+
return html`
|
|
235
|
+
<search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.dataGrist.fetch()}></search-form>
|
|
236
|
+
|
|
237
|
+
<data-grist
|
|
238
|
+
.mode=${isMobileDevice() ? 'LIST' : 'GRID'}
|
|
239
|
+
.config=${this._config}
|
|
240
|
+
.fetchHandler="${this.fetchHandler.bind(this)}"
|
|
241
|
+
></data-grist>
|
|
242
|
+
`
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async pageInitialized() {
|
|
246
|
+
this._gristData = { total: 0, records: [] }
|
|
247
|
+
this._products = []
|
|
248
|
+
|
|
249
|
+
const [_partnersReq] = await Promise.allSettled([this._fetchPartners()])
|
|
250
|
+
|
|
251
|
+
this._partners = _partnersReq.status == 'fulfilled' ? _partnersReq.value : []
|
|
252
|
+
|
|
253
|
+
this._searchFields = this.searchFields
|
|
254
|
+
this._config = this.reportConfig
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async pageUpdated(changes, lifecycle) {
|
|
258
|
+
if (this.active) {
|
|
259
|
+
this.dataGrist.fetch()
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async fetchHandler({ page, limit, sorters = [] }) {
|
|
264
|
+
try {
|
|
265
|
+
this._validate()
|
|
266
|
+
let filters = this.searchForm.queryFilters.map(filter => {
|
|
267
|
+
switch (filter.name) {
|
|
268
|
+
case 'fromDate':
|
|
269
|
+
let fromDt = new Date(filter.value)
|
|
270
|
+
fromDt.setHours(0)
|
|
271
|
+
filter.value = fromDt.toISOString()
|
|
272
|
+
break
|
|
273
|
+
case 'toDate':
|
|
274
|
+
let toDt = new Date(filter.value)
|
|
275
|
+
toDt.setHours(23, 59, 59)
|
|
276
|
+
filter.value = toDt.toISOString()
|
|
277
|
+
break
|
|
278
|
+
default:
|
|
279
|
+
break
|
|
280
|
+
}
|
|
281
|
+
return filter
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
const pagination = { page, limit }
|
|
285
|
+
const sortings = sorters
|
|
286
|
+
|
|
287
|
+
const response = await client.query({
|
|
288
|
+
query: gql`
|
|
289
|
+
query costingReport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
290
|
+
costingReport(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
291
|
+
items {
|
|
292
|
+
bizplace {
|
|
293
|
+
name
|
|
294
|
+
description
|
|
295
|
+
}
|
|
296
|
+
product {
|
|
297
|
+
sku
|
|
298
|
+
name
|
|
299
|
+
description
|
|
300
|
+
type
|
|
301
|
+
}
|
|
302
|
+
qty
|
|
303
|
+
uomValue
|
|
304
|
+
uom
|
|
305
|
+
weightedAvgUnitCost
|
|
306
|
+
totalCost
|
|
307
|
+
}
|
|
308
|
+
total
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
`,
|
|
312
|
+
variables: { filters, pagination, sortings },
|
|
313
|
+
context: gqlContext()
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
const data = {
|
|
317
|
+
total: response.data.costingReport.total,
|
|
318
|
+
records:
|
|
319
|
+
response.data.costingReport.items.map(itm => {
|
|
320
|
+
itm = {
|
|
321
|
+
...itm,
|
|
322
|
+
weightedAvgUnitCost: parseFloat(itm.weightedAvgUnitCost ? itm.weightedAvgUnitCost : 0).toFixed(4),
|
|
323
|
+
totalCost: parseFloat(itm.totalCost ? itm.totalCost : 0).toFixed(4)
|
|
324
|
+
}
|
|
325
|
+
return flattenObject({ ...itm, bizplace: { name: `${itm.bizplace.name} ${itm.bizplace.description}` } })
|
|
326
|
+
}) || []
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
this._gristData = {
|
|
330
|
+
...data
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return data
|
|
334
|
+
} catch (e) {
|
|
335
|
+
this._showToast(e)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
async _fetchPartners() {
|
|
340
|
+
const filters = []
|
|
341
|
+
const response = await client.query({
|
|
342
|
+
query: gql`
|
|
343
|
+
query partnersBizplaces($filters: [Filter!]) {
|
|
344
|
+
partnersBizplaces(filters: $filters) {
|
|
345
|
+
items {
|
|
346
|
+
id
|
|
347
|
+
name
|
|
348
|
+
description
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
`,
|
|
353
|
+
variables: { filters }
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
if (!response.errors) {
|
|
357
|
+
return response.data.partnersBizplaces.items
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
_validate() {
|
|
361
|
+
if (!this.searchForm.shadowRoot.querySelector('form').checkValidity())
|
|
362
|
+
throw new Error(i18next.t('text.invalid_form_value'))
|
|
363
|
+
if (!this._bizplaceSelector.value) throw new Error(i18next.t('text.no_company_selected'))
|
|
364
|
+
if (!this._fromDateInput.value) throw new Error(i18next.t('text.from_date_is_empty'))
|
|
365
|
+
if (!this._toDateInput.value) throw new Error(i18next.t('text.to_date_is_empty'))
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
_compareValues(key, order = 'asc') {
|
|
369
|
+
return function innerSort(a, b) {
|
|
370
|
+
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
|
|
371
|
+
return 0
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
|
|
375
|
+
const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]
|
|
376
|
+
|
|
377
|
+
let comparison = 0
|
|
378
|
+
if (varA > varB) {
|
|
379
|
+
comparison = 1
|
|
380
|
+
} else if (varA < varB) {
|
|
381
|
+
comparison = -1
|
|
382
|
+
}
|
|
383
|
+
return order === 'desc' ? comparison * -1 : comparison
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
_modifyDateRange(e) {
|
|
388
|
+
const fromDate = e.currentTarget.value
|
|
389
|
+
|
|
390
|
+
let min = new Date(fromDate)
|
|
391
|
+
let max = new Date(fromDate)
|
|
392
|
+
max.setMonth(max.getMonth() + 2)
|
|
393
|
+
|
|
394
|
+
min = min.toISOString().split('T')[0]
|
|
395
|
+
max = max.toISOString().split('T')[0]
|
|
396
|
+
|
|
397
|
+
if (this._toDateInput.value < fromDate) this._toDateInput.value = fromDate
|
|
398
|
+
|
|
399
|
+
if (this._toDateInput.value > max) this._toDateInput.value = max
|
|
400
|
+
|
|
401
|
+
this._toDateInput.max = max
|
|
402
|
+
this._toDateInput.min = min
|
|
403
|
+
this._submit()
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
_submit(e) {
|
|
407
|
+
this._config = { ...this.reportConfig }
|
|
408
|
+
this.searchForm.submit()
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
async _exportableData() {
|
|
412
|
+
try {
|
|
413
|
+
var headerSetting = [
|
|
414
|
+
{ header: i18next.t('field.company'), key: 'bizplace|name', width: 60, type: 'string' },
|
|
415
|
+
{ header: i18next.t('field.sku'), key: 'product|sku', width: 25, type: 'string' },
|
|
416
|
+
{ header: i18next.t('field.product_name'), key: 'product|name', width: 50, type: 'string' },
|
|
417
|
+
{ header: i18next.t('field.product_description'), key: 'product|description', width: 50, type: 'string' },
|
|
418
|
+
{ header: i18next.t('field.product_type'), key: 'product|type', width: 30, type: 'string' },
|
|
419
|
+
{ header: i18next.t('field.qty'), key: 'qty', width: 15, type: 'string' },
|
|
420
|
+
{ header: i18next.t('field.uom_value'), key: 'uomValue', width: 15, type: 'string' },
|
|
421
|
+
{ header: i18next.t('field.uom'), key: 'uom', width: 15, type: 'string' },
|
|
422
|
+
{ header: 'Weighted Avg Unit Cost', key: 'weightedAvgUnitCost', width: 15, type: 'string' },
|
|
423
|
+
{ header: i18next.t('field.total_cost'), key: 'totalCost', width: 15, type: 'string' }
|
|
424
|
+
]
|
|
425
|
+
|
|
426
|
+
var exportData = {
|
|
427
|
+
header: [...headerSetting],
|
|
428
|
+
data: (await this.fetchHandler({ page: 1, limit: 9999999 })).records.map(itm => {
|
|
429
|
+
return {
|
|
430
|
+
...itm
|
|
431
|
+
}
|
|
432
|
+
})
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return exportData
|
|
436
|
+
} catch (e) {
|
|
437
|
+
this._showToast(e)
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
_showToast({ type, message }) {
|
|
442
|
+
document.dispatchEvent(
|
|
443
|
+
new CustomEvent('notify', {
|
|
444
|
+
detail: {
|
|
445
|
+
type,
|
|
446
|
+
message
|
|
447
|
+
}
|
|
448
|
+
})
|
|
449
|
+
)
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
window.customElements.define('costing-report', CostingReport)
|
|
@@ -362,6 +362,12 @@ class InboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVie
|
|
|
362
362
|
header: i18next.t('field.uom'),
|
|
363
363
|
width: 100
|
|
364
364
|
},
|
|
365
|
+
{
|
|
366
|
+
type: 'string',
|
|
367
|
+
name: 'unitCost',
|
|
368
|
+
header: i18next.t('field.unit_cost'),
|
|
369
|
+
width: 100
|
|
370
|
+
},
|
|
365
371
|
{
|
|
366
372
|
type: 'float',
|
|
367
373
|
name: 'unitVolume',
|
|
@@ -497,6 +503,7 @@ class InboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVie
|
|
|
497
503
|
'qty',
|
|
498
504
|
'uomValue',
|
|
499
505
|
'uom',
|
|
506
|
+
'unitCost',
|
|
500
507
|
'unitVolume',
|
|
501
508
|
'totalVolume',
|
|
502
509
|
'unitNettWeight',
|
|
@@ -613,6 +620,7 @@ class InboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVie
|
|
|
613
620
|
qty
|
|
614
621
|
uomValue
|
|
615
622
|
uom
|
|
623
|
+
unitCost
|
|
616
624
|
unitVolume
|
|
617
625
|
totalVolume
|
|
618
626
|
unitNettWeight
|
|
@@ -643,6 +651,11 @@ class InboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVie
|
|
|
643
651
|
total: response.data.inboundOrderDetailsReport.total,
|
|
644
652
|
records:
|
|
645
653
|
response.data.inboundOrderDetailsReport.items.map(itm => {
|
|
654
|
+
itm = {
|
|
655
|
+
...itm,
|
|
656
|
+
unitCost: parseFloat(itm.unitCost ? itm.unitCost : 0).toFixed(2)
|
|
657
|
+
}
|
|
658
|
+
|
|
646
659
|
return flattenObject({ ...itm, bizplace: { name: `${itm.bizplace.name} ${itm.bizplace.description}` } })
|
|
647
660
|
}) || []
|
|
648
661
|
}
|
|
@@ -758,6 +771,7 @@ class InboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVie
|
|
|
758
771
|
{ header: i18next.t('field.qty'), key: 'qty', width: 15, type: 'string' },
|
|
759
772
|
{ header: i18next.t('field.uom_value'), key: 'uomValue', width: 15, type: 'string' },
|
|
760
773
|
{ header: i18next.t('field.uom'), key: 'uom', width: 15, type: 'string' },
|
|
774
|
+
{ header: i18next.t('field.unit_cost'), key: 'unitCost', width: 15, type: 'string' },
|
|
761
775
|
{ header: i18next.t('field.unit_volume'), key: 'unitVolume', width: 15, type: 'string' },
|
|
762
776
|
{ header: i18next.t('field.total_volume'), key: 'totalVolume', width: 15, type: 'string' },
|
|
763
777
|
{ header: i18next.t('field.unit_nett_weight'), key: 'unitNettWeight', width: 15, type: 'string' },
|
|
@@ -330,6 +330,12 @@ class OutboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVi
|
|
|
330
330
|
header: i18next.t('field.uom'),
|
|
331
331
|
width: 100
|
|
332
332
|
},
|
|
333
|
+
{
|
|
334
|
+
type: 'string',
|
|
335
|
+
name: 'unitCost',
|
|
336
|
+
header: i18next.t('field.unit_cost'),
|
|
337
|
+
width: 100
|
|
338
|
+
},
|
|
333
339
|
{
|
|
334
340
|
type: 'float',
|
|
335
341
|
name: 'returnToLocationQty',
|
|
@@ -489,6 +495,7 @@ class OutboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVi
|
|
|
489
495
|
'qty',
|
|
490
496
|
'uomValue',
|
|
491
497
|
'uom',
|
|
498
|
+
'unitCost',
|
|
492
499
|
'returnToLocationQty',
|
|
493
500
|
'returnToLocationUomValue',
|
|
494
501
|
'unitVolume',
|
|
@@ -609,6 +616,7 @@ class OutboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVi
|
|
|
609
616
|
returnToLocationQty
|
|
610
617
|
returnToLocationUomValue
|
|
611
618
|
uom
|
|
619
|
+
unitCost
|
|
612
620
|
unitVolume
|
|
613
621
|
totalVolume
|
|
614
622
|
unitNettWeight
|
|
@@ -642,6 +650,10 @@ class OutboundOrderDetailsReport extends connect(store)(localize(i18next)(PageVi
|
|
|
642
650
|
total: response.data.outboundOrderDetailsReport.total,
|
|
643
651
|
records:
|
|
644
652
|
response.data.outboundOrderDetailsReport.items.map(itm => {
|
|
653
|
+
itm = {
|
|
654
|
+
...itm,
|
|
655
|
+
unitCost: parseFloat(itm.unitCost ? itm.unitCost : 0).toFixed(2)
|
|
656
|
+
}
|
|
645
657
|
return flattenObject({ ...itm, bizplace: { name: `${itm.bizplace.name} ${itm.bizplace.description}` } })
|
|
646
658
|
}) || []
|
|
647
659
|
}
|
|
@@ -786,12 +786,21 @@ class PrintProductLabel extends connect(store)(localize(i18next)(PageView)) {
|
|
|
786
786
|
}
|
|
787
787
|
} catch (ex) {
|
|
788
788
|
this._showToast({ level: 'error', message: ex })
|
|
789
|
-
|
|
790
789
|
delete this.printer
|
|
791
790
|
break
|
|
792
791
|
} finally {
|
|
793
792
|
// we only need to update when the counter is more than 0
|
|
794
|
-
if (printCounter > 0)
|
|
793
|
+
if (printCounter > 0) {
|
|
794
|
+
try {
|
|
795
|
+
await this._updatePrintedLabelSequence(record.type, printCounter, record.bizplaceId)
|
|
796
|
+
} catch (e) {
|
|
797
|
+
this._showToast({
|
|
798
|
+
level: 'error',
|
|
799
|
+
message: i18next.t('text.unable_to_save_print_history_x', { state: { counter: printCounter } })
|
|
800
|
+
})
|
|
801
|
+
return
|
|
802
|
+
}
|
|
803
|
+
}
|
|
795
804
|
}
|
|
796
805
|
}
|
|
797
806
|
}
|
|
@@ -801,8 +810,8 @@ class PrintProductLabel extends connect(store)(localize(i18next)(PageView)) {
|
|
|
801
810
|
try {
|
|
802
811
|
await client.mutate({
|
|
803
812
|
mutation: gql`
|
|
804
|
-
mutation
|
|
805
|
-
|
|
813
|
+
mutation upsertSequence($type: String!, $counter: Float!, $bizplaceId: String!) {
|
|
814
|
+
upsertSequence(type: $type, counter: $counter, bizplaceId: $bizplaceId) {
|
|
806
815
|
pattern
|
|
807
816
|
seq
|
|
808
817
|
}
|
|
@@ -814,8 +823,8 @@ class PrintProductLabel extends connect(store)(localize(i18next)(PageView)) {
|
|
|
814
823
|
bizplaceId
|
|
815
824
|
}
|
|
816
825
|
})
|
|
817
|
-
} catch (
|
|
818
|
-
|
|
826
|
+
} catch (error) {
|
|
827
|
+
throw error
|
|
819
828
|
}
|
|
820
829
|
}
|
|
821
830
|
|
package/client/route.js
CHANGED
|
@@ -463,6 +463,10 @@ export default function route(page) {
|
|
|
463
463
|
case 'outbound_serial_number_report':
|
|
464
464
|
import('./pages/report/outbound-serial-number-report')
|
|
465
465
|
return page
|
|
466
|
+
|
|
467
|
+
case 'costing_report':
|
|
468
|
+
import('./pages/report/costing-report')
|
|
469
|
+
return page
|
|
466
470
|
/**
|
|
467
471
|
* Custom ELCCL Menus Section
|
|
468
472
|
*/
|