@things-factory/operato-wms 3.8.7 → 3.8.8

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.
@@ -1,6 +1,7 @@
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'
4
5
 
5
6
  import gql from 'graphql-tag'
6
7
  import { css, html } from 'lit-element'
@@ -65,6 +66,11 @@ class B2bOrderRequests extends localize(i18next)(PageView) {
65
66
  title: i18next.t('button.batch_picking'),
66
67
  action: this._openBatchPickingPopup.bind(this),
67
68
  ...CommonButtonStyles.activate
69
+ },
70
+ {
71
+ title: i18next.t('button.generate_worksheet'),
72
+ action: this._openBatchGenerateSinglePickingWorksheetPopup.bind(this),
73
+ ...CommonButtonStyles.activate
68
74
  }
69
75
  ],
70
76
  exportable: {
@@ -442,6 +448,24 @@ class B2bOrderRequests extends localize(i18next)(PageView) {
442
448
  )
443
449
  }
444
450
 
451
+ _openBatchGenerateSinglePickingWorksheetPopup() {
452
+ openPopup(
453
+ html`
454
+ <batch-generate-single-picking-worksheet-popup
455
+ @generated="${() => {
456
+ this._showToast({ message: i18next.t('text.orders_has_been_activated') })
457
+ this.dataGrist.fetch()
458
+ }}"
459
+ ></batch-generate-single-picking-worksheet-popup>
460
+ `,
461
+ {
462
+ backdrop: true,
463
+ size: 'large',
464
+ title: i18next.t('title.generate_picking_worksheet')
465
+ }
466
+ )
467
+ }
468
+
445
469
  _compareValues(key, order = 'asc') {
446
470
  return function innerSort(a, b) {
447
471
  if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
@@ -1,6 +1,7 @@
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'
4
5
 
5
6
  import gql from 'graphql-tag'
6
7
  import { css, html } from 'lit-element'
@@ -70,6 +71,11 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
70
71
  title: i18next.t('button.batch_picking'),
71
72
  action: this._openBatchPickingPopup.bind(this),
72
73
  ...CommonButtonStyles.activate
74
+ },
75
+ {
76
+ title: i18next.t('button.generate_worksheet'),
77
+ action: this._openBatchGenerateSinglePickingWorksheetPopup.bind(this),
78
+ ...CommonButtonStyles.activate
73
79
  }
74
80
  ],
75
81
  exportable: {
@@ -563,6 +569,43 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
563
569
  }
564
570
  }
565
571
 
