@feedmepos/mf-order-setting 0.0.28 → 0.0.29

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 (28) hide show
  1. package/dist/{KioskDevicesView-BgXkmJ7v.js → KioskDevicesView-Dvr4RUmt.js} +1 -1
  2. package/dist/{KioskDevicesView.vue_vue_type_script_setup_true_lang-DZT0BuUN.js → KioskDevicesView.vue_vue_type_script_setup_true_lang-CJ-xAR8i.js} +2 -2
  3. package/dist/{KioskSettingView-DyX3Wv_2.js → KioskSettingView-DaJz8ZZi.js} +1 -1
  4. package/dist/{KioskView-Bgff7QPc.js → KioskView-v8Yl4x4R.js} +4 -4
  5. package/dist/{OrderSettingsView-C63s4uCD.js → OrderSettingsView-CN1PFwX_.js} +10911 -10700
  6. package/dist/{app-Dp79Gu_F.js → app-d1Lptg6A.js} +36 -15
  7. package/dist/app.js +1 -1
  8. package/dist/{dayjs.min-B2ZkfNUH.js → dayjs.min-BLlPHZkl.js} +1 -1
  9. package/dist/frontend/mf-order/src/api/remoteOrder/index.d.ts +1 -0
  10. package/dist/frontend/mf-order/src/app.d.ts +21 -0
  11. package/dist/frontend/mf-order/src/main.d.ts +21 -0
  12. package/dist/frontend/mf-order/src/stores/menu/menu.d.ts +1 -0
  13. package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
  14. package/dist/{index-DzQn92Tp.js → index-Cg9kSeyn.js} +2 -2
  15. package/dist/package/entity/incoming-order/incoming-order.dto.d.ts +3 -0
  16. package/dist/package/entity/order/pickup/pickup.dto.d.ts +37 -0
  17. package/dist/package/entity/order-platform/grabfood/grabfood.dto.d.ts +40 -0
  18. package/dist/package/entity/order-platform/grabfood/grabfood.enum.d.ts +2 -0
  19. package/dist/package/entity/queue/queue.dto.d.ts +11446 -93
  20. package/dist/package/entity/user/user.do.d.ts +129 -18
  21. package/dist/{queue.do-BUtcyDk3.js → queue.do-zk6sqriQ.js} +4543 -4509
  22. package/package.json +2 -2
  23. package/src/api/remoteOrder/index.ts +3 -0
  24. package/src/locales/en-US.json +8 -1
  25. package/src/locales/th-TH.json +8 -1
  26. package/src/locales/zh-CN.json +8 -1
  27. package/src/views/order-settings/delivery/integrated-delivery/GrabfoodSetting.vue +38 -1
  28. package/src/views/order-settings/discount-rule/DiscountRuleSetting.vue +40 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feedmepos/mf-order-setting",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "type": "module",
5
5
  "module": "./dist/app.js",
6
6
  "license": "UNLICENSED",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@feedmepos/core": "^2.14.19",
30
- "@feedmepos/menu": "^1.5.18",
30
+ "@feedmepos/menu": "^1.5.21",
31
31
  "@feedmepos/mf-common": "1.20.0-beta.2",
32
32
  "@feedmepos/ordering": "^0.0.3",
33
33
  "@feedmepos/ui-library": "1.5.2-beta.1",
@@ -88,6 +88,9 @@ export const remoteOrderApi = {
88
88
  async syncGrabfoodMenu(merchantId: string): Promise<FdoGrabfoodSettings> {
89
89
  return getData(await deliveryClientInstance('grabfood').get(`/menu-sync/${merchantId}`));
90
90
  },
91
+ async startSelfServeFlow(restaurantId: string): Promise<string> {
92
+ return getData(await deliveryClientInstance('grabfood').get(`/setting/integration-url/${restaurantId}`));
93
+ },
91
94
 
92
95
  async readShopeefood(restaurantId: string): Promise<FdoShopeeFoodSettings | null> {
93
96
  return getData(await deliveryClientInstance('shopeefood').get(`/setting/${restaurantId}`));
@@ -207,6 +207,11 @@
207
207
  "selectRestaurant": "Select Restaurant",
208
208
  "selectServiceChargeType": "Select service charge type",
209
209
  "selectTable": "Select table",
210
+ "selfServeActivation": {
211
+ "title": "Self Serve Activation",
212
+ "subTitle": "New to the flow? Click here to",
213
+ "learnMore": "learn more"
214
+ },
210
215
  "serve": "serve",
211
216
  "serviceCharge": "Service Charge",
212
217
  "serviceChargeRule": "* Service Charge required POS version 4.0.0 or higher",
@@ -286,7 +291,9 @@
286
291
  "syncSuccess": "Discount rule setting synced to all restaurants",
287
292
  "title": "Discount Rule",
288
293
  "updateSuccess": "Discount rule setting updated",
289
- "version": "Version"
294
+ "version": "Version",
295
+ "promotion": "Promotion",
296
+ "voucher": "Voucher"
290
297
  }
291
298
  }
