@things-factory/operato-mms 4.0.0-alpha.7 → 4.0.0-beta.1

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 (71) hide show
  1. package/Dockerfile +2 -1
  2. package/client/bootstrap.js +32 -16
  3. package/client/components/marketplace-order-max-weight.js +158 -0
  4. package/client/components/mms-home-cards.js +1 -1
  5. package/client/components/stock-allocation-ratio.js +17 -23
  6. package/client/pages/catalogue/products.js +2 -1
  7. package/client/pages/catalogue/warehouse-products.js +2 -1
  8. package/client/pages/catalogue-variation/product-variations.js +72 -15
  9. package/client/pages/inventory/inventory-by-product.js +3 -2
  10. package/client/pages/order/logistics/batch-init-popup.js +566 -0
  11. package/client/pages/order/logistics/lazada-order-init-batch-popup.js +233 -21
  12. package/client/pages/order/logistics/order-shipping-items.js +47 -16
  13. package/client/pages/order/logistics/order-shipping.js +7 -4
  14. package/client/pages/order/logistics/request-ro-popup.js +104 -17
  15. package/client/pages/order/logistics/shopee-order-init-batch-popup.js +431 -129
  16. package/client/pages/order/order-by-store.js +176 -149
  17. package/client/pages/setting/marketplace-setting.js +12 -0
  18. package/dist-server/graphql/index.js +1 -1
  19. package/dist-server/graphql/resolvers/index.js +1 -1
  20. package/dist-server/graphql/resolvers/interface-with-hub/add-release-order.js +74 -13
  21. package/dist-server/graphql/resolvers/interface-with-hub/add-release-order.js.map +1 -1
  22. package/dist-server/graphql/resolvers/interface-with-hub/auto-add-release-order.js +74 -13
  23. package/dist-server/graphql/resolvers/interface-with-hub/auto-add-release-order.js.map +1 -1
  24. package/dist-server/graphql/resolvers/interface-with-hub/generate-replenishment-order.js +1 -1
  25. package/dist-server/graphql/resolvers/interface-with-hub/generate-replenishment-order.js.map +1 -1
  26. package/dist-server/graphql/resolvers/interface-with-hub/warehouse-marketplace-products.js +53 -36
  27. package/dist-server/graphql/resolvers/interface-with-hub/warehouse-marketplace-products.js.map +1 -1
  28. package/dist-server/graphql/resolvers/warehouse-product/auto-link-warehouse-marketplace-product-variations.js +5 -5
  29. package/dist-server/graphql/resolvers/warehouse-product/auto-link-warehouse-marketplace-product-variations.js.map +1 -1
  30. package/dist-server/graphql/types/index.js +1 -1
  31. package/dist-server/graphql/types/interface-with-hub/new-stock-replenishment.js +1 -1
  32. package/dist-server/graphql/types/interface-with-hub/new-stock-replenishment.js.map +1 -1
  33. package/dist-server/graphql/types/interface-with-hub/replenishment-order-product.js +1 -1
  34. package/dist-server/graphql/types/interface-with-hub/replenishment-order-product.js.map +1 -1
  35. package/dist-server/graphql/types/interface-with-hub/stock-replenishment-list.js +1 -1
  36. package/dist-server/graphql/types/interface-with-hub/stock-replenishment-list.js.map +1 -1
  37. package/dist-server/graphql/types/interface-with-hub/stock-replenishment.js +1 -1
  38. package/dist-server/graphql/types/interface-with-hub/stock-replenishment.js.map +1 -1
  39. package/dist-server/graphql/types/interface-with-hub/warehouse-inventory.js +1 -1
  40. package/dist-server/graphql/types/interface-with-hub/warehouse-inventory.js.map +1 -1
  41. package/dist-server/graphql/types/interface-with-hub/warehouse-marketplace-product-list.js +1 -1
  42. package/dist-server/graphql/types/interface-with-hub/warehouse-marketplace-product-list.js.map +1 -1
  43. package/dist-server/graphql/types/interface-with-hub/warehouse-marketplace-product.js +1 -1
  44. package/dist-server/graphql/types/interface-with-hub/warehouse-marketplace-product.js.map +1 -1
  45. package/dist-server/graphql/types/warehouse-product/warehouse-product.js +1 -1
  46. package/dist-server/graphql/types/warehouse-product/warehouse-product.js.map +1 -1
  47. package/dist-server/index.js +1 -1
  48. package/dist-server/migrations/1599732967233-SeedCommonCode.js +5 -5
  49. package/dist-server/migrations/1599732967233-SeedCommonCode.js.map +1 -1
  50. package/dist-server/migrations/1608009991075-SeedUser.js +4 -4
  51. package/dist-server/migrations/1608009991075-SeedUser.js.map +1 -1
  52. package/dist-server/routers/etrax-router.js +7 -6
  53. package/dist-server/routers/etrax-router.js.map +1 -1
  54. package/dist-server/routers/shopify-pos-public-router.js +10 -10
  55. package/dist-server/routers/shopify-pos-public-router.js.map +1 -1
  56. package/dist-server/util/interface-helper.js +2 -2
  57. package/dist-server/util/interface-helper.js.map +1 -1
  58. package/dist-server/util/no-generator.js +2 -2
  59. package/dist-server/util/no-generator.js.map +1 -1
  60. package/package.json +65 -63
  61. package/server/graphql/resolvers/interface-with-hub/add-release-order.ts +83 -14
  62. package/server/graphql/resolvers/interface-with-hub/auto-add-release-order.ts +79 -11
  63. package/server/graphql/resolvers/interface-with-hub/warehouse-marketplace-products.ts +50 -33
  64. package/server/routers/etrax-router.ts +6 -4
  65. package/translations/en.json +16 -0
  66. package/translations/ko.json +14 -0
  67. package/translations/ms.json +14 -0
  68. package/translations/zh.json +14 -0
  69. package/views/auth-page.html +1 -1
  70. package/views/public/home.html +1 -1
  71. package/config.development.js +0 -54
