@things-factory/operato-wms 5.0.0-alpha.2 → 5.0.0-alpha.22

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 (52) hide show
  1. package/client/pages/inbound/serial-number-list-popup.js +342 -0
  2. package/client/pages/inbound/unload-product.js +220 -41
  3. package/client/pages/inbound/unloaded-inventories-popup.js +7 -0
  4. package/client/pages/inventory/non-loaded-inventory.js +297 -0
  5. package/client/pages/order/release-order/b2b/b2b-order-list.js +41 -18
  6. package/client/pages/order/release-order/b2c/b2c-order-requests.js +40 -18
  7. package/client/pages/outbound/packing-product.js +88 -80
  8. package/client/pages/outbound/picking-product.js +61 -36
  9. package/client/pages/outbound/serial-number-popup.js +150 -64
  10. package/client/pages/report/inbound-serial-number-report.js +452 -0
  11. package/client/pages/report/outbound-order-details-report.js +64 -9
  12. package/client/pages/report/outbound-serial-number-report.js +467 -0
  13. package/client/route.js +11 -0
  14. package/dist-server/graphql/resolvers/reports/inbound-serial-number-report.js +111 -0
  15. package/dist-server/graphql/resolvers/reports/inbound-serial-number-report.js.map +1 -0
  16. package/dist-server/graphql/resolvers/reports/index.js +3 -1
  17. package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
  18. package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js +53 -48
  19. package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js.map +1 -1
  20. package/dist-server/graphql/resolvers/reports/outbound-serial-number-report.js +118 -0
  21. package/dist-server/graphql/resolvers/reports/outbound-serial-number-report.js.map +1 -0
  22. package/dist-server/graphql/types/reports/inbound-serial-number-report-list.js +14 -0
  23. package/dist-server/graphql/types/reports/inbound-serial-number-report-list.js.map +1 -0
  24. package/dist-server/graphql/types/reports/inbound-serial-number-report.js +23 -0
  25. package/dist-server/graphql/types/reports/inbound-serial-number-report.js.map +1 -0
  26. package/dist-server/graphql/types/reports/index.js +10 -0
  27. package/dist-server/graphql/types/reports/index.js.map +1 -1
  28. package/dist-server/graphql/types/reports/outbound-order-details-report.js +3 -0
  29. package/dist-server/graphql/types/reports/outbound-order-details-report.js.map +1 -1
  30. package/dist-server/graphql/types/reports/outbound-serial-number-report-list.js +14 -0
  31. package/dist-server/graphql/types/reports/outbound-serial-number-report-list.js.map +1 -0
  32. package/dist-server/graphql/types/reports/outbound-serial-number-report.js +25 -0
  33. package/dist-server/graphql/types/reports/outbound-serial-number-report.js.map +1 -0
  34. package/dist-server/migrations/1568858861188-SeedSetting.js +2 -1
  35. package/dist-server/migrations/1568858861188-SeedSetting.js.map +1 -1
  36. package/package.json +67 -66
  37. package/server/graphql/resolvers/reports/inbound-serial-number-report.ts +128 -0
  38. package/server/graphql/resolvers/reports/index.ts +5 -0
  39. package/server/graphql/resolvers/reports/outbound-order-details-report.ts +54 -48
  40. package/server/graphql/resolvers/reports/outbound-serial-number-report.ts +135 -0
  41. package/server/graphql/types/reports/inbound-serial-number-report-list.ts +8 -0
  42. package/server/graphql/types/reports/inbound-serial-number-report.ts +17 -0
  43. package/server/graphql/types/reports/index.ts +11 -0
  44. package/server/graphql/types/reports/outbound-order-details-report.ts +3 -0
  45. package/server/graphql/types/reports/outbound-serial-number-report-list.ts +8 -0
  46. package/server/graphql/types/reports/outbound-serial-number-report.ts +19 -0
  47. package/server/migrations/1568858861188-SeedSetting.ts +5 -2
  48. package/things-factory.config.js +12 -0
  49. package/translations/en.json +26 -6
  50. package/translations/ko.json +21 -2
  51. package/translations/ms.json +21 -2
  52. package/translations/zh.json +25 -6
