feat(B09): 기계 수송비를 세움 — 기계경비의 셋째 몫이 통째로 빠져 있었음
기계경비 = 기계손료 + 운전경비 + 수송비인데 수송비가 없었음. 수송비를 내는 공종 FP-10-04 중기운반은 표가 미판정이라 단가가 아예 안 섰음. - 산림품셈 10-4 사이클 그대로 — 트레일러(20TON) t1=20·t3=20·t4=0.42 / 트럭(10.5TON) t1=10·t3=10·t4=5 · ㎝=t1+t2+t3+t4 · N=60×0.9/㎝, 단위는 회당. - 거리·도로 구분은 설계 입력 — 비면 줄이 안 서고 사유만 남음(임의 거리 금지). - 원문이 「-」로 둔 칸(트레일러·고속4차선)은 지어내지 않고 사유로 냄. - ⚠ 우리가 정한 둘을 화면 근거에 적음 — 속도를 8-1-6의 2 나 이동속도표에서 가져온 것, 운반시간을 왕복으로 본 것. - 곁다리: 운전경비 표가 페이지에서 잘려 앞자리를 못 이어받아 39 기종이 통째로 버려지고 있었음(그 안에 수송 차량 2702 가 있었음). 이어받되 카탈로그에 있는 코드일 때만 받게 함 — 운전경비 줄 92 → 158. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -536,11 +536,22 @@ export interface MiscMaterialRow {
|
||||
base_note: string;
|
||||
}
|
||||
|
||||
/** 기계 수송비 칸 — 거리·도로 구분이 있어야 줄이 선다(산림품셈 10-4). */
|
||||
export interface TransportRow {
|
||||
distance_km: string;
|
||||
road: string;
|
||||
roads: Array<{ key: string; label: string }>;
|
||||
variants: Array<{ key: string; label: string; unit_price_krw: string }>;
|
||||
basis: string[];
|
||||
notes: string[];
|
||||
}
|
||||
|
||||
export interface FactorChoicesDto {
|
||||
status: string;
|
||||
ranges: RangeFactorRow[];
|
||||
machines: MachineChoiceRow[];
|
||||
misc_material?: MiscMaterialRow;
|
||||
transport?: TransportRow;
|
||||
notes: string[];
|
||||
}
|
||||
|
||||
@@ -560,6 +571,8 @@ export async function saveFactorChoices(
|
||||
machine_choices?: Record<string, string>;
|
||||
misc_material_percent?: string;
|
||||
fuel_region?: string;
|
||||
transport_distance_km?: string;
|
||||
transport_road?: string;
|
||||
},
|
||||
): Promise<void> {
|
||||
const response = await fetch(
|
||||
@@ -726,5 +739,48 @@ export function drawFactorChoices(
|
||||
for (const line of misc.basis) body.append(note(line));
|
||||
}
|
||||
|
||||
const transport = data.transport;
|
||||
if (transport) {
|
||||
body.append(
|
||||
percentBox(
|
||||
"기계 수송 거리 (인근 시·군·구청 → 현장, 편도 ㎞)",
|
||||
transport.distance_km,
|
||||
"비움",
|
||||
(text) => {
|
||||
void saveFactorChoices(projectId, { transport_distance_km: text })
|
||||
.then(reload)
|
||||
.catch((error: Error) => body.append(note(`⚠ ${error.message}`)));
|
||||
},
|
||||
),
|
||||
);
|
||||
const roadOptions: FactorOption[] = [
|
||||
{ key: "", label: "안 고름" },
|
||||
...transport.roads.map((road) => ({ key: road.key, label: road.label })),
|
||||
];
|
||||
body.append(
|
||||
picker("수송 도로 구분", roadOptions, transport.road, (key) => {
|
||||
void saveFactorChoices(projectId, { transport_road: key })
|
||||
.then(reload)
|
||||
.catch((error: Error) => body.append(note(`⚠ ${error.message}`)));
|
||||
}),
|
||||
);
|
||||
for (const variant of transport.variants) {
|
||||
body.append(
|
||||
note(
|
||||
variant.unit_price_krw
|
||||
? `${variant.label} — 회당 ${variant.unit_price_krw}원`
|
||||
: `${variant.label} — 아직 안 섬`,
|
||||
),
|
||||
);
|
||||
}
|
||||
for (const line of transport.notes) body.append(note(`⚠ ${line}`));
|
||||
for (const line of transport.basis) body.append(note(line));
|
||||
body.append(
|
||||
note(
|
||||
"⚠ 단가는 「회당」입니다 — 몇 대를 몇 번 나르는지(회수)는 설계 입력이라 여기서 안 정합니다.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for (const line of data.notes) body.append(note(line));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user