fix(wallet): keep gold and silver asset details separate

Stop merging count_products into inventory cards so silver items are not duplicated and each metal shows its own total.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-06 13:40:41 +03:30
co-authored by Cursor
parent 3fc62ba100
commit 0f60c1e1a5
@@ -95,7 +95,7 @@
> >
<div class="customer-wallet-balance__detail-group-title"> <div class="customer-wallet-balance__detail-group-title">
<span class="customer-wallet-balance__group-dot" aria-hidden="true" /> <span class="customer-wallet-balance__group-dot" aria-hidden="true" />
<span>{{ metal.label }}</span> <span>{{ minimalMetalLabel(metal) }}</span>
</div> </div>
<div <div
v-for="line in linesForMetal(metal.metal_id)" v-for="line in linesForMetal(metal.metal_id)"
@@ -234,9 +234,21 @@ function targetToneClass(target: ChargeTarget) {
} }
} }
function uniqueInventoryCards() {
const cards = summary.value?.inventory_cards ?? []
const seen = new Set<number>()
const unique: WalletInventoryCard[] = []
for (const card of cards) {
const id = Number(card.product_id)
if (!id || seen.has(id)) continue
seen.add(id)
unique.push(card)
}
return unique
}
function inventoryCards() { function inventoryCards() {
if (!summary.value) return [] as WalletInventoryCard[] return uniqueInventoryCards()
return [...(summary.value.inventory_cards ?? []), ...(summary.value.count_products ?? [])]
} }
function isCountChargeTarget(target: ChargeTarget) { function isCountChargeTarget(target: ChargeTarget) {
@@ -310,22 +322,33 @@ function formatCard(card: WalletInventoryCard) {
return `${qty.toLocaleString('fa-IR', { maximumFractionDigits: 3 })} ${card.unit || 'گرم'}` return `${qty.toLocaleString('fa-IR', { maximumFractionDigits: 3 })} ${card.unit || 'گرم'}`
} }
function linesForMetal(metalId: number) { function formatMetalGroupTotal(metalId: number, metalCards: WalletInventoryCard[], metal?: WalletMetalTotal) {
const cards = summary.value?.inventory_cards ?? [] const allCount = metalCards.length > 0 && metalCards.every((card) => card.display_type === 'count')
const countCards = summary.value?.count_products ?? [] if (allCount) {
const metal = summary.value?.metal_totals?.find((row) => row.metal_id === metalId) const qty = metalCards.reduce((sum, card) => sum + Number(card.quantity ?? 0), 0)
return `${qty.toLocaleString('fa-IR')} عدد`
}
if (metal) {
return formatMetalTotal(metal)
}
return formatMetalDisplayValue(0, metalId)
}
const productLines = [...cards, ...countCards] function linesForMetal(metalId: number) {
.filter((card) => Number(card.metal_id) === metalId && Number(card.quantity ?? 0) > 0) const metal = summary.value?.metal_totals?.find((row) => row.metal_id === metalId)
.map((card) => ({ const metalCards = uniqueInventoryCards().filter(
key: `card-${card.product_id}`, (card) => Number(card.metal_id) === metalId && Number(card.quantity ?? 0) > 0
label: card.title, )
value: formatCard(card)
})) const productLines = metalCards.map((card) => ({
key: `card-${card.product_id}`,
label: card.title,
value: formatCard(card)
}))
const lines: Array<{ key: string; label: string; value: string }> = [...productLines] const lines: Array<{ key: string; label: string; value: string }> = [...productLines]
if (metal && Number(metal.melted_weight ?? 0) > 0 && !productLines.some((line) => line.label.includes('آبشده'))) { if (metal && Number(metal.melted_weight ?? 0) > 0 && !metalCards.some((card) => card.is_melted || card.is_main_wallet)) {
lines.push({ lines.push({
key: 'melted', key: 'melted',
label: 'موجودی آبشده / کیف اصلی', label: 'موجودی آبشده / کیف اصلی',
@@ -333,11 +356,11 @@ function linesForMetal(metalId: number) {
}) })
} }
if (metal && lines.length > 1) { if (lines.length > 0) {
lines.push({ lines.push({
key: 'total', key: 'total',
label: 'مجموع', label: `مجموع ${minimalMetalLabel(metal ?? { metal_id: metalId } as WalletMetalTotal)}`,
value: formatMetalTotal(metal) value: formatMetalGroupTotal(metalId, metalCards, metal)
}) })
} }