@@ -0,0 +1,297 @@
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
+ import { ScrollbarStyles } from '@things-factory/styles'
11
+ import { isMobileDevice } from '@things-factory/utils'
12
+
13
+ class NonLoadedInventory extends connect(store)(localize(i18next)(PageView)) {
14
+ static get styles() {
15
+ return [
16
+ ScrollbarStyles,
17
+ css`
18
+ :host {
19
+ display: flex;
20
+ flex-direction: column;
21
+ overflow: hidden;
22
+ }
23
+ search-form {
24
+ overflow: visible;
25
+ }
26
+ data-grist {
27
+ overflow-y: auto;
28
+ flex: 1;
29
+ }
30
+ `
31
+ ]
32
+ }
33
+
34
+ static get properties() {
35
+ return {
36
+ _email: String,
37
+ _searchFields: Array,
38
+ _expSearchFields: Array,
39
+ _showExpiration: Boolean,
40
+ config: Object,
41
+ data: Object
42
+ }
43
+ }
44
+
45
+ render() {
46
+ return html`
47
+ <search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.dataGrist.fetch()}></search-form>
48
+
49
+ ${this._showExpiration
50
+ ? html`<search-form
51
+ id="search-exp-form"
52
+ .fields=${this._expSearchFields}
53
+ .hideSearchButton=${true}
54
+ @submit=${e => this.dataGrist.fetch()}
55
+ ></search-form>`
56
+ : html``}
57
+
58
+ <data-grist
59
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
60
+ .config=${this.config}
61
+ .fetchHandler="${this.fetchHandler.bind(this)}"
62
+ ></data-grist>
63
+ `
64
+ }
65
+
66
+ get context() {
67
+ return {
68
+ title: i18next.t('title.non_loaded_inventory')
69
+ }
70
+ }
71
+
72
+ async pageInitialized() {
73
+ this.config = {
74
+ list: {
75
+ fields: [
76
+ 'roNo',
77
+ 'palletId',
78
+ 'cartonId',
79
+ 'batchId',
80
+ 'productSku',
81
+ 'productInformation',
82
+ 'product_brand',
83
+ 'packingType',
84
+ 'qty',
85
+ 'uomValue',
86
+ 'uom',
87
+ 'binLocation'
88
+ ]
89
+ },
90
+ pagination: { pages: [20, 50, 100, 500, 999] },
91
+ rows: {
92
+ appendable: false
93
+ },
94
+ columns: [
95
+ { type: 'gutter', gutterName: 'sequence' },
96
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
97
+ {
98
+ type: 'string',
99
+ name: 'releaseOrderNo',
100
+ header: i18next.t('field.ro_no'),
101
+ sortable: true,
102
+ width: 150
103
+ },
104
+ {
105
+ type: 'string',
106
+ name: 'palletId',
107
+ header: i18next.t('field.lot_id'),
108
+ sortable: true,
109
+ width: 150
110
+ },
111
+ {
112
+ type: 'string',
113
+ name: 'cartonId',
114
+ header: i18next.t('field.carton_id'),
115
+ sortable: true,
116
+ width: 120
117
+ },
118
+ {
119
+ type: 'string',
120
+ name: 'batchId',
121
+ header: i18next.t('field.batch_id'),
122
+ imex: { header: i18next.t('field.batch_id'), key: 'batchId', width: 30, type: 'string' },
123
+ sortable: true,
124
+ width: 120
125
+ },
126
+ {
127
+ type: 'string',
128
+ name: 'productSku',
129
+ header: i18next.t('field.sku'),
130
+ sortable: true,
131
+ width: 150
132
+ },
133
+ {
134
+ type: 'string',
135
+ name: 'productName',
136
+ header: i18next.t('field.product'),
137
+ sortable: true,
138
+ width: 250
139
+ },
140
+ {
141
+ type: 'string',
142
+ name: 'productBrand',
143
+ header: i18next.t('field.brand'),
144
+ sortable: true,
145
+ width: 150
146
+ },
147
+ {
148
+ type: 'string',
149
+ name: 'packingType',
150
+ header: i18next.t('field.packing_type'),
151
+ sortable: true,
152
+ width: 150
153
+ },
154
+ {
155
+ type: 'number',
156
+ name: 'pickedQty',
157
+ header: i18next.t('field.qty'),
158
+ width: 80
159
+ },
160
+ {
161
+ type: 'float',
162
+ name: 'pickedUomValue',
163
+ header: i18next.t('field.total_uom_value'),
164
+ width: 110
165
+ },
166
+ {
167
+ type: 'string',
168
+ name: 'uom',
169
+ header: i18next.t('field.uom'),
170
+ sortable: true,
171
+ width: 80
172
+ },
173
+ {
174
+ type: 'string',
175
+ name: 'binLocation',
176
+ header: i18next.t('field.bin_location'),
177
+ sortable: true,
178
+ width: 120
179
+ }
180
+ ]
181
+ }
182
+
183
+ this._searchFields = [
184
+ {
185
+ label: i18next.t('field.product_info'),
186
+ name: 'productInfo',
187
+ type: 'text',
188
+ props: { searchOper: 'eq' }
189
+ },
190
+ {
191
+ label: i18next.t('field.batch_id'),
192
+ name: 'batchId',
193
+ type: 'text',
194
+ props: { searchOper: 'i_like' }
195
+ },
196
+ {
197
+ label: i18next.t('field.lot_id'),
198
+ name: 'palletId',
199
+ type: 'text',
200
+ props: { searchOper: 'i_like' }
201
+ },
202
+ {
203
+ label: i18next.t('field.carton_id'),
204
+ name: 'cartonId',
205
+ type: 'text',
206
+ props: { searchOper: 'i_like' }
207
+ },
208
+ {
209
+ label: i18next.t('field.ro_no'),
210
+ name: 'roNo',
211
+ type: 'text',
212
+ props: { searchOper: 'i_like' }
213
+ },
214
+ {
215
+ label: i18next.t('field.bin_location'),
216
+ name: 'binLocation',
217
+ type: 'text',
218
+ props: { searchOper: 'i_like' }
219
+ }
220
+ ]
221
+ }
222
+
223
+ async pageUpdated(changes, lifecycle) {
224
+ if (this.active) {
225
+ this.dataGrist.fetch()
226
+ }
227
+ }
228
+
229
+ get dataGrist() {
230
+ return this.shadowRoot.querySelector('data-grist')
231
+ }
232
+
233
+ get searchForm() {
234
+ return this.shadowRoot.querySelector('#search-form')
235
+ }
236
+
237
+ async fetchHandler({ page, limit, sorters = [] }) {
238
+ const filters = await this.searchForm.getQueryFilters()
239
+ const response = await client.query({
240
+ query: gql`
241
+ query nonLoadedOrderInventories($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
242
+ nonLoadedOrderInventories(filters: $filters, pagination: $pagination, sortings: $sortings) {
243
+ items {
244
+ releaseGood {
245
+ name
246
+ }
247
+ inventory {
248
+ palletId
249
+ cartonId
250
+ }
251
+ packingType
252
+ batchId
253
+ pickedQty
254
+ pickedUomValue
255
+ uom
256
+ product {
257
+ sku
258
+ name
259
+ brand
260
+ description
261
+ }
262
+ binLocation {
263
+ name
264
+ }
265
+ updatedAt
266
+ }
267
+ total
268
+ }
269
+ }
270
+ `,
271
+ variables: {
272
+ filters,
273
+ pagination: { page, limit },
274
+ sortings: sorters
275
+ }
276
+ })
277
+
278
+ return {
279
+ total: response.data.nonLoadedOrderInventories.total || 0,
280
+ records:
281
+ response.data.nonLoadedOrderInventories.items.map(item => {
282
+ return {
283
+ ...item,
284
+ productName: `${item.product.name} ${item.product.description}`,
285
+ productSku: item.product.sku,
286
+ productBrand: item.product.brand,
287
+ binLocation: item.binLocation.name,
288
+ palletId: item.inventory.palletId,
289
+ cartonId: item.inventory.cartonId,
290
+ releaseOrderNo: item.releaseGood.name
291
+ }
292
+ }) || []
293
+ }
294
+ }
295
+ }
296
+
297
+ window.customElements.define('non-loaded-inventory', NonLoadedInventory)
@@ -1,14 +1,13 @@
1
1
  import '@things-factory/form-ui'
