B08_Quantity 86 · B09_Estimation 111 파일을 old_code/ 로 옮김(지우지 않음). 화면은 메뉴·주소·단계 막대만 남은 빈 틀 둘 — main.py 라우터 13 개는 끊음. B07 이 빌려 쓰던 비탈 길이·면적은 필요한 함수만 B07_DesignDetail_Engine_SlopeGeometry 로 옮겨 적음(면적 적분·노면 면적·측점 묶음은 안 옮김) · 시험 하나를 새로 둠. B07 구조물도 조립(Cad_StandardSheet)은 2026-09-13 에 이미 도면 목록에서 빠져 부르는 곳이 없어 old_code 로 같이 보냄 — 구조물 그림은 되살리지 않음. B06 구조물 몫 조회는 빈 값으로 두어 화면이 그대로 서게 함. B08·B09 를 부르던 시험 25 개도 old_code/resources/tester 로 옮김. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
77 lines
3.1 KiB
TypeScript
77 lines
3.1 KiB
TypeScript
/* =============================================================================
|
|
* B09_Estimation_UI_Tab_PriceBasis.ts
|
|
* B09 단가산출근거 탭 — 목록표 + 단가산출근거 (STmate `단가산출근거목록표` · `wM_Edit_San` 보기 · PLAN 12장 1차)
|
|
*
|
|
* - 목록표 = 내역 일위대가가 품은 D 만, **내역에 처음 쓰인 차례**로 「산근 N호표」(내역 비고 「단산 N」과 한 번호).
|
|
* - 본표 줄의 비고에 Q 식·품셈 근거를 **글자 그대로** 보임(서버 줄 `note`).
|
|
* - 「부르는 호표」 칸의 글을 누르면 그 일위대가표로 되돌아 들어감.
|
|
* - Q 식 편집은 2차(브레인 판정).
|
|
* ========================================================================== */
|
|
|
|
import type { B09Tab, B09TabContext } from "./B09_Estimation_UI_Shell_Types";
|
|
import { renderDetail } from "./B09_Estimation_UI_Detail";
|
|
import { L, el, hint, linkButton, sheetTable } from "./B09_Estimation_UI_Sheet";
|
|
import { listHead, listRow } from "./B09_Estimation_UI_Tab_UnitPrice";
|
|
import { loadBill, type BillDto } from "./B09_Estimation_UI_Store";
|
|
|
|
let selected = "";
|
|
|
|
function draw(ctx: B09TabContext, bill: BillDto): void {
|
|
const entries = bill.price_basis.entries;
|
|
const page = el("div", "b09s-split");
|
|
const { wrap, tbody } = sheetTable(listHead(L("B09_Sheet_Col_Basis")));
|
|
const detail = el("div", "b09s-split");
|
|
for (const entry of entries) {
|
|
const row = {
|
|
...entry,
|
|
label: `${L("B09_Sheet_Basis_Long")} ${entry.number}${L("B09_Sheet_Basis_Suffix")}`,
|
|
};
|
|
const tr = listRow(row, entry.unit_price_krw ?? "", entry.code === selected);
|
|
const note = tr.lastElementChild as HTMLElement;
|
|
for (const code of entry.unit_price_codes ?? []) {
|
|
const sheet = bill.unit_price_sheet.entries.find((item) => item.code === code);
|
|
if (sheet) note.append(linkButton(sheet.label, () => ctx.open("unit_price", code)));
|
|
}
|
|
tr.addEventListener("click", () => {
|
|
selected = entry.code;
|
|
ctx.body.replaceChildren();
|
|
draw(ctx, bill);
|
|
});
|
|
tbody.append(tr);
|
|
}
|
|
page.append(el("div", "b09s-title", L("B09_Sheet_BasisList")), wrap);
|
|
if (entries.length === 0) page.append(hint(L("B09_Sheet_EmptyList")));
|
|
page.append(detail);
|
|
ctx.body.append(page);
|
|
if (!selected) {
|
|
detail.append(hint(L("B09_Sheet_PickSheet")));
|
|
return;
|
|
}
|
|
const picked = entries.find((entry) => entry.code === selected);
|
|
const label = picked
|
|
? `${L("B09_Sheet_Basis_Long")} ${picked.number}${L("B09_Sheet_Basis_Suffix")}`
|
|
: selected;
|
|
renderDetail(ctx, detail, "price_basis", selected, label);
|
|
}
|
|
|
|
export const priceBasisTab: B09Tab = {
|
|
key: "price_basis",
|
|
label: () => L("B09_Estimation_Tab_PriceBasis"),
|
|
render(ctx, arg) {
|
|
if (!ctx.projectId) {
|
|
ctx.body.append(hint(L("B09_Sheet_NoProject")));
|
|
return;
|
|
}
|
|
if (arg) selected = arg;
|
|
ctx.body.append(hint(L("B09_Sheet_Loading")));
|
|
loadBill(ctx.projectId)
|
|
.then((bill) => {
|
|
ctx.body.replaceChildren();
|
|
draw(ctx, bill);
|
|
})
|
|
.catch((error: Error) => {
|
|
ctx.body.replaceChildren(hint(`${L("B09_Sheet_LoadFailed")} ${error.message}`, true));
|
|
});
|
|
},
|
|
};
|