572
+ _openBatchGenerateSinglePickingWorksheetPopup() {
573
+ openPopup(
574
+ html`
575
+ <batch-generate-single-picking-worksheet-popup
576
+ @generated="${() => {
577
+ this._showToast({ message: i18next.t('text.orders_has_been_activated') })
578
+ this.dataGrist.fetch()
579
+ }}"
580
+ ></batch-generate-single-picking-worksheet-popup>
581
+ `,
582
+ {
583
+ backdrop: true,
584
+ size: 'large',
585
+ title: i18next.t('title.generate_picking_worksheet')
586
+ }
587
+ )
588
+ }
589
+
590
+ _compareValues(key, order = 'asc') {
591
+ return function innerSort(a, b) {
592
+ if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
593
+ return 0
594
+ }
595
+
596
+ const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
597
+ const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]
598
+
599
+ let comparison = 0
600
+ if (varA > varB) {
601
+ comparison = 1
602
+ } else if (varA < varB) {
603
+ comparison = -1
604
+ }
605
+ return order === 'desc' ? comparison * -1 : comparison
606
+ }
607
+ }
608
+
566
609
  _modifyDateRange(e) {
567
610
  const fromDate = e.currentTarget.value
568
611
 
@@ -0,0 +1,314 @@
1
+ import '@things-factory/grist-ui'
2
+ import { MultiColumnFormStyles } from '@things-factory/form-ui'
3
+ import { openPopup } from '@things-factory/layout-base'
4
+ import { client, CustomAlert } from '@things-factory/shell'
5
+ import { i18next, localize } from '@things-factory/i18n-base'
6
+ import { isMobileDevice } from '@things-factory/utils'
7
+ import { css, html, LitElement } from 'lit-element'
8
+ import gql from 'graphql-tag'
9
+ import { ScrollbarStyles } from '@things-factory/styles'
10
+ import { ORDER_STATUS } from '../../constants'
11
+ import '@things-factory/biz-ui'
12
+
13
+ class BatchGenerateSinglePickingWorksheetPopup extends localize(i18next)(LitElement) {
14
+ static get properties() {
15
+ return {
16
+ _searchFields: Array,
17
+ config: Object,
18
+ data: Object
19
+ }
20
+ }
21
+
22
+ static get styles() {
23
+ return [
24
+ MultiColumnFormStyles,
25
+ ScrollbarStyles,
26
+ css`
27
+ :host {
28
+ display: flex;
29
+ flex-direction: column;
30
+ overflow: hidden;
31
+ background-color: white;
32
+ padding: var(--padding-default);
33
+ }
34
+ search-form {
35
+ overflow: visible;
36
+ }
37
+ .grist {
38
+ display: flex;
39
+ flex-direction: column;
40
+ flex: 1;
41
+ overflow-y: auto;
42
+ }
43
+ .grist-container {
44
+ overflow-y: hidden;
45
+ display: flex;
46
+ flex: 1;
47
+ }
48
+ data-grist {
49
+ overflow-y: hidden;
50
+ flex: 1;
51
+ }
52
+ h2 {
53
+ padding: var(--subtitle-padding);
54
+ font: var(--subtitle-font);
55
+ color: var(--subtitle-text-color);
56
+ border-bottom: var(--subtitle-border-bottom);
57
+ }
58
+ .grist h2 {
59
+ font: var(--grist-title-font);
60
+ }
61
+ .button-container {
62
+ padding: var(--button-container-padding);
63
+ margin: var(--button-container-margin);
64
+ text-align: var(--button-container-align);
65
+ background-color: var(--button-container-background);
66
+ height: var(--button-container-height);
67
+ }
68
+ `
69
+ ]
70
+ }
71
+
72
+ submit() {
73
+ this.dispatchEvent(new CustomEvent('submit'))
74
+ }
75
+
76
+ render() {
77
+ return html`
78
+ <search-form .fields=${this._searchFields} @submit=${() => this.releaseOrderGrist.fetch()}></search-form>
79
+
80
+ <div class="grist-container">
81
+ <div class="grist">
82
+ <h2>${i18next.t('title.release_order')}</h2>
83
+ <data-grist
84
+ id="releaseOrder"
85
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
86
+ .config=${this.roConfig}
87
+ .fetchHandler="${this.fetchReadyToPickOrders.bind(this)}"
88
+ ></data-grist>
89
+ </div>
90
+ </div>
91
+
92
+ <div class="button-container">
93
+ <mwc-button
94
+ @click="${this.generatePickingWorksheet.bind(this)}"
95
+ raised
96
+ label="${i18next.t('button.generate_worksheet')}"
97
+ ></mwc-button>
98
+ </div>
99
+ `
100
+ }
101
+
102
+ async firstUpdated() {
103
+ const partners = await this._fetchPartners()
104
+ this._searchFields = [
105
+ {
106
+ label: i18next.t('field.company'),
107
+ name: 'bizplace',
108
+ type: 'select',
109
+ options: [
110
+ { value: '' },
111
+ ...partners
112
+ .map(partner => {
113
+ return {
114
+ name: `${partner.name} ${partner.description ? `(${partner.description})` : ''}`,
115
+ value: partner.id
116
+ }
117
+ })
118
+ .sort(this._compareValues('name', 'asc'))
119
+ ],
120
+ props: { searchOper: 'eq' }
121
+ },
122
+ {
123
+ label: i18next.t('field.release_date'),
124
+ name: 'releaseDate',
125
+ type: 'date',
126
+ props: { searchOper: 'lte' }
127
+ }
128
+ ]
129
+
130
+ this.roConfig = {
131
+ pagination: { pages: [100, 200, 300, 500], limit: 200 },
132
+ rows: {
133
+ selectable: { multiple: true },
134
+ appendable: false
135
+ },
136
+ list: { fields: ['name', 'refNo', 'bizplace', 'releaseDate'] },
137
+ columns: [
138
+ { type: 'gutter', gutterName: 'sequence' },
139
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
140
+ {
141
+ type: 'string',
142
+ name: 'name',
143
+ header: i18next.t('field.release_good_no'),
144
+ width: 150
145
+ },
146
+ {
147
+ type: 'string',
148
+ name: 'refNo',
149
+ header: i18next.t('field.ref_no'),
150
+ width: 130
151
+ },
152
+ {
153
+ type: 'object',
154
+ name: 'bizplace',
155
+ header: i18next.t('field.company'),
156
+ width: 200
157
+ },
158
+ {
159
+ type: 'date',
160
+ name: 'releaseDate',
161
+ header: i18next.t('field.release_date'),
162
+ sortable: true,
163
+ width: 150
164
+ }
165
+ ]
166
+ }
167
+ }
168
+
169
+ get searchForm() {
170
+ return this.renderRoot.querySelector('search-form')
171
+ }
172
+
173
+ get releaseOrderGrist() {
174
+ return this.shadowRoot.querySelector('data-grist#releaseOrder')
175
+ }
176
+
177
+ get orderInventoryGrist() {
178
+ return this.shadowRoot.querySelector('data-grist#orderInventory')
179
+ }
180
+
181
+ async _fetchPartners() {
182
+ const response = await client.query({
183
+ query: gql`
184
+ query partnersBizplaces($filters: [Filter!]) {
185
+ partnersBizplaces(filters: $filters) {
186
+ items {
187
+ id
188
+ name
189
+ description
190
+ }
191
+ }
192
+ }
193
+ `,
194
+ variables: { filters: [] }
195
+ })
196
+
197
+ if (!response.errors) {
198
+ return response.data.partnersBizplaces.items
199
+ }
200
+ }
201
+
202
+ async fetchReadyToPickOrders({ page, limit, sorters = [{ name: 'releaseDate' }] }) {
203
+ // if (!this.partnerBizplace) return { total: 0, records: [] }
204
+
205
+ const filters = [
206
+ ...(await this.searchForm.getQueryFilters()).filter(x => x.name != 'partnerBizplace'),
207
+ { name: 'status', operator: 'eq', value: ORDER_STATUS.PENDING_WORKSHEET.value },
208
+ { name: 'crossDocking', operator: 'eq', value: false }
209
+ ]
210
+
211
+ if (this.partnerBizplace) {
212
+ filters.push({ name: 'bizplaceId', operator: 'eq', value: this.partnerBizplace.id })
213
+ }
214
+
215
+ const pagination = { page, limit }
216
+ const sortings = sorters
217
+
218
+ const response = await client.query({
219
+ query: gql`
220
+ query releaseGoodRequests($filters: [Filter], $pagination: Pagination, $sortings: [Sorting]) {
221
+ releaseGoodRequests(filters: $filters, pagination: $pagination, sortings: $sortings) {
222
+ items {
223
+ id
224
+ name
225
+ refNo
226
+ releaseDate
227
+ type
228
+ bizplace {
229
+ id
230
+ name
231
+ description
232
+ }
233
+ }
234
+ total
235
+ }
236
+ }
237
+ `,
238
+ variables: { filters, pagination, sortings }
239
+ })
240
+ if (!response.errors) {
241
+ return {
242
+ total: response.data.releaseGoodRequests.total || 0,
243
+ records: response.data.releaseGoodRequests.items || []
244
+ }
245
+ }
246
+ }
247
+
248
+ async generatePickingWorksheet() {
249
+ try {
250
+ let releaseGoodNos = []
251
+ releaseGoodNos = this.releaseOrderGrist.selected.map(record => record.name)
252
+
253
+ if (releaseGoodNos.length <= 0) throw new Error('Please select one or more order to generate worksheet')
254
+
255
+ let result = await CustomAlert({
256
+ title: i18next.t('title.are_you_sure'),
257
+ text: i18next.t('text.generate_worksheet'),
258
+ confirmButton: { text: i18next.t('button.submit') },
259
+ cancelButton: { text: i18next.t('button.cancel') }
260
+ })
261
+
262
+ if (!result.value) return
263
+
264
+ const response = await client.mutate({
265
+ mutation: gql`
266
+ mutation generateMultipleReleaseGoodWorksheet($releaseGoodNos: [String!]) {
267
+ generateMultipleReleaseGoodWorksheet(releaseGoodNos: $releaseGoodNos)
268
+ }
269
+ `,
270
+ variables: {
271
+ releaseGoodNos
272
+ }
273
+ })
274
+
275
+ if (!response.errors) {
276
+ this.dispatchEvent(new CustomEvent('generated'))
277
+ history.back()
278
+ }
279
+ } catch (e) {
280
+ this._showToast(e)
281
+ }
282
+ }
283
+
284
+ _compareValues(key, order = 'asc') {
285
+ return function innerSort(a, b) {
286
+ if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
287
+ return 0
288
+ }
289
+
290
+ const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
291
+ const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]
292
+
293
+ let comparison = 0
294
+ if (varA > varB) {
295
+ comparison = 1
296
+ } else if (varA < varB) {
297
+ comparison = -1
298
+ }
299
+ return order === 'desc' ? comparison * -1 : comparison
300
+ }
301
+ }
302
+
303
+ _showToast({ type, message }) {
304
+ document.dispatchEvent(
305
+ new CustomEvent('notify', {
306
+ detail: {
307
+ type,
308
+ message
309
+ }
310
+ })
311
+ )
312
+ }
313
+ }
314
+ window.customElements.define('batch-generate-single-picking-worksheet-popup', BatchGenerateSinglePickingWorksheetPopup)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/operato-wms",
3
- "version": "3.8.7",
3
+ "version": "3.8.8",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -46,7 +46,7 @@
46
46
  "@things-factory/attachment-ui": "^3.8.0",