@@ -1,11 +1,15 @@
1
- import { MultiColumnFormStyles } from '@things-factory/form-ui'
2
1
  import '@things-factory/grist-ui'
3
- import { i18next, localize } from '@things-factory/i18n-base'
4
- import { client, CustomAlert } from '@things-factory/shell'
5
- import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
2
+
6
3
  import gql from 'graphql-tag'
7
4
  import { css, html, LitElement } from 'lit-element'
8
5
 
6
+ import { MultiColumnFormStyles } from '@things-factory/form-ui'
7
+ import { i18next, localize } from '@things-factory/i18n-base'
8
+ import { client, CustomAlert } from '@things-factory/shell'
9
+ import { isMobileDevice } from '@things-factory/utils'
10
+
11
+ import { PLATFORM } from '../../constants'
12
+
9
13
  class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
10
14
  static get properties() {
11
15
  return {
@@ -16,16 +20,23 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
16
20
  addressList: Array,
17
21
  timeSlotList: Array,
18
22
  _type: String,
19
- store: Object
23
+ _searchFields: Array,
24
+ store: Object,
25
+ marketplaceSettings: Array,
26
+ maxWeightSetting: Object,
27
+ ownShippingProviders: Array,
28
+ shippingProviders: Array
20
29
  }
21
30
  }
22
31
 
23
32
  constructor() {
24
33
  super()
25
- this.logisticsParam = { pickup: true, dropoff: true }
34
+ this._searchFields = []
26
35
  this.addressList = []
27
36
  this.timeSlotList = []
28
37
  this.branchList = []
38
+ this.marketplaceSettings = []
39
+ this.maxWeightSetting = []
29
40
  }
30
41
 
31
42
  static get styles() {
@@ -69,6 +80,25 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
69
80
  return html`
70
81
  <search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.grist.fetch()}></search-form>
71
82
 
83
+ ${this._type === 'non_integrated'
84
+ ? html`<div name="batchUpdate" class="multi-column-form">
85
+ <label>${i18next.t('label.own_shipping_provider')}</label>
86
+ <select name="ownShippingProvider-select">
87
+ <option value="">${i18next.t('text.select_courier')}</option>
88
+ ${(this.ownShippingProviders || []).map(
89
+ shippingProvider => html` <option value="${shippingProvider.name}">${shippingProvider.name}</option> `
90
+ )}
91
+ </select>
92
+
93
+ <div class="set-button-container">
94
+ <mwc-button
95
+ @click="${e => this.setShippingProvider()}"
96
+ raised
97
+ label="${i18next.t('button.set')}"
98
+ ></mwc-button>
99
+ </div>
100
+ </div>`
101
+ : ''}
72
102
  ${this._type === 'pickup'
73
103
  ? html` <div name="batchUpdate" class="multi-column-form">
74
104
  <label>${i18next.t('label.address')}</label>
@@ -98,13 +128,17 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
98
128
  id="grist"
99
129
  .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
100
130
  .config=${this.config}
101
- .data="${this.data}"
102
- .fetchHandler="${this.fetchHandler.bind(this)}"
131
+ .fetchHandler=${this.fetchHandler.bind(this)}
103
132
  @field-change="${this._onFieldChangeHandler.bind(this)}"
104
133
  ></data-grist>
105
134
  </div>
106
135
 
107
136
  <div class="button-container">
137
+ <mwc-button
138
+ @click="${this.splitOrders.bind(this)}"
139
+ raised
140
+ label="${i18next.t('button.split_order')}"
141
+ ></mwc-button>
108
142
  <mwc-button
109
143
  @click="${this.initLogistics.bind(this)}"
110
144
  raised
@@ -130,7 +164,12 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
130
164
  return this.shadowRoot.querySelector('select[name=pickupdate-select]')
131
165
  }
