@things-factory/operato-wms 3.7.2 → 3.7.7

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.
Files changed (84) hide show
  1. package/client/pages/components/select-product-popup.js +5 -1
  2. package/client/pages/constants/order.js +10 -0
  3. package/client/pages/inbound/putaway-product.js +162 -139
  4. package/client/pages/inventory-check/inspecting-product.js +146 -80
  5. package/client/pages/manifest/create-loading-manifest.js +314 -0
  6. package/client/pages/manifest/dispatcher-verification-popup.js +86 -0
  7. package/client/pages/manifest/loading-manifest-detail.js +345 -0
  8. package/client/pages/manifest/loading-manifest-list.js +305 -0
  9. package/client/pages/order/arrival-notice/create-arrival-notice.js +8 -1
  10. package/client/pages/order/goods-received-note/received-note-list.js +138 -6
  11. package/client/pages/order/release-order/b2b/b2b-order-list.js +45 -5
  12. package/client/pages/order/release-order/b2b/b2b-order-requests.js +45 -5
  13. package/client/pages/order/release-order/b2c/b2c-order-requests.js +181 -21
  14. package/client/pages/order/release-order/bulk-print-packing-list.js +23 -0
  15. package/client/pages/order/release-order/create-release-order.js +25 -4
  16. package/client/pages/order/release-order/receive-release-order-request.js +27 -24
  17. package/client/pages/order/release-order/release-extra-product-popup.js +189 -56
  18. package/client/pages/order/release-order/release-order-detail.js +292 -71
  19. package/client/pages/order/reverse-kitting-order/reverse-kitting-order-detail.js +115 -50
  20. package/client/pages/order/reverse-kitting-order/reverse-kitting-order-list.js +1 -6
  21. package/client/pages/order/reverse-kitting-order/reverse-kitting-pallet-label-popup.js +239 -0
  22. package/client/pages/order/transport-order/delivery-order-list.js +99 -59
  23. package/client/pages/outbound/loading-product.js +4 -1
  24. package/client/pages/outbound/merged-outbound-worksheet.js +39 -1
  25. package/client/pages/outbound/packing-product.js +4 -1
  26. package/client/pages/outbound/packing-worksheet-list.js +39 -1
  27. package/client/pages/outbound/picking-product.js +622 -290
  28. package/client/pages/outbound/serial-number-popup.js +280 -0
  29. package/client/pages/outbound/worksheet-picking.js +28 -2
  30. package/client/pages/report/product-label-report.js +401 -0
  31. package/client/pages/support/inventory-comparison.js +296 -0
  32. package/client/pages/vas/print-product-label.js +298 -132
  33. package/client/pages/vas/reverse-kitting/execute-reverse-kitting.js +30 -12
  34. package/client/pages/vas/reverse-kitting/popup-combination-sets.js +75 -5
  35. package/client/pages/vas/reverse-kitting/popup-reverse-kitting-template.js +113 -18
  36. package/client/route.js +23 -0
  37. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +64 -54
  38. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js.map +1 -1
  39. package/dist-server/graphql/resolvers/extra/add-release-good-products.js +34 -9
  40. package/dist-server/graphql/resolvers/extra/add-release-good-products.js.map +1 -1
  41. package/dist-server/graphql/resolvers/index.js +3 -1
  42. package/dist-server/graphql/resolvers/index.js.map +1 -1
  43. package/dist-server/graphql/resolvers/inventory-comparison/index.js +6 -0
  44. package/dist-server/graphql/resolvers/inventory-comparison/index.js.map +1 -0
  45. package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js +78 -0
  46. package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js.map +1 -0
  47. package/dist-server/graphql/resolvers/reports/index.js +2 -1
  48. package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
  49. package/dist-server/graphql/resolvers/reports/product-label-report.js +56 -0
  50. package/dist-server/graphql/resolvers/reports/product-label-report.js.map +1 -0
  51. package/dist-server/graphql/types/index.js +5 -2
  52. package/dist-server/graphql/types/index.js.map +1 -1
  53. package/dist-server/graphql/types/inventory-comparison/index.js +13 -0
  54. package/dist-server/graphql/types/inventory-comparison/index.js.map +1 -0
  55. package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js +14 -0
  56. package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js.map +1 -0
  57. package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js +18 -0
  58. package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js.map +1 -0
  59. package/dist-server/graphql/types/reports/index.js +6 -1
  60. package/dist-server/graphql/types/reports/index.js.map +1 -1
  61. package/dist-server/graphql/types/reports/product-label-report-list.js +14 -0
  62. package/dist-server/graphql/types/reports/product-label-report-list.js.map +1 -0
  63. package/dist-server/graphql/types/reports/product-label-report.js +16 -0
  64. package/dist-server/graphql/types/reports/product-label-report.js.map +1 -0
  65. package/package.json +65 -65
  66. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +75 -65
  67. package/server/graphql/resolvers/extra/add-release-good-products.ts +57 -15
  68. package/server/graphql/resolvers/index.ts +3 -1
  69. package/server/graphql/resolvers/inventory-comparison/index.ts +5 -0
  70. package/server/graphql/resolvers/inventory-comparison/inventory-comparison-list.ts +99 -0
  71. package/server/graphql/resolvers/reports/index.ts +3 -1
  72. package/server/graphql/resolvers/reports/product-label-report.ts +56 -0
  73. package/server/graphql/types/index.ts +5 -2
  74. package/server/graphql/types/inventory-comparison/index.ts +11 -0
  75. package/server/graphql/types/inventory-comparison/inventory-comparison-list.ts +8 -0
  76. package/server/graphql/types/inventory-comparison/inventory-comparison.ts +12 -0
  77. package/server/graphql/types/reports/index.ts +6 -1
  78. package/server/graphql/types/reports/product-label-report-list.ts +8 -0
  79. package/server/graphql/types/reports/product-label-report.ts +10 -0
  80. package/things-factory.config.js +24 -0
  81. package/translations/en.json +64 -12
  82. package/translations/ko.json +50 -1
  83. package/translations/ms.json +51 -1
  84. package/translations/zh.json +50 -1
