diff --git a/M02_MasterTemplete/M02_Sangeun_Calc.py b/M02_MasterTemplete/M02_Sangeun_Calc.py index 449d2dee9..311d7e5b5 100644 --- a/M02_MasterTemplete/M02_Sangeun_Calc.py +++ b/M02_MasterTemplete/M02_Sangeun_Calc.py @@ -373,9 +373,7 @@ def run( if detail and one.get("종류") == "로직" and at not in gaps: mark |= _detail(one, int(hit[1]), whole) if sd.is_rate(one): # 율 줄 = 율 · 「기준의 %」(화면 % 줄 · `per_unit` 수량 그대로) - rate = one["고정"]["비율"] - group = {"노무비": "인력", "재료비": "재료", "경비": "경비"}[rate["비목"]] - mark |= {"율": Decimal(str(one["수량"])), "규격": _rate_text(rate), "묶음": group} + mark |= {"율": Decimal(str(one["수량"])), "규격": _rate_text(one["고정"]["비율"])} lines.append( {**line, "cid": cid, **mark, **({"원값": mine["원값"]} if "원값" in mine else {})} ) diff --git a/M02_MasterTemplete/M02_Sangeun_Doc.py b/M02_MasterTemplete/M02_Sangeun_Doc.py index fe274b615..94e7513ad 100644 --- a/M02_MasterTemplete/M02_Sangeun_Doc.py +++ b/M02_MasterTemplete/M02_Sangeun_Doc.py @@ -436,6 +436,8 @@ def _add_item(one: dict) -> dict: qty = text(one["수량"]) if "참조" in one or "고정" in one: kept = {k: one[k] for k in ("참조", "고정") if k in one} + if is_rate(one): # 율 줄(778-4) = 그 비목 한 칸(엔진 묶음 · 보기 상자 = 비목) + kept["비목"] = one["고정"]["비율"]["비목"] return {**head, "종류": "로직", "요소": None, "수량": qty, **kept, "값묶음": None} if one.get("종류") == "로직": args = "".join( diff --git a/M02_MasterTemplete/logic/M02_Sangeun_Cover_Model.ts b/M02_MasterTemplete/logic/M02_Sangeun_Cover_Model.ts index 8cd386119..4c4ad7acc 100644 --- a/M02_MasterTemplete/logic/M02_Sangeun_Cover_Model.ts +++ b/M02_MasterTemplete/logic/M02_Sangeun_Cover_Model.ts @@ -78,6 +78,8 @@ export interface SkLine { 묶음?: string | null; cid: string; 율?: number; + /** % 줄 밑 이름(「노무비의 %」 · 율 줄 「인력의 %」) */ + 규격?: string; /** 못 셈 줄(725) — 금액 없음 · 계에 안 듦 */ 까닭?: string; /** 둘째 기초(727-2) — 세부 줄 · 뺀 세부 · 그 기초 지문 · 원문번호 */ @@ -179,6 +181,13 @@ function flatIds(ans: SkAnswer): string[] { return ans.정체.flatMap((c) => by.get(c)?.펼침?.map((x) => x.cid) ?? [c]); } +/** 율 더한줄(778-4) 비율 — `add:#k` 의 고정 `비율` · 아니면 undefined */ +const rateOf = (doc: SkDoc, cid: string): { 비목: string } | undefined => { + const hit = ADD_RE.exec(cid); + const one = hit ? doc.더한줄?.[Number(hit[1])] : undefined; + return (one?.고정 as { 비율?: { 비목: string } } | undefined)?.비율; +}; + /** 기초 수 — 로직 바탕 · 더한줄 로직 */ const baseCount = (doc: SkDoc): number => (doc.바탕?.로직 ? 1 : 0) + (doc.더한줄 ?? []).filter((x) => x.종류 === "로직").length; @@ -257,7 +266,7 @@ export function rowsOf(ans: SkAnswer, bare: SkAnswer | null, doc: SkDoc): CoverR const one = added === null ? undefined : doc.더한줄?.[added]; const owner = at ? doc.더한줄?.[at.k] : undefined; const cover = at ? owner?.덮개?.[at.cid] : added === null ? doc.덮개?.[cid] : undefined; - const pct = (at?.cid ?? cid).startsWith("pct:") || extra.율 !== undefined; // 덧줄 · 율 줄(778-4) + const pct = (at?.cid ?? cid).startsWith("pct:") || !!rateOf(doc, cid); // 덧줄 · 율 줄(778-4) const keys = Object.keys(parts); const shown = added === null && !at ? (was.get(cid) ?? null) : null; const base = at @@ -514,6 +523,11 @@ export function hoView( extra.push([cid, { ...((known.get(cid) as HoExtra) ?? { 이름: name, 식: "" }), ...tag }]); continue; } + const rate = rateOf(doc, cid); // 율 더한줄(778-4) = 비목 상자 % 줄(식 = 「인력의 %」) + if (rate) { + extra.push([cid, { 이름: name, 식: String(l?.규격 ?? ""), 비목: rate.비목, ...tag }]); + continue; + } if (at) { const kind = KIND_OF[at.cid.split(":")[0]] ?? "로직"; const qty = String(l?.율 ?? l?.원문?.수량 ?? l?.수량 ?? ""); // 세부 품 = M01 원문(744-1) @@ -544,7 +558,8 @@ export function hoView( const hit = ADD_RE.exec(cid); const a = hit ? doc.더한줄?.[Number(hit[1])] : undefined; const part = PART_OF[String(a?.비목 ?? "")]; - if (a) covers[i] = { qty: a.수량 / t, ...(a.단가 != null && part ? { [part]: a.단가 } : {}) }; + const own = rateOf(doc, cid) ? 1 : t; // 율 = 그대로 + if (a) covers[i] = { qty: a.수량 / own, ...(a.단가 != null && part ? { [part]: a.단가 } : {}) }; const at = subOf(cid); const owner = at ? doc.더한줄?.[at.k] : undefined; const c = hit ? undefined : at ? owner?.덮개?.[at.cid] : doc.덮개?.[cid];