added setting for users
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
import { useAxios } from '@core/utils/useAxios'
|
||||||
|
import type { TableInput } from '@core/type/baseTable'
|
||||||
|
|
||||||
|
export const getCustomerSpecialPricePackageTable = async (params: TableInput) =>
|
||||||
|
await useAxios.post('/admin/customer_special_price_packages/table', params)
|
||||||
|
|
||||||
|
export const getCustomerSpecialPricePackage = async (id: number) =>
|
||||||
|
await useAxios.get(`/admin/customer_special_price_packages/${id}`)
|
||||||
|
|
||||||
|
export const createCustomerSpecialPricePackage = async (payload: Record<string, unknown>) =>
|
||||||
|
await useAxios.post('/admin/customer_special_price_packages', payload)
|
||||||
|
|
||||||
|
export const updateCustomerSpecialPricePackage = async (id: number, payload: Record<string, unknown>) =>
|
||||||
|
await useAxios.put(`/admin/customer_special_price_packages/${id}`, payload)
|
||||||
|
|
||||||
|
export const deleteCustomerSpecialPricePackage = async (id: number) =>
|
||||||
|
await useAxios.delete(`/admin/customer_special_price_packages/${id}`)
|
||||||
|
|
||||||
|
export const toggleCustomerSpecialPricePackage = async (id: number) =>
|
||||||
|
await useAxios.put(`/admin/customer_special_price_packages/${id}/toggle`)
|
||||||
|
|
||||||
|
export const searchSpecialPriceCustomers = async (q: string) =>
|
||||||
|
await useAxios.get('/admin/customer_special_price_packages/search-customers', { params: { q } })
|
||||||
|
|
||||||
|
export const getProductsByCategories = async (category_names: string[]) =>
|
||||||
|
await useAxios.post('/admin/customer_special_price_packages/products-by-categories', {
|
||||||
|
category_names
|
||||||
|
})
|
||||||
@@ -202,7 +202,7 @@ import SettingValueField from './SettingValueField.vue'
|
|||||||
import SettingCard from './SettingCard.vue'
|
import SettingCard from './SettingCard.vue'
|
||||||
import { refreshAppModeMenu } from '@/router'
|
import { refreshAppModeMenu } from '@/router'
|
||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { applyBannerEnabledFromRows, applyTrackingSystemsEnabledFromRows, applyConditionalOrderEnabledFromRows, applyProductFundsEnabledFromRows, applyPriceTriggerEnabledFromRows, applyAppNotificationEnabledFromRows, applyPriceProviderFromRows, applyPriceChannelAccessFromRows, applySupportChatMenuEnabledFromRows, applyGroupSmsFromRows, setBannerEnabledFromSettings, setConditionalOrderEnabledFromSettings, setProductFundsEnabledFromSettings, setPriceTriggerEnabledFromSettings, setAppNotificationEnabledFromSettings, setPriceProviderFromSettings, setPriceChannelAccessFromSettings, setStoreModeFromSettings, setTrackingSystemsEnabledFromSettings, setGroupSmsEnabledFromSettings } from '@/utils/config'
|
import { applyBannerEnabledFromRows, applyTrackingSystemsEnabledFromRows, applyConditionalOrderEnabledFromRows, applyProductFundsEnabledFromRows, applyPriceTriggerEnabledFromRows, applyAppNotificationEnabledFromRows, applyPriceProviderFromRows, applyPriceChannelAccessFromRows, applySupportChatMenuEnabledFromRows, applyGroupSmsFromRows, applyCustomerSpecialPricingFromRows, setBannerEnabledFromSettings, setConditionalOrderEnabledFromSettings, setProductFundsEnabledFromSettings, setPriceTriggerEnabledFromSettings, setAppNotificationEnabledFromSettings, setPriceProviderFromSettings, setPriceChannelAccessFromSettings, setStoreModeFromSettings, setTrackingSystemsEnabledFromSettings, setGroupSmsEnabledFromSettings, setCustomerSpecialPricingEnabledFromSettings } from '@/utils/config'
|
||||||
import {
|
import {
|
||||||
EDITABLE_SETTING_GROUPS,
|
EDITABLE_SETTING_GROUPS,
|
||||||
SYSTEM_SETTING_GROUPS,
|
SYSTEM_SETTING_GROUPS,
|
||||||
@@ -485,12 +485,14 @@ async function initConfig() {
|
|||||||
applyPriceChannelAccessFromRows(baseData.value)
|
applyPriceChannelAccessFromRows(baseData.value)
|
||||||
applySupportChatMenuEnabledFromRows(baseData.value)
|
applySupportChatMenuEnabledFromRows(baseData.value)
|
||||||
applyGroupSmsFromRows(baseData.value)
|
applyGroupSmsFromRows(baseData.value)
|
||||||
|
applyCustomerSpecialPricingFromRows(baseData.value)
|
||||||
// در صفحهٔ عادی price_provider و show_to_users_chat و price_channel_access (can_edit=0) نیستند — از کل تنظیمات بخوان
|
// در صفحهٔ عادی price_provider و show_to_users_chat و price_channel_access (can_edit=0) نیستند — از کل تنظیمات بخوان
|
||||||
if (
|
if (
|
||||||
!baseData.value.some((row) => row.key === 'price_provider') ||
|
!baseData.value.some((row) => row.key === 'price_provider') ||
|
||||||
!baseData.value.some((row) => row.key === 'show_to_users_chat') ||
|
!baseData.value.some((row) => row.key === 'show_to_users_chat') ||
|
||||||
!baseData.value.some((row) => row.key === 'price_channel_access') ||
|
!baseData.value.some((row) => row.key === 'price_channel_access') ||
|
||||||
!baseData.value.some((row) => row.key === 'group_sms')
|
!baseData.value.some((row) => row.key === 'group_sms') ||
|
||||||
|
!baseData.value.some((row) => row.key === 'customer_special_pricing')
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const { getConfiguration } = await import('@/api/configuration')
|
const { getConfiguration } = await import('@/api/configuration')
|
||||||
@@ -500,6 +502,7 @@ async function initConfig() {
|
|||||||
applySupportChatMenuEnabledFromRows(rows)
|
applySupportChatMenuEnabledFromRows(rows)
|
||||||
applyPriceChannelAccessFromRows(rows)
|
applyPriceChannelAccessFromRows(rows)
|
||||||
applyGroupSmsFromRows(rows)
|
applyGroupSmsFromRows(rows)
|
||||||
|
applyCustomerSpecialPricingFromRows(rows)
|
||||||
} catch {
|
} catch {
|
||||||
/* کش قبلی میماند */
|
/* کش قبلی میماند */
|
||||||
}
|
}
|
||||||
@@ -572,6 +575,9 @@ function syncMenuFlagsFromSetting(key: string | undefined, value: string) {
|
|||||||
if (key === 'group_sms') {
|
if (key === 'group_sms') {
|
||||||
setGroupSmsEnabledFromSettings(isSwitchOn(value))
|
setGroupSmsEnabledFromSettings(isSwitchOn(value))
|
||||||
}
|
}
|
||||||
|
if (key === 'customer_special_pricing') {
|
||||||
|
setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(value))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onValueChange(row: Const, value: string) {
|
function onValueChange(row: Const, value: string) {
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ export const SYSTEM_SETTING_GROUPS: SettingGroupDef[] = [
|
|||||||
title: 'دسترسی مشتری به قابلیتها',
|
title: 'دسترسی مشتری به قابلیتها',
|
||||||
icon: 'vuesax-linear:people',
|
icon: 'vuesax-linear:people',
|
||||||
match: (k) =>
|
match: (k) =>
|
||||||
/^(enable_conditional_order|enable_product_funds|has_page_price_trigger|has_page_notification|has_page_gift_card|enable_customer_level_profit|banner_enabled|jibit_enabled|customer_direct_sms|has_page_earn_money|group_sms|tracking_systems_enabled|permision__enabled|show_to_users_chat)$/.test(
|
/^(enable_conditional_order|enable_product_funds|has_page_price_trigger|has_page_notification|has_page_gift_card|enable_customer_level_profit|banner_enabled|jibit_enabled|customer_direct_sms|has_page_earn_money|group_sms|customer_special_pricing|tracking_systems_enabled|permision__enabled|show_to_users_chat)$/.test(
|
||||||
k
|
k
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
|||||||
sms_notif_wallet_alert: 'switch',
|
sms_notif_wallet_alert: 'switch',
|
||||||
sms_notif_support_admin: 'switch',
|
sms_notif_support_admin: 'switch',
|
||||||
group_sms: 'switch',
|
group_sms: 'switch',
|
||||||
|
customer_special_pricing: 'switch',
|
||||||
montzar_closed: 'switch',
|
montzar_closed: 'switch',
|
||||||
montzar_open_buy: 'switch',
|
montzar_open_buy: 'switch',
|
||||||
montzar_open_sell: 'switch',
|
montzar_open_sell: 'switch',
|
||||||
@@ -825,6 +826,8 @@ const KEY_HELP_FALLBACK: Record<string, string> = {
|
|||||||
'روشن: وقتی مشتری اولین پیام خواندهنشده را در چت پشتیبانی میفرستد و ادمین همان گفتگو را باز و visible ندارد، پیامک به ادمینهای دارای «ارسال پیامک» میرود. خاموش: اعلان پیامک چت نمیرود.',
|
'روشن: وقتی مشتری اولین پیام خواندهنشده را در چت پشتیبانی میفرستد و ادمین همان گفتگو را باز و visible ندارد، پیامک به ادمینهای دارای «ارسال پیامک» میرود. خاموش: اعلان پیامک چت نمیرود.',
|
||||||
group_sms:
|
group_sms:
|
||||||
'روشن: دکمه ارسال پیامک گروهی در پنل ادمین فعال است (ارسال ۱۰تایی). خاموش: ارسال پیامک گروهی غیرفعال است. فقط از تنظیمات پیشرفته.',
|
'روشن: دکمه ارسال پیامک گروهی در پنل ادمین فعال است (ارسال ۱۰تایی). خاموش: ارسال پیامک گروهی غیرفعال است. فقط از تنظیمات پیشرفته.',
|
||||||
|
customer_special_pricing:
|
||||||
|
'روشن: زیرمنوی قیمت ویژه در مشتریان و اعمال سود خرید/فروش پکیج روی مظنه و سفارش برای کاربران انتخابشده. خاموش: غیرفعال. فقط از دیپلوی قابل تغییر است.',
|
||||||
profit_gold_api_enabled:
|
profit_gold_api_enabled:
|
||||||
'روشن: محاسبه سود طلا از API خارجی فعال است. خاموش: محاسبه سود از API خارجی انجام نمیشود (حالت پیشفرض اکثر نصبها).',
|
'روشن: محاسبه سود طلا از API خارجی فعال است. خاموش: محاسبه سود از API خارجی انجام نمیشود (حالت پیشفرض اکثر نصبها).',
|
||||||
main_wallet_products:
|
main_wallet_products:
|
||||||
@@ -986,6 +989,7 @@ export const KEY_LABEL_FALLBACK: Record<string, string> = {
|
|||||||
open_register: 'ثبتنام باز',
|
open_register: 'ثبتنام باز',
|
||||||
sms_panel: 'پنل پیامک (کیف پول)',
|
sms_panel: 'پنل پیامک (کیف پول)',
|
||||||
customer_direct_sms: 'پیامک تکی به مشتری از لیست',
|
customer_direct_sms: 'پیامک تکی به مشتری از لیست',
|
||||||
|
customer_special_pricing: 'قیمت ویژه مشتری',
|
||||||
charge_notif: 'پیامک شارژ ادمین',
|
charge_notif: 'پیامک شارژ ادمین',
|
||||||
sms_notif_order_admin: 'پیامک خرید/فروش به ادمین',
|
sms_notif_order_admin: 'پیامک خرید/فروش به ادمین',
|
||||||
sms_notif_order_customer: 'پیامک خرید/فروش به مشتری',
|
sms_notif_order_customer: 'پیامک خرید/فروش به مشتری',
|
||||||
@@ -1080,6 +1084,7 @@ export const SETTING_LOCKED_KEYS = new Set([
|
|||||||
'fee_deduct_from_gold',
|
'fee_deduct_from_gold',
|
||||||
'referral_bonus_amount',
|
'referral_bonus_amount',
|
||||||
'group_sms',
|
'group_sms',
|
||||||
|
'customer_special_pricing',
|
||||||
'customer_direct_sms',
|
'customer_direct_sms',
|
||||||
'enable_conditional_order',
|
'enable_conditional_order',
|
||||||
'enable_product_funds',
|
'enable_product_funds',
|
||||||
|
|||||||
@@ -4,23 +4,27 @@
|
|||||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<div class="flex items-center justify-center gap-2">
|
<div class="flex items-center justify-center gap-2">
|
||||||
<a-tooltip placement="bottom">
|
<a-tooltip
|
||||||
|
placement="bottom"
|
||||||
|
class="cursor-pointer"
|
||||||
|
:get-popup-container="tooltipContainer"
|
||||||
|
@click="openAssetFunds(record)"
|
||||||
|
>
|
||||||
<template #title><span>قلکهای این دارایی</span></template>
|
<template #title><span>قلکهای این دارایی</span></template>
|
||||||
<Icon
|
<span class="inline-flex">
|
||||||
class="cursor-pointer"
|
<Icon icon="vuesax-linear:safe-home" color="#7C3AED" />
|
||||||
icon="vuesax-linear:safe-home"
|
</span>
|
||||||
color="#7C3AED"
|
|
||||||
@click="openAssetFunds(record)"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip placement="bottom">
|
<a-tooltip
|
||||||
|
placement="bottom"
|
||||||
|
class="cursor-pointer"
|
||||||
|
:get-popup-container="tooltipContainer"
|
||||||
|
@click="openAssetTx(record)"
|
||||||
|
>
|
||||||
<template #title><span>تراکنشهای این دارایی</span></template>
|
<template #title><span>تراکنشهای این دارایی</span></template>
|
||||||
<Icon
|
<span class="inline-flex">
|
||||||
class="cursor-pointer"
|
<Icon icon="vuesax-linear:receipt-2" color="#4572E9" />
|
||||||
icon="vuesax-linear:receipt-2"
|
</span>
|
||||||
color="#4572E9"
|
|
||||||
@click="openAssetTx(record)"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -59,6 +63,7 @@ import {
|
|||||||
} from '@/api/user'
|
} from '@/api/user'
|
||||||
import BasicActionSheet from '@/components/BasicActionSheet.vue'
|
import BasicActionSheet from '@/components/BasicActionSheet.vue'
|
||||||
import BasicShowContext from '@/components/BasicShowContext.vue'
|
import BasicShowContext from '@/components/BasicShowContext.vue'
|
||||||
|
import { toJalali } from '@core/utils/useDataTime'
|
||||||
|
|
||||||
const [submit, reload] = useBaseTable()
|
const [submit, reload] = useBaseTable()
|
||||||
const [assetFundsSubmit] = useBaseTable()
|
const [assetFundsSubmit] = useBaseTable()
|
||||||
@@ -106,7 +111,13 @@ const assetTxCols = [
|
|||||||
{ title: 'نوع', dataIndex: 'type_str', key: 'type_str', type: 'Text' },
|
{ title: 'نوع', dataIndex: 'type_str', key: 'type_str', type: 'Text' },
|
||||||
{ title: 'طلا', dataIndex: 'gold', key: 'gold', type: 'Number' },
|
{ title: 'طلا', dataIndex: 'gold', key: 'gold', type: 'Number' },
|
||||||
{ title: 'ریال', dataIndex: 'cash', key: 'cash', type: 'Number' },
|
{ title: 'ریال', dataIndex: 'cash', key: 'cash', type: 'Number' },
|
||||||
{ title: 'تاریخ', dataIndex: 'created_at', key: 'created_at', type: 'Text' }
|
{
|
||||||
|
title: 'تاریخ',
|
||||||
|
dataIndex: 'created_at',
|
||||||
|
key: 'created_at',
|
||||||
|
type: 'DateTime',
|
||||||
|
customRender: (r: any) => (r.record?.created_at ? toJalali(r.record.created_at) : '—')
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const assetTxTblProps = computed(() => ({
|
const assetTxTblProps = computed(() => ({
|
||||||
@@ -133,8 +144,17 @@ function openAssetTx(record: any) {
|
|||||||
assetTxVisible.value = true
|
assetTxVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tooltipContainer = () => document.body
|
||||||
|
|
||||||
const fetch = () => reload()
|
const fetch = () => reload()
|
||||||
defineExpose({ fetch })
|
defineExpose({ fetch })
|
||||||
|
|
||||||
onMounted(() => {})
|
onMounted(() => {})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.ant-popover,
|
||||||
|
.ant-tooltip {
|
||||||
|
z-index: 1001 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -4,14 +4,16 @@
|
|||||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<div class="flex items-center justify-center gap-2">
|
<div class="flex items-center justify-center gap-2">
|
||||||
<a-tooltip placement="bottom">
|
<a-tooltip
|
||||||
|
placement="bottom"
|
||||||
|
class="cursor-pointer"
|
||||||
|
:get-popup-container="tooltipContainer"
|
||||||
|
@click="openDetails(record)"
|
||||||
|
>
|
||||||
<template #title><span>مشخصات / تراکنشها</span></template>
|
<template #title><span>مشخصات / تراکنشها</span></template>
|
||||||
<Icon
|
<span class="inline-flex">
|
||||||
class="cursor-pointer"
|
<Icon icon="vuesax-linear:info-circle" color="#4572E9" />
|
||||||
icon="vuesax-linear:info-circle"
|
</span>
|
||||||
color="#4572E9"
|
|
||||||
@click="openDetails(record)"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -96,6 +98,15 @@ function openDetails(record: any) {
|
|||||||
detailsVisible.value = true
|
detailsVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tooltipContainer = () => document.body
|
||||||
|
|
||||||
const fetch = () => reload()
|
const fetch = () => reload()
|
||||||
defineExpose({ fetch })
|
defineExpose({ fetch })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.ant-popover,
|
||||||
|
.ant-tooltip {
|
||||||
|
z-index: 1001 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -21,14 +21,23 @@ import { computed } from 'vue'
|
|||||||
import BasicMenu from '@/components/BasicMenu/index.vue'
|
import BasicMenu from '@/components/BasicMenu/index.vue'
|
||||||
import { useRouterStore } from '@core/stores/router'
|
import { useRouterStore } from '@core/stores/router'
|
||||||
import { get } from 'lodash'
|
import { get } from 'lodash'
|
||||||
|
import { customerSpecialPricingEnabledSetting, initWalletSettingsFromApi } from '@/utils/config'
|
||||||
|
|
||||||
|
initWalletSettingsFromApi()
|
||||||
|
|
||||||
const routerStore = useRouterStore()
|
const routerStore = useRouterStore()
|
||||||
const menu = computed(() => {
|
const menu = computed(() => {
|
||||||
const item = routerStore.routes.find((item) => item.name === 'customers')
|
const item = routerStore.routes.find((item) => item.name === 'customers')
|
||||||
const children = get(item, 'children[0].children', []) as Array<{ meta?: { order?: number } }>
|
const children = get(item, 'children[0].children', []) as Array<{
|
||||||
return [...children].sort(
|
name?: string
|
||||||
(a, b) => (a.meta?.order ?? 99) - (b.meta?.order ?? 99)
|
meta?: { order?: number }
|
||||||
)
|
}>
|
||||||
|
return [...children]
|
||||||
|
.filter(
|
||||||
|
(child) =>
|
||||||
|
child.name !== 'customerMain_specialPrice' || customerSpecialPricingEnabledSetting.value
|
||||||
|
)
|
||||||
|
.sort((a, b) => (a.meta?.order ?? 99) - (b.meta?.order ?? 99))
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
<a-form :model="form" ref="formRef" layout="vertical" class="space-y-3">
|
||||||
|
<a-form-item label="عنوان پکیج" name="title" :rules="[{ required: true, message: 'عنوان الزامی است' }]">
|
||||||
|
<BasicInput v-model:value="form.title" placeholder="مثلاً مشتریان VIP" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="گروه دستهبندی" name="category_names" :rules="[{ required: true, type: 'array', min: 1, message: 'دسته را انتخاب کنید' }]">
|
||||||
|
<BasicSelect
|
||||||
|
v-model:value="form.category_names"
|
||||||
|
:items="categoryItems"
|
||||||
|
valueName="value"
|
||||||
|
keyName="key"
|
||||||
|
mode="multiple"
|
||||||
|
class="w-full"
|
||||||
|
placeholder="یک یا چند دسته"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="محصول" name="product_ids" :rules="[{ required: true, type: 'array', min: 1, message: 'محصول را انتخاب کنید' }]">
|
||||||
|
<BasicSelect
|
||||||
|
v-model:value="form.product_ids"
|
||||||
|
:items="productItems"
|
||||||
|
valueName="title"
|
||||||
|
keyName="id"
|
||||||
|
mode="multiple"
|
||||||
|
class="w-full"
|
||||||
|
:disabled="!form.category_names?.length"
|
||||||
|
placeholder="ابتدا دسته را انتخاب کنید"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="لیست کاربران زیر مجموعه" name="customer_ids" :rules="[{ required: true, type: 'array', min: 1, message: 'کاربر را انتخاب کنید' }]">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.customer_ids"
|
||||||
|
mode="multiple"
|
||||||
|
class="w-full"
|
||||||
|
placeholder="جستجو نام یا شماره…"
|
||||||
|
show-search
|
||||||
|
:filter-option="false"
|
||||||
|
:options="customerOptions"
|
||||||
|
@search="onCustomerSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<div class="grid gap-3 md:grid-cols-2">
|
||||||
|
<a-form-item label="سود فروش" name="profit_sell">
|
||||||
|
<BasicInput v-model:value="form.profit_sell" type="price" addon-before="ریال" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="سود خرید" name="profit_buy">
|
||||||
|
<BasicInput v-model:value="form.profit_buy" type="price" addon-before="ریال" />
|
||||||
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-form-item label="نمایش محصول">
|
||||||
|
<a-switch v-model:checked="form.show_product">
|
||||||
|
<template #checkedChildren>فعال</template>
|
||||||
|
<template #unCheckedChildren>مخفی</template>
|
||||||
|
</a-switch>
|
||||||
|
<p class="m-0 mt-1 text-xs text-gray-500">
|
||||||
|
خاموش = این محصولات برای کاربران پکیج در اپ مخفی میشوند.
|
||||||
|
</p>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="وضعیت پکیج">
|
||||||
|
<a-switch v-model:checked="form.is_active">
|
||||||
|
<template #checkedChildren>فعال</template>
|
||||||
|
<template #unCheckedChildren>غیرفعال</template>
|
||||||
|
</a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { FormInstance } from 'ant-design-vue'
|
||||||
|
import { debounce } from 'lodash'
|
||||||
|
import { onMounted, ref, watch } from 'vue'
|
||||||
|
import BasicInput from '@/components/BasicInput.vue'
|
||||||
|
import BasicSelect from '@/components/BasicSelect.vue'
|
||||||
|
import { syncAndLoadCategories, type CategorySelectItem } from '@/utils/categorySelect'
|
||||||
|
import {
|
||||||
|
getProductsByCategories,
|
||||||
|
searchSpecialPriceCustomers
|
||||||
|
} from '@/api/customerSpecialPrice'
|
||||||
|
|
||||||
|
export type SpecialPriceForm = {
|
||||||
|
title: string
|
||||||
|
category_names: string[]
|
||||||
|
product_ids: number[]
|
||||||
|
customer_ids: number[]
|
||||||
|
profit_buy: number | string
|
||||||
|
profit_sell: number | string
|
||||||
|
show_product: boolean
|
||||||
|
is_active: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
form: SpecialPriceForm
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const categoryItems = ref<CategorySelectItem[]>([])
|
||||||
|
const productItems = ref<Array<{ id: number; title: string }>>([])
|
||||||
|
const customerOptions = ref<Array<{ value: number; label: string }>>([])
|
||||||
|
|
||||||
|
async function loadCategories() {
|
||||||
|
categoryItems.value = await syncAndLoadCategories({ selectOnly: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadProducts() {
|
||||||
|
const names = props.form.category_names || []
|
||||||
|
if (!names.length) {
|
||||||
|
productItems.value = []
|
||||||
|
props.form.product_ids = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res: any = await getProductsByCategories(names)
|
||||||
|
const rows = res?.products ?? res?.data?.products ?? res ?? []
|
||||||
|
productItems.value = (Array.isArray(rows) ? rows : []).map((p: any) => ({
|
||||||
|
id: Number(p.id),
|
||||||
|
title: `${p.title || '-'} (${p.group_type || '-'})`
|
||||||
|
}))
|
||||||
|
const allowed = new Set(productItems.value.map((p) => p.id))
|
||||||
|
props.form.product_ids = (props.form.product_ids || []).filter((id) => allowed.has(Number(id)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCustomerSearch = debounce(async (q: string) => {
|
||||||
|
const res: any = await searchSpecialPriceCustomers(q || '')
|
||||||
|
const rows = res?.customers ?? res?.data?.customers ?? []
|
||||||
|
const mapped = (Array.isArray(rows) ? rows : []).map((c: any) => ({
|
||||||
|
value: Number(c.id),
|
||||||
|
label: `${c.name || '-'} — ${c.mobile || ''} (#${c.id})`
|
||||||
|
}))
|
||||||
|
const selected = new Set((props.form.customer_ids || []).map(Number))
|
||||||
|
for (const item of customerOptions.value) {
|
||||||
|
if (selected.has(item.value) && !mapped.some((m) => m.value === item.value)) {
|
||||||
|
mapped.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customerOptions.value = mapped
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [...(props.form.category_names || [])],
|
||||||
|
() => {
|
||||||
|
void loadProducts()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await loadCategories()
|
||||||
|
await loadProducts()
|
||||||
|
await onCustomerSearch('')
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
validate: () => formRef.value?.validate(),
|
||||||
|
seedCustomers: (rows: Array<{ id: number; name?: string; mobile?: string }>) => {
|
||||||
|
customerOptions.value = rows.map((c) => ({
|
||||||
|
value: Number(c.id),
|
||||||
|
label: `${c.name || '-'} — ${c.mobile || ''} (#${c.id})`
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
seedProducts: (rows: Array<{ id: number; title?: string; group_type?: string }>) => {
|
||||||
|
productItems.value = rows.map((p) => ({
|
||||||
|
id: Number(p.id),
|
||||||
|
title: `${p.title || '-'} (${p.group_type || '-'})`
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
|
<BasicShowContext title="پکیجهای قیمت ویژه">
|
||||||
|
<template v-if="isMobile" #extra>
|
||||||
|
<BaseButton type="primary" size="small" icon="vuesax-linear:add" @click="emits('add')">
|
||||||
|
افزودن
|
||||||
|
</BaseButton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<BaseTable v-bind="tblProps" @register="submit" class="h-full min-h-0">
|
||||||
|
<template #extraHeader>
|
||||||
|
<BaseButton type="primary" size="small" icon="vuesax-linear:add" @click="emits('add')">
|
||||||
|
افزودن پکیج
|
||||||
|
</BaseButton>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<div class="flex items-center justify-center gap-2">
|
||||||
|
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('edit', record)">
|
||||||
|
<template #title><span>ویرایش</span></template>
|
||||||
|
<Icon icon="vuesax-linear:edit-2" color="#4572E9" />
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('toggle', record)">
|
||||||
|
<template #title>
|
||||||
|
<span>{{ record.is_active ? 'غیرفعال کردن' : 'فعال کردن' }}</span>
|
||||||
|
</template>
|
||||||
|
<Icon
|
||||||
|
:icon="record.is_active ? 'vuesax-linear:toggle-on-circle' : 'vuesax-linear:toggle-off-circle'"
|
||||||
|
:color="record.is_active ? '#54AD06' : '#ad0627'"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-popconfirm
|
||||||
|
title="پکیج حذف شود؟"
|
||||||
|
ok-text="تایید"
|
||||||
|
cancel-text="انصراف"
|
||||||
|
@confirm="emits('delete', record)"
|
||||||
|
>
|
||||||
|
<a-tooltip placement="bottom" class="cursor-pointer">
|
||||||
|
<template #title><span>حذف</span></template>
|
||||||
|
<Icon icon="vuesax-linear:trash" color="#C53030" />
|
||||||
|
</a-tooltip>
|
||||||
|
</a-popconfirm>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</BaseTable>
|
||||||
|
</BasicShowContext>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { TableInput } from '@core/type/baseTable'
|
||||||
|
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||||
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
|
import BasicShowContext from '@/components/BasicShowContext.vue'
|
||||||
|
import { getCustomerSpecialPricePackageTable } from '@/api/customerSpecialPrice'
|
||||||
|
import { getSpecialPricePackageColumns } from '../hooks/specialPriceColumns'
|
||||||
|
import { isMobile } from '@core/utils/is'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: 'add'): void
|
||||||
|
(e: 'edit', record: any): void
|
||||||
|
(e: 'toggle', record: any): void
|
||||||
|
(e: 'delete', record: any): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const [submit, reload] = useBaseTable()
|
||||||
|
|
||||||
|
const tblProps = ref({
|
||||||
|
columns: getSpecialPricePackageColumns(),
|
||||||
|
api: (params: TableInput) => getCustomerSpecialPricePackageTable(params)
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({ fetch: reload })
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||||
|
import { usePrice } from '@core/utils/usePrice'
|
||||||
|
import { toJalali } from '@core/utils/useDataTime'
|
||||||
|
|
||||||
|
export function getSpecialPricePackageColumns(): BaseTableColumn[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: 'ردیف',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'row',
|
||||||
|
filterable: false,
|
||||||
|
sortable: false,
|
||||||
|
customRender: (record: any) => record.index + 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'عنوان پکیج',
|
||||||
|
dataIndex: 'title',
|
||||||
|
key: 'title',
|
||||||
|
type: 'Text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'تعداد کاربر',
|
||||||
|
dataIndex: 'customers_count',
|
||||||
|
key: 'customers_count',
|
||||||
|
type: 'Number',
|
||||||
|
filterable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'تعداد محصول',
|
||||||
|
dataIndex: 'products_count',
|
||||||
|
key: 'products_count',
|
||||||
|
type: 'Number',
|
||||||
|
filterable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'سود خرید',
|
||||||
|
dataIndex: 'profit_buy',
|
||||||
|
key: 'profit_buy',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: ({ record }) => usePrice(record.profit_buy ?? 0, true, '')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'سود فروش',
|
||||||
|
dataIndex: 'profit_sell',
|
||||||
|
key: 'profit_sell',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: ({ record }) => usePrice(record.profit_sell ?? 0, true, '')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'نمایش محصول',
|
||||||
|
dataIndex: 'show_product',
|
||||||
|
key: 'show_product',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: ({ record }) => (record.show_product ? 'فعال' : 'مخفی')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'وضعیت',
|
||||||
|
dataIndex: 'is_active',
|
||||||
|
key: 'is_active',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: ({ record }) => (record.is_active ? 'فعال' : 'غیرفعال')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'تاریخ',
|
||||||
|
dataIndex: 'updated_at',
|
||||||
|
key: 'updated_at',
|
||||||
|
type: 'DateTime',
|
||||||
|
customRender: (r: any) => (r.record?.updated_at ? toJalali(r.record.updated_at) : '—')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'عملیات',
|
||||||
|
dataIndex: 'action',
|
||||||
|
key: 'action',
|
||||||
|
slot: 'action',
|
||||||
|
filterable: false,
|
||||||
|
sortable: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex h-full w-full flex-col">
|
||||||
|
<tbl
|
||||||
|
ref="tableRef"
|
||||||
|
class="h-full w-full"
|
||||||
|
@add="openAdd"
|
||||||
|
@edit="openEdit"
|
||||||
|
@toggle="onToggle"
|
||||||
|
@delete="onDelete"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BasicActionSheet
|
||||||
|
v-model:visible="editorVisible"
|
||||||
|
:title="sheetTitle"
|
||||||
|
modal-width="40rem"
|
||||||
|
drawer-height="90vh"
|
||||||
|
:loading="loading"
|
||||||
|
:show-button="true"
|
||||||
|
:show-cancel="true"
|
||||||
|
:show-ok="true"
|
||||||
|
ok-text="ثبت"
|
||||||
|
cancel-text="انصراف"
|
||||||
|
@ok="submitForm"
|
||||||
|
@close="closeEditor"
|
||||||
|
@cancel="closeEditor"
|
||||||
|
>
|
||||||
|
<SpecialPriceEditorForm ref="editorRef" :form="form" />
|
||||||
|
</BasicActionSheet>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { message, Modal } from 'ant-design-vue'
|
||||||
|
import BasicActionSheet from '@/components/BasicActionSheet.vue'
|
||||||
|
import tbl from './components/table.vue'
|
||||||
|
import SpecialPriceEditorForm, {
|
||||||
|
type SpecialPriceForm
|
||||||
|
} from './components/SpecialPriceEditorForm.vue'
|
||||||
|
import {
|
||||||
|
createCustomerSpecialPricePackage,
|
||||||
|
deleteCustomerSpecialPricePackage,
|
||||||
|
getCustomerSpecialPricePackage,
|
||||||
|
toggleCustomerSpecialPricePackage,
|
||||||
|
updateCustomerSpecialPricePackage
|
||||||
|
} from '@/api/customerSpecialPrice'
|
||||||
|
|
||||||
|
const tableRef = ref<null | { fetch: () => void }>(null)
|
||||||
|
const editorRef = ref<null | {
|
||||||
|
validate: () => Promise<void>
|
||||||
|
seedCustomers: (rows: any[]) => void
|
||||||
|
seedProducts: (rows: any[]) => void
|
||||||
|
}>(null)
|
||||||
|
|
||||||
|
const editorVisible = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const editId = ref<number | null>(null)
|
||||||
|
|
||||||
|
const emptyForm = (): SpecialPriceForm => ({
|
||||||
|
title: '',
|
||||||
|
category_names: [],
|
||||||
|
product_ids: [],
|
||||||
|
customer_ids: [],
|
||||||
|
profit_buy: 0,
|
||||||
|
profit_sell: 0,
|
||||||
|
show_product: true,
|
||||||
|
is_active: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const form = ref<SpecialPriceForm>(emptyForm())
|
||||||
|
|
||||||
|
const sheetTitle = computed(() => (editId.value ? 'ویرایش پکیج قیمت ویژه' : 'افزودن پکیج قیمت ویژه'))
|
||||||
|
|
||||||
|
function openAdd() {
|
||||||
|
editId.value = null
|
||||||
|
form.value = emptyForm()
|
||||||
|
editorVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openEdit(record: any) {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res: any = await getCustomerSpecialPricePackage(Number(record.id))
|
||||||
|
const data = res?.data ?? res
|
||||||
|
editId.value = Number(record.id)
|
||||||
|
form.value = {
|
||||||
|
title: data?.package?.title ?? '',
|
||||||
|
category_names: data?.category_names ?? [],
|
||||||
|
product_ids: (data?.product_ids ?? []).map(Number),
|
||||||
|
customer_ids: (data?.customer_ids ?? []).map(Number),
|
||||||
|
profit_buy: data?.package?.profit_buy ?? 0,
|
||||||
|
profit_sell: data?.package?.profit_sell ?? 0,
|
||||||
|
show_product: Boolean(data?.package?.show_product ?? true),
|
||||||
|
is_active: Boolean(data?.package?.is_active ?? true)
|
||||||
|
}
|
||||||
|
editorVisible.value = true
|
||||||
|
await Promise.resolve()
|
||||||
|
editorRef.value?.seedCustomers(data?.customers ?? [])
|
||||||
|
editorRef.value?.seedProducts(data?.products ?? [])
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.response?.data?.message ?? 'خطا در دریافت پکیج')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeEditor() {
|
||||||
|
editorVisible.value = false
|
||||||
|
editId.value = null
|
||||||
|
form.value = emptyForm()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showWarnings(warnings?: string[]) {
|
||||||
|
if (!warnings?.length) return
|
||||||
|
Modal.warning({
|
||||||
|
title: 'هشدار تداخل پکیج',
|
||||||
|
content: warnings.slice(0, 8).join('\n'),
|
||||||
|
width: 520,
|
||||||
|
okText: 'متوجه شدم'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitForm() {
|
||||||
|
try {
|
||||||
|
await editorRef.value?.validate()
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const payload = {
|
||||||
|
title: form.value.title,
|
||||||
|
category_names: form.value.category_names,
|
||||||
|
product_ids: form.value.product_ids.map(Number),
|
||||||
|
customer_ids: form.value.customer_ids.map(Number),
|
||||||
|
profit_buy: form.value.profit_buy,
|
||||||
|
profit_sell: form.value.profit_sell,
|
||||||
|
show_product: form.value.show_product,
|
||||||
|
is_active: form.value.is_active
|
||||||
|
}
|
||||||
|
let res: any
|
||||||
|
if (editId.value) {
|
||||||
|
res = await updateCustomerSpecialPricePackage(editId.value, payload)
|
||||||
|
message.success(res?.message ?? 'بهروز شد')
|
||||||
|
} else {
|
||||||
|
res = await createCustomerSpecialPricePackage(payload)
|
||||||
|
message.success(res?.message ?? 'ثبت شد')
|
||||||
|
}
|
||||||
|
showWarnings(res?.warnings ?? res?.data?.warnings)
|
||||||
|
closeEditor()
|
||||||
|
tableRef.value?.fetch()
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.response?.data?.message ?? 'خطا در ذخیره')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onToggle(record: any) {
|
||||||
|
try {
|
||||||
|
const res: any = await toggleCustomerSpecialPricePackage(Number(record.id))
|
||||||
|
message.success(res?.message ?? 'وضعیت تغییر کرد')
|
||||||
|
tableRef.value?.fetch()
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.response?.data?.message ?? 'خطا')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDelete(record: any) {
|
||||||
|
try {
|
||||||
|
await deleteCustomerSpecialPricePackage(Number(record.id))
|
||||||
|
message.success('حذف شد')
|
||||||
|
tableRef.value?.fetch()
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.response?.data?.message ?? 'خطا در حذف')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -70,6 +70,16 @@ const Customers: RouteRecordRaw = {
|
|||||||
title: 'احراز هویت',
|
title: 'احراز هویت',
|
||||||
order: 3
|
order: 3
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'customerMain_specialPrice',
|
||||||
|
path: 'special-price',
|
||||||
|
component: () => import('@/pages/menuPages/customers/specialPrice/index.vue'),
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:dollar-circle',
|
||||||
|
title: 'قیمت ویژه',
|
||||||
|
order: 4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ export const priceTriggerEnabledSetting = ref(false)
|
|||||||
/** reactive — دکمه ارسال پیامک گروهی در صفحه پیامکها */
|
/** reactive — دکمه ارسال پیامک گروهی در صفحه پیامکها */
|
||||||
export const groupSmsEnabledSetting = ref(false)
|
export const groupSmsEnabledSetting = ref(false)
|
||||||
|
|
||||||
|
/** reactive — زیرمنوی قیمت ویژه مشتری */
|
||||||
|
export const customerSpecialPricingEnabledSetting = ref(false)
|
||||||
|
|
||||||
/** reactive — منو و زنگوله اعلان داخل اپ */
|
/** reactive — منو و زنگوله اعلان داخل اپ */
|
||||||
export const appNotificationEnabledSetting = ref(true)
|
export const appNotificationEnabledSetting = ref(true)
|
||||||
|
|
||||||
@@ -156,6 +159,10 @@ export function setGroupSmsEnabledFromSettings(value: boolean): void {
|
|||||||
groupSmsEnabledSetting.value = value
|
groupSmsEnabledSetting.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setCustomerSpecialPricingEnabledFromSettings(value: boolean): void {
|
||||||
|
customerSpecialPricingEnabledSetting.value = value
|
||||||
|
}
|
||||||
|
|
||||||
export function setConditionalOrderEnabledFromSettings(value: boolean): void {
|
export function setConditionalOrderEnabledFromSettings(value: boolean): void {
|
||||||
conditionalOrderEnabledSetting.value = value
|
conditionalOrderEnabledSetting.value = value
|
||||||
}
|
}
|
||||||
@@ -262,6 +269,13 @@ export function applyGroupSmsFromRows(rows: Array<{ key?: string; value?: string
|
|||||||
if (row) setGroupSmsEnabledFromSettings(isSwitchOn(row.value))
|
if (row) setGroupSmsEnabledFromSettings(isSwitchOn(row.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyCustomerSpecialPricingFromRows(
|
||||||
|
rows: Array<{ key?: string; value?: string | null }>
|
||||||
|
) {
|
||||||
|
const row = rows.find((item) => item.key === 'customer_special_pricing')
|
||||||
|
if (row) setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(row.value))
|
||||||
|
}
|
||||||
|
|
||||||
export function applyConditionalOrderEnabledFromRows(
|
export function applyConditionalOrderEnabledFromRows(
|
||||||
rows: Array<{ key?: string; value?: string | null }>
|
rows: Array<{ key?: string; value?: string | null }>
|
||||||
) {
|
) {
|
||||||
@@ -330,6 +344,7 @@ async function bootstrapSettingsFromApi(): Promise<void> {
|
|||||||
applyTrackingSystemsEnabledFromRows(list)
|
applyTrackingSystemsEnabledFromRows(list)
|
||||||
applyCustomerDirectSmsFromRows(list)
|
applyCustomerDirectSmsFromRows(list)
|
||||||
applyGroupSmsFromRows(list)
|
applyGroupSmsFromRows(list)
|
||||||
|
applyCustomerSpecialPricingFromRows(list)
|
||||||
applyConditionalOrderEnabledFromRows(list)
|
applyConditionalOrderEnabledFromRows(list)
|
||||||
applyProductFundsEnabledFromRows(list)
|
applyProductFundsEnabledFromRows(list)
|
||||||
applyCustomerLevelProfitEnabledFromRows(list)
|
applyCustomerLevelProfitEnabledFromRows(list)
|
||||||
|
|||||||
Reference in New Issue
Block a user