Files
Aislo/M02_MasterTemplete/M02_Labor_LogicMats_Model.ts
T
eomsangdonandClaude Opus 5.5 f79078f9c9 feat(m02): 일위대가 자재목록 로직 자재 기본 줄 · [바꾸기] 고름 · 사용자 추가분만 삭제(103-1)
- 문서 담은로직[].고름 {호표 차례: MT키} 정리 · 검사(재료 줄 · M01 자재품목만)
- run_line 을 엔진 choosing(고름)으로 감쌈 · 로직 자재 줄(차례 · 품목 · 단가 · 금액 · 가격 · 걸림) 내보냄
- 로직 자재 금액은 합 · 알약에 안 더함 · 사용자 자재와 같은 품목은 저장 때 400
- 단가승격 · 사전조합 안 로직도 고름 따름(없으면 지금 값)
- 프로젝트 사본 고른자재 씨앗 = 문서 고름 · 단가 묶음에 고른 품목 줄
- 화면: 자재목록 표 앞에 로직 자재 줄(삭제 없음 · [바꾸기] · 바꾼 줄 [기본]) · 입력 바뀌면 걸린 고름 풂 · 로직 자재와 같은 품목 추가 막음
- 시험 test_m02_labor_logic_mats.py(서버 · Node 짝)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
2026-10-08 16:18:21 +09:00

54 lines
2.4 KiB
TypeScript

/* =============================================================================
* M02_Labor_LogicMats_Model.ts
* 로직 자재(103-1) 자료 · 규칙(화면 없음) — 서버 calc `줄[].재료`(짝 `M02_Labor_Doc.logic_mats`) ·
* 입력이 바뀌면 그 입력에 걸린 고름을 풂(`releaseTied`) · 사용자 자재와 같은 품목 막기(`insideKeys`).
* 시험 `resources/tester/test_m02_labor_logic_mats.py`(Node 헬퍼).
* ========================================================================== */
/** 잡힌 품목 — 엔진 답 `품목`(값칸 = 단가가 나온 값 열) */
export interface LogicMatItem {
키: string;
이름?: string | null;
규격?: string | null;
단위?: string | null;
값칸?: string | null;
}
/** 로직 자재 한 줄 — 맨 위 층 호표 재료 줄(금액은 로직 재료비 안 · 합에 안 더함) */
export interface LogicMat {
차례: number;
이름: string;
단위: string;
수량: number | null;
단가: number | null;
금액: number | null;
까닭?: string | null;
품목: LogicMatItem | null;
/** M01 자재품목 값 열 다섯(빈 값 null) */
가격?: Record<string, number | null>;
고름: boolean;
/** 품목 조건에 든 입력 이름 — 그 입력이 바뀌면 고름을 풂 */
걸림: string[];
}
/** 입력값이 `before` 에서 바뀐 이름에 걸린 고름을 지움(다 풀리면 `고름` 칸째) — `row` 를 고쳐 돌려줌 */
export function releaseTied<
T extends { 입력값: Record<string, unknown>; 고름?: Record<string, string> },
>(row: T, before: Record<string, unknown>, mats: readonly LogicMat[]): T {
if (!row.고름) return row;
const text = (v: unknown): string => (v === null || v === undefined ? "" : String(v));
const keys = new Set([...Object.keys(before), ...Object.keys(row.입력값)]);
const changed = [...keys].filter((k) => text(before[k]) !== text(row.입력값[k]));
for (const mat of mats)
if (mat.걸림.some((n) => changed.includes(n))) delete row.고름[String(mat.차례)];
if (!Object.keys(row.고름).length) delete row.고름;
return row;
}
/** calc 답의 로직 자재 품목 키 전부 — 사용자 자재 추가 막기 */
export function insideKeys(lines: readonly { 재료?: LogicMat[] }[] | undefined): Set<string> {
return new Set(
(lines ?? []).flatMap((l) => (l.재료 ?? []).flatMap((m) => (m.품목 ? [m.품목.키] : []))),
);
}