import { ref } from 'vue' import { getSettings } from '@/api/configuration' export const serviceFeePercentage = ref(0.01) /** true = مبالغ رند: فروش → ریال دقیق (کارمزد از طلا)؛ خرید → وزن دقیق (کارمزد از ریال) */ export const feeDeductFromGold = ref(false) /** آخرین فیلدی که کاربر مستقیم ویرایش کرده — مبنای به‌روزرسانی هنگام تغییر قیمت */ export type TradeInputLock = 'gram' | 'rial' | null function feeRate() { return Number(serviceFeePercentage.value) } export async function loadServiceFeeFromSettings() { try { const settings = await getSettings() if (settings && Array.isArray(settings)) { const feeSetting = settings.find( (s) => s?.key === 'fee_service_charge_percentage' && s?.is_active === true ) if (feeSetting?.value !== undefined && feeSetting?.value !== null) { serviceFeePercentage.value = Number(feeSetting.value) } const feeModeSetting = settings.find( (s) => s?.key === 'fee_deduct_from_gold' && s?.is_active === true ) if (feeModeSetting?.value !== undefined && feeModeSetting?.value !== null) { const raw = String(feeModeSetting.value).trim().toLowerCase() feeDeductFromGold.value = raw === 'true' || raw === '1' } else { feeDeductFromGold.value = false } } } catch (e) { console.log(e) } } export function calcFeeInGrams(goldValue?: number | null) { return parseFloat(((goldValue ?? 0) * Number(serviceFeePercentage.value)).toFixed(4)) } /** گرم معادل برای دریافت دقیق مبلغ ریالی در فروش */ export function calcGoldAmountFromTargetRial(rialAmount: number, unitPriceRial: number) { if (!rialAmount || !unitPriceRial) return 0 return parseFloat((rialAmount / unitPriceRial).toFixed(6)) } /** وقتی کاربر گرم را قفل کرده — ریال نمایشی/قابل پرداخت از همان گرم */ export function calcRialFromLockedGram(displayGram: number, unitPriceRial: number, isBuy: boolean) { const grams = Number(displayGram) const unit = Number(unitPriceRial) if (!grams || !unit) return 0 const fee = feeRate() if (isBuy) { if (feeDeductFromGold.value) { return Math.round(grams * unit * (1 + fee)) } return Math.round(grams * unit) } if (feeDeductFromGold.value) { return Math.round(grams * unit) } return Math.round(grams * unit * (1 - fee)) } /** وقتی کاربر ریال را قفل کرده — گرم نمایشی از همان مبلغ */ export function calcGramFromLockedRial(rialAmount: number, unitPriceRial: number, isBuy: boolean) { const rial = Number(rialAmount) const unit = Number(unitPriceRial) if (!rial || !unit) return 0 const fee = feeRate() if (isBuy) { if (feeDeductFromGold.value) { return parseFloat((rial / (unit * (1 + fee))).toFixed(6)) } const grossGrams = rial / unit return parseFloat((grossGrams * (1 - fee)).toFixed(6)) } if (feeDeductFromGold.value) { return parseFloat((rial / unit).toFixed(6)) } return parseFloat((rial / (unit * (1 - fee))).toFixed(6)) } /** مبلغ نهایی قابل پرداخت (خرید) یا دریافت (فروش) به ریال */ export function calcPayablePriceRial( finalPriceRial: number, feeInRial: number, isBuy: boolean, targetRialCash?: number | null ) { if (feeDeductFromGold.value) { if (isBuy) return finalPriceRial + feeInRial if (targetRialCash != null && Number(targetRialCash) > 0) return Number(targetRialCash) return finalPriceRial } return isBuy ? finalPriceRial : Math.max(0, finalPriceRial - feeInRial) } /** وزن ارسالی به سرور */ export function calcOrderGoldAmount( goldValue?: number | null, goldCash?: number | null, unitPriceRial?: number, isBuy?: boolean, inputLock?: TradeInputLock ) { const gold = Number(goldValue ?? 0) const cash = Number(goldCash ?? 0) const unit = Number(unitPriceRial ?? 0) if (isBuy && inputLock === 'rial' && !feeDeductFromGold.value && cash > 0 && unit > 0) { return parseFloat((cash / unit).toFixed(6)) } if (!isBuy && feeDeductFromGold.value) { if (inputLock === 'rial' && cash > 0 && unit > 0) { return calcGoldAmountFromTargetRial(cash, unit) } if (inputLock !== 'rial') { return parseFloat(gold.toFixed(6)) } const targetCash = calcSellTargetCash(goldCash, goldValue, unitPriceRial, inputLock) if (targetCash != null && unit > 0) { return calcGoldAmountFromTargetRial(targetCash, unit) } } return parseFloat(gold.toFixed(6)) } /** مبلغ ریالی دقیق دریافتی در فروش (فقط وقتی کاربر با ریال وارد کرده) */ export function calcSellTargetCash( goldCash?: number | null, goldValue?: number | null, unitPriceRial?: number, inputLock?: TradeInputLock ) { if (!feeDeductFromGold.value) return undefined if (inputLock === 'gram') return undefined const cash = Number(goldCash ?? 0) if (cash <= 0) return undefined if (inputLock === 'rial') return Math.round(cash) const gold = Number(goldValue ?? 0) const unit = Number(unitPriceRial ?? 0) if (gold > 0 && unit > 0) { const derived = Math.round(gold * unit) if (Math.abs(derived - Math.round(cash)) <= 1) return undefined } return Math.round(cash) } /** کل طلای کسرشونده از کیف در فروش (شامل کارمزد وقتی fee_deduct_from_gold روشن است) */ export function calcSellGoldDebit(goldValue?: number | null, feeInGrams?: number | null) { const gold = Number(goldValue ?? 0) const fee = Number(feeInGrams ?? 0) if (feeDeductFromGold.value) { return parseFloat((gold + fee).toFixed(4)) } return gold }