diff --git a/src/models/products.ts b/src/models/products.ts index 4268cdb..70c5aac 100644 --- a/src/models/products.ts +++ b/src/models/products.ts @@ -20,6 +20,8 @@ export interface Product { percent_fee_sell: number | undefined cash_fee_buy: number | undefined cash_fee_sell: number | undefined + cash_fee_buy_is_percent?: boolean + cash_fee_sell_is_percent?: boolean order_limit_enabled?: boolean min_order_cash?: number | null max_order_cash?: number | null @@ -56,6 +58,8 @@ export interface PInventory { percent_fee_sell: number cash_fee_buy: number cash_fee_sell: number + cash_fee_buy_is_percent?: boolean + cash_fee_sell_is_percent?: boolean reading_method: any created_at: any updated_at: any diff --git a/src/utils/productCashFee.ts b/src/utils/productCashFee.ts new file mode 100644 index 0000000..4ea68b2 --- /dev/null +++ b/src/utils/productCashFee.ts @@ -0,0 +1,74 @@ +export type ProductCashFeeSource = { + cash_fee_buy?: number | null + cash_fee_sell?: number | null + cash_fee_buy_is_percent?: boolean | null + cash_fee_sell_is_percent?: boolean | null +} + +/** 5 => 5% ، 0.05 => 5% (اعشاری) */ +export function resolveFeePercentRatio(percentValue?: number | null) { + const offset = Number(percentValue ?? 0) + if (!offset) { + return 0 + } + + if (Math.abs(offset) > 0 && Math.abs(offset) < 1) { + return offset + } + + return offset / 100 +} + +export function resolveProductCashFeeRial( + feeValue: number | null | undefined, + isPercent: boolean | null | undefined, + basePriceRial: number, +) { + const raw = Number(feeValue ?? 0) + if (!raw || !Number.isFinite(raw)) { + return 0 + } + + if (!isPercent) { + return Math.round(raw) + } + + const base = Number(basePriceRial) + if (!base || base <= 0) { + return 0 + } + + return Math.round(Math.abs(base * resolveFeePercentRatio(raw))) +} + +export function resolveProductCashFeeBuyRial(product: ProductCashFeeSource, basePriceRial: number) { + return resolveProductCashFeeRial( + product.cash_fee_buy, + product.cash_fee_buy_is_percent, + basePriceRial, + ) +} + +export function resolveProductCashFeeSellRial(product: ProductCashFeeSource, basePriceRial: number) { + return resolveProductCashFeeRial( + product.cash_fee_sell, + product.cash_fee_sell_is_percent, + basePriceRial, + ) +} + +export function formatProductCashFeeLabel( + feeValue: number | null | undefined, + isPercent?: boolean | null, +) { + const raw = Number(feeValue ?? 0) + if (!raw) { + return '۰' + } + + if (isPercent) { + return `${raw}%` + } + + return `${raw} ریال` +} diff --git a/src/utils/productDealMethod.ts b/src/utils/productDealMethod.ts index cf94163..6b63381 100644 --- a/src/utils/productDealMethod.ts +++ b/src/utils/productDealMethod.ts @@ -13,6 +13,7 @@ import { usesQuantityTrade, } from '@/utils/productCategories' import { formatInventoryCardValue } from '@/utils/productAssets' +import { resolveProductCashFeeBuyRial, resolveProductCashFeeSellRial } from '@/utils/productCashFee' import { TRADE_GRAM_DISPLAY_DECIMALS } from '@/utils/serviceFee' import { formatGoldAmount } from '@/utils/usePrice' @@ -371,7 +372,7 @@ export function resolveProductTradeBuyUnitPrice(product?: Product | null) { return 0 } - const basePrice = (product.price ?? 0) + (product.cash_fee_buy ?? 0) + const basePrice = (product.price ?? 0) + resolveProductCashFeeBuyRial(product, product.price ?? 0) return basePrice * productPriceAmountFactor(product) } @@ -380,7 +381,7 @@ export function resolveProductTradeSellUnitPrice(product?: Product | null) { return 0 } - const basePrice = (product.price ?? 0) - (product.cash_fee_sell ?? 0) + const basePrice = (product.price ?? 0) - resolveProductCashFeeSellRial(product, product.price ?? 0) return basePrice * productPriceAmountFactor(product) } diff --git a/src/utils/productPrice.ts b/src/utils/productPrice.ts index e6fff34..1f23284 100644 --- a/src/utils/productPrice.ts +++ b/src/utils/productPrice.ts @@ -1,5 +1,6 @@ import type { Product } from '@/models/products' import { getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@/utils/price' +import { resolveProductCashFeeBuyRial, resolveProductCashFeeSellRial } from '@/utils/productCashFee' import { isMetalCommodityGroup, isMeltedProductUsingAppPrice, isMeltedTradeGroup, usesQuantityTrade } from '@/utils/productCategories' import { productPriceAmountFactor } from '@/utils/productDealMethod' @@ -104,7 +105,7 @@ export function getProductBuyPrice(product: Product): number { return 0 } - const fee = Number(product.cash_fee_buy ?? 0) + const fee = resolveProductCashFeeBuyRial(product, base) if ( isMeltedProductUsingAppPrice(product) @@ -159,7 +160,7 @@ export function getProductSellPrice(product: Product): number { } if (isMeltedProductUsingAppPrice(product) || isMeltedTradeGroup(product.group_type) || usesQuantityTrade(product)) { - return base - Number(product.cash_fee_sell ?? 0) + return base - resolveProductCashFeeSellRial(product, base) } return base diff --git a/src/views/base/copper&silver/index.vue b/src/views/base/copper&silver/index.vue index b93b501..484f24b 100644 --- a/src/views/base/copper&silver/index.vue +++ b/src/views/base/copper&silver/index.vue @@ -232,6 +232,7 @@ import type { Product } from '@/models/products' import { useFundUserStore } from '@/store/fundStore' import {useConfigStore} from "@/store/configStore"; import { calcFeeInGrams, calcPayablePriceRial, calcSellGoldDebit, feeDeductFromGold, loadServiceFeeFromSettings } from '@/utils/serviceFee' +import { resolveProductCashFeeBuyRial, resolveProductCashFeeSellRial } from '@/utils/productCashFee' import { formatCashWalletBalanceText, formatGoldWalletBalanceText } from '@/utils/productDealMethod' import { getCashWalletBalance } from '@/utils/productAssets' import { isStoreClosed, getStoreClosedMessage } from '@/utils/storeHours' @@ -283,13 +284,12 @@ const basePriceValue = computed(() => { const product = props?.ProductItem if (!product) return undefined - const { price_profit = 0, price = 0, cash_fee_buy = 0, cash_fee_sell = 0 } = product + const { price_profit = 0, price = 0 } = product const base = price_profit + price + const buyFee = resolveProductCashFeeBuyRial(product, base) + const sellFee = resolveProductCashFeeSellRial(product, base) - const rawPrice = isBuy.value - ? base + cash_fee_buy - : base - cash_fee_sell - return rawPrice + return isBuy.value ? base + buyFee : base - sellFee }) const finalPrice = computed(() => { @@ -299,15 +299,17 @@ const finalPrice = computed(() => { const product = props?.ProductItem if (!product) return 0 - const { price_profit = 0, price = 0, cash_fee_buy = 0, cash_fee_sell = 0 } = product + const { price_profit = 0, price = 0 } = product const base = price_profit + price + const buyFee = resolveProductCashFeeBuyRial(product, base) + const sellFee = resolveProductCashFeeSellRial(product, base) if (isBuy.value) { - return gold * (base + cash_fee_buy) - } else { - return gold * (base - cash_fee_sell) + return gold * (base + buyFee) } + + return gold * (base - sellFee) }) const payablePrice = computed(() => @@ -533,20 +535,30 @@ watch( } ) +function productFeeBase(product?: Product) { + return (product?.price_profit ?? 0) + (product?.price ?? 0) +} + function calculateCash(val: number) { priceErrorVisible.value = false if (!lastPrice.value) return + const product = props?.ProductItem + if (!product) return + + const base = productFeeBase(product) + const buyFee = resolveProductCashFeeBuyRial(product, base) + const sellFee = resolveProductCashFeeSellRial(product, base) const tradeBuy = getTradeBuyPrice(lastPrice.value) - form.value.goldVazn = parseFloat((val * ((props?.ProductItem?.price) + (props?.ProductItem?.cash_fee_buy))) / tradeBuy).toFixed(1) + form.value.goldVazn = parseFloat(String((val * (base + buyFee)) / tradeBuy)).toFixed(1) if (isBuy.value) { form.value.goldCash = val - ? parseFloat(String(val * ((props?.ProductItem?.price) + (props?.ProductItem?.cash_fee_buy)))) + ? parseFloat(String(val * (base + buyFee))) : 0 if (!val) form.value.goldVazn = 0 } else { form.value.goldCash = val - ? parseFloat(String((val * props?.ProductItem?.price) - (props?.ProductItem?.cash_fee_sell))) + ? parseFloat(String(val * base - sellFee)) : 0 if (!val) form.value.goldVazn = 0 } @@ -554,9 +566,16 @@ function calculateCash(val: number) { function calculateGold(val: number) { if (price.value) { + const product = props?.ProductItem + if (!product) return + + const base = productFeeBase(product) + const buyFee = resolveProductCashFeeBuyRial(product, base) + const sellFee = resolveProductCashFeeSellRial(product, base) + if (isBuy.value) { if (val) { - form.value.goldValue = toFixedDownThreeChar(parseFloat(val / (((props?.ProductItem?.price_profit) + (props?.ProductItem?.price)) + (props?.ProductItem?.cash_fee_buy)))) + form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / (base + buyFee)))) if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false } @@ -571,7 +590,7 @@ function calculateGold(val: number) { } else { if (val) { - form.value.goldValue = toFixedDownThreeChar(parseFloat(val / (((props?.ProductItem?.price_profit) + (props?.ProductItem?.price)) + (props?.ProductItem?.cash_fee_sell)))) + form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / (base - sellFee)))) if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false } else if (val.toString() === '') { diff --git a/src/views/base/products/components/DealProduct.vue b/src/views/base/products/components/DealProduct.vue index a7ee1df..2470a65 100644 --- a/src/views/base/products/components/DealProduct.vue +++ b/src/views/base/products/components/DealProduct.vue @@ -281,6 +281,7 @@ import type { TableEngineInput, TableOutput } from '@/models/table' import { getTransactionTable } from '@/api/transaction' import { getLastPrices, getTradeBuyPrice, getTradeSellPrice, lastPrice, setIntervalGetAllPrice, stopPriceInterval } from '@/utils/price' import { getProductBuyPrice, getProductSellPrice, isProductPriceInactive } from '@/utils/productPrice' +import { resolveProductCashFeeBuyRial, resolveProductCashFeeSellRial } from '@/utils/productCashFee' import { Product } from '@/models/products' import BasicSelect from '@/components/BasicPacks/BasicSelect.vue' import Bg_main from '@/components/bg_main.vue' @@ -402,22 +403,9 @@ interface Prop { const props = withDefaults(defineProps(), {}) const emit = defineEmits<{ ordered: [] }>() const isBuy = ref(true) -const buyTotalPrice = computed(() => { - const item = props?.ProductItem - if (!item) return 0 - const basePrice = (item.price ?? 0) + (item.cash_fee_buy ?? 0) +const buyTotalPrice = computed(() => resolveProductTradeBuyUnitPrice(props?.ProductItem)) - return basePrice * productPriceAmountFactor(item) -}) - -const sellTotalPrice = computed(() => { - const item = props?.ProductItem - if (!item) return 0 - - const basePrice = (item.price ?? 0) - (item.cash_fee_sell ?? 0) - - return basePrice * productPriceAmountFactor(item) -}) +const sellTotalPrice = computed(() => resolveProductTradeSellUnitPrice(props?.ProductItem)) const buyFee = computed(() => ((props?.ProductItem?.amount * (props?.ProductItem?.percent_fee_buy ?? 0) * (props?.ProductItem?.price ?? 0)).toFixed(0))) const sellFee = computed(() => ((props?.ProductItem?.amount * (props?.ProductItem?.percent_fee_sell ?? 0) * (props?.ProductItem?.sellPrice ?? 0)).toFixed(0))) @@ -738,7 +726,8 @@ function calculateCash(val: number) { // form.value.goldVazn = parseFloat((val * (( props?.ProductItem?.price) + (props?.ProductItem?.cash_fee_buy)))/lastPrice.value?.buy).toFixed(2) if (isBuy.value) { if (val){ - const unitPrice = (props?.ProductItem?.price ?? 0) + (props?.ProductItem?.cash_fee_buy ?? 0) + const base = props?.ProductItem?.price ?? 0 + const unitPrice = base + resolveProductCashFeeBuyRial(props?.ProductItem, base) form.value.goldCash = parseFloat(String(val * unitPrice * productPriceAmountFactor(props?.ProductItem))).toFixed(0) } else { @@ -748,7 +737,8 @@ function calculateCash(val: number) { } else { if (val){ - const unitPrice = (props?.ProductItem?.price ?? 0) - (props?.ProductItem?.cash_fee_sell ?? 0) + const base = props?.ProductItem?.price ?? 0 + const unitPrice = base - resolveProductCashFeeSellRial(props?.ProductItem, base) form.value.goldCash = parseFloat(String(val * unitPrice * productPriceAmountFactor(props?.ProductItem))).toFixed(0) } else{ @@ -839,8 +829,11 @@ async function initPrice() { await getLastPrices() // await setIntervalGetPrice() loading.value = true - props.ProductItem.price = lastPrice?.value?.price? (lastPrice?.value?.price + props.ProductItem?.cash_fee_buy) * props.ProductItem?.amount: 0 - props.ProductItem.sellPrice = lastPrice?.value?.price? (lastPrice?.value?.price - props.ProductItem?.percent_fee_sell) * props.ProductItem?.amount:0 + const livePrice = lastPrice?.value?.price ?? 0 + const buyFee = resolveProductCashFeeBuyRial(props.ProductItem, livePrice) + const sellFee = resolveProductCashFeeSellRial(props.ProductItem, livePrice) + props.ProductItem.price = livePrice ? (livePrice + buyFee) * props.ProductItem.amount : 0 + props.ProductItem.sellPrice = livePrice ? (livePrice - sellFee) * props.ProductItem.amount : 0 } catch (e) { console.log(e) } finally {