@@ -0,0 +1,401 @@
1
+ import '@things-factory/form-ui'
2
+ import '@things-factory/grist-ui'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html } from 'lit-element'
6
+ import { connect } from 'pwa-helpers/connect-mixin'
7
+
8
+ import { i18next, localize } from '@things-factory/i18n-base'
9
+ import { client, PageView, store } from '@things-factory/shell'
10
+
11
+ class ProductLabelReport extends connect(store)(localize(i18next)(PageView)) {
12
+ static get styles() {
13
+ return css`
14
+ :host {
15
+ display: flex;
16
+ flex-direction: column;
17
+ width: 100%;
18
+ }
19
+
20
+ data-report {
21
+ flex: 1;
22
+ }
23
+ `
24
+ }
25
+
26
+ static get properties() {
27
+ return {
28
+ _searchFields: Object,
29
+ _config: Object,
30
+ _partners: Object,
31
+ data: Object
32
+ }
33
+ }
34
+
35
+ get context() {
36
+ return {
37
+ title: i18next.t('title.product_label_report'),
38
+ printable: {
39
+ accept: ['preview'],
40
+ content: this
41
+ },
42
+ exportable: {
43
+ name: i18next.t('title.date_product_label', {
44
+ state: {
45
+ text: (() => {
46
+ let date = new Date()
47
+ return date.getFullYear().toString() + (date.getMonth() + 1).toString() + date.getDate().toString()
48
+ })()
49
+ }
50
+ }),
51
+ data: this._exportableData.bind(this)
52
+ },
53
+ help: 'operato-wms/report/inventory-report'
54
+ }
55
+ }
56
+
57
+ get report() {
58
+ return this.shadowRoot.querySelector('data-report')
59
+ }
60
+
61
+ get searchForm() {
62
+ return this.shadowRoot.querySelector('search-form')
63
+ }
64
+
65
+ get _bizplaceSelector() {
66
+ return this.searchForm.shadowRoot.querySelector('select[name=bizplace]')
67
+ }
68
+
69
+ get _fromDateInput() {
70
+ return this.searchForm.shadowRoot.querySelector('input[name=fromDate]')
71
+ }
72
+
73
+ get _toDateInput() {
74
+ return this.searchForm.shadowRoot.querySelector('input[name=toDate]')
75
+ }
76
+
77
+ render() {
78
+ return html`
79
+ <search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.report.fetch()}></search-form>
80
+
81
+ <data-report .config=${this._config} .fetchHandler=${this.fetchHandler.bind(this)}></data-report>
82
+ `
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: new Date().toISOString().split('T')[0]
131
+ },
132
+ value: new Date().toISOString().split('T')[0]
133
+ },
134
+ {
135
+ label: i18next.t('field.product_type'),
136
+ name: 'type',
137
+ type: 'string',
138
+ props: { searchOper: 'in' }
139
+ }
140
+ ]
141
+ }
142
+
143
+ get reportConfig() {
144
+ return {
145
+ rows: {
146
+ selectable: false,
147
+ groups: [{ column: 'type', title: 'Sub Total' }],
148
+ totals: ['count']
149
+ },
150
+ columns: [
151
+ {
152
+ type: 'string',
153
+ name: 'type',
154
+ header: i18next.t('field.type'),
155
+ imex: { header: i18next.t('field.type'), key: 'type', width: 25, type: 'string' },
156
+ width: 400
157
+ },
158
+ {
159
+ type: 'string',
160
+ name: 'date',
161
+ header: i18next.t('field.date'),
162
+ sortable: true,
163
+ imex: { header: i18next.t('field.date'), key: 'createdAt', width: 25, type: 'string' },
164
+ width: 200
165
+ },
166
+ {
167
+ type: 'number',
168
+ name: 'count',
169
+ header: i18next.t('field.count'),
170
+ record: { align: 'center' },
171
+ sortable: true,
172
+ imex: { header: i18next.t('field.count'), key: 'count', width: 25, type: 'string' },
173
+ width: 120
174
+ }
175
+ ]
176
+ }
177
+ }
178
+
179
+ async pageInitialized() {
180
+ this._products = []
181
+ this._partners = [...(await this._fetchPartners())]
182
+
183
+ this._searchFields = this.searchFields
184
+ this._config = this.reportConfig
185
+ }
186
+
187
+ async pageUpdated(changes, lifecycle) {
188
+ if (this.active) {
189
+ this.report.fetch()
190
+ }
191
+ }
192
+
193
+ async fetchHandler({ page, limit, sorters = [] }) {
194
+ // return {
195
+ // total: 0,
196
+ // records: [
197
+ // { productType: 'DRUM', count: 16, createdAt: '2021/10/13' },
198
+ // { productType: 'WOOD', count: 50, createdAt: '2021/10/18' },
199
+ // { productType: 'WOOD', count: 6, createdAt: '2021/10/11' },
200
+ // { productType: 'WOOD', count: 21, createdAt: '2021/10/15' },
201
+ // { productType: 'GSC', count: 30, createdAt: '2021/10/20' },
202
+ // { productType: 'GSC', count: 3, createdAt: '2021/10/11' },
203
+ // { productType: 'WOOD', count: 8, createdAt: '2021/10/12' },
204
+ // { productType: 'FG', count: 4, createdAt: '2021/10/18' },
205
+ // { productType: 'GSC', count: 2, createdAt: '2021/10/14' },
206
+ // { productType: 'GSC', count: 213, createdAt: '2021/10/12' },
207
+ // { productType: 'WOOD', count: 3, createdAt: '2021/10/20' },
208
+ // { productType: 'GSC', count: 51, createdAt: '2021/10/16' },
209
+ // { productType: 'PKG', count: 1, createdAt: '2021/10/18' },
210
+ // { productType: 'GSC', count: 27, createdAt: '2021/10/15' },
211
+ // { productType: 'GSC', count: 174, createdAt: '2021/10/18' }
212
+ // ]
213
+ // }
214
+ try {
215
+ this._validate()
216
+
217
+ var tzoffset = new Date().getTimezoneOffset() * 60
218
+ const response = await client.query({
219
+ query: gql`
220
+ query productLabelReport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
221
+ productLabelReport(filters: $filters, pagination: $pagination, sortings: $sortings) {
222
+ items {
223
+ type
224
+ date
225
+ count
226
+ bizplace {
227
+ id
228
+ name
229
+ }
230
+ }
231
+ total
232
+ }
233
+ }
234
+ `,
235
+ variables: {
236
+ filters: [...this.searchForm.queryFilters, { name: 'tzoffset', operator: 'custom', value: tzoffset }],
237
+ pagination: { page, limit },
238
+ sortings: sorters
239
+ }
240
+ })
241
+
242
+ return {
243
+ total: response.data.productLabelReport.total,
244
+ records: response.data.productLabelReport.items
245
+ }
246
+
247
+ // @farishelmi any usage for this? If no please remove.
248
+ // return {
249
+ // total: 0,
250
+ // records:
251
+ // response.data.inventoryHistoryReport.map(item => {
252
+ // let date = new Date(parseInt(item.createdAt))
253
+ // return flattenObject({
254
+ // ...item,
255
+ // createdAt:
256
+ // date.getDate().toString() + '/' + (date.getMonth() + 1).toString() + '/' + date.getFullYear().toString()
257
+ // })
258
+ // }) || []
259
+ // }
260
+ } catch (e) {
261
+ this._showToast(e)
262
+ }
263
+ }
264
+
265
+ async _fetchPartners() {
266
+ const filters = []
267
+ const response = await client.query({
268
+ query: gql`
269
+ query partnersBizplaces($filters: [Filter!]) {
270
+ partnersBizplaces(filters: $filters) {
271
+ items {
272
+ id
273
+ name
274
+ description
275
+ }
276
+ }
277
+ }
278
+ `,
279
+ variables: { filters }
280
+ })
281
+
282
+ if (!response.errors) {
283
+ return response.data.partnersBizplaces.items
284
+ }
285
+ }
286
+
287
+ _validate() {
288
+ if (!this.searchForm.shadowRoot.querySelector('form').checkValidity())
289
+ throw new Error(i18next.t('text.invalid_form_value'))
290
+ if (!this._bizplaceSelector.value) throw new Error(i18next.t('text.no_company_selected'))
291
+ if (!this._fromDateInput.value) throw new Error(i18next.t('text.from_date_is_empty'))
292
+ if (!this._toDateInput.value) throw new Error(i18next.t('text.to_date_is_empty'))
293
+ }
294
+
295
+ _modifyDateRange(e) {
296
+ const fromDate = e.currentTarget.value
297
+
298
+ if (this._toDateInput.value < fromDate) this._toDateInput.value = fromDate
299
+
300
+ let min = new Date(fromDate)
301
+ let today = new Date()
302
+ today.setHours(0, 0, 0, 0)
303
+
304
+ min = min.toISOString().split('T')[0]
305
+
306
+ this._toDateInput.min = min
307
+ }
308
+
309
+ _compareValues(key, order = 'asc') {
310
+ return function innerSort(a, b) {
311
+ if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
312
+ return 0
313
+ }
314
+
315
+ const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
316
+ const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]
317
+
318
+ let comparison = 0
319
+ if (varA > varB) {
320
+ comparison = 1
321
+ } else if (varA < varB) {
322
+ comparison = -1
323
+ }
324
+ return order === 'desc' ? comparison * -1 : comparison
325
+ }
326
+ }
327
+
328
+ // @farishelmi any usage for this function? If no please remove.
329
+ async _bizplaceChange(e) {
330
+ /* let bizplace = [{ name: 'bizplace', operator: 'eq', value: e.currentTarget.value }]
331
+ if (e.currentTarget.value == '') {
332
+ this.searchFields
333
+ this._searchFields.filter(x => x.name == 'product')[0].options = [{ name: 'All', value: '' }]
334
+ this._searchFields = [...this._searchFields]
335
+ } else {
336
+ const response = await client.query({
337
+ query: gql`
338
+ query {
339
+ productsByBizplace(${gqlBuilder.buildArgs({
340
+ filters: [...bizplace]
341
+ })}) {
342
+ items {
343
+ id
344
+ name
345
+ }
346
+ }
347
+ }
348
+ `
349
+ })
350
+
351
+ if (!response.errors) {
352
+ this.searchFields
353
+ this._searchFields.filter(x => x.name == 'product')[0].options = [
354
+ { name: 'All', value: '' },
355
+ ...response.data.productsByBizplace.items.map(item => {
356
+ return {
357
+ name: item.name,
358
+ value: item.id
359
+ }
360
+ })
361
+ ]
362
+ this._searchFields = [...this._searchFields]
363
+ }
364
+ } */
365
+ }
366
+
367
+ _exportableData() {
368
+ try {
369
+ const report = this.report
370
+ var headerSetting = [
371
+ ...report._config.columns
372
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
373
+ .map(column => {
374
+ return column.imex
375
+ })
376
+ ]
377
+
378
+ return {
379
+ header: headerSetting,
380
+ data: report.data.records,
381
+ groups: report._config.rows.groups,
382
+ totals: report._config.rows.totals
383
+ }
384
+ } catch (e) {
385
+ this._showToast(e)
386
+ }
387
+ }
388
+
389
+ _showToast({ type, message }) {
390
+ document.dispatchEvent(
391
+ new CustomEvent('notify', {
392
+ detail: {
393
+ type,
394
+ message
395
+ }
396
+ })
397
+ )
398
+ }
399
+ }
400
+
401
+ window.customElements.define('product-label-report', ProductLabelReport)
@@ -0,0 +1,296 @@
1
+ import '@things-factory/form-ui'
2
+ import '@things-factory/grist-ui'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html } from 'lit-element'
6
+ import { connect } from 'pwa-helpers/connect-mixin'
7
+
8
+ import { getPartnerCodeByName } from '@things-factory/code-base'
9
+ import { i18next, localize } from '@things-factory/i18n-base'
10
+ import { client, PageView, store } from '@things-factory/shell'
11
+ import { ScrollbarStyles } from '@things-factory/styles'
12
+ import { isMobileDevice } from '@things-factory/utils'
13
+
14
+ class InventoryComparison extends connect(store)(localize(i18next)(PageView)) {
15
+ static get styles() {
16
+ return [
17
+ ScrollbarStyles,
18
+ css`
19
+ :host {
20
+ display: flex;
21
+ flex-direction: column;
22
+ overflow: hidden;
23
+ }
24
+
25
+ search-form {
26
+ overflow: visible;
27
+ }
28
+
29
+ data-grist {
30
+ overflow-y: auto;
31
+ flex: 1;
32
+ }
33
+ `
34
+ ]
35
+ }
36
+
37
+ static get properties() {
38
+ return {
39
+ _config: Object,
40
+ _searchFields: Object,
41
+ _partners: Object,
42
+ _gristData: Object,
43
+ _nonTally: Boolean,
44
+ data: Object
45
+ }
46
+ }
47
+
48
+ get dataGrist() {
49
+ return this.shadowRoot.querySelector('data-grist')
50
+ }
51
+
52
+ get searchForm() {
53
+ return this.shadowRoot.querySelector('search-form')
54
+ }
55
+
56
+ get _bizplaceSelector() {
57
+ return this.searchForm.shadowRoot.querySelector('select[name=bizplace]')
58
+ }
59
+
60
+ get _toDateInput() {
61
+ return this.searchForm.shadowRoot.querySelector('input[name=toDate]')
62
+ }
63
+
64
+ get searchFields() {
65
+ return [
66
+ {
67
+ label: i18next.t('field.company'),
68
+ name: 'bizplace',
69
+ type: 'select',
70
+ options: [
71
+ { value: '' },
72
+ ...this._partners
73
+ .map(partner => {
74
+ return {
75
+ name: `${partner.name} ${partner.description ? `(${partner.description})` : ''}`,
76
+ value: partner.id
77
+ }
78
+ })
79
+ .sort(this._compareValues('name', 'asc'))
80
+ ],
81
+ props: { searchOper: 'eq' }
82
+ },
83
+ {
84
+ label: i18next.t('field.date'),
85
+ name: 'toDate',
86
+ type: 'date',
87
+ props: {
88
+ searchOper: 'eq',
89
+ min: (() => {
90
+ let date = new Date()
91
+ date.setMonth(date.getMonth() - 1)
92
+ return date.toISOString().split('T')[0]
93
+ })(),
94
+ max: new Date().toISOString().split('T')[0]
95
+ },
96
+ value: new Date().toISOString().split('T')[0]
97
+ },
98
+ {
99
+ label: i18next.t('field.product_info'),
100
+ name: 'product',
101
+ type: 'string',
102
+ props: { searchOper: 'in' }
103
+ },
104
+ {
105
+ label: i18next.t('field.non_tally'),
106
+ name: 'nonTally',
107
+ type: 'checkbox',
108
+ value: this._nonTally,
109
+ props: { searchOper: 'eq' }
110
+ }
111
+ ]
112
+ }
113
+
114
+ get context() {
115
+ return {
116
+ title: i18next.t('title.inventory_comparison_list')
117
+ }
118
+ }
119
+
120
+ async pageInitialized() {
121
+ this._partners = [...(await this._fetchPartners())]
122
+ this._searchFields = this.searchFields
123
+ this._gristData = { total: 0, records: [] }
124
+ this._config = {
125
+ list: {
126
+ fields: ['productSku', 'productName', 'batchId', 'packingType', 'closingQty', 'remainQty']
127
+ },
128
+ pagination: { limit: 50, pages: [50, 100, 200, 500, 1000] },
129
+ rows: {
130
+ selectable: false,
131
+ insertable: false,
132
+ appendable: false
133
+ },
134
+ columns: [
135
+ { type: 'gutter', gutterName: 'sequence' },
136
+ {
137
+ type: 'string',
138
+ name: 'productSku',
139
+ header: i18next.t('field.sku'),
140
+ width: 150
141
+ },
142
+ {
143
+ type: 'string',
144
+ name: 'productName',
145
+ header: i18next.t('field.product'),
146
+ width: 400
147
+ },
148
+ {
149
+ type: 'string',
150
+ name: 'batchId',
151
+ header: i18next.t('field.batch_id'),
152
+ width: 150
153
+ },
154
+ {
155
+ type: 'string',
156
+ name: 'packingType',
157
+ header: i18next.t('field.packing_type'),
158
+ width: 150
159
+ },
160
+ {
161
+ type: 'number',
162
+ name: 'closingQty',
163
+ header: i18next.t('field.summary_report_quantity'),
164
+ width: 200
165
+ },
166
+ {
167
+ type: 'number',
168
+ name: 'remainQty',
169
+ header: i18next.t('field.onhand_inventory_quantity'),
170
+ width: 200
171
+ }
172
+ ]
173
+ }
174
+ }
175
+
176
+ pageUpdated(changes, lifecycle) {
177
+ if (this.active) {
178
+ this.dataGrist.fetch()
179
+ }
180
+ }
181
+
182
+ async fetchHandler({ page, limit, sorters = [] }) {
183
+ try {
184
+ let filter = this.searchForm.queryFilters.map(filter => {
185
+ switch (filter.name) {
186
+ case 'toDate':
187
+ let toDt = new Date(filter.value)
188
+ toDt.setHours(23, 59, 59)
189
+ filter.value = toDt.toISOString()
190
+ break
191
+ default:
192
+ break
193
+ }
194
+ return filter
195
+ })
196
+
197
+ const response = await client.query({
198
+ query: gql`
199
+ query inventoryComparisonList($filters: [Filter], $pagination: Pagination, $sortings: [Sorting]) {
200
+ inventoryComparisonList(filters: $filters, pagination: $pagination, sortings: $sortings) {
201
+ items {
202
+ productSku
203
+ productName
204
+ packingType
205
+ closingQty
206
+ remainQty
207
+ batchId
208
+ }
209
+ total
210
+ }
211
+ }
212
+ `,
213
+ variables: { filters: filter, pagination: { page, limit }, sortings: sorters }
214
+ })
215
+
216
+ if (!response.errors) {
217
+ return {
218
+ total: response.data?.inventoryComparisonList?.total || 0,
219
+ records: response.data?.inventoryComparisonList?.items || []
220
+ }
221
+ }
222
+ } catch (error) {
223
+ throw error
224
+ }
225
+ }
226
+
227
+ render() {
228
+ return html`
229
+ <search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.dataGrist.fetch()}></search-form>
230
+
231
+ <data-grist
232
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
233
+ .config=${this._config}
234
+ .fetchHandler="${this.fetchHandler.bind(this)}"
235
+ ></data-grist>
236
+ `
237
+ }
238
+
239
+ async _companyChanged(e) {
240
+ this._productType = !this._bizplaceSelector.value
241
+ ? []
242
+ : await getPartnerCodeByName(
243
+ 'PRODUCT_TYPES',
244
+ this._partners.find(p => p.id == this._bizplaceSelector.value)?.company?.domainId || ''
245
+ )
246
+
247
+ this._searchFields = [...this.searchFields]
248
+ }
249
+
250
+ _compareValues(key, order = 'asc') {
251
+ return function innerSort(a, b) {
252
+ if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
253
+ return 0
254
+ }
255
+
256
+ const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
257
+ const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]
258
+
259
+ let comparison = 0
260
+ if (varA > varB) {
261
+ comparison = 1
262
+ } else if (varA < varB) {
263
+ comparison = -1
264
+ }
265
+ return order === 'desc' ? comparison * -1 : comparison
266
+ }
267
+ }
268
+
269
+ async _fetchPartners() {
270
+ const filters = []
271
+ const response = await client.query({
272
+ query: gql`
273
+ query partnersBizplaces($filters: [Filter!]) {
274
+ partnersBizplaces(filters: $filters) {
275
+ items {
276
+ id
277
+ name
278
+ description
279
+ company {
280
+ id
281
+ domainId
282
+ }
283
+ }
284
+ }
285
+ }
286
+ `,
287
+ variables: { filters }
288
+ })
289
+
290
+ if (!response.errors) {
291
+ return response.data.partnersBizplaces.items
292
+ }
293
+ }
294
+ }
295
+
296
+ window.customElements.define('inventory-comparison', InventoryComparison)