safavi works
This commit is contained in:
+178
-178
@@ -5,7 +5,7 @@ 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 { isMeltedTradeGroup, normalizeProductGroupType, LEGACY_GROUP_KATOD, LEGACY_GROUP_MAFTOL } from '@/utils/productCategories'
|
||||
import defaultImg from '@/assets/img/defaultAbshodeh.svg'
|
||||
import goyImg from '@/assets/img/goyImg.svg'
|
||||
import mokaabImg from '@/assets/img/mokaabImg.svg'
|
||||
@@ -95,24 +95,19 @@ export function resolveMetalAssetsDisplayLabel(
|
||||
}
|
||||
}
|
||||
|
||||
export type HomeAssetRowInfo = 'metal' | 'rial' | 'none'
|
||||
export type BoursecuHomeAssetRowId = 'copper-total' | 'rial-total'
|
||||
|
||||
export interface HomeAssetRow {
|
||||
id: string
|
||||
export interface BoursecuAssetPopupLine {
|
||||
label: string
|
||||
value: string
|
||||
metal?: WalletMetalTotal
|
||||
info: HomeAssetRowInfo
|
||||
/** boursecu — متن مودال توضیحات (info) */
|
||||
modalText?: string
|
||||
/** boursecu — عنوان مودال (مثلاً کل دارایی مس) */
|
||||
modalTitle?: string
|
||||
/** boursecu — محتوای چندخطی مودال */
|
||||
modalContent?: string
|
||||
tone?: 'profit' | 'loss' | 'default'
|
||||
}
|
||||
|
||||
function formatInventoryCardProductLabel(card: WalletInventoryCard): string {
|
||||
return `دارایی ${card.title}`
|
||||
export interface BoursecuHomeAssetRow {
|
||||
id: BoursecuHomeAssetRowId
|
||||
label: string
|
||||
value: string
|
||||
popupLines: BoursecuAssetPopupLine[]
|
||||
}
|
||||
|
||||
/** boursecu — متن مودال برای ردیفهای metal_totals */
|
||||
@@ -129,6 +124,44 @@ export function formatBoursecuMetalModalText(metal: WalletMetalTotal): string {
|
||||
}
|
||||
}
|
||||
|
||||
function isBoursecuKatodCard(card: WalletInventoryCard) {
|
||||
const group = normalizeProductGroupType(card.group_type)
|
||||
return group === LEGACY_GROUP_KATOD || (card.title ?? '').includes('کاتد')
|
||||
}
|
||||
|
||||
function isBoursecuMaftolCard(card: WalletInventoryCard) {
|
||||
const group = normalizeProductGroupType(card.group_type)
|
||||
return group === LEGACY_GROUP_MAFTOL || (card.title ?? '').includes('مفتول')
|
||||
}
|
||||
|
||||
function isBoursecuShamshCard(card: WalletInventoryCard) {
|
||||
return (card.title ?? '').includes('شمش')
|
||||
}
|
||||
|
||||
function findBoursecuProductCard(
|
||||
inventoryCards: WalletInventoryCard[],
|
||||
countProducts: WalletInventoryCard[],
|
||||
matcher: (card: WalletInventoryCard) => boolean
|
||||
) {
|
||||
return inventoryCards.find(matcher) ?? countProducts.find(matcher)
|
||||
}
|
||||
|
||||
function resolveBoursecuCardQuantityValue(
|
||||
card: WalletInventoryCard | undefined,
|
||||
metal: WalletMetalTotal | undefined,
|
||||
defaultUnit: string
|
||||
): string {
|
||||
if (card) {
|
||||
return formatInventoryCardValue(card)
|
||||
}
|
||||
|
||||
if (metal) {
|
||||
return formatBoursecuMetalRowValue(metal)
|
||||
}
|
||||
|
||||
return `0 ${defaultUnit}`
|
||||
}
|
||||
|
||||
/** boursecu — جمع موجودی کاتد، مفتول و شمش از کارتهای دارایی صفحه اصلی */
|
||||
function sumBoursecuHomeProductInventories(
|
||||
inventoryCards: WalletInventoryCard[],
|
||||
@@ -159,91 +192,6 @@ function sumBoursecuHomeProductInventories(
|
||||
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)
|
||||
}
|
||||
@@ -256,95 +204,151 @@ function formatBoursecuMetalRowValue(metal: WalletMetalTotal): string {
|
||||
return `${amount}${metal.unit ?? ''}`
|
||||
}
|
||||
|
||||
/** boursecu home — هر محصول / فلز / ریال از customer/wallet/assets جدا نمایش داده میشود */
|
||||
function formatRialNumber(value: number): string {
|
||||
return usePriceWithoutType(Math.round(value))
|
||||
}
|
||||
|
||||
function formatBoursecuProfitLossLine(profitLoss?: number): BoursecuAssetPopupLine {
|
||||
const amount = Number(profitLoss ?? 0)
|
||||
|
||||
if (amount > 0) {
|
||||
return {
|
||||
label: 'میزان سود یا زیان',
|
||||
value: `${formatRialNumber(amount)} ریال (سود)`,
|
||||
tone: 'profit',
|
||||
}
|
||||
}
|
||||
|
||||
if (amount < 0) {
|
||||
return {
|
||||
label: 'میزان سود یا زیان',
|
||||
value: `${formatRialNumber(Math.abs(amount))} ریال (زیان)`,
|
||||
tone: 'loss',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
label: 'میزان سود یا زیان',
|
||||
value: `${formatRialNumber(0)} ریال`,
|
||||
}
|
||||
}
|
||||
|
||||
function buildBoursecuCopperPopupLines(summary: {
|
||||
inventory_cards?: WalletInventoryCard[]
|
||||
count_products?: WalletInventoryCard[]
|
||||
metal_totals?: WalletMetalTotal[]
|
||||
}): BoursecuAssetPopupLine[] {
|
||||
const inventoryCards = summary.inventory_cards ?? []
|
||||
const countProducts = summary.count_products ?? []
|
||||
const metalTotals = summary.metal_totals ?? []
|
||||
const copperMetal = findMetalTotalById(metalTotals, METAL_COPPER)
|
||||
const shamshMetal = findMetalTotalById(metalTotals, METAL_GOLD)
|
||||
const weightUnit = copperMetal?.unit || 'کیلوگرم'
|
||||
const totalWeight = sumBoursecuHomeProductInventories(inventoryCards, countProducts)
|
||||
|
||||
const katodCard = findBoursecuProductCard(inventoryCards, countProducts, isBoursecuKatodCard)
|
||||
const maftolCard = findBoursecuProductCard(inventoryCards, countProducts, isBoursecuMaftolCard)
|
||||
const shamshCard = findBoursecuProductCard(inventoryCards, countProducts, isBoursecuShamshCard)
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'دارایی کاتد مس',
|
||||
value: resolveBoursecuCardQuantityValue(katodCard, undefined, 'کیلوگرم'),
|
||||
},
|
||||
{
|
||||
label: 'دارایی مفتول مس',
|
||||
value: resolveBoursecuCardQuantityValue(maftolCard, undefined, 'کیلوگرم'),
|
||||
},
|
||||
{
|
||||
label: 'دارایی شمش مس',
|
||||
value: resolveBoursecuCardQuantityValue(shamshCard, shamshMetal, 'عدد'),
|
||||
},
|
||||
{
|
||||
label: 'مجموع کل دارایی مس',
|
||||
value: `${usePriceWithoutType(totalWeight, false)} ${weightUnit}`,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
function buildBoursecuRialPopupLines(
|
||||
summary: {
|
||||
cash_wallet?: number
|
||||
total_rial_value?: number
|
||||
assets_rial_value?: number
|
||||
metal_totals?: WalletMetalTotal[]
|
||||
profit_loss?: number
|
||||
},
|
||||
liveCopperPrice: number
|
||||
): BoursecuAssetPopupLine[] {
|
||||
const cash = Number(summary.cash_wallet ?? 0)
|
||||
const metalRial = resolveAssetsRialValue(summary, liveCopperPrice)
|
||||
const total =
|
||||
Number(summary.total_rial_value ?? 0) > 0
|
||||
? Number(summary.total_rial_value)
|
||||
: cash + metalRial
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'کیف پول ریالی',
|
||||
value: `${formatRialNumber(cash)} ریال`,
|
||||
},
|
||||
{
|
||||
label: 'ارزش ریالی مس (وزن × قیمت زنده)',
|
||||
value: `${formatRialNumber(metalRial)} ریال`,
|
||||
},
|
||||
{
|
||||
label: 'مجموع کل دارایی ریالی',
|
||||
value: `${formatRialNumber(total)} ریال`,
|
||||
},
|
||||
formatBoursecuProfitLossLine(summary.profit_loss),
|
||||
]
|
||||
}
|
||||
|
||||
/** boursecu home — دو ردیف کل دارایی مسی و ریالی */
|
||||
export function buildBoursecuHomeAssetRows(
|
||||
summary: {
|
||||
inventory_cards?: WalletInventoryCard[]
|
||||
count_products?: WalletInventoryCard[]
|
||||
metal_totals?: WalletMetalTotal[]
|
||||
cash_wallet?: number
|
||||
total_rial_value?: number
|
||||
} | null | undefined
|
||||
): HomeAssetRow[] {
|
||||
assets_rial_value?: number
|
||||
profit_loss?: number
|
||||
} | null | undefined,
|
||||
liveCopperPrice = 0
|
||||
): BoursecuHomeAssetRow[] {
|
||||
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)
|
||||
const metalTotals = summary.metal_totals ?? []
|
||||
const copperMetal = findMetalTotalById(metalTotals, METAL_COPPER)
|
||||
const weightUnit = copperMetal?.unit || 'کیلوگرم'
|
||||
const totalCopperWeight = sumBoursecuHomeProductInventories(inventoryCards, countProducts)
|
||||
|
||||
for (const card of inventoryCards) {
|
||||
if (card.display_type === 'count') {
|
||||
continue
|
||||
}
|
||||
const cash = Number(summary.cash_wallet ?? 0)
|
||||
const metalRial = resolveAssetsRialValue(summary, liveCopperPrice)
|
||||
const totalRial =
|
||||
Number(summary.total_rial_value ?? 0) > 0
|
||||
? Number(summary.total_rial_value)
|
||||
: cash + metalRial
|
||||
|
||||
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
|
||||
return [
|
||||
{
|
||||
id: 'copper-total',
|
||||
label: 'کل دارایی مسی',
|
||||
value: `${usePriceWithoutType(totalCopperWeight, false)} ${weightUnit}`,
|
||||
popupLines: buildBoursecuCopperPopupLines(summary),
|
||||
},
|
||||
{
|
||||
id: 'rial-total',
|
||||
label: 'کل دارایی ریالی',
|
||||
value: `${formatRialNumber(totalRial)} ریال`,
|
||||
popupLines: buildBoursecuRialPopupLines(summary, liveCopperPrice),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export function sumInventoryCardsWeight(
|
||||
@@ -390,10 +394,6 @@ export function formatMetalAssetsInfoText(metal: WalletMetalTotal): string {
|
||||
return `${metal.label}: مجموع کیف محصولات (${metal.product_weight} ${unit}) + موجودی کیف اصلی (${metal.melted_weight} ${unit})`
|
||||
}
|
||||
|
||||
function formatRialNumber(value: number): string {
|
||||
return usePriceWithoutType(Math.round(value))
|
||||
}
|
||||
|
||||
/** متن توضیح مودال دارایی ریالی */
|
||||
export function formatRialAssetsInfoText(cashWallet: number, metalRialValue: number): string {
|
||||
const total = cashWallet + metalRialValue
|
||||
|
||||
Reference in New Issue
Block a user