@feedmepos/mf-order-setting 0.0.36 → 0.0.37

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 (40) hide show
  1. package/dist/{KioskDevicesView-wPKewwAS.js → KioskDevicesView-D9PQ22G6.js} +1 -1
  2. package/dist/{KioskDevicesView.vue_vue_type_script_setup_true_lang-BCJPU2la.js → KioskDevicesView.vue_vue_type_script_setup_true_lang-BuwHk_0a.js} +2 -2
  3. package/dist/{KioskSettingView-CV54HpY2.js → KioskSettingView-C98iSa7q.js} +1 -1
  4. package/dist/{KioskView-B4mggCt0.js → KioskView-C6s4u6vt.js} +7 -7
  5. package/dist/{OrderSettingsView-CKGRFx_2.js → OrderSettingsView-DFB_C-VO.js} +6030 -5897
  6. package/dist/{app-D4exdzAx.js → app-86WCOyBO.js} +21 -9
  7. package/dist/app.js +1 -1
  8. package/dist/{dayjs.min-C_sCJHuD.js → dayjs.min-BiuO1l2_.js} +1 -1
  9. package/dist/frontend/mf-order/src/app.d.ts +12 -0
  10. package/dist/frontend/mf-order/src/helpers/order-setting.d.ts +6 -0
  11. package/dist/frontend/mf-order/src/main.d.ts +12 -0
  12. package/dist/frontend/mf-order/src/stores/order-setting/index.d.ts +27 -0
  13. package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
  14. package/dist/{index-Cvhc_ltu.js → index-DZKSDqn_.js} +2 -2
  15. package/dist/menu.dto-CT1XwUKO.js +127978 -0
  16. package/dist/package/entity/incoming-order/incoming-order-to-bill.dto.d.ts +24 -24
  17. package/dist/package/entity/incoming-order/incoming-order.dto.d.ts +48 -48
  18. package/dist/package/entity/order/menu/menu.dto.d.ts +10 -0
  19. package/dist/package/entity/order/order-item/order-item.dto.d.ts +48 -48
  20. package/dist/package/entity/order/order.do.d.ts +20 -8
  21. package/dist/package/entity/order/order.dto.d.ts +280 -164
  22. package/dist/package/entity/order-platform/shopeefood/shopeefood-order.do.d.ts +33 -0
  23. package/dist/package/entity/order-platform/shopeefood/shopeefood-order.dto.d.ts +18 -0
  24. package/dist/package/entity/order-setting/order-setting.do.d.ts +168 -0
  25. package/dist/package/entity/order-setting/order-setting.dto.d.ts +134 -0
  26. package/dist/package/entity/order-setting/queue/queue.do.d.ts +95 -1613
  27. package/dist/package/entity/order-setting/queue/queue.dto.d.ts +62 -110
  28. package/dist/package/entity/order-setting/sequence/sequence.do.d.ts +72 -0
  29. package/dist/package/entity/order-setting/sequence/sequence.dto.d.ts +101 -0
  30. package/dist/package/entity/queue/queue.do.d.ts +18 -6
  31. package/dist/package/entity/queue/queue.dto.d.ts +52 -38
  32. package/dist/package/entity/restaurant/restaurant.dto.d.ts +81 -17
  33. package/package.json +1 -1
  34. package/src/helpers/order-setting.ts +20 -0
  35. package/src/locales/en-US.json +4 -0
  36. package/src/locales/th-TH.json +4 -0
  37. package/src/locales/zh-CN.json +4 -0
  38. package/src/stores/order-setting/mapper.ts +56 -56
  39. package/src/views/order-settings/general/GeneralSetting.vue +159 -4
  40. package/dist/menu.dto-CeUdKgTW.js +0 -103445
@@ -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
- qrPay: false,
71
- scanPay: false,
70
+ terminalQrPay: false,
72
71
  terminalScanPay: false,
73
- terminalQrPay: false
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
- payAtCounter:
110
- kioskOrderSettings.takeaway.submitOrderInstruction?.payAtCounter?.['en'] ?? null,
111
- paid: kioskOrderSettings.takeaway.submitOrderInstruction?.paid?.['en'] ?? null
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
- ...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
- }
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
- 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
- }
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
- en: dineInSetting.displayStand.submitOrderInstruction.payAtCounter
194
- }
193
+ en: dineInSetting.displayStand.submitOrderInstruction.payAtCounter
194
+ }
195
195
  : null,
196
196
  paid: dineInSetting.displayStand.submitOrderInstruction?.paid
197
197
  ? {
198
- en: dineInSetting.displayStand.submitOrderInstruction.paid
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
- en: dineInSetting.pickUp.submitOrderInstruction.payAtCounter
209
- }
208
+ en: dineInSetting.pickUp.submitOrderInstruction.payAtCounter
209
+ }
210
210
  : null,
211
211
  paid: dineInSetting.pickUp.submitOrderInstruction?.paid
212
212
  ? {
213
- en: dineInSetting.pickUp.submitOrderInstruction.paid
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
- 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
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
 
@@ -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-2/3">
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 { type OrderSettingsDto, type OrderV3Settings, F_ORDER_SUBITEM_DISPLAY_MODE } from '@entity'
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)