Merge remote-tracking branch 'origin/main_laptop_1' into CODEX
This commit is contained in:
@@ -452,27 +452,3 @@
|
||||
width: auto;
|
||||
min-width: 8em;
|
||||
}
|
||||
|
||||
/* 가져온 식 값 · 추정 칸(810-3) — 칸 + 꼬리표 */
|
||||
.lstk-src {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: var(--spacing-4);
|
||||
}
|
||||
|
||||
.lstk-src > .ui-field {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.lstk-src > [data-guess] {
|
||||
width: auto;
|
||||
min-width: 18em;
|
||||
}
|
||||
|
||||
.lstk-src > [data-guess] input {
|
||||
min-width: 18em;
|
||||
}
|
||||
|
||||
.lstk-src > .ui-badge {
|
||||
margin-bottom: var(--spacing-4);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ import {
|
||||
} from "./formula_doc_copy";
|
||||
import { docFoot } from "./formula_doc_foot";
|
||||
import { buildOptions } from "./formula_doc_options";
|
||||
import { buildSourced } from "./line_stack_sourced";
|
||||
import { ft } from "./formula_doc_text";
|
||||
import { addTaken, type Taken } from "../common_util/common_util_line_stack_copy";
|
||||
import type { Layer } from "../M02_MasterTemplete/M02_MasterTemplete_Api_Fetch";
|
||||
@@ -281,10 +280,10 @@ export function createStackScreen(opt: StackScreenOptions) {
|
||||
recalc();
|
||||
draw();
|
||||
};
|
||||
const options = [
|
||||
...buildOptions(doc, given, !!cp && !opt.admin, setOption),
|
||||
...buildSourced(doc, !!cp && !opt.admin, setOption), // 가져온 식 값 · 추정 칸(810-3)
|
||||
];
|
||||
// 가져온 식 = 옵션 가로 안 그림(819-1 · 요구 787 — 값은 왼쪽 공식 묶음에 같이 보임)
|
||||
const options = (doc as { 가져온?: unknown }).가져온
|
||||
? []
|
||||
: buildOptions(doc, given, !!cp && !opt.admin, setOption);
|
||||
const busy = dirty();
|
||||
const tools = [
|
||||
...(mark?.단가기준 && opt.page ? [basisPick(mark.단가기준)] : []), // 모달 = 머리 판 단추(793-3b)
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/* =============================================================================
|
||||
* line_stack_sourced.ts
|
||||
* 가져온 식 옵션 가로 칸(PLAN 810-3 · 요구 705 · 703) — 줄 쌓기 위 옵션 가로(`formula_doc_options.ts`) 뒤에 붙음
|
||||
* 값 칸 = 경쟁사 파일에 값으로 드러난 수(q · K · E · Cm · Q …) · 꼬리표 「원파일」 · 「엑셀」(`sourceOf`) ·
|
||||
* 고침 = 그 숫자 연결 값(부른 쪽 `set` · 캐시 → [저장])
|
||||
* 규격 칸 = 원파일 블록 규격(읽기만) · 추정 칸 = 값 없이 이름만 적힌 품셈 조건 글(문서 `가져온.추정` · 읽기만 ·
|
||||
* M01 기초에 묶지 않음 · 703)
|
||||
* ========================================================================== */
|
||||
|
||||
import { createBadge } from "@ui/ui_template_badge";
|
||||
import { el } from "@ui/ui_template_elements";
|
||||
import { createInputField } from "@ui/ui_template_input";
|
||||
import { varId, type DocVar, type FormulaDoc } from "../common_util/common_util_formula_doc";
|
||||
import { sourceOf } from "../common_util/common_util_line_stack";
|
||||
import { lt } from "./line_stack_text";
|
||||
|
||||
interface Head {
|
||||
원파일?: boolean;
|
||||
규격?: string;
|
||||
추정?: { 행?: number; 글?: string }[];
|
||||
}
|
||||
|
||||
const cell = (field: HTMLElement, tag: string, tone: "info" | "warning", hint: string) =>
|
||||
el("div", {
|
||||
className: "lstk-src",
|
||||
attrs: { title: hint },
|
||||
children: [field, createBadge(tag, tone)],
|
||||
});
|
||||
|
||||
export function buildSourced(
|
||||
doc: FormulaDoc | null,
|
||||
lock: boolean,
|
||||
set: (key: string, v: DocVar, value: unknown) => void,
|
||||
): HTMLElement[] {
|
||||
const head = (doc as { 가져온?: Head } | null)?.가져온;
|
||||
if (!doc || !head) return [];
|
||||
const out: HTMLElement[] = [];
|
||||
for (const v of doc.변수 ?? []) {
|
||||
const tag = sourceOf(doc, v);
|
||||
if (!tag) continue;
|
||||
const id = varId(v);
|
||||
const f = createInputField({
|
||||
label: v.이름 || id,
|
||||
value: String(v.연결?.값 ?? ""),
|
||||
compact: true,
|
||||
size: 28,
|
||||
unit: v.단위 || undefined,
|
||||
});
|
||||
f.input.disabled = lock;
|
||||
f.input.addEventListener("change", () => {
|
||||
const n = Number(f.input.value.trim().replace(/,/g, ""));
|
||||
if (f.input.value.trim() === "" || !Number.isFinite(n))
|
||||
return void (f.input.value = String(v.연결?.값 ?? "")); // 수만 — 빈 값 · 글 = 그대로
|
||||
set(id, v, n); // 수 그대로(글 「0.7」 = 셈 「—」 · 공식 묶음 값 칸 `setRow` 와 같은 꼴 · 812-3)
|
||||
});
|
||||
f.root.dataset.option = id;
|
||||
const tagText = tag === "원파일" ? lt("Src_Native") : tag === "엑셀" ? lt("Src_Excel") : tag;
|
||||
out.push(cell(f.root, tagText, "info", lt("Src_Hint")));
|
||||
}
|
||||
const ro = (label: string, value: string, mark: string, guess: boolean) => {
|
||||
const f = createInputField({ label, value, compact: true, size: 28 });
|
||||
f.input.readOnly = true;
|
||||
f.input.title = value; // 긴 조건 글 = 칸 위에 올리면 다 보임
|
||||
if (guess) f.root.dataset.guess = mark;
|
||||
return guess
|
||||
? cell(f.root, lt("Guess"), "warning", lt("Guess_Hint"))
|
||||
: cell(f.root, lt(head.원파일 ? "Src_Native" : "Src_Excel"), "info", lt("Src_Hint")); // 812-1 엑셀 읽기기 = 「엑셀」
|
||||
};
|
||||
if (head.규격) out.push(ro(lt("Spec"), head.규격, "", false));
|
||||
for (const g of head.추정 ?? [])
|
||||
out.push(
|
||||
ro(
|
||||
`${lt("Guess_Label")}${g.행 !== undefined ? ` · ${g.행}행` : ""}`,
|
||||
String(g.글 ?? "").replace(/^※\s*/, ""),
|
||||
String(g.행 ?? ""),
|
||||
true,
|
||||
),
|
||||
);
|
||||
return out;
|
||||
}
|
||||
@@ -38,17 +38,6 @@ const TEXT = {
|
||||
K_소계: ["소계", "Subtotal"],
|
||||
Src_Native: ["원파일", "Source file"],
|
||||
Src_Excel: ["엑셀", "Excel"],
|
||||
Src_Hint: [
|
||||
"경쟁사 파일에 값으로 적힌 수 — 고치면 이 단가산출 값",
|
||||
"Value written in the competitor file — edit to change",
|
||||
],
|
||||
Guess: ["추정", "Guess"],
|
||||
Guess_Label: ["품셈 조건", "Condition"],
|
||||
Guess_Hint: [
|
||||
"값 없이 이름만 적힌 품셈 조건 — 우리 기초에 묶지 않음",
|
||||
"Condition named without a value — not bound",
|
||||
],
|
||||
Spec: ["규격", "Spec"],
|
||||
K_공식: ["공식", "Formula"],
|
||||
K_표값: ["표 값", "Table values"],
|
||||
K_글: ["근거 글", "Basis note"],
|
||||
|
||||
@@ -363,7 +363,9 @@ def create(kind: str, doc: dict[str, Any]) -> dict[str, Any]:
|
||||
raise _bad("새 키를 못 잡음 — 다시 누름", 409)
|
||||
|
||||
|
||||
def summary(folder: Path, kind: str, key: str, expand: Expand | None = None) -> dict[str, Any]:
|
||||
def summary(
|
||||
folder: Path, kind: str, key: str, expand: Expand | None = None, files: UseFiles | None = None
|
||||
) -> dict[str, Any]:
|
||||
"""층 목록 한 줄에 붙일 것 — `{제목, 단위, 구분, 상세구분, 연결}`(51-12) · `expand` 면
|
||||
1 단위 기준 계(`기준금액` · 51-4)."""
|
||||
try:
|
||||
@@ -392,8 +394,8 @@ def summary(folder: Path, kind: str, key: str, expand: Expand | None = None) ->
|
||||
except Exception: # noqa: BLE001 — 없는 로직 = 키만(셈 때 까닭)
|
||||
pass
|
||||
out["고친줄수"] = sum(len(doc.get(k) or ()) for k in ("덮개", "더한줄", "뺀줄"))
|
||||
# ponytail: SK 마다 모든 층 훑음(users) — 목록이 느려지면 층 훑기 한 번 셈으로
|
||||
out["쓰는곳수"] = len(users({"층": layer, "주인": owner, "키": key}))
|
||||
# SK 마다 모든 층 훑음(users) — 파일 읽기는 판 기억(`_ids_of`)이라 처음 한 번만 무거움
|
||||
out["쓰는곳수"] = len(users({"층": layer, "주인": owner, "키": key}, files))
|
||||
return out
|
||||
|
||||
|
||||
@@ -403,29 +405,58 @@ def summaries(folder: Path, rows: list[dict[str, Any]]) -> None:
|
||||
from M02_MasterTemplete.M02_Labor_Expand import Expand
|
||||
|
||||
expand = Expand(m01.loaded()[1])
|
||||
files = use_files() if any(row["종류"] == "sangeun" for row in rows) else None
|
||||
for row in rows:
|
||||
if row["종류"] in layers.LIBRARY_KINDS:
|
||||
row.update(summary(folder, row["종류"], row["이름"], expand))
|
||||
row.update(summary(folder, row["종류"], row["이름"], expand, files))
|
||||
|
||||
|
||||
# ── 쓰는 곳 · 지우기 ──────────────────────────────────────────────────
|
||||
def users(ref: Ref) -> list[str]:
|
||||
UseFiles = list[tuple[str, str, Path]]
|
||||
|
||||
|
||||
def use_files() -> UseFiles:
|
||||
"""쓰는 곳을 찾을 파일 — (무엇, 어디, 파일) · 목록 한 번에 한 번 찾음(818-1)."""
|
||||
# 「일위대가」 = 사전조합 새 이름(내역 14 확정 1) · 구조물 조합 일위대가 = 「구조물 조합」
|
||||
kinds = (("labor", "구조물 조합"), ("precombo", "일위대가"), ("sangeun", "단가산출"))
|
||||
return [(what, at, path) for kind, what in kinds for at, path in layers.layer_files(kind)]
|
||||
|
||||
|
||||
def users(ref: Ref, files: UseFiles | None = None) -> list[str]:
|
||||
"""`ref` 를 담은 일위대가 · 사전조합 · 단가산출(바탕 · 더한줄) — 「어디 이름」 목록(모든 층 훑음 ·
|
||||
프로젝트 뺌)."""
|
||||
rid, out = ref_id(ref), []
|
||||
# 「일위대가」 = 사전조합 새 이름(내역 14 확정 1) · 구조물 조합 일위대가 = 「구조물 조합」
|
||||
for kind, what in (("labor", "구조물 조합"), ("precombo", "일위대가"), ("sangeun", "단가산출")):
|
||||
for at, path in layers.layer_files(kind):
|
||||
try:
|
||||
doc = json.loads(path.read_bytes())
|
||||
except (OSError, ValueError):
|
||||
continue
|
||||
if any(ref_id(one) == rid for one in refs_in(doc)):
|
||||
name = doc.get("일위대가번") or doc.get("이름") or path.stem
|
||||
out.append(f"{what} {at} 「{name}」")
|
||||
for what, at, path in use_files() if files is None else files:
|
||||
got = _ids_of(path)
|
||||
if got and rid in got[1]:
|
||||
out.append(f"{what} {at} 「{got[0]}」")
|
||||
return out
|
||||
|
||||
|
||||
_IDS: dict[Path, tuple[tuple[int, int], tuple[str, frozenset[str]]]] = {}
|
||||
|
||||
|
||||
def _ids_of(path: Path) -> tuple[str, frozenset[str]] | None:
|
||||
"""파일 하나의 (이름, 참조 이름표들) — 판(고친 때 · 크기)이 같으면 기억한 것(818-1 · 로직 사본으로
|
||||
SK 파일이 MB 단위라 목록 줄마다 모든 층을 다시 읽으면 분 단위)."""
|
||||
try:
|
||||
st = path.stat()
|
||||
stamp = (st.st_mtime_ns, st.st_size)
|
||||
if (hit := _IDS.get(path)) and hit[0] == stamp:
|
||||
return hit[1]
|
||||
doc = json.loads(path.read_bytes())
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
name = (
|
||||
(doc.get("일위대가번") or doc.get("이름") or path.stem)
|
||||
if isinstance(doc, dict)
|
||||
else path.stem
|
||||
)
|
||||
got = (str(name), frozenset(ref_id(one) for one in refs_in(doc)))
|
||||
_IDS[path] = (stamp, got)
|
||||
return got
|
||||
|
||||
|
||||
def refuse_used(folder: Path, kind: str, key: str) -> None:
|
||||
"""쓰는 곳이 있으면 409 + 이름(서고 종류만)."""
|
||||
if kind not in PREFIX:
|
||||
|
||||
@@ -98,8 +98,8 @@ def hourly(key: str) -> dict[str, Any]:
|
||||
logic = logic_of(code)
|
||||
if not logic:
|
||||
return {"ok": False, "reason": f"「{row.get('이름')}」 은 시간당 경비를 셀 자료가 없음"}
|
||||
args = "".join(
|
||||
f", {i['이름']}='{(i.get('고르기') or [''])[0]}'"
|
||||
args = "".join( # 빈칸 든 입력 이름(「전력 계약종별」 · 820-1 파워트로웰)은 따옴표로
|
||||
f", {n if (n := i['이름']).isidentifier() else repr(n)}='{(i.get('고르기') or [''])[0]}'"
|
||||
for i in logic.get("입력") or []
|
||||
if i.get("이름") != "기계"
|
||||
)
|
||||
|
||||
@@ -114,7 +114,8 @@ def hourly_text(key: str | None) -> str | None:
|
||||
got = dim.hourly_link(key, "노무비")
|
||||
if not got:
|
||||
return None
|
||||
return f"로직({got['키']}{''.join(f', {k}={v}' for k, v in got['입력'].items())})"
|
||||
args = "".join(f", {dim._q(k)}={v}" for k, v in got["입력"].items()) # 빈칸 든 이름은 따옴표
|
||||
return f"로직({got['키']}{args})"
|
||||
|
||||
|
||||
def combo_link(one: dict, parts: list[dict]) -> str | None:
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"token": "ya29.a0AX07Cms_Mr_cIxMqI7d3tZp5yvLwc557onouF07rOxMcSChG2hhLwughRmStGGgViEQK7Wf81_mW-u6W6y7_SPMnXy2BPI0KjSpBd8W9c6rELzIgW7w-kUBfOqDMaa-Gc0htcHUTISoPtNbLDbUMFNrmKXlVqkp80DM-YKlQc7pSnM2XMHqjzOzQXC5NsJAaQ0gd4HIaCgYKAawSARMSFQHGX2MijTO-loPa-7a97WycOEat1A0206", "refresh_token": "1//0eA6qtRCSTkERCgYIARAAGA4SNwF-L9Ir5SgGy2MpsHmXX1uNa8hJc_-i_zkyDdRh2-TuplZyeayJKwIegMpeWLjvwtl-I-9RTgA", "token_uri": "https://oauth2.googleapis.com/token", "client_id": "222243854357-eg5aquofa0epa3ri78k5ngpfclroc7rg.apps.googleusercontent.com", "client_secret": "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", "scopes": ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/script.projects"], "universe_domain": "googleapis.com", "account": "", "expiry": "2026-10-12T08:55:12Z"}
|
||||
{"token": "ya29.a0AehfTOlu7Fq0d_Zdgt-0GfZcA2S0671qpvV4n8cNlaKptSyctvQAAACvLpNkr-TISeBg67hmsCDHMjfztwpLUTokWo-AGoFhwK00SKCQ0btNAlDGr21fslVUAVWzep33843KvYILyP_6uFg_2I4sOoDEd4qn5ufRHd44RqJXVwRKOZSPQsxgHlu_mB_-OjHEa6GkLtEaCgYKAfoSARMSFQHGX2Mi0cQPJxIBf5cUoDp4_2LWOg0206", "refresh_token": "1//0eG7w85ZCkaY1CgYIARAAGA4SNwF-L9IriAMPwI3fHOObs-f7m62qLNtFB3yiHcTmfnP675RXTOY5cvwTqLqN7UbEo60fubuy300", "token_uri": "https://oauth2.googleapis.com/token", "client_id": "222243854357-eg5aquofa0epa3ri78k5ngpfclroc7rg.apps.googleusercontent.com", "client_secret": "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", "scopes": ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/script.projects"], "universe_domain": "googleapis.com", "account": "", "expiry": "2026-11-11T13:24:03Z"}
|
||||
@@ -194,3 +194,31 @@
|
||||
| P5 | 값이 빈 우리 자재 줄(치즐 0.7 · 0.4 등)에 이어진 줄 = 이음 완료(로직 문제 아님) · 0 원 줄 흠에서 뺌 · 자재표 값 보강은 27 년 초 프로그램 막바지(요구 776) — J 장 닫음 | 완료 처리 |
|
||||
| P6 | 콘크리트펌프용 파이프 = EST 「레미콘타설(펌프차)(배관타설)」 의 압송관 손료(직관 1 · 2 · 3m · 곡관 45 · 60 · 90° · 손료계수 4,500) · 현행 품셈 기계 목록에 없음 | 조사 끝 |
|
||||
| P7 | STmate 재료 DB 있나(요구 778) | 있음 — 설치 폴더 `ST_BSC\자재단가\시설공통자재\` 넷(2025-상 · 2025-하 · 2026-상 · 2026-상(06) 시설공통자재.STBSC · 각 약 180 KB) · 꼴 = 암호 걸린 ZIP(속 `COST.ST` 등) → 내용은 못 읽음 · 파일 자체는 우리 저장소에 없음(목록만 `STmate/old/30_원자료/system_inventory.csv`) · 공사 파일(.STC) 안 `COSTN` 표의 M 코드 자재(값 여섯 칸)는 지금도 읽음 | 조사 끝 |
|
||||
|
||||
## Q. 요구 781 결정
|
||||
|
||||
| # | 내용 | 상태 |
|
||||
|---|---|---|
|
||||
| Q1 | 없는 기계 경쟁사 계산(요구 781-1) — 전부 **표준 꼴**: 손료(손료계수 × 중기가격) + 주연료 + 잡품 + 조종원(파워트로웰 = +전력 · 브레이카 · 에어호스 · 콘크리트펌프 파이프 · 모노펌프 = 손료만) · **발전기 5.5kW 는 EST main 기계 DB 에 이미 있음**(계 37,760 = 손료 2,362 × 가격 + 경유 0.625ℓ + 잡품 11 % + 일반기계운전사 1인 · 2016 사방 엑셀도 같은 꼴) — 현행 품셈판에만 없음 · 압송관(콘크리트펌프 파이프) · 에어호스 등도 EST DB 에 손료 줄로 있음 | 조사 끝 |
|
||||
| Q2 | 별도계상 = 완료 처리(요구 781-2) — 단가산출에서 금액 안 매기고 프로젝트에서 연결(이미 반영) · 흠 · 미결 목록에서 뺌 | 완료 |
|
||||
| Q3 | 구글 시트 「수동연결(기계)」 · 「수동연결(자재)」 내용 지우고 미해결만 넣기(요구 781-3) — 기계 미해결 13(전부 「우리 표에 없음」 — 새 줄 필요) · 자재 미해결 49 종 | 시트 쓰기(토큰 재로그인 필요) |
|
||||
| Q4 | 자재표 값 보강 대상(요구 781-4) — 이어졌으나 우리 값 빈 자재 50 종(치즐 0.7㎥ 45 · 0.4㎥ 6 · 공기주입기 · 급수호스 · 시스템동바리 부품 · Air Hammer · Button Bit · 흙·골재·아스팔트·콘크리트 시험류 = 시험·견적 성격) · 우리 자재표 값 빈 줄 전체 464 / 30,711 | 시트에 넣기 |
|
||||
|
||||
## R. 없는 기계 값 출처(요구 782 ~ 784)
|
||||
|
||||
- 손료 = 손료계수(품셈) × 중기가격(가격 자료) + 주연료 + 잡품 + 조종원 — 가격 하나로는 못 셈 · 둘 다 필요(사용자 확인).
|
||||
- 공공데이터포털 키(DATA_GO_KR) = 정상(인증 통과) · 그러나 **조달청/나라장터에 건설기계 취득가격 전용 오픈API 없음**(종합쇼핑몰 품목 API = 서비스 폐기 응답 · 건설기계 중기가격 실시간 API 없음).
|
||||
- 공식 가격 출처 = **연간 고시 파일**: 행정안전부 「건설기계 표준시장가격」(원가계산·손료용 · 품셈 8-05 근거) · 「시가표준액표」(지방세용 — 성격 다름) · 연도별 「건설기계경비 산출표」(PDF · 손료계수 + 가격 함께) — 모두 API 아님(파일).
|
||||
- 손료계수 = 품셈 8장(상각·정비·관리 계수) · 소형(발전기 5.5·7·10kW)은 현행 품셈 가격표(25kW~)·손료계수표에 없음 → 같은 기종 계수(발전기 2,362 · 브레이커 6,601) 차용 + 가격은 행안부 표준시장가격 파일.
|
||||
- 사용자 뜻(요구 783 · 784): EST 숫자 안 씀 · 조달청/행안부 공식 자료로 · 행안부 시가표준액표가 있으면 사용.
|
||||
- 미정: 행안부 표준시장가격 파일을 (가) 사용자가 받아 줄지 (나) 브레인이 공개 연도별 「건설기계경비 산출표」에서 해당 기계 값만 뽑을지.
|
||||
|
||||
## S. 품셈 밖 기계·재료 = 개인 관리 검토(요구 790 · 사용자 결정 전)
|
||||
|
||||
- 기계표 668 줄 구성 꼴: 손료+연료+조종원 281 · 손료만 267 · 손료+연료 58 · 손료+조종원 19 · 가격 없는 줄 약 40 · 전력 1 → 네 꼴이 94 % → 신규 기계 입력 칸 = 이름·규격 · 가격 · 손료계수 · 주연료(종류 · ℓ/hr) · 잡품 % · 조종원(직종 · 인) (+ 전력 kWh) · 꼴은 채운 칸으로 자동.
|
||||
- 안 S1(1 번): M01 = 품셈 정본만 · 품셈 밖 기계 = M02 개인 층 「기계 시간당 경비」 단가산출 한 장(손료 = 가격 × 계수 · 주연료 → 우리 유가 · 잡품 % · 조종원 → 우리 노임) · 쓰는 단가산출은 그 장 참조 · 불러오기에서 못 이은 기계는 그 파일 구성(EST 원파일 구성표 · 엑셀 기계경비 시트)으로 자동 생성 · 구성 없는 파일(STmate 원파일)은 값 한 줄 장.
|
||||
- 안 S2(2 번): M01 기계 표 = 목록 · 줄 누르면 상세(값 묶음 · 시간당 계산식 미리보기 · 별칭 · 쓰는 곳) · S1 양식과 같은 부품.
|
||||
- 안 S3(3 번): 층마다 요소 표(저장소)를 새로 두는 것은 비권장(키 둘 · 찾는 차례 · 갱신 책임 · 동봉 · 삭제 깨짐) · 대신 「내 기계 · 내 품목」 모아 보기(읽기 중심 · 같은 이름 묶음 · 쓰는 곳 수) + 만들 때 같은 이름 안내.
|
||||
- 안 S4(4 번): 820-1 의 13 줄(EQ000656 ~ 668) · GC001195 는 S1 방향이면 지움 · 덤프 1 톤(산림품셈 10-9) · 체인톱 시간당 식(산림품셈 2 장) · 별칭 10 은 둠 · 시점 = S1 기능 넣는 묶음에서 같이(공백 없음).
|
||||
- S5(5 번): 차례 = 표기 엔진 · 별칭 · 같은 파일 대조로 품셈 요소에 최대한 → 남는 것만 개인 장 → 반복되면 마스터 승격 제안 · 불러오기 결과에 「개인 생성 n」 표시.
|
||||
- 참고: 현행 품셈 8 장에 조종원 노임 ×16/12 ×25/20 없음(우리 = ÷8) · EST 구성은 옛 환산 포함 → 자동 생성은 우리 틀에 값만 담는 쪽 권장.
|
||||
|
||||
@@ -949,3 +949,47 @@ STmate 의 「굴삭기(1.0m3)은 무한궤도
|
||||
2. 별도 계상은 완료처리하는게 맞는걸로 보임.
|
||||
3. 구글 스프레드시트의 내용 중 기계와 재료의 내용을 삭제하고 기계 별칭안들어간 항목과 해결되지 않은 자재들을 넣어줘.
|
||||
4. 자재표 값 보강이 어떤게 있는지 확인해서 스프레드시트에 넣어줘.
|
||||
|
||||
## 요구 782 (11-11 · 사용자 · 서버 로그인 확인 · 랩탑 앞 · 시트 재인증 · 1·2 기계 새로 추가하되 EST 말고 조달청 자료로 가능한지)
|
||||
|
||||
(서버 재시작 · 구글 재인증 · 시트 세 탭 갱신 요청 포함)
|
||||
1,2 기계를 새로 추가하는게 좋을것같아. 대신 EST 자료 말고 조달청 자료들로 하고 싶은데 가능할까?
|
||||
|
||||
## 요구 783 (11-11 · 사용자 · 1 조달청 장비 가격 API 로 확인 · 2 다른 워크트리에게 — M02 좌측 패널의 단가산출·일위대가 컨테이너 내부 내용 안 보임 확인)
|
||||
|
||||
2번 API로 일단 확인해봐.
|
||||
추가로 다른 워크트리에게 M02의 좌측 패널의 단가산출과 일위대가 컨테이너 내부 내용이 안보임. 확인
|
||||
|
||||
## 요구 784 (11-11 · 사용자 · 행안부 건설기계 시가표준액표가 있으면 쓰는 것도 좋아 보임)
|
||||
|
||||
행안부 건설기계 시가표준액표가 있다면 사용하는것도 좋아보임.
|
||||
|
||||
## 요구 785 (11-11 · 사용자 · 우리 단가에 계산식도 표현돼야 하는데 가능한지 · 가능하면 이 자료를 기술정보 DB 에 md 화해 보관해야 하는지 검토)
|
||||
|
||||
그런데 우리 단가에는 계산식도 표현이 되어야하는데 가능한거지? 그리고 가능하다면 이자료를 기술정보 DB에 md화해서 보관해야하는건 아닌지 검토
|
||||
|
||||
## 요구 786 (11-11 · 사용자 · 확인했음 · 품셈 원문엔 우리가 찾는 정보 없음 · 일단 확인 진행)
|
||||
|
||||
내가 확인했음. 품셈원문을 기준으로 해서 우리가 찾아야하는 정보가 없기는 함. 일단 확인은 진행해봐.
|
||||
|
||||
## 요구 787 (11-11 · 사용자 · 1 기계 만들기 맞음 · 일단 만들어 두고 가격만 확인(어디서 받을지 확인) · 2 엑셀 불러오기 테스트 — 상단 변수 영역은 옵션 선택지 있을 때만 쓰는 곳 · 외부 단가산출 불러오면 옵션 못 쓰고 고정 항목으로 제어 · 상단 값은 좌측 영역에도 있으니 중복 표기 불필요 · 좌측 영역 내용은 유지)
|
||||
|
||||
일단은 기계를 만드는건 맞는것같음. 일단 만들두고 가격만 확인하면 되니까 어디서 받을지 확인해줘.
|
||||
다음 엑셀불러오기로 테스트 해봤음. 이렇게 나오는데 위에 영역은 옵션 변경에따른 선택지가 있는 경우에나 사용되는 영역. 하지만 외부의 단가산출을 불러올 경우 옵션을 사용할 수 없고 고정된 항목들로 제어해야되는 상황임. 그러니 상단의 값들은 사실 좌측영역에도 들어가 있으니 중복표기할 필요없음. 좌측 영역의 내용은 유지.
|
||||
|
||||
## 요구 788 (11-11 · 사용자 · 요청 업무 다 끝나면 랩탑 워크트리 깃 싱크 · 데스크탑 워크트리 제외)
|
||||
|
||||
내가 요청한 업므 다 끝나면 랩탑 워크트리 깃싱크 . 데스크탑 워크트리 제외
|
||||
|
||||
## 요구 789 (11-12 · 사용자 · 경쟁사 세 파일 현재 매칭율 표시)
|
||||
|
||||
경쟁사 3개 파일 현재 매칭율 표시
|
||||
|
||||
## 요구 790 (11-12 · 사용자 · 정밀 검토 요청 — 1 우리 기계는 품셈 기준 그대로 · 새 기계·재료는 M02 단가산출로 개인 관리 · 기계 패턴 분석해 쉬운 신규 기계 생성 로직 · 2 M01 기계 컨테이너 = 표라 값 확인·수정 불편 → 별도 페이지 · 3 M02 에도 기계·재료 개인 관리 기능(중복 확인 · 단가산출 만들 때 복사) — 관리 안 될 것 같으면 반영 안 함 · 4 매칭 안 돼 추가한 기계 10 여 개 삭제 여부 · 5 특수한 경우 빼면 매칭을 높여 개인 관리 최소화)
|
||||
|
||||
1. 잠시 고민해봤는데 조금 문제가 있네. 나중에 다른 기계나 신규 재료 품목이 들어올 경우가 문제네. 우리의 기계는 품셈을 기준으로 그냥두고 새로운 기계나 재료의 경우 m02의 단가산출로 개인관리하게 하는건 어떤가해서? 자재는 품목과 값만 있으면 되니까 문제가 없는데 기계의 경우 조금 복잡함. 기계들의 패턴을 분석해서 쉽게 만드는 방법이 없는지 검토. 이런 기능이 있으면 경쟁사 프로그램에서 가져오는 정보 중 매칭이 안되는 것이 있다고 하더라도 문제없을것같아서 말이야. 그렇다면 단순한 신규 기계 생성로직이 필요한거야.
|
||||
2. m01의 기계 컨테이너의 페이지가 테이블로 구성되어 있음. 리스트는 문제가 없으나값확인이나 수정이 불편함. 별도의 페이지로 접근하게 반영.
|
||||
3. m02에 m01에서와 동일하게 기계와 재료를 개인이 관리할 수 있는 기능이 있는게 어떤지 그럼 중복확인이 쉬울것같은데. 이 역시도 단가산출을 생성할때는 복사하여 사용하는거지. 어떻게 생각함. 관리가 안될것같으면 반영안할거야.
|
||||
4. 이전 반영 중 매칭이 안되서 추가한 기계 10여개는 삭제하는게 어떤지.
|
||||
5. 하지만 특수한 경우를 제외하면 매칭을 높여 개인관리를 최소화해야하는건 맞아.
|
||||
일단 정밀 검토해보자.
|
||||
|
||||
@@ -96,3 +96,22 @@ last_updated: 2026-08-15
|
||||
| 운전사 3구분·수송비·시공능력 기본식 | 건설품셈 8-1-3 ~ 8-1-4 | 〃 |
|
||||
| 환율·유가 원천과 스냅샷 | ECOS·오피넷 실사 2026-08-14 | [원가_기초데이터_원천 §4](원가_기초데이터_원천.md) |
|
||||
| ESTX 기계경비 조립 관측 | 2026-07 배포본 재검증 | [원가_기초데이터_원천 §3](원가_기초데이터_원천.md) |
|
||||
|
||||
## 7. 품셈에 없는 소형·보조 기계 — EST 구성 기준 · 가격 갱신 필요
|
||||
|
||||
현행 품셈 기계 목록(발전기 25㎾~ 등)에 없는 기계를 EST 단가 구성대로 우리 기계표에 둔 줄. 손료계수 · 연료 · 잡품 · 조종원 = 품셈 값(같은 계열 차용) · 가격 = EST 씨앗(임시) — 조달청 · 행안부 건설기계 표준시장가격 · 제조사 값으로 바꿀 것.
|
||||
|
||||
| 기종 | 규격 | 손료계수(10⁻⁷/hr) | 연료 · 잡품 · 전력 | 조종원 | 가격 씨앗(천원) | 시간당 식 | 출처 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 발전기 | 5.5㎾ | 2,362(발전기 계열) | 경유 0.625ℓ · 11 % | 일반기계운전사 1 | 1,063 | GC000268 | EST · 2016 사방품셈(안) 같은 꼴 |
|
||||
| 발전기 | 7㎾ | 2,362 | — | — | 1,828.9 | GC000273(손료만) | 2016 사방품셈(안) 기계경비 |
|
||||
| 발전기 | 10㎾ | 2,362 | — | — | 3,213 | GC000273 | 2016 사방품셈(안) 기계경비 |
|
||||
| 대형 브레이커 | 0.18㎥ | 6,601(0.2㎥ 계수) | — | — | 4,559(0.2㎥ 값) | GC000273 | 굴착기 부속 · 우리 0.2㎥ 줄 |
|
||||
| 에어 호스 | 1.91㎝ | 5,625 | — | — | 105 | GC000273 | EST |
|
||||
| 모노펌프 | 5-20㎥/hr | 4,346 | — | — | 4,900 | GC000273 | EST |
|
||||
| 파워트로웰 | 3.73㎾ | 5,313 | 휘발유 1.0ℓ · 10 % · 전력 3.73㎾h | — | 2,680 | GC001195 | EST |
|
||||
| 콘크리트펌프용 파이프(압송관) | 150㎜ × 1 · 2 · 3m · 곡관 45 · 60 · 90° | 4,500 | — | — | $25 · 37 · 46 · 67 · 84 · 103 × 환율 | GC000273 | EST($ 표기) · 환율 FX000001 |
|
||||
|
||||
- 손료 = 버림(가격 × 1,000 × 손료계수 ÷ 10⁷) · 조종원 = 하루 노임 × 1/8(품셈 본문 · EST 의 16/12 · 25/20 뺌).
|
||||
- 파워트로웰 잡품 = 주연료 줄의 % (전력 줄엔 안 붙임).
|
||||
- 파이프 가격 = 달러 표기 → 환율 적용값 · 원화 갱신 필요.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"다음": {"LB": 409, "EQ": 656, "RT": 20, "MN": 7000, "MT": 30719, "MO": 74, "MP": 364, "FX": 6, "CF": 159, "QF": 477, "GF": 338, "CC": 528, "GC": 1195, "QC": 2060, "GX": 5, "UA": 38},
|
||||
"다음": {"LB": 409, "EQ": 669, "RT": 20, "MN": 7000, "MT": 30719, "MO": 74, "MP": 364, "FX": 6, "CF": 159, "QF": 477, "GF": 338, "CC": 528, "GC": 1196, "QC": 2060, "GX": 5, "UA": 38},
|
||||
"폐기": {"MT000001": "자재품목 휘발유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000002": "자재품목 경유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000003": "자재품목 선박용경유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000004": "자재품목 중유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000005": "자재품목 등유 — 값이 비고 글뿐 · 유가 테이블로 감", "LB000399": "이름 「〃」 — 직종이 아니라 되풀이 기호 · 소요량 13-6-9 에서 윗줄 직종으로 바로잡음", "MN": "재료_나라장터자재 — old 로 옮김 · 로직은 자재품목·품셈재료로 갈아 끼움", "LB000372": "미확보 고급기능사 — 측량노임 항공사진고급기능사 옛이름으로 옮김", "LB000393": "미확보 리베팅공 — 건설노임 철골공 옛이름으로 옮김(2010 통합표 연번10)", "LB000405": "미확보 Belt Conveyor 설치공 — 품셈 13-10-1 주② 배분으로 다섯 직종에 나눔", "MT000006": "자재품목 전력 — 재료_유가전력 전력 줄로 감", "MT000007": "자재품목 전력 — 재료_유가전력 전력 줄로 감", "LB000368": "미확보 기술사 — 기술사(건설) 옛이름으로 옮김", "LB000369": "미확보 특급기술자 — 특급기술자(건설) 옛이름으로 옮김", "LB000370": "미확보 고급기술자 — 고급기술자(건설) 옛이름으로 옮김", "LB000361": "미확보 중급기술자 — 중급기술자(건설) 옛이름으로 옮김", "LB000364": "미확보 초급기술자 — 초급기술자(건설) 옛이름으로 옮김", "LB000365": "미확보 고급숙련기술자 — 고급숙련기술자(건설) 옛이름으로 옮김", "LB000366": "미확보 중급숙련기술자 — 중급숙련기술자(건설) 옛이름으로 옮김", "LB000367": "미확보 초급숙련기술자 — 초급숙련기술자(건설) 옛이름으로 옮김", "LB000389": "미확보 기계기사 — 초급기술자(기계·설비) 옛이름으로 옮김", "LB000388": "미확보 기계산업기사 — 초급숙련기술자(기계·설비) 옛이름으로 옮김", "MO000055": {"원문번호": "주택용저압:기본_200이하", "파일": "재료_유가전력.json"}, "MO000056": {"원문번호": "주택용저압:기본_201~400", "파일": "재료_유가전력.json"}, "MO000057": {"원문번호": "주택용저압:기본_400초과", "파일": "재료_유가전력.json"}, "MO000059": {"원문번호": "주택용저압:전력량_다음200", "파일": "재료_유가전력.json"}, "MO000060": {"원문번호": "주택용저압:전력량_400초과", "파일": "재료_유가전력.json"}, "MO000061": {"원문번호": "주택용저압:월간최저요금", "파일": "재료_유가전력.json"}, "MO000062": {"원문번호": "일반용갑I저압:기본", "파일": "재료_유가전력.json"}, "MO000063": {"원문번호": "일반용갑I저압:전력량_여름철", "파일": "재료_유가전력.json"}, "MO000064": {"원문번호": "일반용갑I저압:전력량_봄가을철", "파일": "재료_유가전력.json"}, "MO000065": {"원문번호": "일반용갑I저압:전력량_겨울철", "파일": "재료_유가전력.json"}, "MO000066": {"원문번호": "산업용갑I저압:기본", "파일": "재료_유가전력.json"}, "MO000067": {"원문번호": "산업용갑I저압:전력량_여름철", "파일": "재료_유가전력.json"}, "MO000068": {"원문번호": "산업용갑I저압:전력량_봄가을철", "파일": "재료_유가전력.json"}, "MO000069": {"원문번호": "산업용갑I저압:전력량_겨울철", "파일": "재료_유가전력.json"}, "MO000070": {"원문번호": "임시전력갑:기본요금적용", "파일": "재료_유가전력.json"}, "MO000071": {"원문번호": "임시전력갑:전력량요금적용", "파일": "재료_유가전력.json"}, "MO000072": {"원문번호": "임시전력갑:월간최저요금", "파일": "재료_유가전력.json"}, "GC001145": "작업량당 기계경비 — 부르는 곳 0 · 필요하면 단가산출에 기계 하나 넣어 만듦(요구 734-4 · 735-4 · 813-2)", "GC001148": "작업량당 기계경비 — 부르는 곳 0 · 필요하면 단가산출에 기계 하나 넣어 만듦(요구 734-4 · 735-4 · 813-2)", "GC001151": "작업량당 기계경비 — 부르는 곳 0 · 필요하면 단가산출에 기계 하나 넣어 만듦(요구 734-4 · 735-4 · 813-2)", "GC001156": "작업량당 기계경비 — 부르는 곳 0 · 필요하면 단가산출에 기계 하나 넣어 만듦(요구 734-4 · 735-4 · 813-2)", "GC001159": "작업량당 기계경비 — 부르는 곳 0 · 필요하면 단가산출에 기계 하나 넣어 만듦(요구 734-4 · 735-4 · 813-2)", "GC001166": "작업량당 기계경비 — 부르는 곳 0 · 필요하면 단가산출에 기계 하나 넣어 만듦(요구 734-4 · 735-4 · 813-2)"},
|
||||
"키": {
|
||||
"CC000001": {"원문번호": "공통 1-3-1 콘크리트 및 포장용 재료", "파일": "계수_건설품셈_01장_적용기준.json"},
|
||||
@@ -1342,6 +1342,19 @@
|
||||
"EQ000653": {"원문번호": "2-2-11 트럭탑재형크레인", "파일": "기계.json"},
|
||||
"EQ000654": {"원문번호": "2-2-11 타이어형크레인", "파일": "기계.json"},
|
||||
"EQ000655": {"원문번호": "10-9 덤프트럭(4륜구동) 1ton", "파일": "기계.json"},
|
||||
"EQ000656": {"원문번호": "자체 발전기 5.5㎾", "파일": "기계.json"},
|
||||
"EQ000657": {"원문번호": "자체 발전기 7㎾", "파일": "기계.json"},
|
||||
"EQ000658": {"원문번호": "자체 발전기 10㎾", "파일": "기계.json"},
|
||||
"EQ000659": {"원문번호": "자체 대형 브레이커 0.18㎥", "파일": "기계.json"},
|
||||
"EQ000660": {"원문번호": "자체 에어 호스 1.91㎝", "파일": "기계.json"},
|
||||
"EQ000661": {"원문번호": "자체 모노펌프 5-20㎥/hr", "파일": "기계.json"},
|
||||
"EQ000662": {"원문번호": "자체 파워트로웰 3.73㎾", "파일": "기계.json"},
|
||||
"EQ000663": {"원문번호": "자체 콘크리트펌프용 파이프 150㎜×1m", "파일": "기계.json"},
|
||||
"EQ000664": {"원문번호": "자체 콘크리트펌프용 파이프 150㎜×2m", "파일": "기계.json"},
|
||||
"EQ000665": {"원문번호": "자체 콘크리트펌프용 파이프 150㎜×3m", "파일": "기계.json"},
|
||||
"EQ000666": {"원문번호": "자체 콘크리트펌프용 파이프 곡관 150㎜ 45°", "파일": "기계.json"},
|
||||
"EQ000667": {"원문번호": "자체 콘크리트펌프용 파이프 곡관 150㎜ 60°", "파일": "기계.json"},
|
||||
"EQ000668": {"원문번호": "자체 콘크리트펌프용 파이프 곡관 150㎜ 90°", "파일": "기계.json"},
|
||||
"FX000001": {"원문번호": "0000001", "파일": "환율_한국은행환율.json"},
|
||||
"FX000002": {"원문번호": "0000002", "파일": "환율_한국은행환율.json"},
|
||||
"FX000003": {"원문번호": "0000003", "파일": "환율_한국은행환율.json"},
|
||||
@@ -2535,6 +2548,7 @@
|
||||
"GC001192": {"원문번호": "공통 1-5-4 건설폐기물 발생량", "파일": "로직_건설품셈_01장_적용기준.json"},
|
||||
"GC001193": {"원문번호": "공통 1-5-6 공사용수", "파일": "로직_건설품셈_01장_적용기준.json"},
|
||||
"GC001194": {"원문번호": "공통 3-2-1 잔토처리(인력)", "파일": "로직_건설품셈_03장_토공사.json"},
|
||||
"GC001195": {"원문번호": "공통 8 파워트로웰 시간당 경비", "파일": "로직_건설품셈_08장_건설기계.json"},
|
||||
"GF000001": {"원문번호": "3-1 경계표시", "파일": "로직_산림품셈_03장_작업장_관리.json"},
|
||||
"GF000002": {"원문번호": "3-3 작업로 설치", "파일": "로직_산림품셈_03장_작업장_관리.json"},
|
||||
"GF000003": {"원문번호": "3-4-2 임산물 운반로 신설 작업량", "파일": "로직_산림품셈_03장_작업장_관리.json"},
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
"""품셈에 없는 소형 · 보조 기계를 우리 기계표 줄로(PLAN 820-1 · 요구 785 ~ 787 · 방향 장부 Q1 · R).
|
||||
|
||||
EST 단가 구성 → 우리 줄 — 손료계수 · 연료 · 잡품 · 조종원 = 품셈 값(발전기 계열 2,362 · 대형 브레이커 6,601) ·
|
||||
가격 = EST 씨앗(출처 「자체」 · 비고 「갱신 필요」) · 콘크리트펌프용 파이프 = 달러값 × 한국은행 환율(FX000001).
|
||||
계산식:
|
||||
손료만(브레이커 0.18 · 에어 호스 · 모노펌프 · 파이프 · 발전기 7 · 10㎾) = GC000273 고르기에 더함
|
||||
발전기 5.5㎾(경유 · 잡품 · 일반기계운전사) = GC000268 고르기에 더함
|
||||
→ 고르기 더하기는 `build_기계목록_빠진기계_814_1`(로직 · 수식 문서 목록 같이)
|
||||
파워트로웰(휘발유 · 잡품 · 전력 · 조종원 없음) = 새 기계경비식 GC001195 — 기계 줄 값을 바로 읽음
|
||||
(`M02_Machine_Hourly._own` 이 고름) · 잡품 = 주연료 줄의 % (전력 줄엔 안 붙임)
|
||||
더하기만 — 다른 줄 · 서식 그대로 · 두 번 돌려도 같음.
|
||||
|
||||
쓰기: venv python resources/master_data/scripts/build_기계_소형보조_820_1.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
DATA = HERE.parent
|
||||
ROOT = DATA.parents[1]
|
||||
MACHINE = DATA / "기계.json"
|
||||
BOOK = DATA / "_키대장.json"
|
||||
LOGIC = DATA / "로직_건설품셈_08장_건설기계.json"
|
||||
DOC = DATA / "수식문서" / "수식_건설품셈_08장_건설기계.json"
|
||||
|
||||
USD = 1414.9 # 원/USD — 한국은행 환율 FX000001(2026-08-14)
|
||||
SEED = "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요)"
|
||||
GEN = {"상각비계수": 1125, "정비비계수": 563, "관리비계수": 674, "손료계수": 2362} # 발전기 계열
|
||||
BRK = {"상각비계수": 3000, "정비비계수": 2833, "관리비계수": 768, "손료계수": 6601} # 0230-0002
|
||||
UNIT = {
|
||||
"가격": "천원", "상각비계수": "10^-7/시간", "정비비계수": "10^-7/시간",
|
||||
"관리비계수": "10^-7/시간", "손료계수": "10^-7/시간", "주연료": "ℓ/hr", "주연료종류": "",
|
||||
"잡재료율": "주연료의 %", "조종원": "인/일", "조종원직종": "", "전력": "㎾h/hr",
|
||||
} # fmt: skip
|
||||
FIX_SRC = {"발전기": "건설품셈 공통 8-3-8", "브레이커": "건설품셈 공통 8-3-1"}
|
||||
WAGE = "건설품셈 공통 8-1-3 5 · 건설노임 1050"
|
||||
SAB = "2016 사방사업표준품셈(안) 기계경비"
|
||||
PIPE = {"150㎜×1m": 25, "150㎜×2m": 37, "150㎜×3m": 46,
|
||||
"곡관 150㎜ 45°": 67, "곡관 150㎜ 60°": 84, "곡관 150㎜ 90°": 103} # fmt: skip
|
||||
|
||||
|
||||
def _row(n, gubun, detail, name, spec, value, note, fix=None):
|
||||
src = {k: (FIX_SRC[fix] if fix and k in GEN else "자체") for k in value}
|
||||
if "조종원직종" in value:
|
||||
src["조종원직종"] = WAGE
|
||||
return {
|
||||
"키": f"EQ{n:06d}",
|
||||
"원문번호": f"자체 {name} {spec}",
|
||||
"원문": "건설품셈",
|
||||
"구분": gubun,
|
||||
"상세구분": detail,
|
||||
"이름": name,
|
||||
"규격": spec,
|
||||
"단위": {k: UNIT[k] for k in value},
|
||||
"값": value,
|
||||
"출처": src,
|
||||
"비고": f"{SEED} · {note}",
|
||||
}
|
||||
|
||||
|
||||
def rows() -> list[dict]:
|
||||
g, c, t = "[70]기타기계", "[40]콘크리트기계", "[00]토공기계"
|
||||
fuel5 = {
|
||||
"주연료": 0.625,
|
||||
"주연료종류": "경유",
|
||||
"잡재료율": 11,
|
||||
"조종원": 1,
|
||||
"조종원직종": "1050",
|
||||
}
|
||||
out = [
|
||||
_row(656, g, "발전기", "발전기", "5.5㎾", {"가격": 1063, **GEN, **fuel5},
|
||||
"EST 계 37,760 · 주연료 · 잡품 · 조종원(일반기계운전사) = " + SAB + "과 같음", "발전기"),
|
||||
_row(657, g, "발전기", "발전기", "7㎾", {"가격": 1828.9, **GEN},
|
||||
f"가격 = {SAB}(1,828,900 원) · 그 표 = 손료만(연료 · 조종원 없음)", "발전기"),
|
||||
_row(658, g, "발전기", "발전기", "10㎾", {"가격": 3213, **GEN},
|
||||
f"가격 = {SAB}(3,213,000 원) · 그 표 = 손료만(연료 · 조종원 없음)", "발전기"),
|
||||
_row(659, t, "브레이커", "대형 브레이커", "0.18㎥", {"가격": 4559, **BRK},
|
||||
"손료만(굴착기 부속) · 가격 = 0.2㎥(0230-0002) 값 · 계수 = 0.2㎥ 계수", "브레이커"),
|
||||
_row(660, g, "에어 호스", "에어 호스", "1.91㎝", {"가격": 105, "손료계수": 5625},
|
||||
"손료만 · EST 계 59"),
|
||||
_row(661, g, "모노펌프", "모노펌프", "5-20㎥/hr", {"가격": 4900, "손료계수": 4346},
|
||||
"손료만 · EST 계 2,129"),
|
||||
_row(662, c, "파워트로웰", "파워트로웰", "3.73㎾",
|
||||
{"가격": 2680, "손료계수": 5313, "주연료": 1.0, "주연료종류": "휘발유", "잡재료율": 10, "전력": 3.73},
|
||||
"주연료 휘발유 · 잡품 · 전력 3.73 ㎾h · 조종원 없음 · EST 계 3,858 · 시간당 경비 = GC001195"),
|
||||
] # fmt: skip
|
||||
for i, (spec, usd) in enumerate(PIPE.items()):
|
||||
out.append(
|
||||
_row(663 + i, c, "콘크리트펌프용 파이프", "콘크리트펌프용 파이프", spec,
|
||||
{"가격": round(usd * USD / 1000, 4), "손료계수": 4500},
|
||||
f"압송관 · 손료만 · ${usd} 표기 · 환율 적용({USD:,} 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요")
|
||||
) # fmt: skip
|
||||
return out
|
||||
|
||||
|
||||
EQ = "EQ000662"
|
||||
LOGIC_ROW = {
|
||||
"키": "GC001195",
|
||||
"원문번호": "8",
|
||||
"구분": "건설품셈 공통",
|
||||
"상세구분": "08장 건설기계",
|
||||
"이름": "파워트로웰 시간당 기계경비",
|
||||
"결과단위": "원/시간",
|
||||
"출처": "건설품셈 공통 8-1-5 · 8-1-6",
|
||||
"부품": {"갈래": "기계경비식"},
|
||||
"소유": "공용",
|
||||
"비고": f"품셈에 없는 기계 — {SEED} · 기계표 {EQ} 파워트로웰 3.73㎾ 값을 읽음 · 손료 = 가격 × 손료계수 · 잡품 = 주연료 줄의 % · 전력 = 기계표 전력 칸 · 조종원 없음",
|
||||
"입력": [
|
||||
{
|
||||
"이름": "지역",
|
||||
"고르기": ["전국평균", "전국", "서울", "경기", "강원", "충북", "충남", "전북", "경북", "경남", "부산", "제주", "대구", "인천", "대전", "울산", "세종", "전남광주"],
|
||||
"출처": "건설품셈 공통 8-1-7 5",
|
||||
},
|
||||
{
|
||||
"이름": "전력 계약종별",
|
||||
"고르기": ["주택용 저압", "일반용(갑)Ⅰ 저압"],
|
||||
"출처": "유가전력 한전 전기요금표 2025-01-01",
|
||||
"비고": "품셈·계약예규에 계약종별 규정 없음(전력비는 실비 계상) · 임시전력(갑)은 주택용 저압 요금 그대로(요금표 6.가)",
|
||||
},
|
||||
],
|
||||
"중간": [
|
||||
{"이름": "손료", "식": f"버림({EQ}.가격 * 1000 * {EQ}.손료계수 / 10000000, 0)", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4"},
|
||||
],
|
||||
"호표": [
|
||||
{"종류": "재료", "요소": "MO:휘발유:{지역}", "이름": "주연료", "단위": "ℓ", "수량": f"{EQ}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1"},
|
||||
{"종류": "재료", "요소": {"이름": "전력량요금", "계약종별": "입력"}, "이름": "전력", "단위": "㎾h", "수량": f"{EQ}.전력", "비목": "재료비", "출처": "자체"},
|
||||
],
|
||||
"덧줄": [
|
||||
{"이름": "잡재료비", "식": f"줄.'주연료' * {EQ}.잡재료율 / 100", "비목": "재료비", "출처": "건설품셈 공통 8-4 주②"},
|
||||
{"이름": "기계손료", "식": "손료", "비목": "경비", "출처": "건설품셈 공통 8-1-6 2"},
|
||||
],
|
||||
"끝수": "손료 원 미만 버림(건설품셈 공통 8-1-5 12) · 합계 원문 규정 없음",
|
||||
"변수표": {
|
||||
"지역": {"기호": "S", "아래": "지역"},
|
||||
"전력 계약종별": {"기호": "S", "아래": "전력계약종별"},
|
||||
"손료": {"기호": "C", "아래": "손료"},
|
||||
},
|
||||
} # fmt: skip
|
||||
|
||||
|
||||
def _block(obj: dict, nl: str) -> str:
|
||||
"""줄 하나 — 두 칸 들여쓴 JSON 을 넷 칸 자리에."""
|
||||
text = json.dumps(obj, ensure_ascii=False, indent=2)
|
||||
return nl.join(" " + line for line in text.split("\n"))
|
||||
|
||||
|
||||
def _insert_tail(path: Path, objs: list[dict]) -> None:
|
||||
"""「줄」 목록 끝(`]` 앞)에 더함 — 이미 있는 키는 건너뜀."""
|
||||
text = path.read_text("utf-8")
|
||||
have = {r["키"] for r in json.loads(text)["줄"]}
|
||||
new = [o for o in objs if o["키"] not in have]
|
||||
if not new:
|
||||
return
|
||||
nl = "\r\n" if "\r\n" in text else "\n"
|
||||
close = text.rstrip().rindex("]")
|
||||
head = text[:close].rstrip()
|
||||
body = "".join(f",{nl}{_block(o, nl)}" for o in new)
|
||||
out = head + body + nl + " " + text[close:]
|
||||
json.loads(out)
|
||||
path.write_text(out, "utf-8", newline="")
|
||||
|
||||
|
||||
def _insert_after(path: Path, after_key: str, obj: dict) -> None:
|
||||
"""키 `after_key` 블록 뒤에 줄 하나 — 이미 있으면 건너뜀."""
|
||||
text = path.read_text("utf-8")
|
||||
if f'"키": "{obj["키"]}"' in text:
|
||||
return
|
||||
nl = "\r\n" if "\r\n" in text else "\n"
|
||||
data = json.loads(text)
|
||||
at = text.index(f'"키": "{after_key}"')
|
||||
nxt = [r["키"] for r in data["줄"]]
|
||||
follow = nxt[nxt.index(after_key) + 1]
|
||||
cut = text.rindex("{", 0, text.index(f'"키": "{follow}"'))
|
||||
cut = text.rindex(",", at, cut) + 1
|
||||
out = text[:cut] + nl + _block(obj, nl) + "," + text[cut:]
|
||||
json.loads(out)
|
||||
path.write_text(out, "utf-8", newline="")
|
||||
|
||||
|
||||
def _book(machines: list[dict]) -> None:
|
||||
text = BOOK.read_text("utf-8")
|
||||
nl = "\r\n" if "\r\n" in text else "\n"
|
||||
adds = [(r["키"], r["원문번호"], "기계.json", "EQ000655") for r in machines]
|
||||
adds.append(("GC001195", "공통 8 파워트로웰 시간당 경비", LOGIC.name, "GC001194"))
|
||||
for key, number, file, after in adds:
|
||||
if f'"{key}":' in text:
|
||||
continue
|
||||
line = f' "{key}": {json.dumps({"원문번호": number, "파일": file}, ensure_ascii=False)},'
|
||||
prev = max((k for k, *_ in adds if k[:2] == key[:2] and f'"{k}":' in text), default=after)
|
||||
at = text.index(f' "{prev}":')
|
||||
end = text.index(nl, at) + len(nl)
|
||||
text = text[:end] + line + nl + text[end:]
|
||||
book = json.loads(text)
|
||||
nums = {"EQ": 669, "GC": 1196}
|
||||
for tid, n in nums.items():
|
||||
old = book["다음"][tid]
|
||||
if old < n:
|
||||
text = text.replace(f'"{tid}": {old},', f'"{tid}": {n},', 1)
|
||||
json.loads(text)
|
||||
BOOK.write_text(text, "utf-8", newline="")
|
||||
|
||||
|
||||
def _doc() -> None:
|
||||
"""GC001195 수식 문서 — 옛 로직 변환(`master_doc_convert`) · 파일 끝에 더함."""
|
||||
for p in (str(ROOT), str(HERE)):
|
||||
if p not in sys.path:
|
||||
sys.path.insert(0, p)
|
||||
import master_doc_convert as cv
|
||||
import master_doc_link as ml
|
||||
|
||||
from M01_MasterData import M01_MasterData_Store as m01
|
||||
|
||||
data = json.loads(DOC.read_text("utf-8"))
|
||||
if any(d.get("키") == "GC001195" for d in data["줄"]):
|
||||
return
|
||||
files, whole = m01.loaded()
|
||||
doc, notes = cv.convert(whole, LOGIC_ROW)
|
||||
if notes:
|
||||
print("변환 알림:", notes)
|
||||
data["줄"].append(doc)
|
||||
DOC.write_text(ml.dump(data), "utf-8", newline="")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
machines = rows()
|
||||
_insert_tail(MACHINE, machines)
|
||||
_book(machines)
|
||||
_insert_after(LOGIC, "GC000276", LOGIC_ROW)
|
||||
_doc()
|
||||
import build_기계목록_빠진기계_814_1 as b814
|
||||
|
||||
b814.main()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.path.insert(0, str(HERE))
|
||||
main()
|
||||
@@ -39717,6 +39717,355 @@
|
||||
"가격": "산림품셈 10-9"
|
||||
},
|
||||
"비고": "원문 이름: 4륜구동 1톤 덤프트럭 · 중기가격 = 조달청 등재가격(기본값 28,000 천원 = EST 2026-07 「덤프트럭 1.0Ton」 · 바꿀 수 있음) · 작업량은 건설품셈 · 손료 및 운전경비 = 2.5톤 덤프트럭(0602-0025) · 주 연료 = 2.5톤의 80% · 시간당 경비 = GF000145"
|
||||
},
|
||||
{
|
||||
"키": "EQ000656",
|
||||
"원문번호": "자체 발전기 5.5㎾",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[70]기타기계",
|
||||
"상세구분": "발전기",
|
||||
"이름": "발전기",
|
||||
"규격": "5.5㎾",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"상각비계수": "10^-7/시간",
|
||||
"정비비계수": "10^-7/시간",
|
||||
"관리비계수": "10^-7/시간",
|
||||
"손료계수": "10^-7/시간",
|
||||
"주연료": "ℓ/hr",
|
||||
"주연료종류": "",
|
||||
"잡재료율": "주연료의 %",
|
||||
"조종원": "인/일",
|
||||
"조종원직종": ""
|
||||
},
|
||||
"값": {
|
||||
"가격": 1063,
|
||||
"상각비계수": 1125,
|
||||
"정비비계수": 563,
|
||||
"관리비계수": 674,
|
||||
"손료계수": 2362,
|
||||
"주연료": 0.625,
|
||||
"주연료종류": "경유",
|
||||
"잡재료율": 11,
|
||||
"조종원": 1,
|
||||
"조종원직종": "1050"
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"상각비계수": "건설품셈 공통 8-3-8",
|
||||
"정비비계수": "건설품셈 공통 8-3-8",
|
||||
"관리비계수": "건설품셈 공통 8-3-8",
|
||||
"손료계수": "건설품셈 공통 8-3-8",
|
||||
"주연료": "자체",
|
||||
"주연료종류": "자체",
|
||||
"잡재료율": "자체",
|
||||
"조종원": "자체",
|
||||
"조종원직종": "건설품셈 공통 8-1-3 5 · 건설노임 1050"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · EST 계 37,760 · 주연료 · 잡품 · 조종원(일반기계운전사) = 2016 사방사업표준품셈(안) 기계경비과 같음"
|
||||
},
|
||||
{
|
||||
"키": "EQ000657",
|
||||
"원문번호": "자체 발전기 7㎾",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[70]기타기계",
|
||||
"상세구분": "발전기",
|
||||
"이름": "발전기",
|
||||
"규격": "7㎾",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"상각비계수": "10^-7/시간",
|
||||
"정비비계수": "10^-7/시간",
|
||||
"관리비계수": "10^-7/시간",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 1828.9,
|
||||
"상각비계수": 1125,
|
||||
"정비비계수": 563,
|
||||
"관리비계수": 674,
|
||||
"손료계수": 2362
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"상각비계수": "건설품셈 공통 8-3-8",
|
||||
"정비비계수": "건설품셈 공통 8-3-8",
|
||||
"관리비계수": "건설품셈 공통 8-3-8",
|
||||
"손료계수": "건설품셈 공통 8-3-8"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 가격 = 2016 사방사업표준품셈(안) 기계경비(1,828,900 원) · 그 표 = 손료만(연료 · 조종원 없음)"
|
||||
},
|
||||
{
|
||||
"키": "EQ000658",
|
||||
"원문번호": "자체 발전기 10㎾",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[70]기타기계",
|
||||
"상세구분": "발전기",
|
||||
"이름": "발전기",
|
||||
"규격": "10㎾",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"상각비계수": "10^-7/시간",
|
||||
"정비비계수": "10^-7/시간",
|
||||
"관리비계수": "10^-7/시간",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 3213,
|
||||
"상각비계수": 1125,
|
||||
"정비비계수": 563,
|
||||
"관리비계수": 674,
|
||||
"손료계수": 2362
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"상각비계수": "건설품셈 공통 8-3-8",
|
||||
"정비비계수": "건설품셈 공통 8-3-8",
|
||||
"관리비계수": "건설품셈 공통 8-3-8",
|
||||
"손료계수": "건설품셈 공통 8-3-8"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 가격 = 2016 사방사업표준품셈(안) 기계경비(3,213,000 원) · 그 표 = 손료만(연료 · 조종원 없음)"
|
||||
},
|
||||
{
|
||||
"키": "EQ000659",
|
||||
"원문번호": "자체 대형 브레이커 0.18㎥",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[00]토공기계",
|
||||
"상세구분": "브레이커",
|
||||
"이름": "대형 브레이커",
|
||||
"규격": "0.18㎥",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"상각비계수": "10^-7/시간",
|
||||
"정비비계수": "10^-7/시간",
|
||||
"관리비계수": "10^-7/시간",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 4559,
|
||||
"상각비계수": 3000,
|
||||
"정비비계수": 2833,
|
||||
"관리비계수": 768,
|
||||
"손료계수": 6601
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"상각비계수": "건설품셈 공통 8-3-1",
|
||||
"정비비계수": "건설품셈 공통 8-3-1",
|
||||
"관리비계수": "건설품셈 공통 8-3-1",
|
||||
"손료계수": "건설품셈 공통 8-3-1"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 손료만(굴착기 부속) · 가격 = 0.2㎥(0230-0002) 값 · 계수 = 0.2㎥ 계수"
|
||||
},
|
||||
{
|
||||
"키": "EQ000660",
|
||||
"원문번호": "자체 에어 호스 1.91㎝",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[70]기타기계",
|
||||
"상세구분": "에어 호스",
|
||||
"이름": "에어 호스",
|
||||
"규격": "1.91㎝",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 105,
|
||||
"손료계수": 5625
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 손료만 · EST 계 59"
|
||||
},
|
||||
{
|
||||
"키": "EQ000661",
|
||||
"원문번호": "자체 모노펌프 5-20㎥/hr",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[70]기타기계",
|
||||
"상세구분": "모노펌프",
|
||||
"이름": "모노펌프",
|
||||
"규격": "5-20㎥/hr",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 4900,
|
||||
"손료계수": 4346
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 손료만 · EST 계 2,129"
|
||||
},
|
||||
{
|
||||
"키": "EQ000662",
|
||||
"원문번호": "자체 파워트로웰 3.73㎾",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "파워트로웰",
|
||||
"이름": "파워트로웰",
|
||||
"규격": "3.73㎾",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간",
|
||||
"주연료": "ℓ/hr",
|
||||
"주연료종류": "",
|
||||
"잡재료율": "주연료의 %",
|
||||
"전력": "㎾h/hr"
|
||||
},
|
||||
"값": {
|
||||
"가격": 2680,
|
||||
"손료계수": 5313,
|
||||
"주연료": 1.0,
|
||||
"주연료종류": "휘발유",
|
||||
"잡재료율": 10,
|
||||
"전력": 3.73
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체",
|
||||
"주연료": "자체",
|
||||
"주연료종류": "자체",
|
||||
"잡재료율": "자체",
|
||||
"전력": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 주연료 휘발유 · 잡품 · 전력 3.73 ㎾h · 조종원 없음 · EST 계 3,858 · 시간당 경비 = GC001195"
|
||||
},
|
||||
{
|
||||
"키": "EQ000663",
|
||||
"원문번호": "자체 콘크리트펌프용 파이프 150㎜×1m",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "콘크리트펌프용 파이프",
|
||||
"이름": "콘크리트펌프용 파이프",
|
||||
"규격": "150㎜×1m",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 35.3725,
|
||||
"손료계수": 4500
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 압송관 · 손료만 · $25 표기 · 환율 적용(1,414.9 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요"
|
||||
},
|
||||
{
|
||||
"키": "EQ000664",
|
||||
"원문번호": "자체 콘크리트펌프용 파이프 150㎜×2m",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "콘크리트펌프용 파이프",
|
||||
"이름": "콘크리트펌프용 파이프",
|
||||
"규격": "150㎜×2m",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 52.3513,
|
||||
"손료계수": 4500
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 압송관 · 손료만 · $37 표기 · 환율 적용(1,414.9 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요"
|
||||
},
|
||||
{
|
||||
"키": "EQ000665",
|
||||
"원문번호": "자체 콘크리트펌프용 파이프 150㎜×3m",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "콘크리트펌프용 파이프",
|
||||
"이름": "콘크리트펌프용 파이프",
|
||||
"규격": "150㎜×3m",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 65.0854,
|
||||
"손료계수": 4500
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 압송관 · 손료만 · $46 표기 · 환율 적용(1,414.9 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요"
|
||||
},
|
||||
{
|
||||
"키": "EQ000666",
|
||||
"원문번호": "자체 콘크리트펌프용 파이프 곡관 150㎜ 45°",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "콘크리트펌프용 파이프",
|
||||
"이름": "콘크리트펌프용 파이프",
|
||||
"규격": "곡관 150㎜ 45°",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 94.7983,
|
||||
"손료계수": 4500
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 압송관 · 손료만 · $67 표기 · 환율 적용(1,414.9 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요"
|
||||
},
|
||||
{
|
||||
"키": "EQ000667",
|
||||
"원문번호": "자체 콘크리트펌프용 파이프 곡관 150㎜ 60°",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "콘크리트펌프용 파이프",
|
||||
"이름": "콘크리트펌프용 파이프",
|
||||
"규격": "곡관 150㎜ 60°",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 118.8516,
|
||||
"손료계수": 4500
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 압송관 · 손료만 · $84 표기 · 환율 적용(1,414.9 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요"
|
||||
},
|
||||
{
|
||||
"키": "EQ000668",
|
||||
"원문번호": "자체 콘크리트펌프용 파이프 곡관 150㎜ 90°",
|
||||
"원문": "건설품셈",
|
||||
"구분": "[40]콘크리트기계",
|
||||
"상세구분": "콘크리트펌프용 파이프",
|
||||
"이름": "콘크리트펌프용 파이프",
|
||||
"규격": "곡관 150㎜ 90°",
|
||||
"단위": {
|
||||
"가격": "천원",
|
||||
"손료계수": "10^-7/시간"
|
||||
},
|
||||
"값": {
|
||||
"가격": 145.7347,
|
||||
"손료계수": 4500
|
||||
},
|
||||
"출처": {
|
||||
"가격": "자체",
|
||||
"손료계수": "자체"
|
||||
},
|
||||
"비고": "EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 압송관 · 손료만 · $103 표기 · 환율 적용(1,414.9 원/USD · 한국은행 2026-08-14 FX000001) 또는 원화 갱신 필요"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -284,7 +284,8 @@
|
||||
"9090-1300",
|
||||
"9090-1400",
|
||||
"9090-1500",
|
||||
"9090-1600"
|
||||
"9090-1600",
|
||||
"자체 발전기 5.5㎾"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1088,7 +1089,18 @@
|
||||
"9080-1500",
|
||||
"9080-1750",
|
||||
"9080-2000",
|
||||
"9080-3000"
|
||||
"9080-3000",
|
||||
"자체 발전기 7㎾",
|
||||
"자체 발전기 10㎾",
|
||||
"자체 대형 브레이커 0.18㎥",
|
||||
"자체 에어 호스 1.91㎝",
|
||||
"자체 모노펌프 5-20㎥/hr",
|
||||
"자체 콘크리트펌프용 파이프 150㎜×1m",
|
||||
"자체 콘크리트펌프용 파이프 150㎜×2m",
|
||||
"자체 콘크리트펌프용 파이프 150㎜×3m",
|
||||
"자체 콘크리트펌프용 파이프 곡관 150㎜ 45°",
|
||||
"자체 콘크리트펌프용 파이프 곡관 150㎜ 60°",
|
||||
"자체 콘크리트펌프용 파이프 곡관 150㎜ 90°"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1404,6 +1416,114 @@
|
||||
"시간환산": { "기호": "Q", "아래": "시간환산" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"키": "GC001195",
|
||||
"원문번호": "8",
|
||||
"구분": "건설품셈 공통",
|
||||
"상세구분": "08장 건설기계",
|
||||
"이름": "파워트로웰 시간당 기계경비",
|
||||
"결과단위": "원/시간",
|
||||
"출처": "건설품셈 공통 8-1-5 · 8-1-6",
|
||||
"부품": {
|
||||
"갈래": "기계경비식"
|
||||
},
|
||||
"소유": "공용",
|
||||
"비고": "품셈에 없는 기계 — EST 단가 구성 → 우리 줄 · 손료계수·연료 = 품셈 값 · 가격 = EST 씨앗(갱신 필요) · 기계표 EQ000662 파워트로웰 3.73㎾ 값을 읽음 · 손료 = 가격 × 손료계수 · 잡품 = 주연료 줄의 % · 전력 = 기계표 전력 칸 · 조종원 없음",
|
||||
"입력": [
|
||||
{
|
||||
"이름": "지역",
|
||||
"고르기": [
|
||||
"전국평균",
|
||||
"전국",
|
||||
"서울",
|
||||
"경기",
|
||||
"강원",
|
||||
"충북",
|
||||
"충남",
|
||||
"전북",
|
||||
"경북",
|
||||
"경남",
|
||||
"부산",
|
||||
"제주",
|
||||
"대구",
|
||||
"인천",
|
||||
"대전",
|
||||
"울산",
|
||||
"세종",
|
||||
"전남광주"
|
||||
],
|
||||
"출처": "건설품셈 공통 8-1-7 5"
|
||||
},
|
||||
{
|
||||
"이름": "전력 계약종별",
|
||||
"고르기": [
|
||||
"주택용 저압",
|
||||
"일반용(갑)Ⅰ 저압"
|
||||
],
|
||||
"출처": "유가전력 한전 전기요금표 2025-01-01",
|
||||
"비고": "품셈·계약예규에 계약종별 규정 없음(전력비는 실비 계상) · 임시전력(갑)은 주택용 저압 요금 그대로(요금표 6.가)"
|
||||
}
|
||||
],
|
||||
"중간": [
|
||||
{
|
||||
"이름": "손료",
|
||||
"식": "버림(EQ000662.가격 * 1000 * EQ000662.손료계수 / 10000000, 0)",
|
||||
"출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4"
|
||||
}
|
||||
],
|
||||
"호표": [
|
||||
{
|
||||
"종류": "재료",
|
||||
"요소": "MO:휘발유:{지역}",
|
||||
"이름": "주연료",
|
||||
"단위": "ℓ",
|
||||
"수량": "EQ000662.주연료",
|
||||
"비목": "재료비",
|
||||
"출처": "건설품셈 공통 8-4-1"
|
||||
},
|
||||
{
|
||||
"종류": "재료",
|
||||
"요소": {
|
||||
"이름": "전력량요금",
|
||||
"계약종별": "입력"
|
||||
},
|
||||
"이름": "전력",
|
||||
"단위": "㎾h",
|
||||
"수량": "EQ000662.전력",
|
||||
"비목": "재료비",
|
||||
"출처": "자체"
|
||||
}
|
||||
],
|
||||
"덧줄": [
|
||||
{
|
||||
"이름": "잡재료비",
|
||||
"식": "줄.'주연료' * EQ000662.잡재료율 / 100",
|
||||
"비목": "재료비",
|
||||
"출처": "건설품셈 공통 8-4 주②"
|
||||
},
|
||||
{
|
||||
"이름": "기계손료",
|
||||
"식": "손료",
|
||||
"비목": "경비",
|
||||
"출처": "건설품셈 공통 8-1-6 2"
|
||||
}
|
||||
],
|
||||
"끝수": "손료 원 미만 버림(건설품셈 공통 8-1-5 12) · 합계 원문 규정 없음",
|
||||
"변수표": {
|
||||
"지역": {
|
||||
"기호": "S",
|
||||
"아래": "지역"
|
||||
},
|
||||
"전력 계약종별": {
|
||||
"기호": "S",
|
||||
"아래": "전력계약종별"
|
||||
},
|
||||
"손료": {
|
||||
"기호": "C",
|
||||
"아래": "손료"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"키": "GC001143",
|
||||
"원문번호": "8-1-4",
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"갈래": "기계경비식"
|
||||
},
|
||||
"변수": [
|
||||
{"열쇠": "기계", "기호": "S", "아래": "기계", "위": "", "이름": "기계", "단위": "", "연결": {"갈래": "선택", "목록": ["1730-0015", "7204-0055", "0602-0150", "2702-0020", "0101-0007", "0101-0010", "0101-0012", "0101-0019", "0101-0032", "2105-0005", "2104-0010", "2104-0015", "2104-0020", "2104-0025", "2104-0030", "2104-0035", "2104-0040", "2104-0045", "2104-0050", "2104-0060", "2104-0070", "2104-0080", "2104-0100", "2104-0130", "2104-0160", "2104-0200", "2104-0220", "2104-0250", "2104-0300", "4504-0032", "4504-0036", "4504-0041", "4504-0043", "4504-0047", "4504-0052", "4205-0010", "4205-0017", "4205-0020", "4205-0030", "4205-0040", "4205-0045", "2105-0002", "2105-0003", "2105-0010", "2105-0015", "2105-0018", "2502-0025", "0602-0025", "2502-0050", "2101-0010", "2101-0015", "2101-0020", "2101-0025", "2101-0030", "2101-0035", "2101-0040", "2101-0050", "2101-0070", "2101-0080", "2101-0100", "2101-0150", "2101-0220", "2101-0280", "2101-0300", "7204-0018", "7204-0160", "5205-0210", "5405-0110", "7505-0450", "5205-0255", "7505-0150", "5205-0103", "6701-0147", "6701-0184", "5205-0170", "7505-0350", "0302-0134", "7505-0100", "7505-0050", "5205-0071", "7505-0025", "0502-0036", "1306-0100", "1506-0032", "0121-0004", "1305-0007", "7204-0038", "7204-0065", "0302-0057", "5701-0020", "0302-0095", "3201-0003", "1106-0012", "1406-0015", "1206-0008", "3601-0102", "1306-0025", "0211-0018", "0602-0045", "0602-0060", "0602-0105", "1630-0080", "3901-0300", "7505-0250", "2502-0035", "1306-0120", "1106-0010", "3201-0001", "1406-0008", "3601-0202", "3601-0402", "3611-0142", "2502-0020", "2502-0075", "5205-0035", "2702-0030", "2702-0060", "0211-0060", "0211-0080", "0211-0100", "0221-0040", "0221-0070", "0302-0025", "0302-0172", "0302-0229", "0302-0287", "0302-0350", "0302-0500", "0406-0054", "0406-0115", "0406-0161", "0406-0206", "0503-0036", "0602-0200", "0602-0240", "0602-0320", "1106-0015", "1206-0010", "1206-0014", "1209-0001", "1209-0002", "1209-0004", "1209-0006", "1209-0007", "1209-0008", "1209-0013", "1306-0044", "1306-0060", "1406-0025", "1506-0011", "1506-0012", "1506-0015", "1506-0019", "1506-0025", "1506-0030", "1506-0037", "2602-0015", "2602-0025", "2602-0035", "2602-0045", "2702-0040", "3530-0015", "3530-0036", "3601-0204", "3601-0302", "3701-0200", "3805-0120", "4504-0021", "4504-0028", "5405-0150", "5701-0010", "7106-0035", "7505-0125", "7505-0200", "7505-0500", "7505-0700", "9010-0003", "9010-0006", "9010-0010", "9010-0012", "9010-0020", "9010-0022", "9010-0033", "9010-0040", "9010-0044", "9010-0060", "9010-0080", "9020-0010", "9020-0015", "9020-0016", "9020-0022", "9020-0035", "9020-0050", "9020-0072", "9020-0160", "9020-0180", "9020-0200", "9050-0075", "9050-0150", "9050-0450", "9050-0750", "9050-0850", "9090-0800", "9090-1000", "9090-1200", "9090-1300", "9090-1400", "9090-1500", "9090-1600"], "값": "1730-0015"}},
|
||||
{"열쇠": "기계", "기호": "S", "아래": "기계", "위": "", "이름": "기계", "단위": "", "연결": {"갈래": "선택", "목록": ["1730-0015", "7204-0055", "0602-0150", "2702-0020", "0101-0007", "0101-0010", "0101-0012", "0101-0019", "0101-0032", "2105-0005", "2104-0010", "2104-0015", "2104-0020", "2104-0025", "2104-0030", "2104-0035", "2104-0040", "2104-0045", "2104-0050", "2104-0060", "2104-0070", "2104-0080", "2104-0100", "2104-0130", "2104-0160", "2104-0200", "2104-0220", "2104-0250", "2104-0300", "4504-0032", "4504-0036", "4504-0041", "4504-0043", "4504-0047", "4504-0052", "4205-0010", "4205-0017", "4205-0020", "4205-0030", "4205-0040", "4205-0045", "2105-0002", "2105-0003", "2105-0010", "2105-0015", "2105-0018", "2502-0025", "0602-0025", "2502-0050", "2101-0010", "2101-0015", "2101-0020", "2101-0025", "2101-0030", "2101-0035", "2101-0040", "2101-0050", "2101-0070", "2101-0080", "2101-0100", "2101-0150", "2101-0220", "2101-0280", "2101-0300", "7204-0018", "7204-0160", "5205-0210", "5405-0110", "7505-0450", "5205-0255", "7505-0150", "5205-0103", "6701-0147", "6701-0184", "5205-0170", "7505-0350", "0302-0134", "7505-0100", "7505-0050", "5205-0071", "7505-0025", "0502-0036", "1306-0100", "1506-0032", "0121-0004", "1305-0007", "7204-0038", "7204-0065", "0302-0057", "5701-0020", "0302-0095", "3201-0003", "1106-0012", "1406-0015", "1206-0008", "3601-0102", "1306-0025", "0211-0018", "0602-0045", "0602-0060", "0602-0105", "1630-0080", "3901-0300", "7505-0250", "2502-0035", "1306-0120", "1106-0010", "3201-0001", "1406-0008", "3601-0202", "3601-0402", "3611-0142", "2502-0020", "2502-0075", "5205-0035", "2702-0030", "2702-0060", "0211-0060", "0211-0080", "0211-0100", "0221-0040", "0221-0070", "0302-0025", "0302-0172", "0302-0229", "0302-0287", "0302-0350", "0302-0500", "0406-0054", "0406-0115", "0406-0161", "0406-0206", "0503-0036", "0602-0200", "0602-0240", "0602-0320", "1106-0015", "1206-0010", "1206-0014", "1209-0001", "1209-0002", "1209-0004", "1209-0006", "1209-0007", "1209-0008", "1209-0013", "1306-0044", "1306-0060", "1406-0025", "1506-0011", "1506-0012", "1506-0015", "1506-0019", "1506-0025", "1506-0030", "1506-0037", "2602-0015", "2602-0025", "2602-0035", "2602-0045", "2702-0040", "3530-0015", "3530-0036", "3601-0204", "3601-0302", "3701-0200", "3805-0120", "4504-0021", "4504-0028", "5405-0150", "5701-0010", "7106-0035", "7505-0125", "7505-0200", "7505-0500", "7505-0700", "9010-0003", "9010-0006", "9010-0010", "9010-0012", "9010-0020", "9010-0022", "9010-0033", "9010-0040", "9010-0044", "9010-0060", "9010-0080", "9020-0010", "9020-0015", "9020-0016", "9020-0022", "9020-0035", "9020-0050", "9020-0072", "9020-0160", "9020-0180", "9020-0200", "9050-0075", "9050-0150", "9050-0450", "9050-0750", "9050-0850", "9090-0800", "9090-1000", "9090-1200", "9090-1300", "9090-1400", "9090-1500", "9090-1600", "자체 발전기 5.5㎾"], "값": "1730-0015"}},
|
||||
{"열쇠": "지역", "기호": "S", "아래": "지역", "위": "", "이름": "지역", "단위": "", "출처": "건설품셈 공통 8-1-7 5", "연결": {"갈래": "선택", "목록": ["전국평균", "전국", "서울", "경기", "강원", "충북", "충남", "전북", "경북", "경남", "부산", "제주", "대구", "인천", "대전", "울산", "세종", "전남광주"], "값": "전국평균"}},
|
||||
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
|
||||
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
|
||||
@@ -306,7 +306,7 @@
|
||||
"결과단위": "원/시간",
|
||||
"출처": "건설품셈 공통 8-1-5 · 8-1-6",
|
||||
"변수": [
|
||||
{"열쇠": "기계", "기호": "S", "아래": "기계", "위": "", "이름": "기계", "단위": "", "연결": {"갈래": "선택", "목록": ["7620-0003", "7621-0100", "7995-0050", "5210-0013", "5210-0027", "5220-0015", "7730-0150", "6516-0060", "6516-0120", "6516-0250", "6516-0300", "6105-0190", "6202-0060", "0230-0002", "6410-0080", "6410-0100", "6410-0120", "6410-0150", "6410-0200", "6901-0010", "6530-0090", "6530-0120", "6517-0100", "6517-0150", "6517-0200", "6517-0250", "6517-0300", "6510-0100", "6510-0150", "6510-0200", "6510-0250", "6510-0300", "6518-0100", "6518-0150", "6518-0200", "6518-0250", "6518-0300", "5501-0080", "7750-0016", "7750-0025", "7730-0050", "5401-0017", "5202-0127", "5202-0240", "5202-0300", "7611-0200", "7612-0200", "5204-0200", "5204-0300", "5204-0400", "5204-0500", "5204-0600", "5702-0095", "3430-0400", "7431-1300", "7740-0080", "7740-0150", "2101-0010", "2101-0015", "2101-0020", "2101-0025", "2101-0030", "2101-0035", "2101-0040", "2101-0050", "2101-0070", "2101-0080", "2101-0100", "2101-0150", "2101-0220", "2101-0280", "2101-0300", "2104-0010", "2104-0015", "2104-0020", "2104-0025", "2104-0030", "2104-0035", "2104-0040", "2104-0045", "2104-0050", "2104-0060", "2104-0070", "2104-0080", "2104-0100", "2104-0130", "2104-0160", "2104-0200", "2104-0220", "2104-0250", "2104-0300", "2208-5008", "2208-5010", "2208-5012", "2208-5016", "2208-5020", "2105-0002", "2105-0003", "2105-0005", "2105-0010", "2105-0015", "2105-0018", "0201-0012", "0201-0020", "0201-0040", "0201-0060", "0201-0070", "0201-0080", "0201-0100", "0201-0120", "0201-0200", "6105-0390", "6202-0125", "7830-0081", "7950-0149", "7951-0066", "7952-0246", "7953-3400", "7954-1119", "7611-0300", "7431-1100", "7431-2300", "7431-2500", "7611-0400", "7611-0500", "7614-0300", "0250-0100", "5210-0010", "5210-0019", "0103-0016", "0103-0019", "0103-0023", "0103-0027", "0103-0032", "0230-0004", "0230-0006", "0230-0007", "0230-0008", "0230-0010", "0240-0007", "0250-0080", "0407-0054", "0407-0092", "0407-0107", "0407-0161", "0407-0206", "0610-0150", "0610-0200", "0610-0240", "2115-0024", "2115-0031", "2115-0036", "2116-0031", "2116-0036", "2117-0022", "2117-0027", "2118-0010", "2210-0145", "3430-0300", "3450-0642", "4115-0100", "4115-0150", "4115-0200", "4115-0300", "4505-0015", "4505-0026", "4611-0075", "5105-0050", "5105-0100", "5105-0150", "5105-0200", "5111-0040", "5111-0050", "5111-0060", "5111-0076", "5111-0091", "5112-0001", "5112-0002", "5112-0003", "5112-0004", "5112-0005", "5113-0001", "5113-0002", "5113-0003", "5113-0004", "5113-0005", "5113-0006", "5113-0007", "5113-0008", "5113-0009", "5113-0010", "5113-0011", "5114-0001", "5114-0002", "5114-0003", "5114-0004", "5114-0005", "5114-0006", "5114-0007", "5114-0008", "5115-0030", "5115-0055", "5115-0075", "5115-0095", "5116-0001", "5116-0002", "5116-0003", "5116-0004", "5116-0005", "5116-0006", "5116-0007", "5116-0008", "5117-0001", "5117-0002", "5117-0003", "5117-0004", "5117-0005", "5117-0006", "5117-0007", "5117-0008", "5118-0001", "5118-0002", "5118-0003", "5118-0004", "5118-0005", "5118-0006", "5118-0007", "5119-0625", "5203-1800", "5203-2200", "5203-2700", "5203-3500", "5203-4500", "5330-0074", "5805-0002", "5805-0003", "5901-0006", "5901-0010", "5901-0016", "6202-0200", "6408-0015", "6408-0020", "6408-0030", "6408-0040", "6408-0050", "6408-0085", "6408-0100", "6515-0090", "6530-0030", "6530-0040", "6530-0045", "6530-0060", "6532-0220", "6550-0130", "7103-0010", "7104-0010", "7202-0008", "7202-0010", "7205-0125", "7206-0020", "7206-0070", "7206-0100", "7430-1100", "7430-1300", "7430-1500", "7430-2300", "7430-2500", "7612-0300", "7612-0400", "7613-0075", "7613-0150", "7613-0300", "7613-0400", "7613-0600", "7613-0900", "7620-0002", "7730-0080", "7730-0100", "7730-0125", "7740-0100", "7770-0004", "7930-0001", "7930-0002", "7930-0003", "7930-0005", "7930-0007", "7930-0010", "7930-0015", "7930-0020", "7930-0025", "7930-0030", "7930-0040", "7930-0050", "7930-0075", "7930-0100", "7935-0180", "7991-0050", "7991-0100", "7991-0500", "7993-0020", "8201-0100", "8202-0100", "8203-0019", "8204-0100", "8205-0100", "9060-0060", "9060-0100", "9060-0200", "9060-0300", "9060-0500", "9060-0600", "9080-0050", "9080-0080", "9080-0100", "9080-0120", "9080-0150", "9080-0200", "9080-0300", "9080-0500", "9080-0700", "9080-1000", "9080-1100", "9080-1400", "9080-1500", "9080-1750", "9080-2000", "9080-3000"], "값": "7620-0003"}},
|
||||
{"열쇠": "기계", "기호": "S", "아래": "기계", "위": "", "이름": "기계", "단위": "", "연결": {"갈래": "선택", "목록": ["7620-0003", "7621-0100", "7995-0050", "5210-0013", "5210-0027", "5220-0015", "7730-0150", "6516-0060", "6516-0120", "6516-0250", "6516-0300", "6105-0190", "6202-0060", "0230-0002", "6410-0080", "6410-0100", "6410-0120", "6410-0150", "6410-0200", "6901-0010", "6530-0090", "6530-0120", "6517-0100", "6517-0150", "6517-0200", "6517-0250", "6517-0300", "6510-0100", "6510-0150", "6510-0200", "6510-0250", "6510-0300", "6518-0100", "6518-0150", "6518-0200", "6518-0250", "6518-0300", "5501-0080", "7750-0016", "7750-0025", "7730-0050", "5401-0017", "5202-0127", "5202-0240", "5202-0300", "7611-0200", "7612-0200", "5204-0200", "5204-0300", "5204-0400", "5204-0500", "5204-0600", "5702-0095", "3430-0400", "7431-1300", "7740-0080", "7740-0150", "2101-0010", "2101-0015", "2101-0020", "2101-0025", "2101-0030", "2101-0035", "2101-0040", "2101-0050", "2101-0070", "2101-0080", "2101-0100", "2101-0150", "2101-0220", "2101-0280", "2101-0300", "2104-0010", "2104-0015", "2104-0020", "2104-0025", "2104-0030", "2104-0035", "2104-0040", "2104-0045", "2104-0050", "2104-0060", "2104-0070", "2104-0080", "2104-0100", "2104-0130", "2104-0160", "2104-0200", "2104-0220", "2104-0250", "2104-0300", "2208-5008", "2208-5010", "2208-5012", "2208-5016", "2208-5020", "2105-0002", "2105-0003", "2105-0005", "2105-0010", "2105-0015", "2105-0018", "0201-0012", "0201-0020", "0201-0040", "0201-0060", "0201-0070", "0201-0080", "0201-0100", "0201-0120", "0201-0200", "6105-0390", "6202-0125", "7830-0081", "7950-0149", "7951-0066", "7952-0246", "7953-3400", "7954-1119", "7611-0300", "7431-1100", "7431-2300", "7431-2500", "7611-0400", "7611-0500", "7614-0300", "0250-0100", "5210-0010", "5210-0019", "0103-0016", "0103-0019", "0103-0023", "0103-0027", "0103-0032", "0230-0004", "0230-0006", "0230-0007", "0230-0008", "0230-0010", "0240-0007", "0250-0080", "0407-0054", "0407-0092", "0407-0107", "0407-0161", "0407-0206", "0610-0150", "0610-0200", "0610-0240", "2115-0024", "2115-0031", "2115-0036", "2116-0031", "2116-0036", "2117-0022", "2117-0027", "2118-0010", "2210-0145", "3430-0300", "3450-0642", "4115-0100", "4115-0150", "4115-0200", "4115-0300", "4505-0015", "4505-0026", "4611-0075", "5105-0050", "5105-0100", "5105-0150", "5105-0200", "5111-0040", "5111-0050", "5111-0060", "5111-0076", "5111-0091", "5112-0001", "5112-0002", "5112-0003", "5112-0004", "5112-0005", "5113-0001", "5113-0002", "5113-0003", "5113-0004", "5113-0005", "5113-0006", "5113-0007", "5113-0008", "5113-0009", "5113-0010", "5113-0011", "5114-0001", "5114-0002", "5114-0003", "5114-0004", "5114-0005", "5114-0006", "5114-0007", "5114-0008", "5115-0030", "5115-0055", "5115-0075", "5115-0095", "5116-0001", "5116-0002", "5116-0003", "5116-0004", "5116-0005", "5116-0006", "5116-0007", "5116-0008", "5117-0001", "5117-0002", "5117-0003", "5117-0004", "5117-0005", "5117-0006", "5117-0007", "5117-0008", "5118-0001", "5118-0002", "5118-0003", "5118-0004", "5118-0005", "5118-0006", "5118-0007", "5119-0625", "5203-1800", "5203-2200", "5203-2700", "5203-3500", "5203-4500", "5330-0074", "5805-0002", "5805-0003", "5901-0006", "5901-0010", "5901-0016", "6202-0200", "6408-0015", "6408-0020", "6408-0030", "6408-0040", "6408-0050", "6408-0085", "6408-0100", "6515-0090", "6530-0030", "6530-0040", "6530-0045", "6530-0060", "6532-0220", "6550-0130", "7103-0010", "7104-0010", "7202-0008", "7202-0010", "7205-0125", "7206-0020", "7206-0070", "7206-0100", "7430-1100", "7430-1300", "7430-1500", "7430-2300", "7430-2500", "7612-0300", "7612-0400", "7613-0075", "7613-0150", "7613-0300", "7613-0400", "7613-0600", "7613-0900", "7620-0002", "7730-0080", "7730-0100", "7730-0125", "7740-0100", "7770-0004", "7930-0001", "7930-0002", "7930-0003", "7930-0005", "7930-0007", "7930-0010", "7930-0015", "7930-0020", "7930-0025", "7930-0030", "7930-0040", "7930-0050", "7930-0075", "7930-0100", "7935-0180", "7991-0050", "7991-0100", "7991-0500", "7993-0020", "8201-0100", "8202-0100", "8203-0019", "8204-0100", "8205-0100", "9060-0060", "9060-0100", "9060-0200", "9060-0300", "9060-0500", "9060-0600", "9080-0050", "9080-0080", "9080-0100", "9080-0120", "9080-0150", "9080-0200", "9080-0300", "9080-0500", "9080-0700", "9080-1000", "9080-1100", "9080-1400", "9080-1500", "9080-1750", "9080-2000", "9080-3000", "자체 발전기 7㎾", "자체 발전기 10㎾", "자체 대형 브레이커 0.18㎥", "자체 에어 호스 1.91㎝", "자체 모노펌프 5-20㎥/hr", "자체 콘크리트펌프용 파이프 150㎜×1m", "자체 콘크리트펌프용 파이프 150㎜×2m", "자체 콘크리트펌프용 파이프 150㎜×3m", "자체 콘크리트펌프용 파이프 곡관 150㎜ 45°", "자체 콘크리트펌프용 파이프 곡관 150㎜ 60°", "자체 콘크리트펌프용 파이프 곡관 150㎜ 90°"], "값": "7620-0003"}},
|
||||
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
|
||||
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
|
||||
{"열쇠": "k_기계손료", "기호": "k", "아래": "기계손료", "위": "", "이름": "EQ:{기계}.손료계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "손료계수"}}
|
||||
@@ -2213,6 +2213,43 @@
|
||||
"비목": {"방법": "버림", "자리": 0},
|
||||
"끝전": "비목버림"
|
||||
}
|
||||
},
|
||||
{
|
||||
"꼴": "수식문서",
|
||||
"판": 1,
|
||||
"키": "GC001195",
|
||||
"이름": "파워트로웰 시간당 기계경비",
|
||||
"결과단위": "원/시간",
|
||||
"출처": "건설품셈 공통 8-1-5 · 8-1-6",
|
||||
"부품": {
|
||||
"갈래": "기계경비식"
|
||||
},
|
||||
"변수": [
|
||||
{"열쇠": "지역", "기호": "S", "아래": "지역", "위": "", "이름": "지역", "단위": "", "출처": "건설품셈 공통 8-1-7 5", "연결": {"갈래": "선택", "목록": ["전국평균", "전국", "서울", "경기", "강원", "충북", "충남", "전북", "경북", "경남", "부산", "제주", "대구", "인천", "대전", "울산", "세종", "전남광주"], "값": "전국평균"}},
|
||||
{"열쇠": "전력 계약종별", "기호": "S", "아래": "전력계약종별", "위": "", "이름": "전력 계약종별", "단위": "", "출처": "유가전력 한전 전기요금표 2025-01-01", "연결": {"갈래": "선택", "목록": ["주택용 저압", "일반용(갑)Ⅰ 저압"], "값": "주택용 저압"}},
|
||||
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
|
||||
{"열쇠": "P_파워트로웰", "기호": "P", "아래": "파워트로웰", "위": "", "이름": "EQ000662.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ000662", "칸": "가격", "계약종별": "S_전력계약종별"}},
|
||||
{"열쇠": "k_파워트로웰", "기호": "k", "아래": "파워트로웰", "위": "", "이름": "EQ000662.손료계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ000662", "칸": "손료계수", "계약종별": "S_전력계약종별"}},
|
||||
{"열쇠": "P_파워트로웰2", "기호": "P", "아래": "파워트로웰2", "위": "", "이름": "EQ000662.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ000662", "칸": "주연료", "계약종별": "S_전력계약종별"}},
|
||||
{"열쇠": "P_휘발유", "기호": "P", "아래": "휘발유", "위": "", "이름": "휘발유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:휘발유:{S_지역}", "계약종별": "S_전력계약종별"}},
|
||||
{"열쇠": "P_파워트로웰3", "기호": "P", "아래": "파워트로웰3", "위": "", "이름": "EQ000662.전력", "단위": "", "연결": {"갈래": "요소", "키": "EQ000662", "칸": "전력", "계약종별": "S_전력계약종별"}},
|
||||
{"열쇠": "P_전력", "기호": "P", "아래": "전력", "위": "", "이름": "전력단가", "단위": "", "연결": {"갈래": "요소", "재료": {"이름": "전력량요금", "계약종별": "입력"}, "단위": "㎾h", "계약종별": "S_전력계약종별"}},
|
||||
{"열쇠": "r_파워트로웰", "기호": "r", "아래": "파워트로웰", "위": "", "이름": "EQ000662.잡재료율", "단위": "", "연결": {"갈래": "요소", "키": "EQ000662", "칸": "잡재료율", "계약종별": "S_전력계약종별"}}
|
||||
],
|
||||
"식": [
|
||||
{"기호": "C_손료", "식": "버림(P_파워트로웰 × 1000 × k_파워트로웰 ÷ 10000000, 0)"}
|
||||
],
|
||||
"금액": [
|
||||
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_파워트로웰2", "단가": "P_휘발유", "출처": "건설품셈 공통 8-4-1", "기호": "C_주연료"},
|
||||
{"이름": "전력", "단위": "㎾h", "비목": "재료비", "수량": "P_파워트로웰3", "단가": "P_전력", "출처": "자체"},
|
||||
{"이름": "잡재료비", "단위": "식", "비목": "재료비", "단가": "C_주연료 × r_파워트로웰 ÷ 100", "출처": "건설품셈 공통 8-4 주②"},
|
||||
{"이름": "기계손료", "단위": "식", "비목": "경비", "단가": "C_손료", "출처": "건설품셈 공통 8-1-6 2"}
|
||||
],
|
||||
"끝수": {
|
||||
"줄": {"방법": "버림", "자리": 1},
|
||||
"비목": {"방법": "버림", "자리": 0},
|
||||
"끝전": "비목버림"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -114,7 +114,10 @@ def test_no_guess() -> None:
|
||||
got = mf.find("덤프트럭", "3.0Ton")
|
||||
assert got["판정"] == mf.NONE and got["까닭"] == "우리 표에 없음(규격)" and got["키"] is None
|
||||
assert got["후보"][0]["규격"] == "2.5ton" # 보여주기만 — 가까운 규격 먼저
|
||||
for name, spec in (("에어 호스", "1.91cm"), ("모노펌프", "5-20㎥/hr")): # 승인 전 = 별칭 몫
|
||||
for name, spec in (
|
||||
("진공흡입기", "5kW"),
|
||||
("스키드로더", "0.3㎥"),
|
||||
): # 우리 표에 없는 기종 = 별칭 몫
|
||||
got = mf.find(name, spec)
|
||||
assert (got["판정"], got["까닭"]) == (mf.NONE, "기종 모름 — 별칭")
|
||||
got = mf.find("크레인(트럭)", "10Ton") # 「트럭」 = 기계표 괄호에 없는 낱말 → 안 봄
|
||||
|
||||
@@ -105,7 +105,7 @@ def test_est_code_first() -> None:
|
||||
# ── K2 별칭 → 요소 ───────────────────────────────────────────────────────────
|
||||
def test_alias_machine() -> None:
|
||||
with no_aliases("EQ"):
|
||||
assert mf.find("에어 호스", "1.91cm")["판정"] == mf.NONE
|
||||
assert mf.find("진공흡입기", "5kW")["판정"] == mf.NONE
|
||||
assert mf.find("크레인(트럭)", "15Ton")["판정"] != mf.ALIAS # 별칭 전
|
||||
with (
|
||||
no_aliases("EQ"),
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
"""820-1 지킴 — 품셈에 없는 소형 · 보조 기계 13 줄(EST 구성 씨앗 · 가격 갱신 필요 · 요구 785 ~ 787).
|
||||
|
||||
(a) 새 줄 · 값 — 발전기 손료계수 2362 공통(품셈 발전기 계열) · 브레이커 0.18 = 0.2㎥ 계수 · 가격 = 씨앗 ·
|
||||
파이프 = 달러 × 환율(비고에 $ 값) · 비고 「갱신 필요」
|
||||
(b) 계산식 — 손료 = 버림(가격 × 1000 × 손료계수 ÷ 10⁷) · 손료만 = GC000273 · 발전기 5.5 = GC000268 ·
|
||||
파워트로웰 = GC001195(휘발유 + 잡품(주연료 줄의 %) + 전력) · 옛 엔진 = 새 수식 문서 · 시간당 이음 한 길
|
||||
(c) 이음 — 가져온 이름 · 규격 → 새 줄 · 옛 기계 그대로
|
||||
(d) 다른 문서 그대로 — 새 고르기는 목록 끝에만 · 기본값 그대로
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import json
|
||||
import sys
|
||||
from decimal import Decimal
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
for p in (ROOT, ROOT / "resources/master_data/scripts"):
|
||||
if str(p) not in sys.path:
|
||||
sys.path.insert(0, str(p))
|
||||
|
||||
from test_815_1_import_link import no_aliases # noqa: E402 — 진짜 마스터 별칭 빼고
|
||||
|
||||
from M01_MasterData import M01_MasterData_Store as m01 # noqa: E402
|
||||
from M02_MasterTemplete import M02_Doc_Import as di # noqa: E402
|
||||
from M02_MasterTemplete import M02_Machine_Find as mf # noqa: E402
|
||||
from M02_MasterTemplete import M02_Machine_Hourly as mh # noqa: E402
|
||||
|
||||
ml = importlib.import_module("master_doc_link")
|
||||
mc = importlib.import_module("master_doc_calc")
|
||||
b802 = importlib.import_module("build_수식문서_802_2")
|
||||
meq = importlib.import_module("master_equation")
|
||||
|
||||
NEW = {f"EQ{n:06d}" for n in range(656, 669)}
|
||||
SEED = { # 키 → (이름, 규격, 가격, 손료계수, 시간당 식)
|
||||
"EQ000656": ("발전기", "5.5㎾", 1063, 2362, "GC000268"),
|
||||
"EQ000657": ("발전기", "7㎾", 1828.9, 2362, "GC000273"),
|
||||
"EQ000658": ("발전기", "10㎾", 3213, 2362, "GC000273"),
|
||||
"EQ000659": ("대형 브레이커", "0.18㎥", 4559, 6601, "GC000273"),
|
||||
"EQ000660": ("에어 호스", "1.91㎝", 105, 5625, "GC000273"),
|
||||
"EQ000661": ("모노펌프", "5-20㎥/hr", 4900, 4346, "GC000273"),
|
||||
"EQ000662": ("파워트로웰", "3.73㎾", 2680, 5313, "GC001195"),
|
||||
}
|
||||
USD = {"150㎜×1m": 25, "150㎜×2m": 37, "150㎜×3m": 46,
|
||||
"곡관 150㎜ 45°": 67, "곡관 150㎜ 60°": 84, "곡관 150㎜ 90°": 103} # fmt: skip
|
||||
|
||||
|
||||
def _eq() -> dict[str, dict]:
|
||||
return m01.loaded()[1].index["EQ"]
|
||||
|
||||
|
||||
def _docs():
|
||||
docs = ml.load_all()
|
||||
return docs, ml.Links(m01.loaded()[1], docs)
|
||||
|
||||
|
||||
def _loss(price, factor) -> Decimal:
|
||||
return (Decimal(str(price)) * 1000 * Decimal(factor) / 10_000_000).quantize(Decimal(1), "ROUND_DOWN") # fmt: skip
|
||||
|
||||
|
||||
def test_rows_and_values() -> None:
|
||||
eq = _eq()
|
||||
assert NEW <= set(eq)
|
||||
for key, (name, spec, price, factor, _) in SEED.items():
|
||||
row = eq[key]
|
||||
assert (row["이름"], row["규격"]) == (name, spec), key
|
||||
assert row["값"]["가격"] == Decimal(str(price)) and row["값"]["손료계수"] == factor, key
|
||||
assert "갱신 필요" in row["비고"] and row["출처"]["가격"] == "자체", key
|
||||
gens = [r for r in eq.values() if r.get("상세구분") == "발전기"]
|
||||
assert {int(r["값"]["손료계수"]) for r in gens} == {2362} # 발전기 계열 공통
|
||||
small, big = eq["EQ000659"]["값"], eq["EQ000031"]["값"]
|
||||
for k in ("가격", "상각비계수", "정비비계수", "관리비계수", "손료계수"):
|
||||
assert small[k] == big[k], k
|
||||
pipes = {r["규격"]: r for r in eq.values() if r.get("상세구분") == "콘크리트펌프용 파이프"}
|
||||
assert set(pipes) == set(USD)
|
||||
rate = m01.loaded()[1].index["FX"]["FX000001"]["값"]
|
||||
for spec, usd in USD.items():
|
||||
row = pipes[spec]
|
||||
assert row["값"]["손료계수"] == 4500 and f"${usd} 표기" in row["비고"]
|
||||
assert abs(float(row["값"]["가격"]) - usd * float(rate) / 1000) < 1e-3
|
||||
trowel = eq["EQ000662"]["값"]
|
||||
assert (trowel["주연료종류"], trowel["주연료"], trowel["잡재료율"], trowel["전력"]) == ("휘발유", 1, 10, Decimal("3.73")) # fmt: skip
|
||||
|
||||
|
||||
def test_formula_loss_and_one_way() -> None:
|
||||
docs, links = _docs()
|
||||
files, whole = m01.loaded()
|
||||
logic = {r["키"]: r for _, r in b802.rows_of(files)}
|
||||
for key in sorted(NEW):
|
||||
row = _eq()[key]
|
||||
got = mh.hourly(key)
|
||||
assert got["ok"], (key, got)
|
||||
want = SEED.get(key, (None, None, None, None, "GC000273"))[4]
|
||||
assert got["로직"] == want, key
|
||||
lg = logic[want]
|
||||
given = meq.given_of(whole, lg)
|
||||
changed = {"기계": row["원문번호"]} if mh.takes_machine(lg) else None
|
||||
new = b802.new_answer(links, docs[want], changed)
|
||||
old = b802.old_answer(whole, lg, {**given, **(changed or {})})
|
||||
assert old == new and float(new["계"]) == got["계"], key # 옛 엔진 = 새 문서 = 시간당 이음
|
||||
assert new["경비"] == _loss(row["값"]["가격"], row["값"]["손료계수"]), (
|
||||
key
|
||||
) # 손료 = 가격 × 계수
|
||||
if want == "GC000273":
|
||||
assert new["노무비"] == new["재료비"] == 0, key
|
||||
assert di.hourly_link("EQ000662", "재료비")["키"] == "GC001195"
|
||||
assert di.hourly_link("EQ000656", "노무비")["입력"]["기계"] == "'자체 발전기 5.5㎾'"
|
||||
|
||||
|
||||
def test_trowel_lines() -> None:
|
||||
docs, links = _docs()
|
||||
got = mc.calc(docs["GC001195"], links)
|
||||
lines = {x["이름"]: x for x in got["줄"]}
|
||||
assert set(lines) == {"주연료", "전력", "잡재료비", "기계손료"}
|
||||
assert lines["전력"]["수량"] == Decimal("3.73") and lines["주연료"]["수량"] == 1
|
||||
assert lines["잡재료비"]["금액"] == (lines["주연료"]["금액"] * Decimal("0.1")).quantize(Decimal("0.1"), "ROUND_DOWN") # fmt: skip
|
||||
assert got["노무비"] == 0 and got["경비"] == _loss(2680, 5313)
|
||||
|
||||
|
||||
def test_find_links() -> None:
|
||||
cases = {
|
||||
("발전기", "5.5kW"): "EQ000656", ("발전기", "7kW"): "EQ000657",
|
||||
("발전기", "10kW"): "EQ000658", ("발전기", "25kW"): "EQ000452",
|
||||
("에어 호스", "1.91cm"): "EQ000660", ("에어호스", "1.91cm"): "EQ000660",
|
||||
("모노펌프", "5-20㎥/hr"): "EQ000661", ("모노펌프", ""): "EQ000661",
|
||||
("브레이카", "0.18㎥"): "EQ000659", ("대형브레이카", "0.2㎥"): "EQ000031",
|
||||
("파워트로웰", "3.73kW"): "EQ000662",
|
||||
("콘크리트펌프용 파이프", "150mm×1m"): "EQ000663",
|
||||
("콘크리트펌프용 파이프", "150㎜×3m"): "EQ000665",
|
||||
("콘크리트펌프용 파이프", "곡관 45˚"): "EQ000666",
|
||||
("콘크리트펌프용 파이프", "곡관 150㎜ 90°"): "EQ000668",
|
||||
} # fmt: skip
|
||||
with no_aliases("EQ"):
|
||||
for (name, spec), key in cases.items():
|
||||
got = mf.find(name, spec)
|
||||
assert (got["판정"], got["키"]) == (mf.LINKED, key), (name, spec, got)
|
||||
|
||||
|
||||
def test_other_docs_same() -> None:
|
||||
"""새 고르기는 기계경비식 목록 끝에만 · 기본값은 옛 기계 그대로."""
|
||||
text = (ROOT / "resources/master_data/로직_건설품셈_08장_건설기계.json").read_text("utf-8")
|
||||
codes = {r["원문번호"] for k, r in _eq().items() if k in NEW}
|
||||
for row in json.loads(text)["줄"]:
|
||||
for spec in row.get("입력") or []:
|
||||
pick = [str(c) for c in spec.get("고르기") or []]
|
||||
mine = [i for i, c in enumerate(pick) if c in codes]
|
||||
if mine:
|
||||
assert mine == list(range(len(pick) - len(mine), len(pick))), row["키"]
|
||||
assert pick[0] not in codes, row["키"]
|
||||
old = [k for k, r in _eq().items() if k not in NEW]
|
||||
assert not [k for k in old if str(_eq()[k].get("원문번호") or "").startswith("자체 ")]
|
||||
|
||||
|
||||
def test_blank_input_name_link_roundtrip() -> None:
|
||||
"""820-2 — 빈칸 든 입력 이름(「전력 계약종별」)이 이음 글 → 읽기 왕복 · EST main 504 번 = 저장 금액 · 우리 단가 셈."""
|
||||
from M02_MasterTemplete import M02_San_Link as sl
|
||||
from M02_MasterTemplete import M02_Sangeun_Imported as imp
|
||||
|
||||
text = sl.hourly_text("EQ000662")
|
||||
assert "'전력 계약종별'=" in text
|
||||
node = di.dc.cv.mf.parse(text)
|
||||
assert node[0] == "logic" and "전력 계약종별" in [k for k, _ in node[2]]
|
||||
assert imp._link(text, "로직", "시험", imp._whole()) == text
|
||||
import test_810_2_native_doc as t
|
||||
|
||||
out = t.fn.emit(t.native("EST", "main"), 504)
|
||||
sk, _, got = t.doc_and_money(out)
|
||||
assert float(got["계"]) == 546 # 원파일 저장 금액
|
||||
sk[imp.KEY]["단가기준"] = "우리"
|
||||
ours = di.run(di.derive(sk, None, t.whole()), sk, t.whole())
|
||||
assert ours.get("셈됨") is not False and ours["계"] is not None
|
||||
@@ -319,6 +319,17 @@ def test_쓰는_곳이_있으면_지우기_409_없으면_지움(world):
|
||||
assert not (world["system"] / "precombo" / f"{sc}.json").exists()
|
||||
|
||||
|
||||
def test_쓰는_곳_기억은_파일을_고치면_다시_읽음_818_1(world):
|
||||
sc = _combo(world["system"], [{"로직": TEN}])
|
||||
ref = {**SYS, "키": sc}
|
||||
with store.at(world["personal"]):
|
||||
store.write("labor", "x1", "", {"열": "x1", "담은로직": [{"참조": ref}], "자재": []})
|
||||
assert len(refs.users(ref)) == 1 and refs.users(ref) == refs.users(ref, refs.use_files())
|
||||
ver = store.read("labor", "x1")["판"]
|
||||
store.write("labor", "x1", ver, {"열": "x1", "담은로직": [], "자재": []})
|
||||
assert refs.users(ref) == []
|
||||
|
||||
|
||||
def test_복사는_못_읽는_참조를_같이_복사_본뜬(world):
|
||||
inner = _combo(world["personal"], [{"로직": TEN}], "안")
|
||||
sys_sp = _promote(world["system"])
|
||||
|
||||
Reference in New Issue
Block a user