import type { Quantity } from './rebar/quantity'; /** One line of the bridge total: a 강종 and 직경 summed over the piers. */ export interface TotalRow { grade: number; size: string; count: number; totalM: number; kg: number; } export interface QuantityTotal { rows: TotalRow[]; /** Totals by 강종, in the same order as the rows. */ gradeKg: { grade: number; kg: number }[]; kg: number; kgWithWaste: number; ton: number; couplers: { name: string; count: number }[]; /** Bar names with no length, left out of the totals (summed over the piers). */ missingCount: number; } /** 교량 전체 집계: sums the per-pier 재료표 by 강종 and 직경 (the per-pier values are not changed). */ export function aggregateQuantities(items: Quantity[]): QuantityTotal { const byKey = new Map(); const couplers = new Map(); let kg = 0; let kgWithWaste = 0; let missingCount = 0; for (const q of items) { for (const g of q.groups) { for (const d of g.diameters) { const key = `${g.grade}|${d.size}`; const row = byKey.get(key) ?? { grade: g.grade, size: d.size, count: 0, totalM: 0, kg: 0 }; row.count += d.lines.reduce((n, l) => n + l.count, 0); row.totalM += d.totalM; row.kg += d.kg; byKey.set(key, row); } } for (const c of q.couplers) couplers.set(c.name, (couplers.get(c.name) ?? 0) + c.count); kg += q.kg; kgWithWaste += q.kgWithWaste; missingCount += q.missing.length; } const rows = [...byKey.values()].sort((a, b) => a.grade - b.grade || parseInt(a.size.slice(1), 10) - parseInt(b.size.slice(1), 10)); const gradeKg = new Map(); for (const r of rows) gradeKg.set(r.grade, (gradeKg.get(r.grade) ?? 0) + r.kg); return { rows, gradeKg: [...gradeKg].map(([grade, value]) => ({ grade, kg: value })), kg, kgWithWaste, ton: kgWithWaste / 1000, couplers: [...couplers].map(([name, count]) => ({ name, count })), missingCount, }; }