292
299
  }
@@ -203,6 +203,11 @@
203
203
  "selectRestaurant": "เลือกร้านอาหาร",
204
204
  "selectServiceChargeType": "เลือกประเภทค่าบริการ",
205
205
  "selectTable": "เลือกโต๊ะ",
206
+ "selfServeActivation": {
207
+ "title": "เปิดใช้งานการบริการตนเอง",
208
+ "subTitle": "เปิดใช้งานการบริการตนเองเพื่อให้ลูกค้าสามารถสั่งซื้อได้ด้วยตนเอง",
209
+ "learnMore": "เรียนรู้เพิ่มเติม"
210
+ },
206
211
  "serve": "เสิร์ฟ",
207
212
  "serviceCharge": "ค่าบริการ",
208
213
  "serviceChargeRule": "* ค่าบริการจำเป็นต้องใช้ POS เวอร์ชัน 4.0.0 ขึ้นไป",
@@ -281,7 +286,9 @@
281
286
  "syncSuccess": "ซิงค์กฎส่วนลดไปยังร้านอาหารทั้งหมดเรียบร้อยแล้ว",
282
287
  "title": "กฎส่วนลด",
283
288
  "updateSuccess": "อัปเดตกฎส่วนลดเรียบร้อยแล้ว",
284
- "version": "เวอร์ชัน"
289
+ "version": "เวอร์ชัน",
290
+ "promotion": "โปรโมชั่น",
291
+ "voucher": "บัตรกำนัล"
285
292
  }
286
293
  }
287
294
  }
@@ -210,6 +210,11 @@
210
210
  "selectRestaurant": "选择餐厅",
211
211
  "selectServiceChargeType": "选择服务费类型",
212
212
  "selectTable": "选择餐桌",
213
+ "selfServeActivation": {
214
+ "title": "自助激活对接",
215
+ "subTitle": "第一次使用这个流程?点击此处",
216
+ "learnMore": "了解更多"
217
+ },
213
218
  "serve": "服务",
214
219
  "serviceCharge": "服务费",
215
220
  "serviceChargeRule": "* 服务费功能仅适用于POS版本4.0.0或更高版本。",
@@ -289,7 +294,9 @@
289
294
  "syncSuccess": "折扣规则设置已同步到所有餐厅",
290
295
  "title": "折扣规则",
291
296
  "updateSuccess": "折扣规则设置已更新",
292
- "version": "版本"
297
+ "version": "版本",
298
+ "promotion": "促销",
299
+ "voucher": "代金券"
293
300
  }
294
301
  }
295
302
  }
@@ -88,7 +88,7 @@ async function syncMenu() {
88
88
  }
89
89
 
90
90
  import { useSnackbarFunctions } from '@/components/snackbar'
91
- const { showSuccess } = useSnackbarFunctions()
91
+ const { showSuccess, showError } = useSnackbarFunctions()
92
92
 
