Show Shayegan sync table/health in admin and always treat boursecu accounting as Shayegan. Co-authored-by: Cursor <cursoragent@cursor.com>
522 lines
18 KiB
TypeScript
522 lines
18 KiB
TypeScript
import { ref } from 'vue'
|
|
import { setCachedMainMetal } from '@/utils/metalLabels'
|
|
|
|
export type AccountingProvider = 'none' | 'pargar' | 'tahesab' | 'zarin' | 'shayegan'
|
|
|
|
export function getConfigApp(key: string) {
|
|
const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user : {}
|
|
|
|
if (config) {
|
|
return config[key]
|
|
}
|
|
return null
|
|
}
|
|
|
|
/** true اگر ui_config یا app_ui_config در get_user مقدار داشته باشد */
|
|
export function hasAppUiConfig(): boolean {
|
|
const cfg = getConfigApp('ui_config') ?? getConfigApp('app_ui_config')
|
|
if (cfg == null) return false
|
|
if (typeof cfg === 'string') return cfg.trim().length > 0
|
|
if (Array.isArray(cfg)) return cfg.length > 0
|
|
if (typeof cfg === 'object') return Object.keys(cfg as object).length > 0
|
|
return Boolean(cfg)
|
|
}
|
|
|
|
/** true اگر get_user → ui_variant برابر modular باشد (بنرهای تم اپ) */
|
|
export function isModularUiVariant(): boolean {
|
|
return String(getConfigApp('ui_variant') ?? '')
|
|
.trim()
|
|
.toLowerCase() === 'modular'
|
|
}
|
|
|
|
let storeModeFromSettings: boolean | null = null
|
|
let settingsBootstrapped = false
|
|
|
|
/** reactive — برای فیلتر منوی «بنرها» در پیکربندی */
|
|
export const bannerEnabledSetting = ref(false)
|
|
|
|
/** reactive — برای فیلتر منوی «سایتهای ریگیری» در پیکربندی */
|
|
export const trackingSystemsEnabledSetting = ref(false)
|
|
|
|
/** reactive — نمایش UI تهحساب در حسابداری و ... */
|
|
export const tahesabEnabledSetting = ref(false)
|
|
|
|
/** reactive — نمایش UI زرین در حسابداری و ... */
|
|
export const zarinEnabledSetting = ref(false)
|
|
|
|
/** reactive — نمایش UI پرگار در حسابداری و ... */
|
|
export const pargarEnabledSetting = ref(false)
|
|
|
|
/** reactive — نمایش UI شایگان در حسابداری و ... */
|
|
export const shayeganEnabledSetting = ref(false)
|
|
|
|
/** reactive — دکمه پیامک تکی در لیست مشتریان */
|
|
export const customerDirectSmsEnabledSetting = ref(false)
|
|
|
|
/** reactive — منو و UI سفارش شرطی (ادمین + کنترلهای مشتری) */
|
|
export const conditionalOrderEnabledSetting = ref(false)
|
|
|
|
/** reactive — منوی اتوماسیون در تنظیمات ادمین */
|
|
export const automationEnabledSetting = ref(false)
|
|
|
|
/** reactive — قلک per-product در اپ مشتری */
|
|
export const productFundsEnabledSetting = ref(false)
|
|
|
|
/** reactive — سود چندسطحی معرف در لیست مشتریان */
|
|
export const customerLevelProfitEnabledSetting = ref(false)
|
|
|
|
/** reactive — منو و UI هشدار قیمت */
|
|
export const priceTriggerEnabledSetting = ref(false)
|
|
|
|
/** reactive — منوی کارت هدیه ادمین (همان has_page_gift_card اپ کاربر) */
|
|
export const giftCardEnabledSetting = ref(false)
|
|
|
|
/** reactive — دکمه ارسال پیامک گروهی در صفحه پیامکها */
|
|
export const groupSmsEnabledSetting = ref(false)
|
|
|
|
/** reactive — زیرمنوی قیمت ویژه مشتری */
|
|
export const customerSpecialPricingEnabledSetting = ref(false)
|
|
|
|
/** reactive — زیرمنوی اعتبار طلایی در مشتریان */
|
|
export const goldCreditEnabledSetting = ref(false)
|
|
|
|
/** reactive — منو و زنگوله اعلان داخل اپ */
|
|
export const appNotificationEnabledSetting = ref(true)
|
|
|
|
/** reactive — منبع قیمت فعال (montzar / zaarbox / main_product) */
|
|
export const priceProviderSetting = ref('')
|
|
|
|
/** reactive — منوی افقی / دکمه «چت پشتیبانی» */
|
|
export const supportChatMenuEnabledSetting = ref(false)
|
|
|
|
/** reactive — سوییچ دیپلوی show_to_users_chat (برای مخفی کردن has_chat در تنظیمات عادی) */
|
|
export const showToUsersChatSetting = ref(false)
|
|
|
|
/** reactive — منوی تنظیمات وبسایت وقتی has_landing روشن است */
|
|
export const hasLandingSetting = ref(false)
|
|
|
|
/** reactive — سوییچ دیپلوی price_channel_access (گروه کانال در تنظیمات عادی) */
|
|
export const priceChannelAccessSetting = ref(false)
|
|
|
|
export const accountingProviderSetting = ref<AccountingProvider>('none')
|
|
|
|
let tahesabEnabledFromSettings: boolean | null = null
|
|
let zarinEnabledFromSettings: boolean | null = null
|
|
let pargarEnabledFromSettings: boolean | null = null
|
|
let shayeganEnabledFromSettings: boolean | null = null
|
|
let customerDirectSmsFromSettings: boolean | null = null
|
|
let accountingProviderFromSettings: AccountingProvider | null = null
|
|
|
|
function isSwitchOn(value: string | number | boolean | undefined | null): boolean {
|
|
if (value === true || value === 1) return true
|
|
const v = String(value ?? '')
|
|
.trim()
|
|
.toLowerCase()
|
|
return v === 'true' || v === '1' || v === 'yes' || v === 'activate'
|
|
}
|
|
|
|
function normalizeAccountingProvider(value: string | undefined | null): AccountingProvider {
|
|
const v = (value ?? '').trim().toLowerCase()
|
|
if (v === 'pargar' || v === 'tahesab' || v === 'zarin' || v === 'shayegan') return v
|
|
return 'none'
|
|
}
|
|
|
|
/** بورس مس: UI حسابداری همیشه شایگان — settings/legacy نادیده گرفته میشود. */
|
|
function resolveAccountingProviderFromRows(
|
|
_list: Array<{ key?: string; value?: string | null }>
|
|
): AccountingProvider {
|
|
return 'shayegan'
|
|
}
|
|
|
|
export function applyAccountingProviderFromRows(
|
|
list: Array<{ key?: string; value?: string | null }>
|
|
): void {
|
|
const provider = resolveAccountingProviderFromRows(list)
|
|
accountingProviderFromSettings = provider
|
|
accountingProviderSetting.value = provider
|
|
setTahesabEnabledFromSettings(provider === 'tahesab')
|
|
setZarinEnabledFromSettings(provider === 'zarin')
|
|
setPargarEnabledFromSettings(provider === 'pargar')
|
|
setShayeganEnabledFromSettings(provider === 'shayegan')
|
|
}
|
|
|
|
export function setStoreModeFromSettings(value: boolean): void {
|
|
storeModeFromSettings = value
|
|
}
|
|
|
|
export function setBannerEnabledFromSettings(value: boolean): void {
|
|
bannerEnabledSetting.value = value
|
|
}
|
|
|
|
export function setTrackingSystemsEnabledFromSettings(value: boolean): void {
|
|
trackingSystemsEnabledSetting.value = value
|
|
}
|
|
|
|
export function setTahesabEnabledFromSettings(value: boolean): void {
|
|
tahesabEnabledFromSettings = value
|
|
tahesabEnabledSetting.value = value
|
|
}
|
|
|
|
export function setZarinEnabledFromSettings(value: boolean): void {
|
|
zarinEnabledFromSettings = value
|
|
zarinEnabledSetting.value = value
|
|
}
|
|
|
|
export function setPargarEnabledFromSettings(value: boolean): void {
|
|
pargarEnabledFromSettings = value
|
|
pargarEnabledSetting.value = value
|
|
}
|
|
|
|
export function setShayeganEnabledFromSettings(value: boolean): void {
|
|
shayeganEnabledFromSettings = value
|
|
shayeganEnabledSetting.value = value
|
|
}
|
|
|
|
export function setCustomerDirectSmsEnabledFromSettings(value: boolean): void {
|
|
customerDirectSmsFromSettings = value
|
|
customerDirectSmsEnabledSetting.value = value
|
|
}
|
|
|
|
export function setGroupSmsEnabledFromSettings(value: boolean): void {
|
|
groupSmsEnabledSetting.value = value
|
|
}
|
|
|
|
export function setCustomerSpecialPricingEnabledFromSettings(value: boolean): void {
|
|
customerSpecialPricingEnabledSetting.value = value
|
|
}
|
|
|
|
export function setGoldCreditEnabledFromSettings(value: boolean): void {
|
|
goldCreditEnabledSetting.value = value
|
|
}
|
|
|
|
export function setConditionalOrderEnabledFromSettings(value: boolean): void {
|
|
conditionalOrderEnabledSetting.value = value
|
|
}
|
|
|
|
export function setAutomationEnabledFromSettings(value: boolean): void {
|
|
automationEnabledSetting.value = value
|
|
}
|
|
|
|
export function setProductFundsEnabledFromSettings(value: boolean): void {
|
|
productFundsEnabledSetting.value = value
|
|
}
|
|
|
|
export function setCustomerLevelProfitEnabledFromSettings(value: boolean): void {
|
|
customerLevelProfitEnabledSetting.value = value
|
|
}
|
|
|
|
export function setPriceTriggerEnabledFromSettings(value: boolean): void {
|
|
priceTriggerEnabledSetting.value = value
|
|
}
|
|
|
|
export function setGiftCardEnabledFromSettings(value: boolean): void {
|
|
giftCardEnabledSetting.value = value
|
|
}
|
|
|
|
export function setAppNotificationEnabledFromSettings(value: boolean): void {
|
|
appNotificationEnabledSetting.value = value
|
|
}
|
|
|
|
export function setSupportChatMenuEnabledFromSettings(value: boolean): void {
|
|
supportChatMenuEnabledSetting.value = value
|
|
}
|
|
|
|
export function setShowToUsersChatFromSettings(value: boolean): void {
|
|
showToUsersChatSetting.value = value
|
|
}
|
|
|
|
export function setHasLandingFromSettings(value: boolean): void {
|
|
hasLandingSetting.value = value
|
|
}
|
|
|
|
export function setPriceChannelAccessFromSettings(value: boolean): void {
|
|
priceChannelAccessSetting.value = value
|
|
}
|
|
|
|
let lastShowToUsersChat = ''
|
|
let lastHasChat = ''
|
|
let lastChatApi = ''
|
|
|
|
/** منوی چت: show_to_users_chat + has_chat + chat_api */
|
|
export function resolveSupportChatMenuEnabled(
|
|
getValue: (key: string) => string | undefined | null
|
|
): boolean {
|
|
const api = String(getValue('chat_api') ?? '').trim()
|
|
return (
|
|
isSwitchOn(getValue('show_to_users_chat')) &&
|
|
isSwitchOn(getValue('has_chat')) &&
|
|
Boolean(api) &&
|
|
api.toLowerCase() !== 'null'
|
|
)
|
|
}
|
|
|
|
export function applySupportChatMenuEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
): void {
|
|
let touched = false
|
|
for (const row of rows) {
|
|
const key = String(row.key ?? '')
|
|
if (key === 'show_to_users_chat') {
|
|
lastShowToUsersChat = String(row.value ?? '')
|
|
touched = true
|
|
} else if (key === 'has_chat') {
|
|
lastHasChat = String(row.value ?? '')
|
|
touched = true
|
|
} else if (key === 'chat_api') {
|
|
lastChatApi = String(row.value ?? '')
|
|
touched = true
|
|
}
|
|
}
|
|
if (!touched) return
|
|
|
|
setShowToUsersChatFromSettings(isSwitchOn(lastShowToUsersChat))
|
|
setSupportChatMenuEnabledFromSettings(
|
|
resolveSupportChatMenuEnabled((key) => {
|
|
if (key === 'show_to_users_chat') return lastShowToUsersChat
|
|
if (key === 'has_chat') return lastHasChat
|
|
if (key === 'chat_api') return lastChatApi
|
|
return undefined
|
|
})
|
|
)
|
|
}
|
|
|
|
export function setPriceProviderFromSettings(value?: string | null): void {
|
|
priceProviderSetting.value = (value ?? '').trim().toLowerCase()
|
|
}
|
|
|
|
/** فقط وقتی کلید در rows باشد آپدیت میشود — پاسخ ناقص (editable/system) فلگ قبلی را پاک نکند */
|
|
export function applyBannerEnabledFromRows(rows: Array<{ key?: string; value?: string | null }>) {
|
|
const row = rows.find((item) => item.key === 'banner_enabled')
|
|
if (row) setBannerEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyTrackingSystemsEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'tracking_systems_enabled')
|
|
if (row) setTrackingSystemsEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyCustomerDirectSmsFromRows(rows: Array<{ key?: string; value?: string | null }>) {
|
|
const row = rows.find((item) => item.key === 'customer_direct_sms')
|
|
if (row) setCustomerDirectSmsEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyGroupSmsFromRows(rows: Array<{ key?: string; value?: string | null }>) {
|
|
const row = rows.find((item) => item.key === 'group_sms')
|
|
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 applyGoldCreditEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'enable_gold_credit')
|
|
if (row) setGoldCreditEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
/** بعد از همگامسازی سوپرادمین — bootstrap بعدی دوباره از API میخواند */
|
|
export function invalidateSettingsBootstrap(): void {
|
|
settingsBootstrapped = false
|
|
}
|
|
|
|
/**
|
|
* اعمال مستقیم ۱۶ دسترسی سوپرادمین روی فلگهای منو/UI
|
|
* (پاسخ refresh-superadmin.items یا ردیفهای get_settings).
|
|
*/
|
|
export function applySuperAdminAccessFlagsFromItems(
|
|
items: Record<string, string> | Array<{ key?: string; value?: string | null }>
|
|
): void {
|
|
const rows = Array.isArray(items)
|
|
? items
|
|
: Object.entries(items).map(([key, value]) => ({ key, value }))
|
|
applyCustomerDirectSmsFromRows(rows)
|
|
applyGroupSmsFromRows(rows)
|
|
applyCustomerSpecialPricingFromRows(rows)
|
|
applyGoldCreditEnabledFromRows(rows)
|
|
applyConditionalOrderEnabledFromRows(rows)
|
|
applyAutomationEnabledFromRows(rows)
|
|
applyProductFundsEnabledFromRows(rows)
|
|
applyCustomerLevelProfitEnabledFromRows(rows)
|
|
applyPriceTriggerEnabledFromRows(rows)
|
|
applyGiftCardEnabledFromRows(rows)
|
|
applyAppNotificationEnabledFromRows(rows)
|
|
applySupportChatMenuEnabledFromRows(rows)
|
|
applyHasLandingFromRows(rows)
|
|
}
|
|
|
|
export function applyConditionalOrderEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'enable_conditional_order')
|
|
if (row) setConditionalOrderEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyAutomationEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'enable_automation')
|
|
if (row) setAutomationEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyProductFundsEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'enable_product_funds')
|
|
if (row) setProductFundsEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyCustomerLevelProfitEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'enable_customer_level_profit')
|
|
if (row) setCustomerLevelProfitEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyPriceTriggerEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'has_page_price_trigger')
|
|
if (row) setPriceTriggerEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyGiftCardEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'has_page_gift_card')
|
|
if (row) setGiftCardEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyAppNotificationEnabledFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'has_page_notification')
|
|
if (row) setAppNotificationEnabledFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyHasLandingFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'has_landing')
|
|
if (row) setHasLandingFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
export function applyPriceProviderFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'price_provider')
|
|
if (row) {
|
|
setPriceProviderFromSettings(row.value)
|
|
}
|
|
}
|
|
|
|
export function applyPriceChannelAccessFromRows(
|
|
rows: Array<{ key?: string; value?: string | null }>
|
|
) {
|
|
const row = rows.find((item) => item.key === 'price_channel_access')
|
|
if (row) setPriceChannelAccessFromSettings(isSwitchOn(row.value))
|
|
}
|
|
|
|
async function bootstrapSettingsFromApi(): Promise<void> {
|
|
if (settingsBootstrapped) return
|
|
|
|
try {
|
|
const { getConfiguration } = await import('@/api/configuration')
|
|
const { parseMainWalletProductIds } = await import('@/components/mobile/utils/wallet')
|
|
const rows = await getConfiguration()
|
|
const list = Array.isArray(rows) ? rows : []
|
|
const isStoreRow = list.find((item) => item.key === 'is_store')
|
|
const mainWalletRow = list.find((item) => item.key === 'main_wallet_products')
|
|
const mainMetalRow = list.find((item) => item.key === 'main_metal')
|
|
storeModeFromSettings = isStoreRow ? isSwitchOn(isStoreRow.value) : false
|
|
applyAccountingProviderFromRows(list)
|
|
applyBannerEnabledFromRows(list)
|
|
applyTrackingSystemsEnabledFromRows(list)
|
|
applyCustomerDirectSmsFromRows(list)
|
|
applyGroupSmsFromRows(list)
|
|
applyCustomerSpecialPricingFromRows(list)
|
|
applyGoldCreditEnabledFromRows(list)
|
|
applyConditionalOrderEnabledFromRows(list)
|
|
applyAutomationEnabledFromRows(list)
|
|
applyProductFundsEnabledFromRows(list)
|
|
applyCustomerLevelProfitEnabledFromRows(list)
|
|
applyPriceTriggerEnabledFromRows(list)
|
|
applyGiftCardEnabledFromRows(list)
|
|
applyAppNotificationEnabledFromRows(list)
|
|
applySupportChatMenuEnabledFromRows(list)
|
|
applyHasLandingFromRows(list)
|
|
applyPriceProviderFromRows(list)
|
|
applyPriceChannelAccessFromRows(list)
|
|
setCachedMainMetal(mainMetalRow?.value)
|
|
const { setCachedMainWalletProductIds } = await import('@/components/mobile/utils/wallet')
|
|
setCachedMainWalletProductIds(parseMainWalletProductIds(mainWalletRow?.value))
|
|
settingsBootstrapped = true
|
|
} catch {
|
|
// Allow retry on next init* call — do not lock flags to false forever.
|
|
}
|
|
}
|
|
|
|
/** is_store و main_wallet_products از API تنظیمات — نه از get_user */
|
|
export async function initStoreModeFromSettings(): Promise<boolean> {
|
|
if (storeModeFromSettings !== null) return storeModeFromSettings
|
|
|
|
await bootstrapSettingsFromApi()
|
|
|
|
return storeModeFromSettings === true
|
|
}
|
|
|
|
export async function initWalletSettingsFromApi(): Promise<void> {
|
|
await bootstrapSettingsFromApi()
|
|
}
|
|
|
|
export function isStoreApp(): boolean {
|
|
return storeModeFromSettings === true
|
|
}
|
|
|
|
export function isTahesabEnabled(): boolean {
|
|
return tahesabEnabledFromSettings === true
|
|
}
|
|
|
|
export function isZarinEnabled(): boolean {
|
|
return zarinEnabledFromSettings === true
|
|
}
|
|
|
|
export function isPargarEnabled(): boolean {
|
|
return pargarEnabledFromSettings === true
|
|
}
|
|
|
|
export function isShayeganEnabled(): boolean {
|
|
return shayeganEnabledFromSettings === true
|
|
}
|
|
|
|
export function getAccountingProvider(): AccountingProvider {
|
|
return accountingProviderFromSettings ?? 'none'
|
|
}
|
|
|
|
/** بارگذاری accounting_provider و فلگهای UI */
|
|
export async function initAccountingSettingsFromApi(): Promise<AccountingProvider> {
|
|
if (accountingProviderFromSettings !== null) return accountingProviderFromSettings
|
|
|
|
await bootstrapSettingsFromApi()
|
|
|
|
return accountingProviderFromSettings ?? 'none'
|
|
}
|
|
|
|
/** @deprecated از initAccountingSettingsFromApi استفاده کنید */
|
|
export async function initTahesabSettingFromApi(): Promise<boolean> {
|
|
await initAccountingSettingsFromApi()
|
|
return tahesabEnabledFromSettings === true
|
|
}
|
|
|
|
/** @deprecated از initAccountingSettingsFromApi استفاده کنید */
|
|
export async function initPargarSettingFromApi(): Promise<boolean> {
|
|
await initAccountingSettingsFromApi()
|
|
return pargarEnabledFromSettings === true
|
|
}
|