Files
boursecu_admin/src/utils/productEditorPrice.ts
T
2026-06-11 21:25:43 +03:30

160 lines
5.2 KiB
TypeScript

import type { last } from '@/model/price'
import type { MethodePrices } from '@/model/product'
import type { MeltedPriceSource } from '@/utils/productCategories'
import { isMeltedTradeGroup } from '@/utils/productCategories'
const GOLD_DOT_REFERENCE_NAME = 'گلد دات ای از آبشده - رسمی - نقد فردا'
export function findMethodPriceEntry(
prices: MethodePrices[],
readingMethod?: string | null
): MethodePrices | undefined {
if (!readingMethod) return undefined
return prices.find(
(entry) =>
entry.key === readingMethod ||
entry.id === readingMethod ||
entry.name === readingMethod
)
}
export function normalizeReferenceBase(entry: MethodePrices): { base: number; profit: number } {
let base = Number(entry.price) || 0
const profit = Number(entry.profit) || 0
if (entry.name === GOLD_DOT_REFERENCE_NAME) {
base = base / 4.3318
}
return { base, profit }
}
export function adjustedProductPrice(
basePrice: number,
baseProfit: number,
offsetPercent: number
): number {
const reference = basePrice + baseProfit
return Math.round(reference * (1 + (Number(offsetPercent) || 0) / 100))
}
export function resolveAppBasePrice(lastPrice?: Partial<last> & { price?: number } | null): number {
if (!lastPrice) return 0
const rawPrice = Number(lastPrice.price)
if (rawPrice > 0) return rawPrice
const buy = Number(lastPrice.buy) || 0
const sell = Number(lastPrice.sell) || 0
if (buy > 0 && sell > 0) return Math.round((buy + sell) / 2)
return Number(lastPrice.price_last) || 0
}
export type ProductEditorPricePreview =
| { status: 'ready'; amount: number; source: string }
| { status: 'empty'; message: string }
function resolveStoredFallbackPrice(
storedPrice: number | null | undefined,
useLastPriceIfZero: boolean | undefined
): number {
if (!useLastPriceIfZero) {
return 0
}
return Number(storedPrice) || 0
}
export function computeProductEditorPricePreview(input: {
form: {
group_type?: string
price?: number | null
reading_method?: string | null
price_offset_percent?: number | null
use_last_price_if_zero?: boolean | null
}
methodOption: string
meltedPriceOption: MeltedPriceSource
pricesData: MethodePrices[]
appLastPrice?: (Partial<last> & { price?: number }) | null
}): ProductEditorPricePreview {
const offsetPercent = Number(input.form.price_offset_percent ?? 0)
const melted = isMeltedTradeGroup(input.form.group_type)
if (melted) {
if (input.meltedPriceOption === 'fixed') {
const amount = Number(input.form.price) || 0
return amount > 0
? { status: 'ready', amount, source: 'قیمت ثابت' }
: { status: 'empty', message: 'قیمت ثابت را وارد کنید' }
}
if (input.meltedPriceOption === 'app') {
const base = resolveAppBasePrice(input.appLastPrice)
if (base > 0) {
return {
status: 'ready',
amount: adjustedProductPrice(base, 0, offsetPercent),
source: 'قیمت صفحه اصلی اپ'
}
}
const fallback = resolveStoredFallbackPrice(
input.form.price,
input.form.use_last_price_if_zero ?? false
)
return fallback > 0
? { status: 'ready', amount: fallback, source: 'آخرین قیمت ذخیره‌شده' }
: { status: 'empty', message: 'قیمت provider صفر است' }
}
if (!input.form.reading_method) {
return { status: 'empty', message: 'مرجع قیمت را انتخاب کنید' }
}
const entry = findMethodPriceEntry(input.pricesData, input.form.reading_method)
if (!entry) {
return { status: 'empty', message: '' }
}
const { base, profit } = normalizeReferenceBase(entry)
const liveAmount = adjustedProductPrice(base, profit, offsetPercent)
if (liveAmount > 0) {
return { status: 'ready', amount: liveAmount, source: entry.name }
}
const fallback = resolveStoredFallbackPrice(
input.form.price,
input.form.use_last_price_if_zero ?? false
)
return fallback > 0
? { status: 'ready', amount: fallback, source: 'آخرین قیمت ذخیره‌شده' }
: { status: 'empty', message: 'قیمت provider صفر است' }
}
if (input.methodOption === '1') {
const amount = Number(input.form.price) || 0
return amount > 0
? { status: 'ready', amount, source: 'قیمت دستی' }
: { status: 'empty', message: 'قیمت وسط را وارد کنید' }
}
if (!input.form.reading_method) {
return { status: 'empty', message: 'مرجع قیمت را انتخاب کنید' }
}
const entry = findMethodPriceEntry(input.pricesData, input.form.reading_method)
if (!entry) {
return { status: 'empty', message: '' }
}
const { base, profit } = normalizeReferenceBase(entry)
const liveAmount = adjustedProductPrice(base, profit, offsetPercent)
if (liveAmount > 0) {
return { status: 'ready', amount: liveAmount, source: entry.name }
}
const fallback = resolveStoredFallbackPrice(
input.form.price,
input.form.use_last_price_if_zero ?? false
)
return fallback > 0
? { status: 'ready', amount: fallback, source: 'آخرین قیمت ذخیره‌شده' }
: { status: 'empty', message: 'قیمت provider صفر است' }
}