feat(719-2): 공사 쪽 M02 단가산출(SK) — B09 대가 블록 · 산근 · [업데이트] · 내 자료집 SK

- Labor_Source: 굳힌 SK = 품셈 꼴 대가 블록(사본 단가.json 굳힌 키 줄 · M01 안 읽음) · 단가산출 속 일위대가 · SK 줄 = 그 대가 블록 부르는 줄 · 고정 줄 = fixed · 단가 고친 줄 = fixed(M02 셈 단가) · cover = P:+SK 이름표(SK 고쳐도 B09 덮개 그대로) · 줄 sk · poom(품셈 값) · 부르는 줄 수량 ÷ 굳힌 줄 배 · 사전조합 알약 = 굳힌 알약 · 서고 sangeun 사본
- Sangeun: SK 하위 로직 = 산근 · 단가산출 속 참조 걸음 · 결과단위 배 = 사본 줄에서(_unit(row) · unit_of(whole, code))
- Linked: 굳힌 SK 자원 키(굳힌 키 로직 줄 · 고정 이음)
- Refresh: 미리 보기 단가산출(바뀌는 SK 줄) · 서고 사본 원본판 다르면 다시 굳힘
- Bill_Library: 종류 sangeun(내 자료집 SK 불러오기) · changed · refresh_copy(같은 폴더 · 값 그대로 · 원본판 없는 옛 사본 그대로)
- Daega_Personal: 품셈 블록(굳힌 SK 포함) → 개인 층 SK(B09 품 · 단가 덮개 = SK 덮개 · 더한줄 수량 · 단가)
- M02_Item_Sangeun: 굳힌 SK 정체(굳힌 줄 차례 → 원본 cid)
- 화면: 일위대가 펼침 SK 줄 되돌림 [단가산출 값으로] · 곁 글 품셈 값 · 내 자료집 단가산출 글 · 업데이트 미리 보기 SK 줄 · 단가연결 내 것 단가산출(Labor_Api fetchLibrary 종류 넓힘)
- 시험 test_719_2_sk_project 5 통과 + 1 건너뜀(715-1b 엔진 단가 · 값묶음 뒤 자동 실행)
- test_155_5: _unit 인자 = 로직 줄로 바뀜(사본 줄에서 배 읽음) — 부르는 줄 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 16:09:53 +09:00
co-authored by Claude Opus 5.5
parent 1124cf26f6
commit ccabbad6fb
15 changed files with 637 additions and 60 deletions
+10 -5
View File
@@ -80,11 +80,12 @@ function hereItems(ctx: TabContext): Item[] {
return [...of("dg", ctx.sheets.daega), ...of("sg", ctx.sheets.sg_list)];
}
/** 내 것 · 회사 — 구조물 조합(그 층) + 사전조합(그 층 일위대가) */
/** 내 것 · 회사 — 구조물 조합(그 층) + 사전조합(그 층 일위대가) + 단가산출(SK · 719-2) */
async function layerItems(layer: "personal" | "company"): Promise<Item[]> {
const owner = ownOwner(layer, await fetchSessionUser().catch(() => null));
const combos = (await loadRows().catch(() => [])).filter((r) => r.layer === layer);
const pres = owner ? await fetchLibrary({ 층: layer, 주인: owner }, "precombo") : [];
const sks = owner ? await fetchLibrary({ 층: layer, 주인: owner }, "sangeun") : [];
return [
...combos.map((r) => {
const name = itemName(r);
@@ -99,15 +100,19 @@ async function layerItems(layer: "personal" | "company"): Promise<Item[]> {
void importLib({ apply, onPayload: onPayload(ctx) }, pick),
};
}),
...pres.map((r) => {
...[
...pres.map((r) => ["precombo", r] as const),
...sks.map((r) => ["sangeun", r] as const),
].map(([kind, r]) => {
const name = r.제목 || r.이름;
const pick = { kind: "precombo" as const, layer, owner, key: r.이름 };
const tag = kind === "precombo" ? "일위대가" : "단가산출";
const pick = { kind, layer, owner, key: r.이름 };
return {
tag: "일위대가",
tag,
name,
sub: [r.구분, r.상세구분].filter(Boolean).join(" "),
unit: String(r.단위 || ""),
hit: has(`일위대가 ${name} ${r.구분 ?? ""} ${r.상세구분 ?? ""}`),
hit: has(`${tag} ${name} ${r.구분 ?? ""} ${r.상세구분 ?? ""}`),
go: (ctx: TabContext, apply: ApplyRef) =>
void importLib({ apply, onPayload: onPayload(ctx) }, pick),
};