47
47
  "@things-factory/auth-ui": "^3.8.0",
48
48
  "@things-factory/barcode-ui": "^3.8.0",
49
- "@things-factory/biz-ui": "^3.8.0",
49
+ "@things-factory/biz-ui": "^3.8.8",
50
50
  "@things-factory/board-service": "^3.8.0",
51
51
  "@things-factory/board-ui": "^3.8.0",
52
52
  "@things-factory/code-ui": "^3.8.0",
@@ -71,7 +71,7 @@
71
71
  "@things-factory/print-ui": "^3.8.0",
72
72
  "@things-factory/product-base": "^3.8.3",
73
73
  "@things-factory/resource-ui": "^3.8.0",
74
- "@things-factory/sales-ui": "^3.8.7",
74
+ "@things-factory/sales-ui": "^3.8.8",
75
75
  "@things-factory/scene-chartjs": "^3.7.5",
76
76
  "@things-factory/scene-clock": "^3.7.5",
77
77
  "@things-factory/scene-clone": "^3.7.5",
@@ -102,11 +102,11 @@
102
102
  "@things-factory/system-ui": "^3.8.0",
103
103
  "@things-factory/transport-base": "^3.8.0",
104
104
  "@things-factory/tutorial-ui": "^3.8.0",
105
- "@things-factory/warehouse-base": "^3.8.5",
106
- "@things-factory/worksheet-base": "^3.8.7"
105
+ "@things-factory/warehouse-base": "^3.8.8",
106
+ "@things-factory/worksheet-base": "^3.8.8"
107
107
  },