93
93
  async function flowTestOrder() {
94
94
  await startAsyncCallWithErr(async () => {
@@ -108,6 +108,20 @@ async function cancelTestOrder() {
108
108
  })
109
109
  showSuccess('Completed. ')
110
110
  }
111
+
112
+ async function startSelfServeFlow() {
113
+ const url = await startAsyncCallWithErr(async () => {
114
+ return await remoteOrderApi.integratedDelivery.startSelfServeFlow(
115
+ currentRestaurant.value?._id ?? ''
116
+ )
117
+ })
118
+
119
+ if (!url) {
120
+ showError(`Failed to get integration url for ${currentRestaurant?.value?._id}`)
121
+ }
122
+
123
+ window.open(url, '_blank')
124
+ }
111
125
  </script>
112
126
 
113
127
  <template>
@@ -120,4 +134,27 @@ async function cancelTestOrder() {
120
134
  @flow-test-order="flowTestOrder"
121
135
  @cancel-test-order="cancelTestOrder"
122
136
  />
137
+ <div v-if="canUseAutoDeliveryIntegration === true">
138
+ <div class="flex flex-row mt-5 items-center">
139
+ <div class="flex-grow fm-typo-en-title-sm-600 mb-3 mt-3">
140
+ {{ t('order.selfServeActivation.title') }}
141
+ </div>
142
+ <FmButton
143
+ variant="primary"
144
+ :label="t('order.start')"
145
+ @click="startSelfServeFlow"
146
+ class="m-1"
147
+ />
148
+ </div>
149
+ <div>
150
+ {{ t('order.selfServeActivation.subTitle') }}
151
+ <a
152
+ href="https://doc.clickup.com/25608366/d/h/rdg5e-52596/7d44e2bd89752e0"
153
+ target="_blank"
154
+ style="color: blue; text-decoration: underline"
155
+ >
156
+ {{ t('order.selfServeActivation.learnMore') }}</a
157
+ >.
158
+ </div>
159
+ </div>
123
160
  </template>
@@ -85,6 +85,7 @@
85
85
  v-model="sideSheet"
86
86
  >
87
87
  <div>
88
+ <FmSearch v-model="sideSheetSearch" :placeholder="t('order.search')" class="mb-4" />
88
89
  <div class="text-fm-color-typo-secondary mt-5 mb-5 flex flex-row">
89
90
  {{
90
91
  t('order.discountRule.effectSelected', {
@@ -101,22 +102,30 @@
101
102
  ></FmCheckbox>
102
103
 
103
104
  <div
104
- v-for="pEffect in processedEffects"
105
+ v-for="pEffect in filteredProcessedEffects"
105
106
  :key="pEffect.id"
106
- class="flex flex-col mb-2 ml-5"
107
+ class="flex flex-col mb-2 ml-5 cursor-pointer"
107
108
  >
108
109
  <div class="flex flex-row">
109
- <div class="flex flex-row items-center">
110
+ <div
111
+ class="flex flex-row items-center"
112
+ @click="selectEffect(pEffect, !pEffect.isSelectedInCurrentGroup)"
113
+ >
110
114
  <FmCheckbox
111
115
  :model-value="pEffect.isSelectedInCurrentGroup"
112
116
  value=""
113
117
  @update:model-value="(v) => selectEffect(pEffect, v)"
114
118
  :disabled="pEffect.isDisabled"
115
119
  />
116
- <div class="ml-2">
120
+ <div class="ml-2 flex flex-wrap gap-2 items-center">
121
+ <span
122
+ class="fm-corner-radius-md px-4 py-[2px] fm-typo-en-body-md-600 text-fm-color-typo-neutral bg-fm-color-neutral-gray-100 max-w-full"
123
+ >
124
+ {{ pEffect.type }}
125
+ </span>
117
126
  <span>{{ pEffect.name }}</span>
118
127
  <template v-if="pEffect.showUsedInOtherGroupHint">
119
- <span class="text-sm text-fm-color-typo-secondary pl-1">
128
+ <span class="text-sm text-fm-color-typo-secondary">
120
129
  ({{ t('order.discountRule.effectUsedInOtherGroup') }})
121
130
  </span>
122
131
  </template>
@@ -187,6 +196,11 @@ import { components } from '@feedmepos/ui-library'
187
196
  interface Effect {
188
197
  id: string
189
198
  name: string
199
+ type: string
200
+ isSelectedInCurrentGroup: boolean
201
+ isInOtherGroups: boolean
202
+ isDisabled: boolean
203
+ showUsedInOtherGroupHint: boolean
190
204
  }
191
205
 
192
206
  const { startAsyncCallWithErr, isLoading } = useLoading()
@@ -217,6 +231,7 @@ const lastUpdatedAt = ref<string | null>(null)
217
231
  const effects = ref<Effect[]>([])
218
232
  const selectedEffectGroup = ref<FdoEffectGroup | null>(null)
219
233
  const selectedEffectIndex = ref<number | null>(null)
234
+ const sideSheetSearch = ref('')
220
235
 
221
236
  const pad = (n: number) => n.toString().padStart(2, '0')
222
237
 
@@ -284,11 +299,13 @@ const processedEffects = computed(() => {
284
299
  const isSelectedInCurrentGroup =
285
300
  selectedEffectGroup.value?.effectIds?.includes(effect.id) ?? false
286
301
  const isInOtherGroups = isEffectInOtherGroups(effect.id, selectedEffectIndex.value)
302
+ const isPromotion = effect.id.startsWith('promotion_')
287
303
 
288
304
  return {
289
305
  ...effect,
290
306
  id: effect.id,
291
307
  name: effect.name,
308
+ type: isPromotion ? t('order.discountRule.promotion') : t('order.discountRule.voucher'),
292
309
  isSelectedInCurrentGroup,
293
310
  isInOtherGroups,
294
311
  isDisabled: isInOtherGroups && !isSelectedInCurrentGroup,
@@ -297,25 +314,25 @@ const processedEffects = computed(() => {
297
314
  })
298
315
  })
299
316
 
300
- const isAllSelectedForCurrentGroup = computed(() => {
301
- if (!selectedEffectGroup.value || !effects.value.length || selectedEffectIndex.value === null)
302
- return false
303
-
304
- const selectableEffectsInCurrentGroup = effects.value.filter(
305
- (effect: Effect) =>
306
- selectedEffectGroup.value?.effectIds.includes(effect.id) ||
307
- !isEffectInOtherGroups(effect.id, selectedEffectIndex.value)
317
+ const filteredProcessedEffects = computed(() => {
318
+ const search = sideSheetSearch.value.trim().toLowerCase()
319
+ if (!search) return processedEffects.value
320
+ return processedEffects.value.filter(
321
+ (effect) =>
322
+ effect.name.toLowerCase().includes(search) || effect.type.toLowerCase().includes(search)
308
323
  )
324
+ })
309
325
 
310
- if (!selectableEffectsInCurrentGroup.length && effects.value.length > 0) {
311
- return false
312
- }
313
- if (!selectableEffectsInCurrentGroup.length && effects.value.length === 0) {
326
+ const isAllSelectedForCurrentGroup = computed(() => {
327
+ if (
328
+ !selectedEffectGroup.value ||
329
+ !filteredProcessedEffects.value.length ||
330
+ selectedEffectIndex.value === null
331
+ )
314
332
  return false
315
- }
316
333
 
317
- return selectableEffectsInCurrentGroup.every((effect: Effect) =>
318
- selectedEffectGroup.value?.effectIds.includes(effect.id)
334
+ return filteredProcessedEffects.value.every(
335
+ (effect: Effect) => effect.isSelectedInCurrentGroup || effect.isDisabled
319
336
  )
320
337
  })
321
338
 
@@ -323,8 +340,8 @@ function selectAllEffects(v: boolean) {
323
340
  if (!selectedEffectGroup.value || selectedEffectIndex.value === null) return
324
341
 
325
342
  if (v) {
326
- const effectsToAdd = effects.value
327
- .filter((effect: Effect) => !isEffectInOtherGroups(effect.id, selectedEffectIndex.value))
343
+ const effectsToAdd = filteredProcessedEffects.value
344
+ .filter((effect: Effect) => !effect.isInOtherGroups)
328
345
  .map((effect: Effect) => effect.id)
329
346
  const currentEffectsInGroup = selectedEffectGroup.value.effectIds || []
330
347
  selectedEffectGroup.value.effectIds = [...new Set([...currentEffectsInGroup, ...effectsToAdd])]
@@ -353,6 +370,7 @@ function selectEffect(effect: { id: string; isInOtherGroups: boolean }, isSelect
353
370
  }
354
371
 
355
372
  function toggleSideSheet(index: number) {
373
+ sideSheetSearch.value = ''
356
374
  selectedEffectGroup.value = effectGroups.value[index] ? { ...effectGroups.value[index] } : null
357
375
  selectedEffectIndex.value = index
358
376
  sideSheet.value = true