132
166
 
167
+ get ownShippingProviderSelect() {
168
+ return this.shadowRoot.querySelector('select[name=ownShippingProvider-select]')
169
+ }
170
+
133
171
  get gristConfig() {
172
+ const maxWeight = this.maxWeightSetting[0].value
134
173
  return {
135
174
  list: {
136
175
  fields: [
@@ -140,11 +179,25 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
140
179
  'shippingProvider',
141
180
  'itemCount',
142
181
  'totalAmount',
182
+ 'totalVolume',
183
+ 'totalWeight',
143
184
  'status',
144
185
  'updatedAt'
145
186
  ]
146
187
  },
147
- rows: { selectable: { multiple: true }, appendable: false },
188
+ rows: {
189
+ selectable: { multiple: true },
190
+ appendable: false,
191
+ classifier: function (record, rowIndex) {
192
+ const totalWeight = record['totalWeight']
193
+ var emphasized
194
+ if (totalWeight > maxWeight) {
195
+ emphasized = ['#F43838', 'yellow']
196
+ }
197
+
198
+ return { emphasized }
199
+ }
200
+ },
148
201
  pagination: { infinite: true },
149
202
  columns: [
150
203
  { type: 'gutter', gutterName: 'sequence' },
@@ -175,6 +228,13 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
175
228
  sortable: true,
176
229
  width: 130
177
230
  },
231
+ {
232
+ type: 'string',
233
+ name: 'ownShippingProvider',
234
+ header: i18next.t('field.own_shipping_carrier'),
235
+ sortable: true,
236
+ width: 130
237
+ },
178
238
  {
179
239
  type: 'string',
180
240
  name: 'itemCount',
@@ -187,7 +247,21 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
187
247
  name: 'totalAmount',
188
248
  header: i18next.t('field.total_amount'),
189
249
  sortable: true,
190
- width: 100
250
+ width: 80
251
+ },
252
+ {
253
+ type: 'number',
254
+ name: 'totalVolume',
255
+ header: i18next.t('field.total_volume'),
256
+ label: true,
257
+ width: 80
258
+ },
259
+ {
260
+ type: 'number',
261
+ name: 'totalWeight',
262
+ header: i18next.t('field.total_weight'),
263
+ label: true,
264
+ width: 80
191
265
  },
192
266
  {
193
267
  type: 'string',
@@ -201,39 +275,46 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
201
275
  }
202
276
 
203
277
  async firstUpdated() {
204
- const shippingProviders = await this.fetchShippingProvider()
278
+ this.ownShippingProviders = [{ name: 'SeeBuu Logistics' }]
279
+ this.shippingProviders = await this.fetchShippingProvider()
280
+ this.marketplaceSettings = await this.fetchMarketplaceSettings()
281
+ this.maxWeightSetting = this.marketplaceSettings.filter(
282
+ setting => setting.category === 'marketplace_order_max_weight'
283
+ )
284
+
285
+ await this.fetchHandler({ page: 1, limit: 100 })
205
286
  this._initGrist()
206
287
 
207
288
  this._searchFields = [
208
289
  {
209
- label: i18next.t('field.shipping_carrier'),
210
- name: 'shippingProvider',
290
+ label: i18next.t('field.type'),
291
+ name: 'logisticsType',
211
292
  type: 'select',
212
293
  options: [
213
- { value: '' },
214
- ...shippingProviders.map(shippingProvider => {
294
+ { name: '', value: '' },
295
+ ...Object.keys(this.logisticsParam).map(key => {
215
296
  return {
216
- name: shippingProvider.name,
217
- value: shippingProvider.name
297
+ name: key,
298
+ value: key
218
299
  }
219
300
  })
220
301
  ],
302
+ handlers: { change: this._initGrist.bind(this) },
221
303
  props: { searchOper: 'eq' }
222
304
  },
223
305
  {
224
- label: i18next.t('field.type'),
225
- name: 'logisticsType',
306
+ label: i18next.t('field.shipping_carrier'),
307
+ name: 'shippingProvider',
226
308
  type: 'select',
227
309
  options: [
228
- { name: '', value: '' },
229
- ...Object.keys(this.logisticsParam).map(key => {
310
+ { value: '' },
311
+ ...this.shippingProviders.map(shippingProvider => {
230
312
  return {
231
- name: key,
232
- value: key
313
+ name: shippingProvider.name,
314
+ value: shippingProvider.name
233
315
  }
234
316
  })
235
317
  ],
236
- handlers: { change: this._initGrist.bind(this) },
237
318
  props: { searchOper: 'eq' }
238
319
  }
239
320
  ]
@@ -241,8 +322,6 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
241
322
 
242
323
  async fetchHandler({ page, limit, sorters = [{ name: 'orderUpdatedAt', desc: true }] }) {
243
324
  try {
244
- this._validateInput()
245
-
246
325
  let filters = [
247
326
  {
248
327
  name: 'marketplaceStore',
@@ -251,7 +330,8 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
251
330
  },
252
331
  {
253
332
  name: 'trackingNo',
254
- operator: 'is_null'
333
+ operator: 'is_null',
334
+ value: ''
255
335
  },
256
336
  {
257
337
  name: 'status',
@@ -264,7 +344,6 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
264
344
  const pagination = { page, limit }
265
345
  const sortings = sorters
266
346
 
267
- // should add store filter conditions
268
347
  const response = await client.query({
269
348
  query: gql`
270
349
  query marketplaceOrdersForBatchInit($filters: [Filter], $pagination: Pagination, $sortings: [Sorting]) {
@@ -295,6 +374,13 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
295
374
  phone2
296
375
  attentionTo
297
376
  trackingNo
377
+ ownTrackingNo
378
+ transporter
379
+ ownTransporter
380
+ totalWeight
381
+ weightUnit
382
+ totalVolume
383
+ volumeUnit
298
384
  }
299
385
  marketplaceProductVariation {
300
386
  name
@@ -308,10 +394,12 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
308
394
  status
309
395
  itemCount
310
396
  shippingProvider
397
+ ownShippingProvider
311
398
  totalAmount
312
399
  orderCreatedAt
313
400
  orderUpdatedAt
314
401
  trackingNo
402
+ ownTrackingNo
315
403
  updatedAt
316
404
  fullLogisticsDetail {
317
405
  pickup
@@ -352,74 +440,92 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
352
440
  })
353
441
 
354
442
  if (!response.errors) {
355
- let marketplaceOrders = response.data.marketplaceOrdersForBatchInit.items
356
- marketplaceOrders = marketplaceOrders.map(item => {
443
+ const marketplaceOrders = response.data.marketplaceOrdersForBatchInit.items.map(item => {
357
444
  return {
358
445
  ...item,
359
- trackingNo: this.getTrackingNos(item.marketplaceOrderItems)
446
+ trackingNo: this.getOrderShippingInformation(item.marketplaceOrderItems, 'trackingNo'),
447
+ ownTrackingNo: this.getOrderShippingInformation(item.marketplaceOrderItems, 'ownTrackingNo'),
448
+ totalWeight: this.getOrderShippingInformation(item.marketplaceOrderItems, 'totalWeight'),
449
+ totalVolume: this.getOrderShippingInformation(item.marketplaceOrderItems, 'totalVolume')
360
450
  }
361
451
  })
362
452
 
363
- const records = marketplaceOrders.map(itm => {
364
- switch (this._type) {
365
- case 'pickup':
366
- return {
367
- ...itm,
368
- rowOptionPickupAddress: {
369
- options: [
370
- {
371
- display: '',
372
- value: ''
373
- },
374
- ...itm.fullLogisticsDetail.logisticsDetail.pickup.map(pickup => {
375
- const addressDetail = {
376
- display: pickup.address + ' ,' + pickup.city + ' ,' + pickup.zipcode + ' ,' + pickup.state,
377
- value: pickup.addressId.toString(),
378
- timeSlot: pickup.timeSlot
379
- }
453
+ const logisticsDetails = marketplaceOrders.map(order => order.fullLogisticsDetail)
454
+ this.logisticsParam = this.buildLogisticsParam(logisticsDetails)
380
455
 
381
- if (!this.addressList.map(list => list.value).includes(addressDetail.value)) {
382
- this.addressList = Array.from(new Set([...this.addressList, addressDetail]))
383
- }
456
+ let records = []
457
+ if (this._type) {
458
+ records = marketplaceOrders.map(itm => {
459
+ switch (this._type) {
460
+ case 'pickup':
461
+ if (itm.fullLogisticsDetail?.pickup?.length > 0) {
462
+ return {
463
+ ...itm,
464
+ rowOptionPickupAddress: {
465
+ options: [
466
+ {
467
+ display: '',
468
+ value: ''
469
+ },
470
+ ...itm.fullLogisticsDetail.logisticsDetail.pickup.map(pickup => {
471
+ const addressDetail = {
472
+ display: pickup.address + ' ,' + pickup.city + ' ,' + pickup.zipcode + ' ,' + pickup.state,
473
+ value: pickup.addressId.toString(),
474
+ timeSlot: pickup.timeSlot
475
+ }
384
476
 
385
- return addressDetail
386
- })
387
- ]
477
+ if (!this.addressList.map(list => list.value).includes(addressDetail.value)) {
478
+ this.addressList = Array.from(new Set([...this.addressList, addressDetail]))
479
+ }
480
+
481
+ return addressDetail
482
+ })
483
+ ]
484
+ }
485
+ }
486
+ } else {
487
+ return
388
488
  }
389
- }
390
489
 
391
- case 'dropoff':
392
- return {
393
- ...itm,
394
- requiredBranch: itm.fullLogisticsDetail.dropoff.indexOf('branch_id') >= 0 ? true : false,
395
- requiredSender: itm.fullLogisticsDetail.dropoff.indexOf('sender_real_name') >= 0 ? true : false,
396
- requiredTracking: itm.fullLogisticsDetail.dropoff.indexOf('tracking_no') >= 0 ? true : false,
397
- rowOptionDropoffBranch: {
398
- options: [
399
- {
400
- display: '',
401
- value: ''
402
- },
403
- ...itm.fullLogisticsDetail.logisticsDetail.dropoff.map(dropoff => {
404
- const addressDetail = {
405
- display: dropoff.address + ' ,' + dropoff.city + ' ,' + dropoff.zipcode + ' ,' + dropoff.state,
406
- value: dropoff.branchId.toString()
407
- }
490
+ case 'dropoff':
491
+ if (itm.fullLogisticsDetail?.dropoff?.length > 0) {
492
+ return {
493
+ ...itm,
494
+ requiredBranch: itm.fullLogisticsDetail.dropoff.includes('branch_id'),
495
+ requiredSender: itm.fullLogisticsDetail.dropoff.includes('sender_real_name'),
496
+ requiredTracking: itm.fullLogisticsDetail.dropoff.includes('tracking_no'),
497
+ rowOptionDropoffBranch: {
498
+ options: [
499
+ {
500
+ display: '',
501
+ value: ''
502
+ },
503
+ ...itm.fullLogisticsDetail.logisticsDetail.dropoff.map(dropoff => {
504
+ const addressDetail = {
505
+ display:
506
+ dropoff.address + ' ,' + dropoff.city + ' ,' + dropoff.zipcode + ' ,' + dropoff.state,
507
+ value: dropoff.branchId.toString()
508
+ }
408
509
 
409
- if (!this.addressList.map(list => list.value).includes(addressDetail.value)) {
410
- this.addressList = Array.from(new Set([...this.addressList, addressDetail]))
411
- }
510
+ if (!this.addressList.map(list => list.value).includes(addressDetail.value)) {
511
+ this.addressList = Array.from(new Set([...this.addressList, addressDetail]))
512
+ }
412
513
 
413
- return addressDetail
414
- })
415
- ]
514
+ return addressDetail
515
+ })
516
+ ]
517
+ }
518
+ }
519
+ } else {
520
+ return { ...itm }
416
521
  }
417
- }
418
522
 
419
- default:
420
- break
421
- }
422
- })
523
+ default:
524
+ return { ...itm }
525
+ }
526
+ })
527
+ }
528
+
423
529
  return {
424
530
  total: records.length || 0,
425
531
  records
@@ -430,8 +536,19 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
430
536
  }
431
537
  }
432
538
 
433
- getTrackingNos(marketplaceOrderItems) {
434
- let trackingNo = ''
539
+ buildLogisticsParam(logisticsDetails) {
540
+ let logisticsParam = {}
541
+
542
+ if (logisticsDetails.some(param => param.pickup !== null)) logisticsParam = { ...logisticsParam, pickup: true }
543
+ if (logisticsDetails.some(param => param.dropoff !== null)) logisticsParam = { ...logisticsParam, dropoff: true }
544
+ if (logisticsDetails.some(param => param.non_integrated !== null))
545
+ logisticsParam = { ...logisticsParam, non_integrated: true }
546
+
547
+ return logisticsParam
548
+ }
549
+
550
+ getOrderShippingInformation(marketplaceOrderItems, type) {
551
+ let item
435
552
  let marketplaceOrderShippings = []
436
553
 
437
554
  marketplaceOrderItems.map(item => {
@@ -446,27 +563,86 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
446
563
  return marketplaceOrderShippings.find(a => a.id === id)
447
564
  })
448
565
 
449
- if (uniqueMarketplaceOrderShippings) {
450
- uniqueMarketplaceOrderShippings.map(marketplaceOrderShipping => {
451
- if (this.store?.platform === PLATFORM.LAZADA.value) {
452
- var newTrackingNo = []
453
- if (marketplaceOrderShipping?.trackingNo) {
454
- const trackingNos = JSON.parse(marketplaceOrderShipping.trackingNo)
455
- newTrackingNo = trackingNos.map(item => item.tracking_code)
456
- }
457
- let uniqueTrackingNos = [...new Set(newTrackingNo)]
458
- trackingNo = uniqueTrackingNos.join(', ')
459
- } else {
460
- trackingNo = marketplaceOrderShipping.trackingNo
566
+ switch (type) {
567
+ case 'trackingNo':
568
+ if (uniqueMarketplaceOrderShippings) {
569
+ uniqueMarketplaceOrderShippings.map(marketplaceOrderShipping => {
570
+ if (this.store?.platform === PLATFORM.LAZADA.value) {
571
+ var newTrackingNo = []
572
+ if (marketplaceOrderShipping?.trackingNo) {
573
+ const trackingNos = JSON.parse(marketplaceOrderShipping.trackingNo)
574
+ newTrackingNo = trackingNos.map(item => item.tracking_code)
575
+ }
576
+ let uniqueTrackingNos = [...new Set(newTrackingNo)]
577
+ item = uniqueTrackingNos.join(', ')
578
+ } else {
579
+ item = marketplaceOrderShipping.trackingNo
580
+ }
581
+ })
461
582
  }
462
- })
583
+ break
584
+ case 'ownTrackingNo':
585
+ if (uniqueMarketplaceOrderShippings) {
586
+ uniqueMarketplaceOrderShippings.map(marketplaceOrderShipping => {
587
+ if (this.store?.platform === PLATFORM.LAZADA.value) {
588
+ var newTrackingNo = []
589
+ if (marketplaceOrderShipping?.ownTrackingNo) {
590
+ const trackingNos = JSON.parse(marketplaceOrderShipping.ownTrackingNo)
591
+ newTrackingNo = trackingNos.map(item => item.tracking_code)
592
+ }
593
+ let uniqueTrackingNos = [...new Set(newTrackingNo)]
594
+ item = uniqueTrackingNos.join(', ')
595
+ } else {
596
+ item = marketplaceOrderShipping.ownTrackingNo
597
+ }
598
+ })
599
+ }
600
+ break
601
+ case 'totalVolume':
602
+ let totalVolume = 0
603
+ if (uniqueMarketplaceOrderShippings) {
604
+ uniqueMarketplaceOrderShippings.map(marketplaceOrderShipping => {
605
+ totalVolume += marketplaceOrderShipping?.totalVolume || 0
606
+ })
607
+ }
608
+
609
+ item = parseFloat(totalVolume) || 0
610
+ break
611
+ case 'totalWeight':
612
+ let totalWeight = 0
613
+ if (uniqueMarketplaceOrderShippings) {
614
+ uniqueMarketplaceOrderShippings.map(marketplaceOrderShipping => {
615
+ totalWeight += marketplaceOrderShipping?.totalWeight
616
+ })
617
+ }
618
+ item = parseFloat(totalWeight) || 0
619
+ break
463
620
  }
464
621
 
465
- return trackingNo
622
+ return item
466
623
  }
467
624
 
468
625
  _initGrist() {
469
626
  let extension = []
627
+ let trackingNoColumn = {}
628
+ if (this.store.isOwnTransport) {
629
+ trackingNoColumn = {
630
+ type: 'string',
631
+ name: 'ownTrackingNo',
632
+ header: i18next.t('field.own_tracking_no'),
633
+ record: { editable: true },
634
+ width: 300
635
+ }
636
+ } else {
637
+ trackingNoColumn = {
638
+ type: 'string',
639
+ name: 'trackingNo',
640
+ header: i18next.t('field.tracking_no'),
641
+ record: { editable: true },
642
+ width: 300
643
+ }
644
+ }
645
+
470
646
  switch (this.searchForm.serialize().logisticsType) {
471
647
  case 'pickup':
472
648
  extension = [
@@ -522,19 +698,14 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
522
698
  header: i18next.t('field.required_tracking'),
523
699
  width: 110
524
700
  },
525
- {
526
- type: 'string',
527
- name: 'trackingNo',
528
- header: i18next.t('field.tracking_no'),
529
- record: { editable: true },
530
- width: 300
531
- }
701
+ trackingNoColumn
532
702
  ]
533
703
  this._type = 'dropoff'
534
704
  break
535
705
 
536
- default:
537
- this._type = ''
706
+ case 'non_integrated':
707
+ extension = [trackingNoColumn]
708
+ this._type = 'non_integrated'
538
709
  break
539
710
  }
540
711
 
@@ -548,15 +719,14 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
548
719
  try {
549
720
  const response = await client.query({
550
721
  query: gql`
551
- query {
552
- getStoreLogistics(${gqlBuilder.buildArgs({
553
- storeId: this.store.id
554
- })}) {
722
+ query getStoreLogistics($storeId: String!) {
723
+ getStoreLogistics(storeId: $storeId) {
555
724
  name
556
725
  isDefault
557
726
  }
558
727
  }
559
- `
728
+ `,
729
+ variables: { storeId: this.store.id }
560
730
  })
561
731
 
562
732
  if (!response.errors) {
@@ -567,6 +737,74 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
567
737
  }
568
738
  }
569
739
 
740
+ async fetchMarketplaceSettings() {
741
+ const filters = []
742
+ const sortings = []
743
+
744
+ const response = await client.query({
745
+ query: gql`
746
+ query marketplaceSettings($filters: [Filter], $sortings: [Sorting]) {
747
+ marketplaceSettings(filters: $filters, sortings: $sortings) {
748
+ items {
749
+ id
750
+ name
751
+ marketplaceStore {
752
+ id
753
+ name
754
+ storeName
755
+ platform
756
+ description
757
+ }
758
+ category
759
+ value
760
+ updatedAt
761
+ }
762
+ total
763
+ }
764
+ }
765
+ `,
766
+ variables: { filters, sortings }
767
+ })
768
+
769
+ if (!response.error) {
770
+ return response.data.marketplaceSettings.items || []
771
+ }
772
+ }
773
+
774
+ async setShippingProvider() {
775
+ try {
776
+ let selectedData = this.grist.selected
777
+ if (!selectedData?.length) throw new Error('please select at least one order')
778
+
779
+ const ownShippingProviderValue = this.ownShippingProviderSelect?.value
780
+ if (!ownShippingProviderValue) throw new Error('Own Shipping provider selection is required')
781
+
782
+ const patches = selectedData.map(patch => {
783
+ return {
784
+ id: patch.id,
785
+ orderNo: patch.orderNo,
786
+ ownShippingProvider: ownShippingProviderValue
787
+ }
788
+ })
789
+
790
+ const response = await client.mutate({
791
+ mutation: gql`
792
+ mutation setOwnShippingProviderByOrders($patches: [LogisticsInfo]!) {
793
+ setOwnShippingProviderByOrders(patches: $patches)
794
+ }
795
+ `,
796
+ variables: { patches }
797
+ })
798
+
799
+ if (!response.errors) {
800
+ await this.fetchHandler({ page: 1, limit: 100 })
801
+ this._initGrist()
802
+ }
803
+ } catch (e) {
804
+ this._showToast(e)
805
+ }
806
+ }
807
+
570
808
  async initLogistics() {
571
809
  let result = await CustomAlert({
572
810
  title: i18next.t('title.are_you_sure'),
@@ -580,6 +818,7 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
580
818
  try {
581
819
  let selectedData = this.grist.selected
582
820
  let deliveryType = this.searchForm.queryFilters.find(itm => itm.name == 'logisticsType')?.value
821
+ let shippingProvider = this.searchForm.queryFilters.find(itm => itm.name == 'shippingProvider')?.value
583
822
  let patches = []
584
823
  this._validateInit(selectedData)
585
824
 
@@ -589,7 +828,7 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
589
828
  return {
590
829
  id: patch.id,
591
830
  orderNo: patch.orderNo,
592
- deliveryType: deliveryType,
831
+ deliveryType,
593
832
  addressId: parseInt(patch?.addressId),
594
833
  pickupTimeId: patch?.pickupTimeId
595
834
  }
@@ -601,14 +840,27 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
601
840
  } else if (this._type == 'dropoff') {
602
841
  patches = selectedData.map(patch => {
603
842
  let data = {
604
- id: data.id,
843
+ id: patch.id,
605
844
  orderNo: patch.orderNo,
606
- deliveryType: deliveryType
845
+ deliveryType
607
846
  }
608
847
 
609
- if (itm.requiredBranch) data = { ...data, branchId: patch.branchId }
610
- if (itm.requiredSender) data = { ...data, senderRealName: patch.senderRealName }
611
- if (itm.requiredTracking) data = { ...data, trackingNo: patch.trackingNo }
848
+ if (patch.requiredBranch) data = { ...data, branchId: patch.branchId }
849
+ if (patch.requiredSender) data = { ...data, senderRealName: patch.senderRealName }
850
+ if (patch.requiredTracking) data = { ...data, trackingNo: patch.trackingNo }
851
+
852
+ return data
853
+ })
854
+ } else if (this._type == 'non_integrated') {
855
+ patches = selectedData.map(patch => {
856
+ return {
857
+ id: patch.id,
858
+ orderNo: patch.orderNo,
859
+ deliveryType,
860
+ trackingNo: patch.trackingNo,
861
+ ownTrackingNo: patch.ownTrackingNo,
862
+ shippingProvider
863
+ }
612
864
  })
613
865
  }
614
866
 
@@ -724,25 +976,18 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
724
976
  return { ...item, ...updateData }
725
977
  })
726
978
  ]
727
- }
728
979
 
729
- this.grist.refresh()
980
+ this.grist.refresh()
981
+ }
730
982
  } catch (e) {
731
983
  this._showToast(e)
732
984
  }
733
985
  }
734
986
 
735
- _validateInput() {
736
- const shippingProvider = this.searchForm.queryFilters.find(filter => filter.name == 'shippingProvider')
737
- if (!(shippingProvider && shippingProvider.value)) {
738
- throw new Error(i18next.t('text.kindly_select_a_shipping_provider'))
739
- }
740
- }
741
-
742
987
  _validateInit(patches) {
743
988
  if (this._type == 'pickup') {
744
989
  patches.forEach(itm => {
745
- if (itm.orderNo == '' || itm.addressId == NaN || itm.pickupTimeId == undefined)
990
+ if (itm.orderNo == '' || isNaN(itm.addressId) || itm.pickupTimeId == undefined)
746
991
  throw new Error(i18next.t('text.invalid_data'))
747
992
  })
748
993
  }
@@ -756,6 +1001,63 @@ class ShopeeOrderInitBatchPopup extends localize(i18next)(LitElement) {
756
1001
  throw new Error(i18next.t('text.tracking_is_required'))
757
1002
  })
758
1003
  }
1004
+
1005
+ if (this._type == 'non_integrated') {
1006
+ let deliveryType = this.searchForm.queryFilters.find(itm => itm.name == 'logisticsType')?.value
1007
+ let shippingProvider = this.searchForm.queryFilters.find(itm => itm.name == 'shippingProvider')?.value
1008
+
1009
+ if (!shippingProvider || shippingProvider === '') {
1010
+ throw new Error('Shipping provider selection is required for initiate logistics')
1011
+ }
1012
+
1013
+ if (!deliveryType || deliveryType === '') {
1014
+ throw new Error('Delivery type selection is required for initiate logistics')
1015
+ }
1016
+
1017
+ patches.forEach(itm => {
1018
+ if (!itm?.trackingNo) throw new Error(i18next.t('text.tracking_is_required'))
1019
+ })
1020
+ }
1021
+ }
1022
+
1023
+ async splitOrders() {
1024
+ try {
1025
+ let selectedData = this.grist.selected
1026
+ this._validateSplitting(selectedData)
1027
+
1028
+ const patches = selectedData.map(patch => {
1029
+ return {
1030
+ id: patch.id,
1031
+ orderNo: patch.orderNo
1032
+ }
1033
+ })
1034
+
1035
+ const response = await client.mutate({
1036
+ mutation: gql`
1037
+ mutation splitOrdersByBatch($patches: [LogisticsInfo]!) {
1038
+ splitOrdersByBatch(patches: $patches)
1039
+ }
1040
+ `,
1041
+ variables: { patches }
1042
+ })
1043
+
1044
+ if (!response.errors) {
1045
+ this.dispatchEvent(new CustomEvent('order-updated'))
1046
+ history.back()
1047
+ }
1048
+ } catch (e) {
1049
+ this._showToast(e)
1050
+ }
1051
+ }
1052
+
1053
+ _validateSplitting(data) {
1054
+ if (!data) {
1055
+ throw new Error('No order to split')
1056
+ }
1057
+
1058
+ if (data.some(item => item.trackingNo)) {
1059
+ throw new Error('Order with tracking no not allowed to split')
1060
+ }
759
1061
  }
760
1062
 
761
1063
  _showToast({ type, message }) {