108
108
  "devDependencies": {
109
109
  "@things-factory/builder": "^3.7.5"
110
110
  },
111
- "gitHead": "5b7ecbd2cfac8f61714fe0942c2dd235244a31b2"
111
+ "gitHead": "3f0cf4cd9eba27f4b4a7688c462cc3183dd9df00"
112
112
  }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "title.generate_picking_worksheet": "generate picking worksheet",
2
3
  "arrival_notice_created": "arrival notice created",
3
4
  "button.activate": "activate",
4
5
  "button.add_edit": "add & edit",
@@ -1066,6 +1067,7 @@
1066
1067
  "text.gan_pending_company_approval": "GAN pending company approval",
1067
1068
  "text.gan_will_be_sent_for_company_approval": "GAN will be sent for company approval",
1068
1069
  "text.generate_putaway_worksheet": "generate putaway worksheet",
1070
+ "text.generate_worksheet": "generate worksheet",
1069
1071
  "text.goods_delivery_note_uploaded": "goods delivery note uploaded",
1070
1072
  "text.goods_received_note_has_been_received": "GRN has been marked received",
1071
1073
  "text.goods_received_note_has_been_sent_successfully": "GRN has been sent successfully",
@@ -1,4 +1,5 @@
1
1
  {
2
+ "title.generate_picking_worksheet": "[ko]generate picking worksheet",
2
3
  "arrival_notice_created": "입고주문이 생성 되었습니다.",
3
4
  "arrival_notice_updated": "[ko]arrival notice updated",
4
5
  "button.activate": "활성화",
@@ -1819,5 +1820,6 @@
1819
1820
  "title.worksheet": "작업지시서",
1820
1821
  "vas_order_created": "부가서비스주문 생성됨",
1821
1822
  "title.location_scanned_is_not_quarantine_zone": "[ko] Location scanned is not a quarantine zone!",
1822
- "text.release_qty_invalid": "[ko] release quantity is invalid"
1823
+ "text.release_qty_invalid": "[ko] release quantity is invalid",
1824
+ "text.generate_worksheet": "[ko] generate worksheet"
1823
1825
  }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "title.generate_picking_worksheet": "[ms]generate picking worksheet",
