Files
boursecu_user/src/utils/productPrice.ts
T

183 lines
5.1 KiB
TypeScript
Raw Normal View History

2026-05-23 13:27:30 +03:30
import type { Product } from '@/models/products'
2026-06-06 15:48:27 +03:30
import { getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@/utils/price'
2026-06-17 16:03:19 +03:30
import { isMetalCommodityGroup, isMeltedProductUsingAppPrice, isMeltedTradeGroup, usesQuantityTrade } from '@/utils/productCategories'
import { productPriceAmountFactor } from '@/utils/productDealMethod'
2026-06-09 21:04:22 +03:30
2026-06-11 21:49:46 +03:30
function productUsesLastPriceIfZero(product: Product): boolean {
return Boolean(product.use_last_price_if_zero)
}
2026-06-22 21:10:25 +03:30
function hasReferenceReadingMethod(product: Product): boolean {
return Boolean(product.reading_method)
}
/** قیمت پایه محصولات با reading_method — بدون fallback وقتی تیک «قیمت صفر از مرجع» خاموش است */
function getReferenceProductBaseBuyPrice(product: Product): number {
const storedUnit = Number(product.price ?? 0)
const useLast = productUsesLastPriceIfZero(product)
if (!useLast) {
return storedUnit > 0 ? storedUnit : 0
}
return storedUnit
}
export function resolvePriceOffsetRatio(offsetPercent?: number | null) {
2026-06-09 21:04:22 +03:30
const offset = Number(offsetPercent ?? 0)
if (!offset) {
return 0
}
// 5 => 5% ، 0.05 => 5% (اعشاری)
if (Math.abs(offset) > 0 && Math.abs(offset) < 1) {
return offset
}
return offset / 100
}
export function applyPriceOffsetPercent(basePrice: number, offsetPercent?: number | null) {
const ratio = resolvePriceOffsetRatio(offsetPercent)
if (!ratio) {
2026-06-09 21:04:22 +03:30
return basePrice
}
return Math.round(basePrice * (1 + ratio))
}
/** boursecu chart: قیمت + (قیمت × offset) */
export function applyChartPriceOffset(basePrice: number, offsetPercent?: number | null) {
const ratio = resolvePriceOffsetRatio(offsetPercent)
if (!ratio) {
return basePrice
}
return Math.round(basePrice + basePrice * ratio)
2026-06-09 21:04:22 +03:30
}
2026-05-23 13:27:30 +03:30
2026-06-11 21:21:15 +03:30
/** قیمت پایه بدون کارمزد — اگر صفر باشد نباید فقط cash_fee به‌عنوان قیمت نمایش داده شود */
export function getProductBaseBuyPrice(product: Product): number {
2026-06-09 21:04:22 +03:30
if (isMeltedProductUsingAppPrice(product)) {
2026-06-11 21:49:46 +03:30
const apiPrice = Number(product.price ?? 0)
const useLast = productUsesLastPriceIfZero(product)
if (!useLast) {
const liveBuy = getTradeBuyPrice(lastPrice.value)
if (liveBuy > 0) {
return applyPriceOffsetPercent(liveBuy, product.price_offset_percent)
}
return 0
2026-06-11 21:21:15 +03:30
}
2026-06-11 21:49:46 +03:30
if (apiPrice > 0) {
return apiPrice
}
const liveBuy = getTradeBuyPrice(lastPrice.value)
if (liveBuy > 0) {
return applyPriceOffsetPercent(liveBuy, product.price_offset_percent)
}
return 0
2026-05-23 13:27:30 +03:30
}
2026-06-09 21:04:22 +03:30
if (isMeltedTradeGroup(product.group_type)) {
2026-06-11 21:21:15 +03:30
return Number(product.price ?? 0)
2026-06-09 21:04:22 +03:30
}
if (isMetalCommodityGroup(product.group_type)) {
2026-06-11 21:21:15 +03:30
return Number(product.price_profit ?? 0) + Number(product.price ?? 0)
2026-05-23 13:27:30 +03:30
}
2026-06-22 21:10:25 +03:30
if (hasReferenceReadingMethod(product)) {
return getReferenceProductBaseBuyPrice(product)
}
2026-06-11 21:21:15 +03:30
return Number(product.price ?? 0)
2026-05-23 13:27:30 +03:30
}
2026-06-11 21:21:15 +03:30
/** قیمت خرید نمایشی محصول (همان مقداری که در لیست و اکشن‌شیت نشان داده می‌شود) */
export function getProductBuyPrice(product: Product): number {
const base = getProductBaseBuyPrice(product)
if (base <= 0) {
return 0
}
const fee = Number(product.cash_fee_buy ?? 0)
if (
isMeltedProductUsingAppPrice(product)
|| isMeltedTradeGroup(product.group_type)
|| isMetalCommodityGroup(product.group_type)
2026-06-17 16:03:19 +03:30
|| usesQuantityTrade(product)
2026-06-11 21:21:15 +03:30
) {
return base + fee
}
const withFee = base + fee
return product.direct_price === 0
2026-06-17 16:03:19 +03:30
? withFee * productPriceAmountFactor(product)
2026-06-11 21:21:15 +03:30
: withFee
}
function getProductBaseSellPrice(product: Product): number {
2026-06-09 21:04:22 +03:30
if (isMeltedProductUsingAppPrice(product)) {
2026-06-11 21:49:46 +03:30
const apiPrice = Number(product.price ?? 0)
const useLast = productUsesLastPriceIfZero(product)
if (!useLast) {
const liveSell = getTradeSellPrice(lastPrice.value)
if (liveSell > 0) {
return applyPriceOffsetPercent(liveSell, product.price_offset_percent)
}
return 0
2026-06-11 21:21:15 +03:30
}
2026-06-11 21:49:46 +03:30
if (apiPrice > 0) {
return apiPrice
}
const liveSell = getTradeSellPrice(lastPrice.value)
if (liveSell > 0) {
return applyPriceOffsetPercent(liveSell, product.price_offset_percent)
}
return 0
2026-06-06 15:48:27 +03:30
}
2026-06-09 21:04:22 +03:30
if (isMeltedTradeGroup(product.group_type)) {
2026-06-11 21:21:15 +03:30
return Number(product.price ?? 0)
2026-06-09 21:04:22 +03:30
}
2026-06-06 15:48:27 +03:30
return getTradeSellPrice(lastPrice.value)
}
2026-06-11 21:21:15 +03:30
/** قیمت فروش نمایشی محصول آبشده‌ای */
export function getProductSellPrice(product: Product): number {
const base = getProductBaseSellPrice(product)
if (base <= 0) {
return 0
}
2026-06-17 16:03:19 +03:30
if (isMeltedProductUsingAppPrice(product) || isMeltedTradeGroup(product.group_type) || usesQuantityTrade(product)) {
2026-06-11 21:21:15 +03:30
return base - Number(product.cash_fee_sell ?? 0)
}
return base
}
2026-05-23 13:27:30 +03:30
export function isProductPriceInactive(product: Product): boolean {
2026-06-22 21:10:25 +03:30
if (
hasReferenceReadingMethod(product)
&& !productUsesLastPriceIfZero(product)
&& product.reference_provider_active === false
) {
return true
}
2026-06-11 21:21:15 +03:30
return getProductBaseBuyPrice(product) <= 0
2026-05-23 13:27:30 +03:30
}
2026-06-09 21:04:22 +03:30
export { isMeltedTradeGroup, isMeltedProductUsingAppPrice } from '@/utils/productCategories'