65 lines
2.7 KiB
JavaScript
65 lines
2.7 KiB
JavaScript
// 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();
|
|
const pkidCounts = new Map();
|
|
for (const row of tables.EstMainDat || [])
|
|
if (row.Code && !Number(row.Level)) {
|
|
targetCounts.set(row.Code, (targetCounts.get(row.Code) || 0) + 1);
|
|
if (row.PkID != null) {
|
|
pkidCounts.set(row.PkID, (pkidCounts.get(row.PkID) || 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;
|
|
}
|
|
const hasUniquePkid = row.PkID != null && pkidCounts.get(row.PkID) === 1;
|
|
if (targetCounts.get(row.Code) !== 1 && !hasUniquePkid) {
|
|
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 Map());
|
|
const key = hasUniquePkid ? `id:${row.PkID}` : `code:${row.Code}`;
|
|
candidates.get(item).set(key, { code: row.Code, pkId: hasUniquePkid ? row.PkID : null });
|
|
}
|
|
for (const [item, entries] of candidates) {
|
|
if (entries.size === 1) {
|
|
const entry = [...entries.values()][0];
|
|
item.TargetCode = entry.code;
|
|
if (entry.pkId != null) {
|
|
item.TargetKey = `id:${entry.pkId}`;
|
|
}
|
|
} else {
|
|
warnings.add(`수량 연결: ${item.Code}에 여러 내역 코드가 연결되어 자동 선택하지 않았습니다.`);
|
|
}
|
|
}
|
|
}
|
|
module.exports = { existingTargets };
|