2
2
  import '@things-factory/grist-ui'
3
3
  import '../batch-picking-popup'
4
- import '../batch-generate-single-picking-worksheet-popup'
5
4
 
6
5
  import gql from 'graphql-tag'
7
6
  import { css, html } from 'lit-element'
8
7
 
9
8
  import { getCodeByName } from '@things-factory/code-base'
10
9
  import { i18next, localize } from '@things-factory/i18n-base'
11
- import { client, navigate, PageView } from '@things-factory/shell'
10
+ import { client, navigate, PageView, CustomAlert } from '@things-factory/shell'
12
11
  import { openPopup } from '@things-factory/layout-base'
13
12
  import { ScrollbarStyles, CommonButtonStyles } from '@things-factory/styles'
14
13
  import { isMobileDevice } from '@things-factory/utils'
@@ -73,7 +72,7 @@ class B2bOrderList extends localize(i18next)(PageView) {
73
72
  },
74
73
  {
75
74
  title: i18next.t('button.generate_worksheet'),
76
- action: this._openBatchGenerateSinglePickingWorksheetPopup.bind(this),
75
+ action: this._generatePickingWorksheet.bind(this),
77
76
  ...CommonButtonStyles.activate
78
77
  }
79
78
  )
@@ -222,6 +221,7 @@ class B2bOrderList extends localize(i18next)(PageView) {
222
221
  pagination: { limit: 100, pages: [20, 50, 100, 200, 500] },
223
222
  columns: [
224
223
  { type: 'gutter', gutterName: 'sequence' },
224
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
225
225
  {
226
226
  type: 'gutter',
227
227
  gutterName: 'button',
@@ -502,22 +502,45 @@ class B2bOrderList extends localize(i18next)(PageView) {
502
502
  )
503
503
  }
504
504
 
505
- _openBatchGenerateSinglePickingWorksheetPopup() {
506
- openPopup(
507
- html`
508
- <batch-generate-single-picking-worksheet-popup
509
- @generated="${() => {
510
- this._showToast({ message: i18next.t('text.orders_has_been_activated') })
511
- this.dataGrist.fetch()
512
- }}"
513
- ></batch-generate-single-picking-worksheet-popup>
514
- `,
515
- {
516
- backdrop: true,
517
- size: 'large',
518
- title: i18next.t('title.generate_picking_worksheet')
505
+ async _generatePickingWorksheet() {
506
+ try {
507
+ let releaseGoodNos = []
508
+ if (this.dataGrist.selected.length <= 0)
509
+ throw new Error(i18next.t('text.please_select_one_or_more_order_to_generate_worksheet'))
510
+
511
+ let readyToPick = this.dataGrist.selected.filter(itm => itm.status === ORDER_STATUS.PENDING_WORKSHEET.value)
512
+ releaseGoodNos = readyToPick.map(record => record.name)
513
+
514
+ if (releaseGoodNos.length <= 0)
515
+ throw new Error(i18next.t('text.selected_release_order(s)_has_existing_worksheet'))
516
+
517
+ let result = await CustomAlert({
518
+ title: i18next.t('title.are_you_sure'),
519
+ text: i18next.t('text.generate_worksheet'),
520
+ confirmButton: { text: i18next.t('button.submit') },
521
+ cancelButton: { text: i18next.t('button.cancel') }
522
+ })
523
+
524
+ if (!result.value) return
525
+
526
+ const response = await client.mutate({
527
+ mutation: gql`
528
+ mutation generateMultipleReleaseGoodWorksheet($releaseGoodNos: [String!]) {
529
+ generateMultipleReleaseGoodWorksheet(releaseGoodNos: $releaseGoodNos)
530
+ }
531
+ `,
532
+ variables: {
533
+ releaseGoodNos
534
+ }
535
+ })
536
+
537
+ if (!response.errors) {
538
+ navigate('single_outbound_worksheets')
539
+ this._showToast({ message: i18next.t('text.worksheet(s)_has_been_generated') })
519
540
  }
520
- )
541
+ } catch (e) {
542
+ this._showToast(e)
543
+ }
521
544
  }
522
545
 
523
546
  _compareValues(key, order = 'asc') {
@@ -1,7 +1,6 @@
1
1
  import '@things-factory/form-ui'
2
2
  import '@things-factory/grist-ui'
3
3
  import '../batch-picking-popup'
4
- import '../batch-generate-single-picking-worksheet-popup'
5
4
 
6
5
  import gql from 'graphql-tag'
7
6
  import { css, html } from 'lit-element'
@@ -12,7 +11,7 @@ import { GhostPrint } from '@operato/ghost-print'
12
11
  import { getCodeByName } from '@things-factory/code-base'
13
12
  import { i18next, localize } from '@things-factory/i18n-base'
14
13
  import { openPopup } from '@things-factory/layout-base'
15
- import { client, navigate, PageView, store } from '@things-factory/shell'
14
+ import { client, navigate, PageView, store, CustomAlert } from '@things-factory/shell'
16
15
  import { CommonButtonStyles, ScrollbarStyles } from '@things-factory/styles'
17
16
  import { isMobileDevice } from '@things-factory/utils'
18
17
 
@@ -91,7 +90,7 @@ class B2cOrderRequests extends connect(store)(localize(i18next)(PageView)) {
91
90
  },
92
91
  {
93
92
  title: i18next.t('button.generate_worksheet'),
94
- action: this._openBatchGenerateSinglePickingWorksheetPopup.bind(this),
93
+ action: this._generatePickingWorksheet.bind(this),
95
94
  ...CommonButtonStyles.activate
96
95
  }
97
96
  ]
@@ -705,22 +704,45 @@ class B2cOrderRequests extends connect(store)(localize(i18next)(PageView)) {
705
704
  }
706
705
  }
707
706
 
708
- _openBatchGenerateSinglePickingWorksheetPopup() {
709
- openPopup(
710
- html`
711
- <batch-generate-single-picking-worksheet-popup
712
- @generated="${() => {
713
- this._showToast({ message: i18next.t('text.orders_has_been_activated') })
714
- this.dataGrist.fetch()
715
- }}"
716
- ></batch-generate-single-picking-worksheet-popup>
717
- `,
718
- {
719
- backdrop: true,
720
- size: 'large',
721
- title: i18next.t('title.generate_picking_worksheet')
707
+ async _generatePickingWorksheet() {
708
+ try {
709
+ let releaseGoodNos = []
710
+ if (this.dataGrist.selected.length <= 0)
711
+ throw new Error(i18next.t('text.please_select_one_or_more_order_to_generate_worksheet'))
712
+
713
+ let readyToPick = this.dataGrist.selected.filter(itm => itm.status === ORDER_STATUS.PENDING_WORKSHEET.value)
714
+ releaseGoodNos = readyToPick.map(record => record.name)
715
+
716
+ if (releaseGoodNos.length <= 0)
717
+ throw new Error(i18next.t('text.selected_release_order(s)_has_existing_worksheet'))
718
+
719
+ let result = await CustomAlert({
720
+ title: i18next.t('title.are_you_sure'),
721
+ text: i18next.t('text.generate_worksheet'),
722
+ confirmButton: { text: i18next.t('button.submit') },
723
+ cancelButton: { text: i18next.t('button.cancel') }
724
+ })
725
+
726
+ if (!result.value) return
727
+
728
+ const response = await client.mutate({
729
+ mutation: gql`
730
+ mutation generateMultipleReleaseGoodWorksheet($releaseGoodNos: [String!]) {
731
+ generateMultipleReleaseGoodWorksheet(releaseGoodNos: $releaseGoodNos)
732
+ }
733
+ `,
734
+ variables: {
735
+ releaseGoodNos
736
+ }
737
+ })
738
+
739
+ if (!response.errors) {
740
+ navigate('single_outbound_worksheets')
741
+ this._showToast({ message: i18next.t('text.worksheet(s)_has_been_generated') })
722
742
  }
723
- )
743
+ } catch (e) {
744
+ this._showToast(e)
745
+ }
724
746
  }
725
747
 
726
748
  _compareValues(key, order = 'asc') {