@feedmepos/mf-order-setting 0.0.36 → 0.0.38
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.
- package/dist/{KioskDevicesView-wPKewwAS.js → KioskDevicesView-DoTQRyXe.js} +1 -1
- package/dist/{KioskDevicesView.vue_vue_type_script_setup_true_lang-BCJPU2la.js → KioskDevicesView.vue_vue_type_script_setup_true_lang-DB0dvpBG.js} +2 -2
- package/dist/{KioskSettingView-CV54HpY2.js → KioskSettingView-DRpVR7Ij.js} +1 -1
- package/dist/{KioskView-B4mggCt0.js → KioskView-4-s6RwC6.js} +7 -7
- package/dist/OrderSettingsView-BqgGXVhY.js +76752 -0
- package/dist/{app-D4exdzAx.js → app-BbOgWoeI.js} +33 -18
- package/dist/app.js +1 -1
- package/dist/{dayjs.min-C_sCJHuD.js → dayjs.min-COLd3dVw.js} +1 -1
- package/dist/frontend/mf-order/src/api/menu/index.d.ts +4 -0
- package/dist/frontend/mf-order/src/app.d.ts +15 -0
- package/dist/frontend/mf-order/src/helpers/order-setting.d.ts +6 -0
- package/dist/frontend/mf-order/src/main.d.ts +15 -0
- package/dist/frontend/mf-order/src/stores/menu/menu.d.ts +13 -4
- package/dist/frontend/mf-order/src/stores/order-setting/index.d.ts +27 -0
- package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{index-Cvhc_ltu.js → index-BewBuJGi.js} +2 -2
- package/dist/menu.dto-Bf0Evx6J.js +127224 -0
- package/dist/package/entity/food-court/order.dto.d.ts +1952 -1952
- package/dist/package/entity/incoming-order/incoming-order-to-bill.dto.d.ts +30 -30
- package/dist/package/entity/incoming-order/incoming-order.do.d.ts +24 -24
- package/dist/package/entity/incoming-order/incoming-order.dto.d.ts +64 -64
- package/dist/package/entity/order/menu/menu.dto.d.ts +10 -0
- package/dist/package/entity/order/order-item/order-item.dto.d.ts +48 -48
- package/dist/package/entity/order/order.do.d.ts +20 -8
- package/dist/package/entity/order/order.dto.d.ts +3466 -3350
- package/dist/package/entity/order/payment/payment.dto.d.ts +1702 -1702
- package/dist/package/entity/order-platform/shopeefood/shopeefood-order.do.d.ts +33 -0
- package/dist/package/entity/order-platform/shopeefood/shopeefood-order.dto.d.ts +18 -0
- package/dist/package/entity/order-setting/order-setting.do.d.ts +168 -0
- package/dist/package/entity/order-setting/order-setting.dto.d.ts +134 -0
- package/dist/package/entity/order-setting/queue/queue.do.d.ts +95 -1613
- package/dist/package/entity/order-setting/queue/queue.dto.d.ts +62 -110
- package/dist/package/entity/order-setting/sequence/sequence.do.d.ts +72 -0
- package/dist/package/entity/order-setting/sequence/sequence.dto.d.ts +101 -0
- package/dist/package/entity/payment/payment.dto.d.ts +3 -3
- package/dist/package/entity/queue/queue.do.d.ts +18 -6
- package/dist/package/entity/queue/queue.dto.d.ts +922 -908
- package/dist/package/entity/restaurant/restaurant.dto.d.ts +363 -20
- package/package.json +4 -4
- package/src/api/menu/index.ts +4 -1
- package/src/helpers/order-setting.ts +20 -0
- package/src/locales/en-US.json +5 -0
- package/src/locales/th-TH.json +5 -0
- package/src/locales/zh-CN.json +5 -0
- package/src/stores/menu/menu.ts +33 -14
- package/src/stores/order-setting/mapper.ts +56 -56
- package/src/views/order-settings/OrderSettingsView.vue +30 -3
- package/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue +0 -1
- package/src/views/order-settings/general/GeneralSetting.vue +159 -4
- package/dist/OrderSettingsView-CKGRFx_2.js +0 -50624
- package/dist/menu.dto-CeUdKgTW.js +0 -103445
package/src/stores/menu/menu.ts
CHANGED
|
@@ -13,6 +13,9 @@ interface MenuState {
|
|
|
13
13
|
menu: { _rev: string } & FdoMenuV4;
|
|
14
14
|
currentCatalogId: string | null;
|
|
15
15
|
currentSchedulerId: string;
|
|
16
|
+
catalogOptions: { label: string; value: string | null }[];
|
|
17
|
+
loadingCatalogOptions: boolean;
|
|
18
|
+
catalogOptionsError: string | null;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
function initMenuState(): MenuState {
|
|
@@ -21,6 +24,9 @@ function initMenuState(): MenuState {
|
|
|
21
24
|
menu: { ...generator.initMenuV4(), _rev: '' },
|
|
22
25
|
currentCatalogId: null,
|
|
23
26
|
currentSchedulerId: '',
|
|
27
|
+
catalogOptions: [],
|
|
28
|
+
loadingCatalogOptions: false,
|
|
29
|
+
catalogOptionsError: null,
|
|
24
30
|
};
|
|
25
31
|
}
|
|
26
32
|
|
|
@@ -120,19 +126,6 @@ export const useMenuStore = defineStore('menu', {
|
|
|
120
126
|
(catalog) => catalog._id === state.currentCatalogId
|
|
121
127
|
);
|
|
122
128
|
},
|
|
123
|
-
|
|
124
|
-
catalogOptions(): { label: string; value: string | null }[] {
|
|
125
|
-
return [
|
|
126
|
-
{
|
|
127
|
-
label: 'Main',
|
|
128
|
-
value: null,
|
|
129
|
-
},
|
|
130
|
-
...this.catalogs.map((catalog) => ({
|
|
131
|
-
label: catalog.name,
|
|
132
|
-
value: catalog._id,
|
|
133
|
-
})),
|
|
134
|
-
];
|
|
135
|
-
},
|
|
136
129
|
categories(): (Omit<FdoMenuV4Category, '_id'> & { _id: string | null })[] {
|
|
137
130
|
const categories = this.mergedMenu.modules.category;
|
|
138
131
|
return [
|
|
@@ -250,9 +243,35 @@ export const useMenuStore = defineStore('menu', {
|
|
|
250
243
|
this.menu = await menuApi.readMenu();
|
|
251
244
|
this.selectCatalog(null);
|
|
252
245
|
},
|
|
246
|
+
|
|
247
|
+
async loadCatalogOptions(restaurantId: string) {
|
|
248
|
+
this.loadingCatalogOptions = true;
|
|
249
|
+
this.catalogOptionsError = null;
|
|
250
|
+
const options: {label:string, value: string | null}[] = [{
|
|
251
|
+
label: 'Main',
|
|
252
|
+
value: null,
|
|
253
|
+
}];
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const resp = await menuApi.readCatalogOptions(restaurantId);
|
|
257
|
+
const restaurntCatalogOptions = resp[restaurantId] ?? [];
|
|
258
|
+
for (let index = 0; index < restaurntCatalogOptions.length; index++) {
|
|
259
|
+
const opt = restaurntCatalogOptions[index];
|
|
260
|
+
options.push({
|
|
261
|
+
label: opt.name,
|
|
262
|
+
value: opt._id
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
this.catalogOptions = options;
|
|
266
|
+
} catch (error) {
|
|
267
|
+
console.error('Failed to load catalog options:', error)
|
|
268
|
+
this.catalogOptionsError = 'order.failedToLoadCatalogOptions';
|
|
269
|
+
} finally {
|
|
270
|
+
this.loadingCatalogOptions = false;
|
|
271
|
+
}
|
|
272
|
+
},
|
|
253
273
|
selectCatalog(id: string | null) {
|
|
254
274
|
this.currentCatalogId = id;
|
|
255
275
|
},
|
|
256
276
|
}
|
|
257
|
-
|
|
258
277
|
});
|
|
@@ -55,7 +55,7 @@ export const defaultKioskOrderSetting: MfKioskOrderSettingForm = {
|
|
|
55
55
|
enabled: false,
|
|
56
56
|
pickUp: defaultPickUp,
|
|
57
57
|
sequenceNumber: FdoOrderKioskDineInSequence.parse({}),
|
|
58
|
-
displayStand: defaultDisplayStand
|
|
58
|
+
displayStand: defaultDisplayStand,
|
|
59
59
|
},
|
|
60
60
|
takeaway: defaultTakeaway,
|
|
61
61
|
paymentSetting: {
|
|
@@ -67,15 +67,15 @@ export const defaultKioskOrderSetting: MfKioskOrderSettingForm = {
|
|
|
67
67
|
nfc: false
|
|
68
68
|
},
|
|
69
69
|
eWallet: {
|
|
70
|
-
|
|
71
|
-
scanPay: false,
|
|
70
|
+
terminalQrPay: false,
|
|
72
71
|
terminalScanPay: false,
|
|
73
|
-
|
|
72
|
+
qrPay: false,
|
|
73
|
+
scanPay: false
|
|
74
74
|
}
|
|
75
|
-
}
|
|
75
|
+
},
|
|
76
76
|
},
|
|
77
77
|
menuItem: {
|
|
78
|
-
showAllOnly: false
|
|
78
|
+
showAllOnly: false,
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -106,10 +106,10 @@ const toKiosk = (
|
|
|
106
106
|
enabled: kioskOrderSettings?.canTakeaway ?? false,
|
|
107
107
|
submitOrderInstruction: kioskOrderSettings?.takeaway?.submitOrderInstruction
|
|
108
108
|
? {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
payAtCounter:
|
|
110
|
+
kioskOrderSettings.takeaway.submitOrderInstruction?.payAtCounter?.['en'] ?? null,
|
|
111
|
+
paid: kioskOrderSettings.takeaway.submitOrderInstruction?.paid?.['en'] ?? null
|
|
112
|
+
}
|
|
113
113
|
: defaultSubmitOrderInstruction
|
|
114
114
|
},
|
|
115
115
|
paymentSetting: {
|
|
@@ -145,35 +145,35 @@ const toKioskDineInSetting = (
|
|
|
145
145
|
sequenceNumber: kioskDineInSeq,
|
|
146
146
|
pickUp: kioskDineInSetting?.pickUp
|
|
147
147
|
? {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
148
|
+
...kioskDineInSetting.pickUp,
|
|
149
|
+
submitOrderInstruction: kioskDineInSetting.pickUp.submitOrderInstruction
|
|
150
|
+
? {
|
|
151
|
+
payAtCounter:
|
|
152
|
+
kioskDineInSetting.pickUp.submitOrderInstruction?.payAtCounter?.['en'] ?? null,
|
|
153
|
+
paid: kioskDineInSetting.pickUp.submitOrderInstruction?.paid?.['en'] ?? null
|
|
154
|
+
}
|
|
155
|
+
: defaultSubmitOrderInstruction,
|
|
156
|
+
enablePaxDialog: kioskDineInSetting.pickUp.enablePaxDialog
|
|
157
|
+
? kioskDineInSetting.pickUp.enablePaxDialog
|
|
158
|
+
: false
|
|
159
|
+
}
|
|
160
160
|
: defaultPickUp,
|
|
161
161
|
displayStand: kioskDineInSetting?.displayStand
|
|
162
162
|
? {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
163
|
+
enabled: kioskDineInSetting.displayStand.enabled,
|
|
164
|
+
standSlotRange: kioskDineInSetting.displayStand.standSlotRange,
|
|
165
|
+
prefix: kioskDineInSetting.displayStand.prefix,
|
|
166
|
+
padDigit: kioskDineInSetting.displayStand.padDigit,
|
|
167
|
+
enablePaxDialog: kioskDineInSetting.displayStand.enablePaxDialog ?? false,
|
|
168
|
+
submitOrderInstruction: kioskDineInSetting.displayStand.submitOrderInstruction
|
|
169
|
+
? {
|
|
170
|
+
payAtCounter:
|
|
171
|
+
kioskDineInSetting.displayStand.submitOrderInstruction?.payAtCounter?.['en'] ??
|
|
172
|
+
null,
|
|
173
|
+
paid: kioskDineInSetting.displayStand.submitOrderInstruction?.paid?.['en'] ?? null
|
|
174
|
+
}
|
|
175
|
+
: defaultSubmitOrderInstruction
|
|
176
|
+
}
|
|
177
177
|
: defaultDisplayStand
|
|
178
178
|
}
|
|
179
179
|
}
|
|
@@ -190,13 +190,13 @@ const toOrderKioskSettingsDto = (
|
|
|
190
190
|
submitOrderInstruction: {
|
|
191
191
|
payAtCounter: dineInSetting.displayStand.submitOrderInstruction?.payAtCounter
|
|
192
192
|
? {
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
en: dineInSetting.displayStand.submitOrderInstruction.payAtCounter
|
|
194
|
+
}
|
|
195
195
|
: null,
|
|
196
196
|
paid: dineInSetting.displayStand.submitOrderInstruction?.paid
|
|
197
197
|
? {
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
en: dineInSetting.displayStand.submitOrderInstruction.paid
|
|
199
|
+
}
|
|
200
200
|
: null
|
|
201
201
|
}
|
|
202
202
|
},
|
|
@@ -205,13 +205,13 @@ const toOrderKioskSettingsDto = (
|
|
|
205
205
|
submitOrderInstruction: {
|
|
206
206
|
payAtCounter: dineInSetting.pickUp.submitOrderInstruction?.payAtCounter
|
|
207
207
|
? {
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
en: dineInSetting.pickUp.submitOrderInstruction.payAtCounter
|
|
209
|
+
}
|
|
210
210
|
: null,
|
|
211
211
|
paid: dineInSetting.pickUp.submitOrderInstruction?.paid
|
|
212
212
|
? {
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
en: dineInSetting.pickUp.submitOrderInstruction.paid
|
|
214
|
+
}
|
|
215
215
|
: null
|
|
216
216
|
}
|
|
217
217
|
}
|
|
@@ -224,19 +224,19 @@ const toOrderKioskSettingsDto = (
|
|
|
224
224
|
paymentSetting: createPaymentSettings(kioskSetting.paymentSetting),
|
|
225
225
|
takeaway: kioskSetting.takeaway.submitOrderInstruction
|
|
226
226
|
? {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
227
|
+
submitOrderInstruction: {
|
|
228
|
+
payAtCounter: kioskSetting.takeaway.submitOrderInstruction.payAtCounter
|
|
229
|
+
? {
|
|
230
|
+
en: kioskSetting.takeaway.submitOrderInstruction.payAtCounter
|
|
231
|
+
}
|
|
232
|
+
: null,
|
|
233
|
+
paid: kioskSetting.takeaway.submitOrderInstruction.paid
|
|
234
|
+
? {
|
|
235
|
+
en: kioskSetting.takeaway.submitOrderInstruction.paid
|
|
236
|
+
}
|
|
237
|
+
: null
|
|
239
238
|
}
|
|
239
|
+
}
|
|
240
240
|
: undefined
|
|
241
241
|
})
|
|
242
242
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="py-[1.5rem]">
|
|
3
3
|
<FmPageHead :title="t('order.orderSetting')" />
|
|
4
|
-
<div class="flex px-[1.5rem]">
|
|
4
|
+
<div class="flex px-[1.5rem] items-center">
|
|
5
5
|
<div class="flex-[2_2_0%] overflow-auto">
|
|
6
6
|
<FmTabs v-model:model-value="selectedOrderSetting" :items="settingItem" :showMoreAt="99" />
|
|
7
7
|
</div>
|
|
8
|
+
<div v-if="menuStore.loadingCatalogOptions" class="flex items-center gap-2 ml-4">
|
|
9
|
+
<FmCircularProgress size="md" />
|
|
10
|
+
<span class="text-sm text-gray-600">{{ t('order.loadingCatalogs') }}</span>
|
|
11
|
+
</div>
|
|
8
12
|
</div>
|
|
9
13
|
</div>
|
|
10
14
|
<component :is="currentComponent" />
|
|
@@ -12,7 +16,7 @@
|
|
|
12
16
|
|
|
13
17
|
<script setup lang="ts">
|
|
14
18
|
import { type FmTabProps } from '@feedmepos/ui-library'
|
|
15
|
-
import { ref, computed } from 'vue'
|
|
19
|
+
import { ref, computed, onMounted, watch } from 'vue'
|
|
16
20
|
import DeliverySetting from './delivery/DeliverySetting.vue'
|
|
17
21
|
import DineInSetting from './dine-in/DineInSetting.vue'
|
|
18
22
|
import PickUpSetting from './pickup/PickUpSetting.vue'
|
|
@@ -21,9 +25,14 @@ import ServiceChargeSetting from './servicecharge/ServiceChargeSetting.vue'
|
|
|
21
25
|
import DiscountRuleSetting from './discount-rule/DiscountRuleSetting.vue'
|
|
22
26
|
|
|
23
27
|
import GeneralSetting from './general/GeneralSetting.vue'
|
|
24
|
-
import { useI18n } from '@feedmepos/mf-common'
|
|
28
|
+
import { useI18n, useCoreStore } from '@feedmepos/mf-common'
|
|
29
|
+
import { useMenuStore } from '@/stores/menu/menu'
|
|
30
|
+
import { useSnackbarFunctions } from '@/components/snackbar'
|
|
25
31
|
|
|
26
32
|
const { t } = useI18n()
|
|
33
|
+
const { currentRestaurant } = useCoreStore()
|
|
34
|
+
const menuStore = useMenuStore()
|
|
35
|
+
const { showError } = useSnackbarFunctions()
|
|
27
36
|
type OrderSettingMenuItemValue =
|
|
28
37
|
| 'delivery'
|
|
29
38
|
| 'pickup'
|
|
@@ -62,4 +71,22 @@ const currentComponent = computed(() => {
|
|
|
62
71
|
return GeneralSetting
|
|
63
72
|
}
|
|
64
73
|
})
|
|
74
|
+
|
|
75
|
+
onMounted(async () => {
|
|
76
|
+
if (currentRestaurant.value?._id) {
|
|
77
|
+
await menuStore.loadCatalogOptions(currentRestaurant.value._id)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
watch(currentRestaurant, async (newRestaurant) => {
|
|
82
|
+
if (newRestaurant?._id) {
|
|
83
|
+
await menuStore.loadCatalogOptions(newRestaurant._id)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
watch(() => menuStore.catalogOptionsError, (errorKey) => {
|
|
88
|
+
if (errorKey) {
|
|
89
|
+
showError(t(errorKey))
|
|
90
|
+
}
|
|
91
|
+
})
|
|
65
92
|
</script>
|
|
@@ -262,7 +262,6 @@ function convertStatusI18n(status: string) {
|
|
|
262
262
|
v-if="modelValue.auto.status === 'FAILED' && modelValue.auto.menuSyncError !== null"
|
|
263
263
|
:content="modelValue.auto.menuSyncError"
|
|
264
264
|
:zIndex="1000"
|
|
265
|
-
:disabled="!canEdit"
|
|
266
265
|
>
|
|
267
266
|
<FmIcon name="info" size="sm" />
|
|
268
267
|
</FmTooltip>
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
<RestaurantSelector />
|
|
4
4
|
</div>
|
|
5
5
|
<div v-if="!isLoading">
|
|
6
|
-
<div class="p-[1.5rem] flex flex-col gap-5 m-5 w-
|
|
7
|
-
<div class="flex-grow fm-typo-en-title-sm-600">{{ t('order.generalSetting') }}</div>
|
|
6
|
+
<div class="p-[1.5rem] flex flex-col gap-5 m-5 mr-8 w-full max-w-4xl">
|
|
8
7
|
<FmSwitch
|
|
9
8
|
:model-value="orderSetting?.v3Settings?.anonymousLoginDialog ?? true"
|
|
10
9
|
:label="t('order.promptAnonymousLoginDialog')"
|
|
@@ -17,6 +16,52 @@
|
|
|
17
16
|
@update:model-value="updateSubItemDisplayMode"
|
|
18
17
|
label-placement="right"
|
|
19
18
|
></FmSwitch>
|
|
19
|
+
|
|
20
|
+
<div class="flex-grow fm-typo-en-title-sm-600 mt-8 mb-2">{{ t('order.orderNumberSettings') }}</div>
|
|
21
|
+
|
|
22
|
+
<div class="mr-9 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-5">
|
|
23
|
+
<div class="min-w-0">
|
|
24
|
+
<div class="bg-gray-50 p-3 rounded-lg border">
|
|
25
|
+
<FmSwitch
|
|
26
|
+
:model-value="!!orderSetting?.sequenceSettings?.autoReset?.resetTime"
|
|
27
|
+
:label="t('order.autoResetOrderNumber')"
|
|
28
|
+
@update:model-value="toggleResetTime"
|
|
29
|
+
label-placement="right"
|
|
30
|
+
></FmSwitch>
|
|
31
|
+
<FmTimePicker
|
|
32
|
+
v-if="!!orderSetting?.sequenceSettings?.autoReset?.resetTime"
|
|
33
|
+
:model-value="orderSetting?.sequenceSettings?.autoReset?.resetTime"
|
|
34
|
+
@update:model-value="(time: string | null) => updateResetTime(time)"
|
|
35
|
+
class="mt-3"
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="mr-9 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-5 mt-5">
|
|
42
|
+
<div v-for="key in sequenceKeys" :key="key" class="min-w-0">
|
|
43
|
+
<FmCard variant="outlined" class="p-3">
|
|
44
|
+
<FmStepperField
|
|
45
|
+
:model-value="orderSetting?.sequenceSettings?.[key]?.digit ?? null"
|
|
46
|
+
:label="getSeqLabel(key)"
|
|
47
|
+
@update:model-value="(digit) => updateSeq(key, 'digit', digit)"
|
|
48
|
+
:show-steppers="false"
|
|
49
|
+
placeholder="3"
|
|
50
|
+
:rules="getSequenceSettingRules(orderSetting?.sequenceSettings?.[key]?.digit)"
|
|
51
|
+
:max="4"
|
|
52
|
+
:min="1"
|
|
53
|
+
/>
|
|
54
|
+
<FmStepperField
|
|
55
|
+
:model-value="orderSetting?.sequenceSettings?.[key]?.current ?? null"
|
|
56
|
+
:label="t('order.currentNumber')"
|
|
57
|
+
@update:model-value="(current) => updateSeq(key, 'current', current ?? 0)"
|
|
58
|
+
:show-steppers="false"
|
|
59
|
+
placeholder="0"
|
|
60
|
+
:rules="getSequenceSettingRules(orderSetting?.sequenceSettings?.[key]?.digit)"
|
|
61
|
+
/>
|
|
62
|
+
</FmCard>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
20
65
|
</div>
|
|
21
66
|
<div class="fm-corner-radius-lg flex flex-col gap-5 m-5">
|
|
22
67
|
<FmButton
|
|
@@ -34,21 +79,70 @@
|
|
|
34
79
|
import { useCoreStore } from '@feedmepos/mf-common'
|
|
35
80
|
import RestaurantSelector from '../components/RestaurantSelector.vue'
|
|
36
81
|
import { useLoading } from '@/composables/loading'
|
|
37
|
-
import {
|
|
82
|
+
import {
|
|
83
|
+
type OrderSettingsDto,
|
|
84
|
+
type OrderV3Settings,
|
|
85
|
+
F_ORDER_SUBITEM_DISPLAY_MODE,
|
|
86
|
+
OrderTakeawaySequenceDto,
|
|
87
|
+
OrderPickUpSequenceDto,
|
|
88
|
+
OrderDeliveryInHouseSequenceDto,
|
|
89
|
+
OrderDeliveryFeedMeSequenceDto
|
|
90
|
+
} from '@entity'
|
|
38
91
|
import { OrderSettingApi } from '@/api/order-setting'
|
|
39
92
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
40
93
|
import { useSnackbarFunctions } from '@/components/snackbar'
|
|
41
94
|
import { useI18n } from '@feedmepos/mf-common'
|
|
95
|
+
import { getSequenceStartEndLabel, sequenceSettingRules } from '@/helpers/order-setting'
|
|
42
96
|
|
|
43
97
|
const { t } = useI18n()
|
|
98
|
+
type SequenceKey = 'takeaway' | 'pickup' | 'inHouseDelivery' | 'feedMeDelivery'
|
|
99
|
+
const sequenceKeys: SequenceKey[] = ['takeaway', 'pickup', 'inHouseDelivery', 'feedMeDelivery']
|
|
100
|
+
|
|
101
|
+
function getSequenceSettingRules(digit?: number | null) {
|
|
102
|
+
return sequenceSettingRules(t('order.sequenceSettingRules'), digit)
|
|
103
|
+
}
|
|
44
104
|
|
|
45
|
-
const { showSuccess } = useSnackbarFunctions()
|
|
105
|
+
const { showSuccess, showError } = useSnackbarFunctions()
|
|
46
106
|
const { currentRestaurant } = useCoreStore()
|
|
47
107
|
const { startAsyncCallWithErr, isLoading } = useLoading()
|
|
48
108
|
|
|
49
109
|
const orderSetting = ref<OrderSettingsDto | undefined>(undefined)
|
|
50
110
|
const v3Settings = ref<OrderV3Settings | undefined>(undefined)
|
|
51
111
|
const anonymousLoginDialog = ref<boolean>(false)
|
|
112
|
+
const isSequenceSettingValid = computed(() => {
|
|
113
|
+
const sequence = orderSetting.value?.sequenceSettings
|
|
114
|
+
if (!sequence) return true
|
|
115
|
+
|
|
116
|
+
return Object.entries(sequence).every((entry) => {
|
|
117
|
+
const [key, value] = entry
|
|
118
|
+
// Ignore autoReset and only validate sequence settings with digit property
|
|
119
|
+
if (key === 'autoReset' || !value || typeof value !== 'object' || !('digit' in value)) return true
|
|
120
|
+
return getSequenceSettingRules(value.digit).every((rule) => rule() === true)
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
function getSeqLabel(key: SequenceKey) {
|
|
125
|
+
let sequence = OrderTakeawaySequenceDto.parse(
|
|
126
|
+
orderSetting.value?.sequenceSettings?.takeaway ?? {}
|
|
127
|
+
)
|
|
128
|
+
let i18n = `order.${key}`
|
|
129
|
+
if (key === 'pickup') {
|
|
130
|
+
sequence = OrderPickUpSequenceDto.parse(orderSetting.value?.sequenceSettings?.pickup ?? {})
|
|
131
|
+
} else if (key === 'inHouseDelivery') {
|
|
132
|
+
sequence = OrderDeliveryInHouseSequenceDto.parse(
|
|
133
|
+
orderSetting.value?.sequenceSettings?.inHouseDelivery ?? {}
|
|
134
|
+
)
|
|
135
|
+
} else if (key === 'feedMeDelivery') {
|
|
136
|
+
sequence = OrderDeliveryFeedMeSequenceDto.parse(
|
|
137
|
+
orderSetting.value?.sequenceSettings?.feedMeDelivery ?? {}
|
|
138
|
+
)
|
|
139
|
+
i18n = `order.feedMeExpress`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const { start, end } = getSequenceStartEndLabel(sequence)
|
|
143
|
+
|
|
144
|
+
return `${t(`${i18n}`)} : ${start} - ${end}`
|
|
145
|
+
}
|
|
52
146
|
|
|
53
147
|
async function init(): Promise<void> {
|
|
54
148
|
if (currentRestaurant.value) {
|
|
@@ -62,6 +156,37 @@ function updateAnonymousLoginDialog(v: boolean) {
|
|
|
62
156
|
}
|
|
63
157
|
}
|
|
64
158
|
|
|
159
|
+
function updateSeq(key: SequenceKey, dtoKey: string, dto?: number) {
|
|
160
|
+
let sequence = {}
|
|
161
|
+
switch (key) {
|
|
162
|
+
case 'takeaway':
|
|
163
|
+
sequence = OrderTakeawaySequenceDto.parse({})
|
|
164
|
+
break
|
|
165
|
+
case 'pickup':
|
|
166
|
+
sequence = OrderPickUpSequenceDto.parse({})
|
|
167
|
+
break
|
|
168
|
+
case 'inHouseDelivery':
|
|
169
|
+
sequence = OrderDeliveryInHouseSequenceDto.parse({})
|
|
170
|
+
break
|
|
171
|
+
case 'feedMeDelivery':
|
|
172
|
+
sequence = OrderDeliveryFeedMeSequenceDto.parse({})
|
|
173
|
+
break
|
|
174
|
+
default:
|
|
175
|
+
throw new Error(`Invalid sequence key - ${key}`)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (orderSetting.value) {
|
|
179
|
+
orderSetting.value.sequenceSettings = {
|
|
180
|
+
...(orderSetting.value?.sequenceSettings ?? {}),
|
|
181
|
+
[key]: {
|
|
182
|
+
...sequence,
|
|
183
|
+
...(orderSetting.value?.sequenceSettings?.[key] ?? {}),
|
|
184
|
+
[`${dtoKey}`]: dto
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
65
190
|
function updateSubItemDisplayMode(v: boolean) {
|
|
66
191
|
if (orderSetting.value) {
|
|
67
192
|
if (v) {
|
|
@@ -72,7 +197,37 @@ function updateSubItemDisplayMode(v: boolean) {
|
|
|
72
197
|
}
|
|
73
198
|
}
|
|
74
199
|
|
|
200
|
+
function toggleResetTime(v: boolean) {
|
|
201
|
+
if (!orderSetting.value) return
|
|
202
|
+
|
|
203
|
+
if (!orderSetting.value.sequenceSettings) {
|
|
204
|
+
orderSetting.value.sequenceSettings = { autoReset: null }
|
|
205
|
+
}
|
|
206
|
+
if (v) {
|
|
207
|
+
orderSetting.value.sequenceSettings = {
|
|
208
|
+
...orderSetting.value.sequenceSettings,
|
|
209
|
+
autoReset: {
|
|
210
|
+
resetTime: '00:00'
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
if (orderSetting.value.sequenceSettings) {
|
|
215
|
+
orderSetting.value.sequenceSettings.autoReset = null
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function updateResetTime(time: string | null) {
|
|
221
|
+
if (orderSetting.value?.sequenceSettings?.autoReset && time) {
|
|
222
|
+
orderSetting.value.sequenceSettings.autoReset.resetTime = time
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
75
226
|
async function updateOrderSetting() {
|
|
227
|
+
if (!isSequenceSettingValid.value) {
|
|
228
|
+
showError(t('order.sequenceSettingRules'))
|
|
229
|
+
return
|
|
230
|
+
}
|
|
76
231
|
await startAsyncCallWithErr(async () => {
|
|
77
232
|
if (orderSetting.value) {
|
|
78
233
|
await OrderSettingApi.updateOrderSetting(orderSetting.value)
|