price handling
This commit is contained in:
@@ -26,6 +26,7 @@ export interface Product {
|
|||||||
direct_price: number | undefined
|
direct_price: number | undefined
|
||||||
price_offset_percent?: number | null
|
price_offset_percent?: number | null
|
||||||
use_last_price_if_zero?: boolean
|
use_last_price_if_zero?: boolean
|
||||||
|
reference_provider_active?: boolean
|
||||||
trade_by_quantity?: boolean
|
trade_by_quantity?: boolean
|
||||||
reading_method: any
|
reading_method: any
|
||||||
created_at: any
|
created_at: any
|
||||||
|
|||||||
+12
-3
@@ -151,6 +151,7 @@ let amountP =0
|
|||||||
let isBuyP=true
|
let isBuyP=true
|
||||||
let NumP=0
|
let NumP=0
|
||||||
let groupTypeP: string | undefined
|
let groupTypeP: string | undefined
|
||||||
|
let meltedBalanceP = 0
|
||||||
const checkNumber = async (_rule: Rule, value: number) => {
|
const checkNumber = async (_rule: Rule, value: number) => {
|
||||||
|
|
||||||
|
|
||||||
@@ -165,12 +166,12 @@ if (isBuyP){
|
|||||||
if (!availableCash && isCashLikeDealMethod(methodP)){
|
if (!availableCash && isCashLikeDealMethod(methodP)){
|
||||||
return Promise.reject(getInsufficientCashWalletMessage(groupTypeP))
|
return Promise.reject(getInsufficientCashWalletMessage(groupTypeP))
|
||||||
}
|
}
|
||||||
if (!walletCash?.walletInfo?.gold && isMainMetalWalletDealMethod(methodP)){
|
if (!meltedBalanceP && isMainMetalWalletDealMethod(methodP)){
|
||||||
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP))
|
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP))
|
||||||
}
|
}
|
||||||
if (priceP * value > availableCash && isCashLikeDealMethod(methodP))
|
if (priceP * value > availableCash && isCashLikeDealMethod(methodP))
|
||||||
return Promise.reject(getInsufficientCashWalletMessage(groupTypeP))
|
return Promise.reject(getInsufficientCashWalletMessage(groupTypeP))
|
||||||
if (amountP * value > walletCash?.walletInfo?.gold && isMainMetalWalletDealMethod(methodP))
|
if (amountP * value > meltedBalanceP && isMainMetalWalletDealMethod(methodP))
|
||||||
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP))
|
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP))
|
||||||
else
|
else
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
@@ -182,12 +183,20 @@ if (isBuyP){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const justNumber2 = (price: number, method?: string , amount?:number ,isBuy?:boolean, groupType?: string) => {
|
export const justNumber2 = (
|
||||||
|
price: number,
|
||||||
|
method?: string,
|
||||||
|
amount?: number,
|
||||||
|
isBuy?: boolean,
|
||||||
|
groupType?: string,
|
||||||
|
meltedBalance?: number,
|
||||||
|
) => {
|
||||||
priceP = price
|
priceP = price
|
||||||
methodP = method
|
methodP = method
|
||||||
amountP=amount
|
amountP=amount
|
||||||
isBuyP=isBuy
|
isBuyP=isBuy
|
||||||
groupTypeP = groupType
|
groupTypeP = groupType
|
||||||
|
meltedBalanceP = meltedBalance ?? 0
|
||||||
return {
|
return {
|
||||||
required: true,
|
required: true,
|
||||||
validator: checkNumber,
|
validator: checkNumber,
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ export function formatMetalAssetsInfoText(metal: WalletMetalTotal): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatRialNumber(value: number): string {
|
function formatRialNumber(value: number): string {
|
||||||
return usePriceWithoutType(Math.round(value))
|
return usePriceWithoutType(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** متن توضیح مودال دارایی ریالی */
|
/** متن توضیح مودال دارایی ریالی */
|
||||||
|
|||||||
+208
-22
@@ -1,4 +1,6 @@
|
|||||||
import type { SelectItem } from '@/models/SelectItem'
|
import type { SelectItem } from '@/models/SelectItem'
|
||||||
|
import type { Product } from '@/models/products'
|
||||||
|
import type { WalletInventoryCard } from '@/models/walletAssets'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
import { isBoursecuProject } from '@/utils/config'
|
||||||
import { useSettingsStore } from '@/store/settingsStore'
|
import { useSettingsStore } from '@/store/settingsStore'
|
||||||
import {
|
import {
|
||||||
@@ -8,7 +10,9 @@ import {
|
|||||||
LEGACY_GROUP_MAFTOL,
|
LEGACY_GROUP_MAFTOL,
|
||||||
normalizeProductGroupType,
|
normalizeProductGroupType,
|
||||||
PRODUCT_CATEGORY_ABSHODE,
|
PRODUCT_CATEGORY_ABSHODE,
|
||||||
|
usesQuantityTrade,
|
||||||
} from '@/utils/productCategories'
|
} from '@/utils/productCategories'
|
||||||
|
import { formatInventoryCardValue } from '@/utils/productAssets'
|
||||||
|
|
||||||
/** @deprecated از isMeltedTradeGroup استفاده کنید */
|
/** @deprecated از isMeltedTradeGroup استفاده کنید */
|
||||||
export const BOURSECU_GROUP_ABSHODE = PRODUCT_CATEGORY_ABSHODE
|
export const BOURSECU_GROUP_ABSHODE = PRODUCT_CATEGORY_ABSHODE
|
||||||
@@ -183,29 +187,190 @@ export function getProductQuantityUnit(product?: ProductUnitSource | null) {
|
|||||||
return getWeightUnit()
|
return getWeightUnit()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultTypeDealOptions(): SelectItem[] {
|
export const MELTED_DEAL_METHOD_PREFIX = 'gold:'
|
||||||
const settingsStore = useSettingsStore()
|
|
||||||
return [
|
export interface ProductDealMethodContext {
|
||||||
{ value: 'نقدی', key: 'cash' },
|
tradedProduct?: Product | null
|
||||||
{ value: settingsStore.metalTypeLabel, key: 'gold' },
|
productMetalId?: number | null
|
||||||
]
|
inventoryCards?: WalletInventoryCard[]
|
||||||
|
catalog?: Product[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProductDealMethodOptions(groupType?: string | null, isBuy = true): SelectItem[] {
|
/** سلکت نحوه معامله فقط وقتی محصول مورد معامله وزن دارد */
|
||||||
|
export function shouldShowProductDealMethodSelector(product?: Product | null) {
|
||||||
|
return hasProductUnitWeight(product)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shouldShowProductDealMethodSelect(
|
||||||
|
product?: Product | null,
|
||||||
|
options?: SelectItem[] | null,
|
||||||
|
) {
|
||||||
|
return shouldShowProductDealMethodSelector(product) && (options?.length ?? 0) > 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildMeltedDealMethodKey(productId: number) {
|
||||||
|
return `${MELTED_DEAL_METHOD_PREFIX}${productId}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseMeltedDealMethodProductId(method?: string | null): number | null {
|
||||||
|
if (!method?.startsWith(MELTED_DEAL_METHOD_PREFIX)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const productId = Number(method.slice(MELTED_DEAL_METHOD_PREFIX.length))
|
||||||
|
return productId > 0 ? productId : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMeltedProductDealMethod(method?: string | null) {
|
||||||
|
return parseMeltedDealMethodProductId(method) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQuantityTradeCatalogProduct(
|
||||||
|
product?: Product | null,
|
||||||
|
metalId?: number | null,
|
||||||
|
excludeProductId?: number | null,
|
||||||
|
) {
|
||||||
|
if (!product || !usesQuantityTrade(product)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludeProductId && Number(product.id) === Number(excludeProductId)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return Number(product.metal_id) === Number(metalId ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function findInventoryCardForProduct(
|
||||||
|
cards: WalletInventoryCard[],
|
||||||
|
productId?: number | null,
|
||||||
|
) {
|
||||||
|
if (!productId) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return cards.find((card) => Number(card.product_id) === Number(productId))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getQuantityTradePaymentDealOptions(
|
||||||
|
context?: ProductDealMethodContext | null,
|
||||||
|
isBuy = true,
|
||||||
|
): SelectItem[] {
|
||||||
|
const metalId = Number(context?.productMetalId ?? 0)
|
||||||
|
const catalog = context?.catalog ?? []
|
||||||
|
const cards = context?.inventoryCards ?? []
|
||||||
|
const tradedProductId = context?.tradedProduct?.id ?? null
|
||||||
|
|
||||||
|
if (!metalId || !catalog.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchingProducts = catalog.filter((product) =>
|
||||||
|
isQuantityTradeCatalogProduct(product, metalId, tradedProductId)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isBuy) {
|
||||||
|
const options: SelectItem[] = []
|
||||||
|
|
||||||
|
for (const product of matchingProducts) {
|
||||||
|
const card = findInventoryCardForProduct(cards, product.id)
|
||||||
|
if (!card || Number(card.quantity ?? 0) <= 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
key: buildMeltedDealMethodKey(product.id),
|
||||||
|
value: `${product.title} — ${formatInventoryCardValue(card)}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingProducts.map((product) => {
|
||||||
|
const card = findInventoryCardForProduct(cards, product.id)
|
||||||
|
const inventorySuffix = card ? ` — ${formatInventoryCardValue(card)}` : ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
key: buildMeltedDealMethodKey(product.id),
|
||||||
|
value: `دریافت ${product.title}${inventorySuffix}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated از getQuantityTradePaymentDealOptions استفاده کنید */
|
||||||
|
export function getMeltedPaymentDealOptions(
|
||||||
|
context?: ProductDealMethodContext | null,
|
||||||
|
isBuy = true,
|
||||||
|
) {
|
||||||
|
return getQuantityTradePaymentDealOptions(context, isBuy)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findMeltedDealMethodCard(
|
||||||
|
method?: string | null,
|
||||||
|
cards: WalletInventoryCard[] = [],
|
||||||
|
) {
|
||||||
|
return findInventoryCardForProduct(cards, parseMeltedDealMethodProductId(method))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findProductDealMethodProduct(
|
||||||
|
method?: string | null,
|
||||||
|
catalog: Product[] = [],
|
||||||
|
) {
|
||||||
|
const productId = parseMeltedDealMethodProductId(method)
|
||||||
|
if (!productId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return catalog.find((product) => Number(product.id) === productId) ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveProductTradeBuyUnitPrice(product?: Product | null) {
|
||||||
|
if (!product) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const basePrice = (product.price ?? 0) + (product.cash_fee_buy ?? 0)
|
||||||
|
return product.direct_price === 0
|
||||||
|
? basePrice * (product.amount ?? 0)
|
||||||
|
: basePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveProductTradeSellUnitPrice(product?: Product | null) {
|
||||||
|
if (!product) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const basePrice = (product.price ?? 0) - (product.cash_fee_sell ?? 0)
|
||||||
|
return product.direct_price === 0
|
||||||
|
? basePrice * (product.amount ?? 0)
|
||||||
|
: basePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultTypeDealOptions(context?: ProductDealMethodContext | null, isBuy = true): SelectItem[] {
|
||||||
|
const cashOption: SelectItem = { value: 'نقدی', key: 'cash' }
|
||||||
|
|
||||||
|
if (!shouldShowProductDealMethodSelector(context?.tradedProduct ?? null)) {
|
||||||
|
return [cashOption]
|
||||||
|
}
|
||||||
|
|
||||||
|
const quantityOptions = getQuantityTradePaymentDealOptions(context, isBuy)
|
||||||
|
if (quantityOptions.length) {
|
||||||
|
return [cashOption, ...quantityOptions]
|
||||||
|
}
|
||||||
|
|
||||||
|
return [cashOption]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProductDealMethodOptions(
|
||||||
|
groupType?: string | null,
|
||||||
|
isBuy = true,
|
||||||
|
context?: ProductDealMethodContext | null,
|
||||||
|
): SelectItem[] {
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
|
|
||||||
if (!isBoursecuProject()) {
|
if (!isBoursecuProject()) {
|
||||||
if (isBuy) {
|
return getDefaultTypeDealOptions(context, isBuy)
|
||||||
return [
|
|
||||||
{ value: 'نقدی', key: 'cash' },
|
|
||||||
{ value: settingsStore.metalTypeLabel, key: 'gold' },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
{ value: 'نقدی', key: 'cash' },
|
|
||||||
{ value: `دریافت ${settingsStore.metalTypeLabel}`, key: 'gold' },
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMaftolMesGroup(groupType)) {
|
if (isMaftolMesGroup(groupType)) {
|
||||||
@@ -230,11 +395,15 @@ export function getProductDealMethodOptions(groupType?: string | null, isBuy = t
|
|||||||
return [{ value: settingsStore.meltedGoldLabel, key: 'gold' }]
|
return [{ value: settingsStore.meltedGoldLabel, key: 'gold' }]
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDefaultTypeDealOptions()
|
return getDefaultTypeDealOptions(context, isBuy)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDefaultProductDealMethod(groupType?: string | null, isBuy = true) {
|
export function getDefaultProductDealMethod(
|
||||||
return getProductDealMethodOptions(groupType, isBuy)[0]?.key ?? 'cash'
|
groupType?: string | null,
|
||||||
|
isBuy = true,
|
||||||
|
context?: ProductDealMethodContext | null,
|
||||||
|
) {
|
||||||
|
return getProductDealMethodOptions(groupType, isBuy, context)[0]?.key ?? 'cash'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProductDealMethodPlaceholder(isBuy = true) {
|
export function getProductDealMethodPlaceholder(isBuy = true) {
|
||||||
@@ -265,7 +434,24 @@ export function isCashLikeDealMethod(method?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isMainMetalWalletDealMethod(method?: string | null) {
|
export function isMainMetalWalletDealMethod(method?: string | null) {
|
||||||
return method === 'gold' || method === 'katod'
|
return method === 'gold' || method === 'katod' || isMeltedProductDealMethod(method)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMeltedDealMethodBalance(
|
||||||
|
method?: string | null,
|
||||||
|
cards: WalletInventoryCard[] = [],
|
||||||
|
mainWalletGold?: number | null,
|
||||||
|
) {
|
||||||
|
const card = findMeltedDealMethodCard(method, cards)
|
||||||
|
if (card) {
|
||||||
|
return Number(card.quantity ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method === 'gold' || method === 'katod') {
|
||||||
|
return Number(mainWalletGold ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/** برچسب کیف فلز اصلی (main wallet gold) — از setting metal_type */
|
/** برچسب کیف فلز اصلی (main wallet gold) — از setting metal_type */
|
||||||
|
|||||||
@@ -7,6 +7,22 @@ function productUsesLastPriceIfZero(product: Product): boolean {
|
|||||||
return Boolean(product.use_last_price_if_zero)
|
return Boolean(product.use_last_price_if_zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
export function resolvePriceOffsetRatio(offsetPercent?: number | null) {
|
||||||
const offset = Number(offsetPercent ?? 0)
|
const offset = Number(offsetPercent ?? 0)
|
||||||
if (!offset) {
|
if (!offset) {
|
||||||
@@ -74,6 +90,10 @@ export function getProductBaseBuyPrice(product: Product): number {
|
|||||||
return Number(product.price_profit ?? 0) + Number(product.price ?? 0)
|
return Number(product.price_profit ?? 0) + Number(product.price ?? 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasReferenceReadingMethod(product)) {
|
||||||
|
return getReferenceProductBaseBuyPrice(product)
|
||||||
|
}
|
||||||
|
|
||||||
return Number(product.price ?? 0)
|
return Number(product.price ?? 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +168,14 @@ export function getProductSellPrice(product: Product): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isProductPriceInactive(product: Product): boolean {
|
export function isProductPriceInactive(product: Product): boolean {
|
||||||
|
if (
|
||||||
|
hasReferenceReadingMethod(product)
|
||||||
|
&& !productUsesLastPriceIfZero(product)
|
||||||
|
&& product.reference_provider_active === false
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return getProductBaseBuyPrice(product) <= 0
|
return getProductBaseBuyPrice(product) <= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-3
@@ -6,18 +6,27 @@ function formatGroupedPrice(price: string | number | null | undefined, digit: bo
|
|||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** مبلغ ریالی — بدون اعشار، گرد به بالا */
|
||||||
|
export function ceilRial(price?: number | string | null): number {
|
||||||
|
const num = Number(price ?? 0)
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.ceil(num)
|
||||||
|
}
|
||||||
|
|
||||||
export function formatNumber(value: string | number | null | undefined, grouped = false): string {
|
export function formatNumber(value: string | number | null | undefined, grouped = false): string {
|
||||||
return formatGroupedPrice(value, grouped)
|
return formatGroupedPrice(value, grouped)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePrice(price: number, digit = true, unit = 'ریال') {
|
export function usePrice(price: number, digit = true, unit = 'ریال') {
|
||||||
price = price ?? 0
|
const formatted = formatGroupedPrice(ceilRial(price), digit)
|
||||||
const formatted = formatGroupedPrice(price, digit)
|
|
||||||
return `${formatted} ${unit}`
|
return `${formatted} ${unit}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePriceWithoutType(price?: number, digit = true) {
|
export function usePriceWithoutType(price?: number, digit = true) {
|
||||||
return formatGroupedPrice(price ?? '', digit)
|
return formatGroupedPrice(ceilRial(price), digit)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useTowDecimal(num: string | number): string | number {
|
export function useTowDecimal(num: string | number): string | number {
|
||||||
|
|||||||
@@ -22,10 +22,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="userStore" class=" mt-5 pb-2 mb-19vh">
|
<div v-if="userStore" class=" mt-5 pb-2 mb-19vh">
|
||||||
<!-- <a-spin :spinning="loading">-->
|
<!-- <a-spin :spinning="loading">-->
|
||||||
<div v-if="!loading" :class="!isBuy? ' bg-red-100' : ' bg-green-100'"
|
<div
|
||||||
class="w-full relative rounded-lg h-[88px] flex flex-col justify-center background-color-transition">
|
v-if="!loading"
|
||||||
<img :src="img1" alt="" class="h-[88px] absolute">
|
class="w-full relative rounded-lg flex flex-col justify-center background-color-transition"
|
||||||
<div class="w-full items-center flex flex-col">
|
:class="[
|
||||||
|
!isBuy ? 'bg-red-100' : 'bg-green-100',
|
||||||
|
selectedMeltedPaymentProduct ? 'min-h-[120px] py-3' : 'h-[88px]',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<img :src="img1" alt="" class="h-full min-h-[88px] absolute inset-0 w-full object-cover">
|
||||||
|
<div class="w-full items-center flex flex-col relative z-1">
|
||||||
<div class="text-gray-700 font-bold">{{ !isBuy ? 'قیمت فروش' : 'قیمت خرید' }}</div>
|
<div class="text-gray-700 font-bold">{{ !isBuy ? 'قیمت فروش' : 'قیمت خرید' }}</div>
|
||||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||||
<div :class="!isBuy? 'text-red-700' : 'text-green-700'" class="font-bold text-2xl color-transition">
|
<div :class="!isBuy? 'text-red-700' : 'text-green-700'" class="font-bold text-2xl color-transition">
|
||||||
@@ -33,6 +39,16 @@
|
|||||||
</div>
|
</div>
|
||||||
ریال
|
ریال
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selectedMeltedPaymentProduct && price"
|
||||||
|
class="flex gap-1 mt-2 text-xs items-center"
|
||||||
|
>
|
||||||
|
<div class="text-gray-600">قیمت {{ selectedMeltedPaymentProduct.title }}:</div>
|
||||||
|
<div :class="!isBuy? 'text-red-700' : 'text-green-700'" class="font-bold text-lg color-transition">
|
||||||
|
{{ usePriceWithoutType(selectedMeltedTradePrice) }}
|
||||||
|
</div>
|
||||||
|
<div>ریال</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="w-full h-[88px]">
|
<div v-else class="w-full h-[88px]">
|
||||||
@@ -48,7 +64,7 @@
|
|||||||
<div class="border-gray-200 border-1 rounded-xl p-5 relative">
|
<div class="border-gray-200 border-1 rounded-xl p-5 relative">
|
||||||
<bg_main />
|
<bg_main />
|
||||||
<div class="z-100 relative">
|
<div class="z-100 relative">
|
||||||
<a-form-item name="method" :rules="[required()]">
|
<a-form-item v-if="showDealMethodSelect" name="method" :rules="[required()]">
|
||||||
<BasicSelect v-model:value="form.method" :items="typeDeal"
|
<BasicSelect v-model:value="form.method" :items="typeDeal"
|
||||||
key-name="key"
|
key-name="key"
|
||||||
:show-search="false"
|
:show-search="false"
|
||||||
@@ -60,7 +76,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item v-if="isBuy" name="goldValue"
|
<a-form-item v-if="isBuy" name="goldValue"
|
||||||
:rules="[justNumber2(props?.ProductItem?.price , form.method , props?.ProductItem?.amount, true, props?.ProductItem?.group_type)]">
|
:rules="[justNumber2(props?.ProductItem?.price , form.method , props?.ProductItem?.amount, true, props?.ProductItem?.group_type, selectedMeltedPaymentBalance)]">
|
||||||
<BasicInput v-model:value="form.goldValue" addon-before="تعداد" addon-bg-color="#000000FF"
|
<BasicInput v-model:value="form.goldValue" addon-before="تعداد" addon-bg-color="#000000FF"
|
||||||
addon-text-color="white"
|
addon-text-color="white"
|
||||||
place-holder="تعداد"
|
place-holder="تعداد"
|
||||||
@@ -97,7 +113,7 @@
|
|||||||
|
|
||||||
<!-- {{walletStore?.walletInfo?.gold}}-->
|
<!-- {{walletStore?.walletInfo?.gold}}-->
|
||||||
<Transition mode="out-in" name="fade" class="mt-2">
|
<Transition mode="out-in" name="fade" class="mt-2">
|
||||||
<div v-if="isBuy && (form.method === 'gold' || form.method === 'katod')" class="font-bold text-xs">
|
<div v-if="isBuy && isMainMetalWalletDealMethod(form.method)" class="font-bold text-xs">
|
||||||
<div>{{ buyMetalWalletBalanceText }}</div>
|
<div>{{ buyMetalWalletBalanceText }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="isBuy && form.method === 'cash'" class="font-bold text-xs">
|
<div v-else-if="isBuy && form.method === 'cash'" class="font-bold text-xs">
|
||||||
@@ -272,6 +288,7 @@ import { Product } from '@/models/products'
|
|||||||
import BasicSelect from '@/components/BasicPacks/BasicSelect.vue'
|
import BasicSelect from '@/components/BasicPacks/BasicSelect.vue'
|
||||||
import Bg_main from '@/components/bg_main.vue'
|
import Bg_main from '@/components/bg_main.vue'
|
||||||
import { useFundUserStore } from '@/store/fundStore'
|
import { useFundUserStore } from '@/store/fundStore'
|
||||||
|
import { getProductsCatalogRef } from '@/composables/useProductsCatalog'
|
||||||
import {
|
import {
|
||||||
getDefaultProductDealMethod,
|
getDefaultProductDealMethod,
|
||||||
getProductDealMethodOptions,
|
getProductDealMethodOptions,
|
||||||
@@ -282,6 +299,12 @@ import {
|
|||||||
formatMainMetalReceiveText,
|
formatMainMetalReceiveText,
|
||||||
calcSellReceivedMetalWeight,
|
calcSellReceivedMetalWeight,
|
||||||
isMainMetalWalletDealMethod,
|
isMainMetalWalletDealMethod,
|
||||||
|
findMeltedDealMethodCard,
|
||||||
|
findProductDealMethodProduct,
|
||||||
|
getMeltedDealMethodBalance,
|
||||||
|
shouldShowProductDealMethodSelect,
|
||||||
|
resolveProductTradeBuyUnitPrice,
|
||||||
|
resolveProductTradeSellUnitPrice,
|
||||||
formatProductWeightAmount,
|
formatProductWeightAmount,
|
||||||
getProductQuantityUnit,
|
getProductQuantityUnit,
|
||||||
getProductTotalWeightLabel,
|
getProductTotalWeightLabel,
|
||||||
@@ -296,10 +319,10 @@ import {
|
|||||||
productMinOrderCash
|
productMinOrderCash
|
||||||
} from '@/utils/productOrderLimit'
|
} from '@/utils/productOrderLimit'
|
||||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||||
import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets'
|
import { formatProductWalletBalanceText, formatInventoryCardValue, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets'
|
||||||
import { isStoreClosed, getStoreClosedMessage } from '@/utils/storeHours'
|
import { isStoreClosed, getStoreClosedMessage } from '@/utils/storeHours'
|
||||||
|
|
||||||
const typeDeal = computed(() => getProductDealMethodOptions(props?.ProductItem?.group_type, isBuy.value))
|
const catalogProducts = getProductsCatalogRef()
|
||||||
|
|
||||||
const isMetalReceiveDeal = computed(() =>
|
const isMetalReceiveDeal = computed(() =>
|
||||||
!isBuy.value && isMainMetalWalletDealMethod(form.value.method)
|
!isBuy.value && isMainMetalWalletDealMethod(form.value.method)
|
||||||
@@ -347,12 +370,6 @@ const productWalletBalanceText = computed(() =>
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
const buyMetalWalletBalanceText = computed(() =>
|
|
||||||
form.value.method === 'katod'
|
|
||||||
? formatMainMetalWalletBalanceText(walletStore?.walletInfo?.gold ?? 0)
|
|
||||||
: goldWalletBalanceText.value
|
|
||||||
)
|
|
||||||
|
|
||||||
const infoVisible = ref(false)
|
const infoVisible = ref(false)
|
||||||
const walletStore = useWalletStore()
|
const walletStore = useWalletStore()
|
||||||
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
||||||
@@ -566,18 +583,98 @@ const form = ref<Gold>({
|
|||||||
goldVazn:undefined
|
goldVazn:undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const inventoryCards = computed(() => assetsSummary.value?.inventory_cards ?? [])
|
||||||
|
|
||||||
|
const dealMethodContext = computed(() => ({
|
||||||
|
tradedProduct: props?.ProductItem ?? null,
|
||||||
|
productMetalId: props?.ProductItem?.metal_id,
|
||||||
|
inventoryCards: inventoryCards.value,
|
||||||
|
catalog: catalogProducts.value,
|
||||||
|
}))
|
||||||
|
|
||||||
|
const typeDeal = computed(() =>
|
||||||
|
getProductDealMethodOptions(props?.ProductItem?.group_type, isBuy.value, dealMethodContext.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const showDealMethodSelect = computed(() =>
|
||||||
|
shouldShowProductDealMethodSelect(props?.ProductItem, typeDeal.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const selectedMeltedPaymentCard = computed(() =>
|
||||||
|
findMeltedDealMethodCard(form.value.method, inventoryCards.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const selectedMeltedPaymentProduct = computed(() =>
|
||||||
|
findProductDealMethodProduct(form.value.method, catalogProducts.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const selectedMeltedTradePrice = computed(() => {
|
||||||
|
const product = selectedMeltedPaymentProduct.value
|
||||||
|
if (!product) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return isBuy.value
|
||||||
|
? resolveProductTradeBuyUnitPrice(product)
|
||||||
|
: resolveProductTradeSellUnitPrice(product)
|
||||||
|
})
|
||||||
|
|
||||||
|
const selectedMeltedPaymentBalance = computed(() =>
|
||||||
|
getMeltedDealMethodBalance(
|
||||||
|
form.value.method,
|
||||||
|
inventoryCards.value,
|
||||||
|
walletStore?.walletInfo?.gold
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const buyMetalWalletBalanceText = computed(() => {
|
||||||
|
const card = selectedMeltedPaymentCard.value
|
||||||
|
const product = selectedMeltedPaymentProduct.value
|
||||||
|
if (card) {
|
||||||
|
return `موجودی ${card.title}: ${formatInventoryCardValue(card)}`
|
||||||
|
}
|
||||||
|
if (product) {
|
||||||
|
return `موجودی ${product.title}: ۰ ${getProductQuantityUnit(product)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.value.method === 'katod') {
|
||||||
|
return formatMainMetalWalletBalanceText(walletStore?.walletInfo?.gold ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return goldWalletBalanceText.value
|
||||||
|
})
|
||||||
|
|
||||||
function resetDealMethod() {
|
function resetDealMethod() {
|
||||||
form.value.method = getDefaultProductDealMethod(props?.ProductItem?.group_type, isBuy.value)
|
form.value.method = getDefaultProductDealMethod(
|
||||||
|
props?.ProductItem?.group_type,
|
||||||
|
isBuy.value,
|
||||||
|
dealMethodContext.value,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props?.ProductItem?.id, props?.ProductItem?.group_type],
|
() => [props?.ProductItem?.id, props?.ProductItem?.group_type, props?.ProductItem?.amount, inventoryCards.value, catalogProducts.value],
|
||||||
() => {
|
() => {
|
||||||
resetDealMethod()
|
resetDealMethod()
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(showDealMethodSelect, (visible) => {
|
||||||
|
if (!visible) {
|
||||||
|
form.value.method = 'cash'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => form.value.method,
|
||||||
|
(method) => {
|
||||||
|
if (!typeDeal.value.some((item) => item.key === method)) {
|
||||||
|
resetDealMethod()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// تابع تبدیل اعداد فارسی به انگلیسی
|
// تابع تبدیل اعداد فارسی به انگلیسی
|
||||||
const persianToEnglish = (str: string | number | undefined): string => {
|
const persianToEnglish = (str: string | number | undefined): string => {
|
||||||
if (!str) return ''
|
if (!str) return ''
|
||||||
@@ -831,7 +928,11 @@ async function ok() {
|
|||||||
goldValue: undefined,
|
goldValue: undefined,
|
||||||
goldCash: undefined,
|
goldCash: undefined,
|
||||||
percentWallet: undefined,
|
percentWallet: undefined,
|
||||||
method: getDefaultProductDealMethod(props?.ProductItem?.group_type, isBuy.value)
|
method: getDefaultProductDealMethod(
|
||||||
|
props?.ProductItem?.group_type,
|
||||||
|
isBuy.value,
|
||||||
|
dealMethodContext.value,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// console.log(e)
|
// console.log(e)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex bg-white border-1 border-gray-200 rounded-lg"
|
<div class="flex bg-white border-1 border-gray-200 rounded-lg"
|
||||||
:class="isClickable ? 'bg-white opacity-100' : 'bg-gray-200 opacity-50'">
|
:class="isClickable ? 'bg-white opacity-100' : 'bg-gray-200 opacity-50 cursor-not-allowed'">
|
||||||
<div class="bg-gray-100 m-2 rounded-lg w-28 h-28 flex justify-center p-2">
|
<div class="bg-gray-100 m-2 rounded-lg w-28 h-28 flex justify-center p-2">
|
||||||
<img :src="displayImage" class="object-contain w-full h-full" alt="">
|
<img :src="displayImage" class="object-contain w-full h-full" alt="">
|
||||||
</div>
|
</div>
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-secondary font-500">{{ props.ProductItem.amount }}گرم</div>-->
|
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-secondary font-500">{{ props.ProductItem.amount }}گرم</div>-->
|
||||||
<!-- <div v-else class="text-secondary font-500">حداقل خرید یک گرم</div>-->
|
<!-- <div v-else class="text-secondary font-500">حداقل خرید یک گرم</div>-->
|
||||||
<!-- <div>{{usePrice((props.ProductItem.price ?? 0) + (props.ProductItem.cash_fee_buy ?? 0))}}</div>-->
|
<!-- <div>{{usePrice((props.ProductItem.price ?? 0) + (props.ProductItem.cash_fee_buy ?? 0))}}</div>-->
|
||||||
<div>{{ usePrice(getProductBuyPrice(props.ProductItem)) }}</div>
|
<div v-if="inactive" class="text-gray-500 font-500">بدون قیمت</div>
|
||||||
|
<div v-else>{{ usePrice(getProductBuyPrice(props.ProductItem)) }}</div>
|
||||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-xs text-gray-400">شامل 33 هزار تومان اجرت</div>-->
|
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-xs text-gray-400">شامل 33 هزار تومان اجرت</div>-->
|
||||||
<!-- <div v-else class="text-xs text-gray-400">محاسبه بر اساس قیمت روز</div>-->
|
<!-- <div v-else class="text-xs text-gray-400">محاسبه بر اساس قیمت روز</div>-->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,10 @@
|
|||||||
<span class="dproducts-card__badge">{{ product.group_type }}</span>
|
<span class="dproducts-card__badge">{{ product.group_type }}</span>
|
||||||
<h3 class="dproducts-card__title">{{ product.title }}</h3>
|
<h3 class="dproducts-card__title">{{ product.title }}</h3>
|
||||||
<p class="dproducts-card__price">
|
<p class="dproducts-card__price">
|
||||||
<template v-if="usesQuantityTrade(product)">
|
<template v-if="inactive">
|
||||||
|
بدون قیمت
|
||||||
|
</template>
|
||||||
|
<template v-else-if="usesQuantityTrade(product)">
|
||||||
{{ usePrice(goldPriceValue) }}
|
{{ usePrice(goldPriceValue) }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|||||||
Reference in New Issue
Block a user