Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_1

This commit is contained in:
2026-09-14 06:01:16 +09:00
3 changed files with 24 additions and 3 deletions
@@ -49,6 +49,14 @@ CORRECTIONS: tuple[tuple[str, str], ...] = (
("material", "재료비"), ("material", "재료비"),
("expense", "경비"), ("expense", "경비"),
) )
#: 고를 때 무엇이 다른지 — 화면에 그대로 적음(2026-09-14 브레인 지시).
#: ⚠ 「기본보정」은 표본이 오면 고칠 자리 — 지금 뜻은 지어낸 것이 아니라 「안 몰고 남김」.
CORRECTION_HINTS = {
"basic": "차액을 어느 비목에도 안 몰고 남김(뜻 확인 대기)",
"labor": "차액을 노무비에 더함",
"material": "차액을 재료비에 더함",
"expense": "차액을 경비에 더함",
}
#: 뜻이 확인 안 된 보정 — 조용히 한쪽에 몰지 않고 차액을 그대로 보임. #: 뜻이 확인 안 된 보정 — 조용히 한쪽에 몰지 않고 차액을 그대로 보임.
CORRECTION_NOT_KNOWN = { CORRECTION_NOT_KNOWN = {
"basic": "「기본보정」의 뜻이 분석 자료에서 확인 안 됨(27번 §4) — 차액을 안 몰고 그대로 보임", "basic": "「기본보정」의 뜻이 분석 자료에서 확인 안 됨(27번 §4) — 차액을 안 몰고 그대로 보임",
@@ -15,6 +15,7 @@ from fastapi import APIRouter
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from B09_Estimation.B09_Estimation_Execution import ( from B09_Estimation.B09_Estimation_Execution import (
CORRECTION_HINTS,
CORRECTIONS, CORRECTIONS,
CUT_UNITS, CUT_UNITS,
SETTINGS_KEY, SETTINGS_KEY,
@@ -57,7 +58,10 @@ async def get_execution(project_id: UUID) -> JSONResponse:
"settings": stored, "settings": stored,
"fields": { "fields": {
"cut_units": list(CUT_UNITS), "cut_units": list(CUT_UNITS),
"corrections": [{"key": k, "label": label} for k, label in CORRECTIONS], "corrections": [
{"key": k, "label": label, "hint": CORRECTION_HINTS[k]}
for k, label in CORRECTIONS
],
}, },
"bill_missing_count": len((bill.get("summary") or {}).get("missing") or []), "bill_missing_count": len((bill.get("summary") or {}).get("missing") or []),
"limit_note": ( "limit_note": (
@@ -68,7 +68,7 @@ interface ExecutionDto {
machines: MachineRow[]; machines: MachineRow[];
totals: { design: Money; execution: Money }; totals: { design: Money; execution: Money };
settings: Settings; settings: Settings;
fields: { cut_units: string[]; corrections: { key: string; label: string }[] }; fields: { cut_units: string[]; corrections: { key: string; label: string; hint: string }[] };
bill_missing_count: number; bill_missing_count: number;
limit_note: string; limit_note: string;
} }
@@ -194,7 +194,7 @@ function input(value: string, onInput: (value: string) => void): HTMLInputElemen
} }
function select( function select(
options: { key: string; label: string }[], options: { key: string; label: string; hint?: string }[],
value: string, value: string,
onChange: (value: string) => void, onChange: (value: string) => void,
): HTMLSelectElement { ): HTMLSelectElement {
@@ -202,6 +202,7 @@ function select(
for (const option of options) { for (const option of options) {
const item = el("option", "", option.label); const item = el("option", "", option.label);
item.value = option.key; item.value = option.key;
if (option.hint) item.title = option.hint;
node.append(item); node.append(item);
} }
node.value = value; node.value = value;
@@ -213,6 +214,14 @@ function select(
function drawMachines(data: ExecutionDto, draft: Settings): HTMLElement { function drawMachines(data: ExecutionDto, draft: Settings): HTMLElement {
const box = el("div"); const box = el("div");
box.append(el("strong", "", `시간/단위당 중기실행단가 — 중기 ${data.machines.length}`)); box.append(el("strong", "", `시간/단위당 중기실행단가 — 중기 ${data.machines.length}`));
// 차액 보정을 고를 때 무엇이 다른지 — 「기본보정」은 뜻 확인 대기(안 몰고 남김).
box.append(
el(
"div",
"b09ex__meta",
data.fields.corrections.map((option) => `${option.label}: ${option.hint}`).join(" · "),
),
);
const table = el("table", "b09ex__table"); const table = el("table", "b09ex__table");
const head = el("tr"); const head = el("tr");
for (const label of [ for (const label of [