2
3
  "arrival_notice_created": "notis ketibaan telah dicipta",
3
4
  "arrival_notice_updated": "notis ketibaan telah dikemaskinikan",
4
5
  "button.activate": "aktifkan",
@@ -1689,5 +1690,6 @@
1689
1690
  "title.worksheet": "lembaran kerja",
1690
1691
  "vas_order_created": "pesanan value added service telah dicipta",
1691
1692
  "title.location_scanned_is_not_quarantine_zone": "[ms] Location scanned is not a quarantine zone!",
1692
- "text.release_qty_invalid": "[ms] release quantity is invalid"
1693
+ "text.release_qty_invalid": "[ms] release quantity is invalid",
1694
+ "text.generate_worksheet": "[ms] generate worksheet"
1693
1695
  }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "title.generate_picking_worksheet": "[zh]generate picking worksheet",
2
3
  "arrival_notice_created": "arrival notice created",
3
4
  "button.activate": "activate",
4
5
  "button.add_edit": "add & edit",
@@ -1639,5 +1640,6 @@
1639
1640
  "title.worksheet": "worksheet",
1640
1641
  "vas_order_created": "vas order created",
1641
1642
  "title.location_scanned_is_not_quarantine_zone": "[zh] Location scanned is not a quarantine zone!",
1642
- "text.release_qty_invalid": "[zh] release quantity is invalid"
1643
+ "text.release_qty_invalid": "[zh] release quantity is invalid",
1644
+ "text.generate_worksheet": "[zh] generate worksheet"
1643
1645
  }