765 lines
22 KiB
TypeScript
765 lines
22 KiB
TypeScript
import type { Product } from '@/models/products'
|
|
import { usePriceWithoutType } from '@/utils/usePrice'
|
|
import type { UserWalletLine } from '@/models/wallet'
|
|
import type { ProductFile } from '@/utils/file'
|
|
import type { WalletInventoryCard, WalletMetalTotal } from '@/models/walletAssets'
|
|
import { getFileUrl } from '@/utils/file'
|
|
import { isCountBasedProduct, getProductQuantityUnit, type ProductUnitSource } from '@/utils/productDealMethod'
|
|
import { isMeltedTradeGroup, normalizeProductGroupType, LEGACY_GROUP_KATOD } from '@/utils/productCategories'
|
|
import defaultImg from '@/assets/img/defaultAbshodeh.svg'
|
|
import goyImg from '@/assets/img/goyImg.svg'
|
|
import mokaabImg from '@/assets/img/mokaabImg.svg'
|
|
import sekkeImg from '@/assets/img/sekkeImg.svg'
|
|
import mesImg from '@/assets/img/mesImg.jpg'
|
|
import noghrehImg from '@/assets/img/noghrehImg.webp'
|
|
import parsianImg from '@/assets/img/parsianImg.svg'
|
|
|
|
export const METAL_GOLD = 1
|
|
export const METAL_SILVER = 2
|
|
export const METAL_COPPER = 3
|
|
|
|
const GROUP_DEFAULT_IMAGES: Record<string, string> = {
|
|
گوی: goyImg,
|
|
مکعب: mokaabImg,
|
|
سکه: sekkeImg,
|
|
مس: mesImg,
|
|
[LEGACY_GROUP_KATOD]: mesImg,
|
|
نقره: noghrehImg,
|
|
'سکه پارسیان': parsianImg,
|
|
طلا: defaultImg,
|
|
آبشده: defaultImg,
|
|
}
|
|
|
|
export function getMetalLabel(metalId: number): string {
|
|
switch (metalId) {
|
|
case METAL_GOLD:
|
|
return 'طلا'
|
|
case METAL_SILVER:
|
|
return 'نقره'
|
|
case METAL_COPPER:
|
|
return 'مس'
|
|
default:
|
|
return 'فلز'
|
|
}
|
|
}
|
|
|
|
export function getTotalMetalLabel(metalId: number): string {
|
|
return `کل دارایی ${getMetalLabel(metalId)}`
|
|
}
|
|
|
|
/** boursecu home — ترتیب نمایش: مس، طلا، سایر فلزها */
|
|
export function resolveBoursecuAssetMetalTotals(
|
|
metalTotals: WalletMetalTotal[]
|
|
): WalletMetalTotal[] {
|
|
if (!metalTotals.length) {
|
|
return []
|
|
}
|
|
|
|
const ordered: WalletMetalTotal[] = []
|
|
const copper = metalTotals.find((metal) => metal.metal_id === METAL_COPPER)
|
|
const gold = metalTotals.find((metal) => metal.metal_id === METAL_GOLD)
|
|
|
|
if (copper) {
|
|
ordered.push(copper)
|
|
}
|
|
if (gold) {
|
|
ordered.push(gold)
|
|
}
|
|
|
|
for (const metal of metalTotals) {
|
|
if (!ordered.some((item) => item.metal_id === metal.metal_id)) {
|
|
ordered.push(metal)
|
|
}
|
|
}
|
|
|
|
return ordered
|
|
}
|
|
|
|
export function resolveMetalAssetsDisplayLabel(
|
|
metal: WalletMetalTotal,
|
|
isBoursecuLayout: boolean
|
|
): string {
|
|
if (!isBoursecuLayout) {
|
|
return metal.label
|
|
}
|
|
|
|
switch (metal.metal_id) {
|
|
case METAL_COPPER:
|
|
return 'دارایی مس'
|
|
case METAL_GOLD:
|
|
return 'دارایی شمش مس'
|
|
case METAL_SILVER:
|
|
return 'دارایی نقره'
|
|
default:
|
|
return metal.label
|
|
}
|
|
}
|
|
|
|
export type HomeAssetRowInfo = 'metal' | 'rial' | 'none'
|
|
|
|
export interface HomeAssetRow {
|
|
id: string
|
|
label: string
|
|
value: string
|
|
metal?: WalletMetalTotal
|
|
info: HomeAssetRowInfo
|
|
/** boursecu — متن مودال توضیحات (info) */
|
|
modalText?: string
|
|
/** boursecu — عنوان مودال (مثلاً کل دارایی مس) */
|
|
modalTitle?: string
|
|
/** boursecu — محتوای چندخطی مودال */
|
|
modalContent?: string
|
|
}
|
|
|
|
function formatInventoryCardProductLabel(card: WalletInventoryCard): string {
|
|
return `دارایی ${card.title}`
|
|
}
|
|
|
|
/** boursecu — متن مودال برای ردیفهای metal_totals */
|
|
export function formatBoursecuMetalModalText(metal: WalletMetalTotal): string {
|
|
switch (metal.metal_id) {
|
|
case METAL_COPPER:
|
|
return getTotalMetalLabel(METAL_COPPER)
|
|
case METAL_GOLD:
|
|
return 'دارایی شمش مس = موجودی شمش مس'
|
|
case METAL_SILVER:
|
|
return 'دارایی نقره = موجودی نقره'
|
|
default:
|
|
return `${resolveMetalAssetsDisplayLabel(metal, true)} = موجودی ${metal.label}`
|
|
}
|
|
}
|
|
|
|
/** boursecu — جمع موجودی کاتد، مفتول و شمش از کارتهای دارایی صفحه اصلی */
|
|
function sumBoursecuHomeProductInventories(
|
|
inventoryCards: WalletInventoryCard[],
|
|
countProducts: WalletInventoryCard[]
|
|
): number {
|
|
let sum = 0
|
|
|
|
for (const card of inventoryCards) {
|
|
if (card.display_type === 'count') {
|
|
continue
|
|
}
|
|
sum += Number(card.quantity ?? 0)
|
|
}
|
|
|
|
for (const card of countProducts) {
|
|
const quantity = Number(card.quantity ?? 0)
|
|
const unitWeight = Number(card.unit_weight ?? 0)
|
|
if (unitWeight > 0) {
|
|
sum += quantity * unitWeight
|
|
continue
|
|
}
|
|
|
|
if (card.unit?.includes('کیلو')) {
|
|
sum += quantity
|
|
}
|
|
}
|
|
|
|
return sum
|
|
}
|
|
|
|
type BoursecuModalProduct = {
|
|
title: string
|
|
quantity: number
|
|
unit: string
|
|
}
|
|
|
|
function toBoursecuModalProduct(card: WalletInventoryCard): BoursecuModalProduct {
|
|
return {
|
|
title: card.title,
|
|
quantity: Number(card.quantity ?? 0),
|
|
unit: card.unit ?? (card.display_type === 'count' ? 'عدد' : 'کیلوگرم'),
|
|
}
|
|
}
|
|
|
|
function resolveBoursecuMetalModalProduct(
|
|
metal: WalletMetalTotal,
|
|
countProducts: WalletInventoryCard[]
|
|
): BoursecuModalProduct {
|
|
const countCard =
|
|
countProducts.find((card) => Number(card.metal_id) === metal.metal_id) ??
|
|
countProducts.find((card) => card.title?.includes('شمش'))
|
|
|
|
if (countCard) {
|
|
return toBoursecuModalProduct(countCard)
|
|
}
|
|
|
|
if (metal.metal_id === METAL_GOLD) {
|
|
return {
|
|
title: 'شمش مس',
|
|
quantity: Number(metal.total_weight ?? 0),
|
|
unit: 'عدد',
|
|
}
|
|
}
|
|
|
|
return {
|
|
title: metal.label,
|
|
quantity: Number(metal.total_weight ?? 0),
|
|
unit: metal.unit ?? 'کیلوگرم',
|
|
}
|
|
}
|
|
|
|
/** boursecu — جزئیات کل دارایی مس در مودال info */
|
|
export function formatBoursecuCopperAssetsModalContent(
|
|
metal: WalletMetalTotal,
|
|
inventoryCards: WalletInventoryCard[],
|
|
countProducts: WalletInventoryCard[],
|
|
product: BoursecuModalProduct
|
|
): string {
|
|
const weightUnit = metal.unit || 'کیلوگرم'
|
|
const productWeight = usePriceWithoutType(
|
|
sumBoursecuHomeProductInventories(inventoryCards, countProducts),
|
|
false
|
|
)
|
|
const clickedQuantity = usePriceWithoutType(product.quantity, false)
|
|
|
|
return [
|
|
`مجموع کیف محصولات: ${productWeight} ${weightUnit}`,
|
|
`موجودی ${product.title}: ${clickedQuantity} ${product.unit}`,
|
|
].join('\n')
|
|
}
|
|
|
|
function withBoursecuCopperModal(
|
|
row: Omit<HomeAssetRow, 'modalTitle' | 'modalContent'>,
|
|
copperTotal: WalletMetalTotal | undefined,
|
|
inventoryCards: WalletInventoryCard[],
|
|
countProducts: WalletInventoryCard[],
|
|
product: BoursecuModalProduct
|
|
): HomeAssetRow {
|
|
if (!copperTotal) {
|
|
return row
|
|
}
|
|
|
|
return {
|
|
...row,
|
|
metal: copperTotal,
|
|
modalTitle: getTotalMetalLabel(METAL_COPPER),
|
|
modalContent: formatBoursecuCopperAssetsModalContent(
|
|
copperTotal,
|
|
inventoryCards,
|
|
countProducts,
|
|
product
|
|
),
|
|
}
|
|
}
|
|
|
|
function findMetalTotalById(metalTotals: WalletMetalTotal[], metalId: number) {
|
|
return metalTotals.find((metal) => metal.metal_id === metalId)
|
|
}
|
|
|
|
function formatBoursecuMetalRowValue(metal: WalletMetalTotal): string {
|
|
const amount = usePriceWithoutType(Number(metal.total_weight ?? 0), false)
|
|
if (metal.metal_id === METAL_GOLD) {
|
|
return `${amount} عدد`
|
|
}
|
|
return `${amount}${metal.unit ?? ''}`
|
|
}
|
|
|
|
/** boursecu home — هر محصول / فلز / ریال از customer/wallet/assets جدا نمایش داده میشود */
|
|
export function buildBoursecuHomeAssetRows(
|
|
summary: {
|
|
inventory_cards?: WalletInventoryCard[]
|
|
count_products?: WalletInventoryCard[]
|
|
metal_totals?: WalletMetalTotal[]
|
|
total_rial_value?: number
|
|
} | null | undefined
|
|
): HomeAssetRow[] {
|
|
if (!summary) {
|
|
return []
|
|
}
|
|
|
|
const rows: HomeAssetRow[] = []
|
|
const metalTotals = summary.metal_totals ?? []
|
|
const inventoryCards = summary.inventory_cards ?? []
|
|
const countProducts = summary.count_products ?? []
|
|
const copperTotal = findMetalTotalById(metalTotals, METAL_COPPER)
|
|
|
|
for (const card of inventoryCards) {
|
|
if (card.display_type === 'count') {
|
|
continue
|
|
}
|
|
|
|
rows.push(
|
|
withBoursecuCopperModal(
|
|
{
|
|
id: `inventory-${card.product_id}`,
|
|
label: formatInventoryCardProductLabel(card),
|
|
value: formatInventoryCardValue(card),
|
|
metal: findMetalTotalById(metalTotals, card.metal_id),
|
|
info: 'metal',
|
|
},
|
|
copperTotal,
|
|
inventoryCards,
|
|
countProducts,
|
|
toBoursecuModalProduct(card)
|
|
)
|
|
)
|
|
}
|
|
|
|
for (const metal of metalTotals) {
|
|
if (metal.metal_id === METAL_COPPER) {
|
|
continue
|
|
}
|
|
|
|
rows.push(
|
|
withBoursecuCopperModal(
|
|
{
|
|
id: `metal-${metal.metal_id}`,
|
|
label: resolveMetalAssetsDisplayLabel(metal, true),
|
|
value: formatBoursecuMetalRowValue(metal),
|
|
metal,
|
|
info: 'metal',
|
|
},
|
|
copperTotal,
|
|
inventoryCards,
|
|
countProducts,
|
|
resolveBoursecuMetalModalProduct(metal, countProducts)
|
|
)
|
|
)
|
|
}
|
|
|
|
for (const card of countProducts) {
|
|
rows.push(
|
|
withBoursecuCopperModal(
|
|
{
|
|
id: `count-${card.product_id}`,
|
|
label: formatInventoryCardProductLabel(card),
|
|
value: formatInventoryCardValue(card),
|
|
metal: findMetalTotalById(metalTotals, card.metal_id),
|
|
info: 'metal',
|
|
},
|
|
copperTotal,
|
|
inventoryCards,
|
|
countProducts,
|
|
toBoursecuModalProduct(card)
|
|
)
|
|
)
|
|
}
|
|
|
|
rows.push({
|
|
id: 'rial-total',
|
|
label: 'دارایی ریالی',
|
|
value: `${formatRialNumber(summary.cash_wallet ?? 0)} ریال`,
|
|
info: 'rial',
|
|
})
|
|
|
|
return rows
|
|
}
|
|
|
|
export function sumInventoryCardsWeight(
|
|
cards: Array<{ metal_id?: number; quantity?: number }>,
|
|
metalId: number
|
|
): number {
|
|
return cards
|
|
.filter((card) => Number(card.metal_id) === metalId)
|
|
.reduce((sum, card) => sum + Number(card.quantity ?? 0), 0)
|
|
}
|
|
|
|
/** ردیفهای جزئی action sheet — فقط محصولاتی که show_in_assets روشن است. */
|
|
export function assetSheetInventoryCards<T extends { metal_id?: number; show_in_assets?: boolean }>(
|
|
cards: T[],
|
|
metalId?: number
|
|
): T[] {
|
|
return cards.filter((card) => {
|
|
if (!card.show_in_assets) {
|
|
return false
|
|
}
|
|
if (metalId == null) {
|
|
return true
|
|
}
|
|
return Number(card.metal_id) === metalId
|
|
})
|
|
}
|
|
|
|
/** همه کارتهای صفحه داراییها — بدون فیلتر show_in_assets. */
|
|
export function fundPageInventoryCards<T>(cards: T[]): T[] {
|
|
return cards.filter((card) => Number((card as { quantity?: number }).quantity ?? 0) > 0)
|
|
}
|
|
|
|
export function resolveSummaryMetalWeight(
|
|
metal: { total_weight: number },
|
|
_cards?: Array<{ metal_id?: number; quantity?: number }>
|
|
): number {
|
|
return Number(metal.total_weight ?? 0)
|
|
}
|
|
|
|
/** متن توضیح مودال دارایی فلزی — بر اساس metal_totals سرور، بدون هاردکد طلا */
|
|
export function formatMetalAssetsInfoText(metal: WalletMetalTotal): string {
|
|
const unit = metal.unit || 'گرم'
|
|
return `${metal.label}: مجموع کیف محصولات (${metal.product_weight} ${unit}) + موجودی کیف اصلی (${metal.melted_weight} ${unit})`
|
|
}
|
|
|
|
function formatRialNumber(value: number): string {
|
|
return usePriceWithoutType(value)
|
|
}
|
|
|
|
/** متن توضیح مودال دارایی ریالی */
|
|
export function formatRialAssetsInfoText(cashWallet: number, metalRialValue: number): string {
|
|
const total = cashWallet + metalRialValue
|
|
return [
|
|
`کیف پول ریالی: ${formatRialNumber(cashWallet)} ریال`,
|
|
`ارزش ریالی طلا (وزن × قیمت زنده): ${formatRialNumber(metalRialValue)} ریال`,
|
|
`مجموع: ${formatRialNumber(total)} ریال`,
|
|
].join('\n')
|
|
}
|
|
|
|
/** ارزش ریالی فلزات از وزن × قیمت زنده — fallback کلاینت قبل از deploy بکاند */
|
|
export function computeMetalRialValue(
|
|
metalTotals: Array<{ metal_id?: number; total_weight?: number }>,
|
|
liveGoldPrice: number,
|
|
livePricesByMetal?: Partial<Record<number, number>>
|
|
): number {
|
|
return metalTotals.reduce((sum, metal) => {
|
|
const weight = Number(metal.total_weight ?? 0)
|
|
if (weight <= 0) {
|
|
return sum
|
|
}
|
|
|
|
const metalId = Number(metal.metal_id ?? 0)
|
|
const unitPrice =
|
|
livePricesByMetal?.[metalId] ??
|
|
(metalId === METAL_GOLD ? liveGoldPrice : 0)
|
|
|
|
return sum + weight * unitPrice
|
|
}, 0)
|
|
}
|
|
|
|
export function resolveAssetsRialValue(
|
|
summary: { assets_rial_value?: number; metal_totals?: Array<{ metal_id?: number; total_weight?: number }> } | null | undefined,
|
|
liveGoldPrice: number
|
|
): number {
|
|
const fromServer = Number(summary?.assets_rial_value ?? 0)
|
|
if (fromServer > 0) {
|
|
return fromServer
|
|
}
|
|
|
|
return computeMetalRialValue(summary?.metal_totals ?? [], liveGoldPrice)
|
|
}
|
|
|
|
export function formatInventoryCardValue(card: {
|
|
quantity?: number
|
|
unit?: string
|
|
display_type?: string
|
|
}): string {
|
|
const quantity = Number(card.quantity ?? 0)
|
|
const unit = card.unit ?? (card.display_type === 'count' ? 'عدد' : 'گرم')
|
|
return `${usePriceWithoutType(quantity, false)} ${unit}`
|
|
}
|
|
|
|
export function findProductInventoryCard(
|
|
cards: WalletInventoryCard[],
|
|
productId?: number | null
|
|
): WalletInventoryCard | undefined {
|
|
if (!productId) {
|
|
return undefined
|
|
}
|
|
|
|
return cards.find((item) => Number(item.product_id) === Number(productId))
|
|
}
|
|
|
|
/**
|
|
* موجودی کیف یک محصول از inventory_cards.
|
|
* fallback: پروژههای ساختار قدیم (مثل گلد علی) کیف محصول ندارند و موجودی روی gold کیف اصلی است.
|
|
*/
|
|
export function getProductInventoryQuantity(
|
|
cards: WalletInventoryCard[],
|
|
productId?: number | null,
|
|
mainWalletGold?: number | null
|
|
): number {
|
|
const card = findProductInventoryCard(cards, productId)
|
|
if (card) {
|
|
return Number(card.quantity ?? 0)
|
|
}
|
|
|
|
return Number(mainWalletGold ?? 0)
|
|
}
|
|
|
|
/** برچسب موجودی کیف محصول — برای فرم خرید/فروش */
|
|
export function formatProductWalletBalanceText(
|
|
product: { id?: number; title?: string | null; unit?: string | null; group_type?: string | null } | null | undefined,
|
|
cards: WalletInventoryCard[] = [],
|
|
mainWalletGold?: number | null
|
|
): string {
|
|
const card = findProductInventoryCard(cards, product?.id)
|
|
const quantity = card ? Number(card.quantity ?? 0) : Number(mainWalletGold ?? 0)
|
|
const unit = card?.unit ?? getProductQuantityUnit(product)
|
|
const title = product?.title?.trim() || 'محصول'
|
|
|
|
return `موجودی کیف ${title}: ${quantity} ${unit}`
|
|
}
|
|
|
|
export function isSingleMetalCatalog(metalIds: number[]): boolean {
|
|
return metalIds.length === 1
|
|
}
|
|
|
|
export function getCatalogMetalIds(products?: Product[] | null): number[] {
|
|
const ids = new Set<number>()
|
|
for (const product of products ?? []) {
|
|
const metalId = Number(product.metal_id)
|
|
if (metalId > 0) {
|
|
ids.add(metalId)
|
|
}
|
|
}
|
|
return Array.from(ids).sort((a, b) => a - b)
|
|
}
|
|
|
|
export function catalogHasCountBasedProducts(products?: Product[] | null): boolean {
|
|
return (products ?? []).some((product) => isCountBasedProduct(product))
|
|
}
|
|
|
|
export function catalogHasMeltedProducts(products?: Product[] | null): boolean {
|
|
return (products ?? []).some((product) => isMeltedTradeGroup(product.group_type))
|
|
}
|
|
|
|
export function enrichInventoryCardsWithCatalog<T extends { product_id?: number; file?: ProductFile | null }>(
|
|
cards: T[],
|
|
catalog: Product[]
|
|
): T[] {
|
|
return cards.map((card) => {
|
|
const fromCatalog = catalog.find((product) => product.id === card.product_id)
|
|
if (!fromCatalog) {
|
|
return card
|
|
}
|
|
|
|
return {
|
|
...card,
|
|
file: card.file ?? fromCatalog.file ?? null,
|
|
}
|
|
})
|
|
}
|
|
|
|
export function enrichInventoryWithCatalog<T extends { id?: number }>(
|
|
items: T[],
|
|
catalog: Product[]
|
|
): T[] {
|
|
return items.map((item) => {
|
|
const fromCatalog = catalog.find((product) => product.id === item.id)
|
|
if (!fromCatalog) {
|
|
return item
|
|
}
|
|
|
|
const current = item as T & Product
|
|
return {
|
|
...fromCatalog,
|
|
...current,
|
|
wallet: current.wallet ?? fromCatalog.wallet,
|
|
file: current.file ?? fromCatalog.file,
|
|
metal_id: current.metal_id ?? fromCatalog.metal_id,
|
|
group_type: current.group_type ?? fromCatalog.group_type,
|
|
}
|
|
})
|
|
}
|
|
|
|
export function getProductDisplayImage(product?: {
|
|
group_type?: string | null
|
|
title?: string | null
|
|
file?: ProductFile | null
|
|
img?: string | null
|
|
} | null): string {
|
|
const fileUrl = getFileUrl(product?.file)
|
|
if (fileUrl) {
|
|
return fileUrl
|
|
}
|
|
|
|
if (product?.img && /^https?:\/\//i.test(product.img)) {
|
|
return product.img
|
|
}
|
|
|
|
const group = normalizeProductGroupType(product?.group_type)
|
|
if (group && GROUP_DEFAULT_IMAGES[group]) {
|
|
return GROUP_DEFAULT_IMAGES[group]
|
|
}
|
|
|
|
return defaultImg
|
|
}
|
|
|
|
type InventoryProduct = ProductUnitSource & {
|
|
metal_id?: number | null
|
|
title?: string | null
|
|
wallet?: { gold?: number | null } | null
|
|
}
|
|
|
|
export function sumCountBasedInventory(products?: InventoryProduct[] | null): number {
|
|
return (products ?? [])
|
|
.filter((product) => product.title !== 'آبشده نقدی' && isCountBasedProduct(product))
|
|
.reduce((sum, product) => sum + Number(product.wallet?.gold ?? 0), 0)
|
|
}
|
|
|
|
export function sumProductWalletByMetal(
|
|
products: InventoryProduct[] | null | undefined,
|
|
metalId: number
|
|
): number {
|
|
return (products ?? [])
|
|
.filter((product) => Number(product.metal_id) === metalId)
|
|
.reduce((sum, product) => sum + Number(product.wallet?.gold ?? 0), 0)
|
|
}
|
|
|
|
export function getMainWalletLine(wallets?: UserWalletLine[] | null): UserWalletLine | undefined {
|
|
return wallets?.find((line) => line.product_id == null)
|
|
}
|
|
|
|
export function getMainWalletGold(wallets?: UserWalletLine[] | null): number {
|
|
return Number(getMainWalletLine(wallets)?.gold ?? 0)
|
|
}
|
|
|
|
export function getMainWalletCash(wallets?: UserWalletLine[] | null): number {
|
|
return Number(getMainWalletLine(wallets)?.cash ?? 0)
|
|
}
|
|
|
|
export function sumWalletsGold(
|
|
wallets?: UserWalletLine[] | null,
|
|
metalId?: number | null
|
|
): number {
|
|
if (!wallets?.length) {
|
|
return 0
|
|
}
|
|
|
|
return wallets.reduce((sum, line) => {
|
|
const weight = Number(line.gold ?? 0)
|
|
if (metalId == null) {
|
|
return sum + weight
|
|
}
|
|
|
|
if (line.product_id == null) {
|
|
return metalId === METAL_GOLD ? sum + weight : sum
|
|
}
|
|
|
|
return Number(line.product?.metal_id) === metalId ? sum + weight : sum
|
|
}, 0)
|
|
}
|
|
|
|
export function sumProductWalletsGold(
|
|
wallets?: UserWalletLine[] | null,
|
|
metalId?: number | null
|
|
): number {
|
|
return (wallets ?? [])
|
|
.filter((line) => line.product_id != null)
|
|
.reduce((sum, line) => {
|
|
const weight = Number(line.gold ?? 0)
|
|
if (metalId == null) {
|
|
return sum + weight
|
|
}
|
|
|
|
return Number(line.product?.metal_id) === metalId ? sum + weight : sum
|
|
}, 0)
|
|
}
|
|
|
|
export function sumInventoryMetalWeight(products?: InventoryProduct[] | null): number {
|
|
return (products ?? [])
|
|
.filter((product) => product.title !== 'آبشده نقدی')
|
|
.reduce((sum, product) => sum + Number(product.wallet?.gold ?? 0), 0)
|
|
}
|
|
|
|
export function getTotalMetalWeight(
|
|
walletInfo?: Record<string, unknown> | null,
|
|
wallets?: UserWalletLine[] | null,
|
|
inventoryProducts?: InventoryProduct[] | null
|
|
): number {
|
|
const fromInventory = sumInventoryMetalWeight(inventoryProducts)
|
|
if (fromInventory > 0) {
|
|
return fromInventory
|
|
}
|
|
|
|
const fromProductWallets = sumProductWalletsGold(wallets)
|
|
if (fromProductWallets > 0) {
|
|
return fromProductWallets
|
|
}
|
|
|
|
if (wallets?.length) {
|
|
return getMainWalletGold(wallets)
|
|
}
|
|
|
|
return Number(walletInfo?.treasure ?? walletInfo?.gold_sum ?? walletInfo?.count_gold ?? 0)
|
|
}
|
|
|
|
/** موجودی ریالی کیف اصلی — با main_wallet_products فیلد cash ممکن است کیف محصول باشد */
|
|
export function getRialCashAmount(
|
|
walletInfo?: Record<string, unknown> | null,
|
|
wallets?: UserWalletLine[] | null
|
|
): number {
|
|
const aggregated = walletInfo?.count_cash_wallet ?? walletInfo?.count_cash
|
|
if (aggregated != null && aggregated !== '') {
|
|
const parsed = Number(aggregated)
|
|
if (!Number.isNaN(parsed)) {
|
|
return parsed
|
|
}
|
|
}
|
|
|
|
const mainCash = getMainWalletCash(wallets)
|
|
if (mainCash > 0) {
|
|
return mainCash
|
|
}
|
|
|
|
return Number(walletInfo?.cash ?? 0)
|
|
}
|
|
|
|
export function getCashWalletBalance(
|
|
walletInfo?: Record<string, unknown> | null,
|
|
wallets?: UserWalletLine[] | null
|
|
): number {
|
|
return getRialCashAmount(walletInfo, wallets)
|
|
}
|
|
|
|
export function getTotalRialEquivalent(walletInfo?: Record<string, unknown> | null): number {
|
|
return Number(walletInfo?.count_cash_total ?? 0)
|
|
}
|
|
|
|
export function getMetalAssetAmount(
|
|
walletInfo: Record<string, unknown> | null | undefined,
|
|
metalId: number,
|
|
inventoryProducts?: InventoryProduct[] | null
|
|
): number {
|
|
if (inventoryProducts?.length) {
|
|
const fromProducts = sumProductWalletByMetal(inventoryProducts, metalId)
|
|
if (fromProducts > 0 || inventoryProducts.some((product) => Number(product.metal_id) === metalId)) {
|
|
return fromProducts
|
|
}
|
|
}
|
|
|
|
if (!walletInfo) {
|
|
return 0
|
|
}
|
|
|
|
switch (metalId) {
|
|
case METAL_GOLD:
|
|
return Number(walletInfo.count_gold_wallets ?? walletInfo.count_gold ?? 0)
|
|
case METAL_SILVER:
|
|
return Number(walletInfo.count_silver ?? 0)
|
|
case METAL_COPPER:
|
|
return Number(walletInfo.count_copper ?? 0)
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
export function getMetalAssetAmountForDisplay(
|
|
walletInfo: Record<string, unknown> | null | undefined,
|
|
metalId: number,
|
|
catalogMetalIds: number[],
|
|
inventoryProducts?: InventoryProduct[] | null,
|
|
wallets?: UserWalletLine[] | null
|
|
): number {
|
|
if (isSingleMetalCatalog(catalogMetalIds)) {
|
|
return getTotalMetalWeight(walletInfo, wallets, inventoryProducts)
|
|
}
|
|
|
|
const productWeight = sumProductWalletByMetal(inventoryProducts, metalId)
|
|
const mainWalletWeight = wallets?.length
|
|
? getMainWalletGold(wallets)
|
|
: Number(walletInfo?.count_gold_wallet ?? 0)
|
|
|
|
if (catalogHasMeltedProducts(inventoryProducts as Product[] | null | undefined) && metalId === catalogMetalIds[0]) {
|
|
return productWeight + mainWalletWeight
|
|
}
|
|
|
|
if (wallets?.length) {
|
|
const walletWeight = sumWalletsGold(wallets, metalId)
|
|
if (walletWeight > 0) {
|
|
return walletWeight
|
|
}
|
|
}
|
|
|
|
return productWeight || getMetalAssetAmount(walletInfo, metalId, inventoryProducts)
|
|
}
|