// REA 0x11167e4 / 0xa911d0: MulCode is split at a tab into sheet and item codes. function existingTargets(tables, sheets, warnings) { const candidates = new Map(); const targetCounts = new Map(); for (const row of tables.EstMainDat || []) if (row.Code && !Number(row.Level)) targetCounts.set(row.Code, (targetCounts.get(row.Code) || 0) + 1); for (const row of tables.EstMainDat || []) { if (Number(row.Level) || !row.MulCode?.binary || !row.MullangIndex || row.ExcelSheetIndex) continue; if (row.MullangIndex !== 1) { warnings.add("수량 연결: 기본 모드 외 연결은 원문에 보존했습니다."); continue; } const bytes = Buffer.from(row.MulCode.binary, "base64"); let text; try { let wide = bytes.length > 1 && bytes.length % 2 === 0; for (let i = 1; wide && i < bytes.length; i += 2) wide = bytes[i] === 0; text = wide ? bytes.toString("utf16le") : new TextDecoder("euc-kr", { fatal: true }).decode(bytes); } catch { warnings.add("수량 연결: 코드 인코딩을 읽을 수 없습니다."); continue; } const parts = text.replace(/\0+$/, "").split("\t"); if (parts.length !== 2 || !parts[0] || !parts[1] || !row.Code) { warnings.add("수량 연결: 문서·항목 코드 또는 내역 코드가 없습니다."); continue; } if (targetCounts.get(row.Code) !== 1) { warnings.add(`수량 연결: 내역 코드 ${row.Code}가 중복되어 자동 선택하지 않았습니다.`); continue; } const sheet = sheets.find((value) => value.Code === parts[0]); const item = sheet?.items.find((value) => value.Code === parts[1]); if (!item) { warnings.add(`수량 연결: ${parts[0]}/${parts[1]} 항목을 찾을 수 없습니다.`); continue; } if (!candidates.has(item)) candidates.set(item, new Set()); candidates.get(item).add(row.Code); } for (const [item, codes] of candidates) if (codes.size === 1) item.TargetCode = [...codes][0]; else warnings.add(`수량 연결: ${item.Code}에 여러 내역 코드가 연결되어 자동 선택하지 않았습니다.`); } module.exports = { existingTargets };