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-14 10:08:46 +03:30
|
|
|
|
export function resolvePriceOffsetRatio(offsetPercent?: number | null) {
|
2026-06-09 21:04:22 +03:30
|
|
|
|
const offset = Number(offsetPercent ?? 0)
|
|
|
|
|
|
if (!offset) {
|
2026-06-14 10:08:46 +03:30
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-14 10:08:46 +03:30
|
|
|
|
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-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-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'
|