Merge branch 'sub_laptop_4' of C:/Aislo_wt/sub_laptop_4 into main_laptop_1

# Conflicts:
#	resources/tester/test_821_3_my_machine_screen.py
This commit is contained in:
2026-11-15 16:46:03 +09:00
36 changed files with 738 additions and 95 deletions
+2
View File
@@ -4,6 +4,7 @@
* 찾아 넣기 = M02 [항목 추가] 창 그대로(`openFindPicker` · 탭 M01 전체 · 찾기 칸 · 표) — 줄 갈래마다 그 종류만
* 인력(노임 LB) · 재료(자재 MT) · 기계(EQ → 시간당 경비 로직 + 기계='원문번호') · 다른 단가산출(M01 단가산출 로직)
* 기계 + M02 개인 층(821-3) = 품셈 기계 위 「내 기계」 묶음 · 머리 [새 기계 만들기] — 고름 = 로직 + 기계='개인 EQP…'
* 재료 + M02 개인 층(840-4) = M01 재료 위 「내 재료」 묶음 — 고름 = 요소 PM 키(M01 재료와 같은 꼴)
* M01 단가산출 기초 줄 쌓기 = 「M01 전체」 탭만 — M01 은 원천 기준값이라 M02 단가산출 · 일위대가를 부르지 않음(요구 680-1)
* M02 단가산출 줄 쌓기(`take` 있음) · 다른 단가산출 = 탭 [M01 전체 | M02 단가산출 | 일위대가](위 층 · 자기 SK 뺌) —
* 고름 = 복사해 펼침(`take(src)` · src = M01 키 | `참조|층|주인|키`) · 참조 줄 없음(요구 681)
@@ -58,6 +59,7 @@ export function openStackPick(
title: `${lt("Find_Title")} — ${lt(copy ? "K_복사" : (`K_${kind}` as never))}`,
kinds: copy ? ["logic", "sk", "pre"] : [want], // M01 = M01 전체만(680-1)
mine: kind === "기계" && m02?.layer === "personal" ? { owner: m02.owner } : undefined,
mineMat: kind === "재료" && m02?.layer === "personal" ? { owner: m02.owner } : undefined, // 840-4 내 재료
query: query.trim() || undefined,
ref: copy
? (r) =>
+8 -5
View File
@@ -23,6 +23,7 @@ from M01_MasterData import M01_MasterData_Store as store
FILE = "기계.json"
OWN_SOURCE = "자체"
HOUR_PARTS = ("시간환산", "상여계수", "휴지계수") # 조종원 노임 1/8 × 16/12 × 25/20(CC000336)
_EQ = re.compile(r"EQ\d{6}")
_cache: dict[str, Any] = {"ver": None, "hourly": {}, "uses": None}
@@ -71,12 +72,14 @@ def lists() -> dict:
if isinstance(r.get("값"), (int, float, Decimal))
]
head = store.read(FILE)[0]
hour = Decimal(1) / Decimal(8)
hour = Decimal(5) / Decimal(24) # 1/8 × 16/12 × 25/20(계수표 없을 때)
for t in files.get("계수_건설품셈_08장_건설기계.json", {}).get("표") or []:
if t.get("키") == "CC000336":
got = next((x for x in t.get("줄") or [] if x.get("구분") == "시간환산"), None)
if got:
hour = Decimal(got["분자"]) / Decimal(got["분모"])
if t.get("키") == "CC000336": # 기계 식 Q_시간환산 과 같은 세 줄(840-5)
got = {x.get("구분"): x for x in t.get("줄") or []}
if all(p in got for p in HOUR_PARTS):
hour = Decimal(1)
for p in HOUR_PARTS:
hour *= Decimal(got[p]["분자"]) / Decimal(got[p]["분모"])
return {
"fuels": fuels,
"jobs": jobs,
+4 -3
View File
@@ -12,6 +12,7 @@ from __future__ import annotations
from typing import Any
from M02_MasterTemplete import M02_Doc_Copy as dc
from M02_MasterTemplete import M02_Material_Own as own
from M02_MasterTemplete import M02_MyMachine as mym
from M02_MasterTemplete import M02_Sangeun_Copy as skc
@@ -46,7 +47,7 @@ def _have(copy: dict) -> set[str]:
def gaps(copy: dict) -> list[str]:
"""값 사본에 없는데 문서 셈이 읽은 M01 줄 키 + 문서의 내 기계 키(셈 틀림 = 읽은 데까지)."""
"""값 사본에 없는데 문서 셈이 읽은 M01 줄 키 + 문서의 내 기계 · 내 재료(840-4) 키(셈 틀림 = 읽은 데까지)."""
if "로직" not in copy or not isinstance(copy.get("문서"), dict):
return []
seen = _Seen(dc.over(copy))
@@ -55,7 +56,7 @@ def gaps(copy: dict) -> list[str]:
except dc._ERR:
pass
have = _have(copy)
return sorted({*seen.keys, *mym.keys_in(copy["문서"])} - have)
return sorted({*seen.keys, *mym.keys_in(copy["문서"]), *own.keys_in(copy["문서"])} - have)
def fill(copy: dict) -> dict:
@@ -76,7 +77,7 @@ def fill_imported(sk: dict, doc: Any) -> dict:
return sk
seen = _Seen(dim._index(sk, None, doc))
dim.run(doc, sk, index=seen) # 셈 틀림 = 읽은 데까지(run 이 받음)
keys = sorted({*seen.keys, *mym.keys_in(doc)} - _have(sk[skc.KEY]))
keys = sorted({*seen.keys, *mym.keys_in(doc), *own.keys_in(doc)} - _have(sk[skc.KEY]))
if not keys:
return sk
return {**sk, skc.KEY: skc.grow(sk[skc.KEY], skc.snap([], keys))}
+6 -2
View File
@@ -241,8 +241,12 @@ def collect(
`extra` = 마스터 밖 로직 줄(굳힌 단가산출 719-1) — 그 줄이 닿는 것만 모음(줄은 안 담음) ·
`over` = M02 로직 사본 줄(795-4) — 같은 키는 M01 줄 대신 · M01 에 없는 키 = `COPY_FILE`."""
files, whole = master()
whole = mym.whole(whole) # 지금 층 내 기계 줄(821-1) — 없으면 M01 그대로
own = {str(r.get("키")): r for r in mym.added(whole)}
from M02_MasterTemplete import M02_Material_Own as mat
whole = mat.whole(
mym.whole(whole)
) # 지금 층 내 기계(821-1) · 내 재료(840-4) — 없으면 M01 그대로
own = {str(r.get("키")): r for r in (*mym.added(whole), *mat.added(whole))}
mine = {str(r.get("키")): r for r in over or []}
if mine:
from M02_MasterTemplete import M02_Sangeun_Copy as skc
+35 -2
View File
@@ -196,10 +196,13 @@ def own_materials(
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
"""개인 자재 목록(148-2) — 개인 층만 · 회사 · 마스터 = 빈 목록."""
"""개인 자재 목록(148-2) — 개인 층만 · 회사 · 마스터 = 빈 목록 · 줄마다 쓰는 곳(840-4)."""
if layer != "personal":
return {"줄": []}
return {"줄": own.rows(_root(session, layer, owner))}
folder = _root(session, layer, owner)
rows = own.rows(folder)
used = own.usage(folder, [str(r.get("키")) for r in rows])
return {"줄": [{**r, "쓰는곳": used[str(r.get("키"))]} for r in rows]}
@router.post("/layers/{layer}/materials")
@@ -215,3 +218,33 @@ def new_material(
raise HTTPException(status_code=400, detail="신규 자재는 개인 층에서만")
folder = _root(session, layer, owner, write=True)
return _call(folder, own.add, folder, body)
@router.put("/layers/{layer}/materials/{key}")
def edit_material(
layer: Layer,
key: str,
body: dict[str, Any],
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
"""내 재료 고침(840-4) — `{이름, 규격, 단위, 값}` · 키 그대로 · 개인 층만."""
if layer != "personal":
raise HTTPException(status_code=400, detail="내 재료는 개인 층에서만")
folder = _root(session, layer, owner, write=True)
return _call(folder, own.update, folder, key, body)
@router.delete("/layers/{layer}/materials/{key}")
def drop_material(
layer: Layer,
key: str,
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
"""내 재료 지움(840-4) — 쓰는 곳 있으면 409 · 개인 층만."""
if layer != "personal":
raise HTTPException(status_code=400, detail="내 재료는 개인 층에서만")
folder = _root(session, layer, owner, write=True)
_call(folder, own.remove, folder, key)
return {"ok": True}
@@ -28,6 +28,7 @@ import { t as L } from "@ui/ui_template_locale";
import { aliasNote, matchLogic } from "@ui/ui_template_logic_find";
import { openNewMaterial } from "./M02_Material_Pick";
import { listMyMachines, mineElement, type MyMachineRow } from "./M02_MyMachine_Api";
import { listMyMaterials, type MyMaterial } from "./M02_MyMaterial_Api";
import { mt } from "./M02_MyMachine_Text";
import { openModal } from "@ui/ui_template_modal";
import { createTabs } from "@ui/ui_template_tabs";
@@ -91,6 +92,8 @@ export interface FindPickOptions {
oil?: (e: M01Element) => void;
/** 821-3 개인 층 내 기계 묶음(`machine` 과 함께) — 주인(null = 자기 층) */
mine?: { owner: string | null };
/** 840-4 개인 층 내 재료(PM) 묶음 — 재료 고름 위 · 주인(null = 자기 층) */
mineMat?: { owner: string | null };
}
/** 727-1 기초마다 한 줄(옛 창 `Labor_Pick` 도 씀) — 규격 칸 = 「옵션 N」 */
@@ -194,6 +197,7 @@ export function openFindPicker(opt: FindPickOptions): void {
let machines: PickItem[] = [];
let oils: PickItem[] = []; // 785-3 유가전력 MO
let mines: MyMachineRow[] = []; // 821-3 내 기계
let mats: MyMaterial[] = []; // 840-4 내 재료
const lists: Record<"sk" | "pre", SangeunRow[] | null> = { sk: null, pre: null };
let shown: Line[] = [];
let seq = 0;
@@ -312,6 +316,16 @@ export function openFindPicker(opt: FindPickOptions): void {
};
});
};
/** 840-4 내 재료 줄 — M01 재료처럼 고름(코드 = PM 키 · 값 = 내 목록 값) */
const matLines = (q: string): Line[] => {
const words = q.toLowerCase().split(/\s+/).filter(Boolean);
return elementLines(
"재료",
mats
.filter((r) => words.every((w) => `${r.이름} ${r.규격} ${r.키}`.toLowerCase().includes(w)))
.map((r) => ({ ref: r.키, 구분: L("M02_FindMyMaterial"), ...r })),
).map((x) => ({ ...x, 출처: x.출처.replace(/^M01 /, "") }));
};
const docLines = (rows: SangeunRow[], kind: string): Line[] =>
rows.map((x) => ({
품명: x.제목 || x.이름,
@@ -329,6 +343,7 @@ export function openFindPicker(opt: FindPickOptions): void {
shown = [
...(ok("logic") ? logicLines(q) : []),
...(ok("labor") ? elementLines("인력", people) : []),
...(opt.mineMat && ok("material") ? matLines(q) : []),
...(ok("material") ? elementLines("재료", goods) : []),
...(opt.oil && ok("oil") ? elementLines("유가", oils) : []),
...(opt.machine && opt.mine && ok("machine") ? mineLines(q) : []),
@@ -456,6 +471,13 @@ export function openFindPicker(opt: FindPickOptions): void {
draw();
})
.catch(fail);
if (opt.mineMat && ok("material"))
void listMyMaterials(opt.mineMat.owner)
.then((rows) => {
mats = rows;
draw();
})
.catch(fail);
void upper(opt.layer, opt.owner)
.then((scopes) =>
Promise.all(
+141 -5
View File
@@ -6,12 +6,16 @@
`master_material.element`). 품번 = `PM` + 6자리 — 모든 사람 통틀어 한 줄 번호(모든 개인 층 파일
가장 큰 번호 + 1 · `store._LOCK` 안 · 화면이 보낸 키는 안 받음). 신규 자재는 개인 층에서만
(회사 · 마스터 층 = 마스터 자재만).
840-4 내 재료 = M01 재료 DB 에 없는 자재를 등록하는 자리 — M01 과 이름 · 규격 · 단위가 같으면 막음(409) ·
고치기 · 지우기(쓰는 곳 있으면 막음) · 단가산출 셈 색인에 M01 재료처럼 얹음(`whole` · `M02_Sangeun_Copy.whole_`)
→ 프로젝트 층 밖 SK 는 값이 바뀌면 자동 따라옴(836-2 `M02_Sk_AutoRenew`) · 프로젝트 층 = 사본 값.
"""
from __future__ import annotations
import json
import re
import unicodedata
from pathlib import Path
from typing import Any
@@ -22,6 +26,7 @@ from M02_MasterTemplete import M02_Template_Layers as layers
FILE = "개인자재.json"
PREFIX = "PM"
KEY = re.compile(rf"^{PREFIX}(\d{{6}})$")
FIND = re.compile(rf"(?<![A-Za-z0-9]){PREFIX}\d{{6}}(?!\d)")
COLS = ("이름", "규격", "단위")
@@ -70,23 +75,154 @@ def _value(v: Any) -> float | int | None:
return int(got) if got.is_integer() else got
def add(folder: str | Path, body: dict[str, Any]) -> dict[str, Any]:
"""새 개인 자재 한 줄 → 그 줄(키는 서버) · 품명 · 단위 빈 = 400 ·
같은 품명 + 규격 + 단위 = 409."""
def _norm(v: Any) -> str:
"""빈칸 · 대소문자 · 겹낱자(㎏ = kg · ㎥ = m3) 무시."""
return unicodedata.normalize("NFKC", " ".join(_text(v).split())).lower()
def m01_same(row: dict[str, Any]) -> dict[str, Any] | None:
"""M01 재료 DB(자재품목 MT)에서 이름 · 규격 · 단위가 같은 줄(빈칸 · 대소문자 무시)."""
from M01_MasterData import M01_MasterData_Store as m01
want = tuple(_norm(row.get(k)) for k in COLS)
for r in (m01.loaded()[1].index.get("MT") or {}).values():
if tuple(_norm(r.get(k)) for k in COLS) == want:
return r
return None
def _checked(body: dict[str, Any], others: list[dict[str, Any]]) -> dict[str, Any]:
"""품명 · 단위 빈 = 400 · 내 목록 같은 줄 · M01 재료 DB 같은 줄 = 409."""
row = {k: _text(body.get(k)) for k in COLS}
if not row["이름"] or not row["단위"]:
raise store.StoreError(400, "품명 · 단위는 꼭 적음")
row["값"] = _value(body.get("값"))
if any(all(_norm(x.get(k)) == _norm(row[k]) for k in COLS) for x in others):
raise store.StoreError(409, f"이미 있는 자재 「{row['이름']} {row['규격']}」")
if m01_same(row):
raise store.StoreError(
409,
f"재료 DB 에 있는 자재 「{row['이름']} {row['규격']}」 — 재료 DB 자재를 고르고 "
"값은 단가산출 안 재료 줄에서 바꿈",
)
return row
def add(folder: str | Path, body: dict[str, Any]) -> dict[str, Any]:
"""새 개인 자재 한 줄 → 그 줄(키는 서버) · 품명 · 단위 빈 = 400 ·
같은 품명 + 규격 + 단위(내 목록 · M01 재료 DB) = 409."""
with store._LOCK:
doc = read(folder)
if any(all(_text(x.get(k)) == row[k] for k in COLS) for x in doc["줄"]):
raise store.StoreError(409, f"이미 있는 자재 「{row['이름']} {row['규격']}」")
row = _checked(body, doc["줄"])
got = {"키": f"{PREFIX}{_last() + 1:06d}", **row}
doc["줄"].append(got)
atomic_write_json(Path(folder) / FILE, doc)
return got
def update(folder: str | Path, key: str, body: dict[str, Any]) -> dict[str, Any]:
"""내 재료 한 줄 고침(키 그대로) — 없는 키 = 404 · 검사는 새로 만들기와 같음."""
with store._LOCK:
doc = read(folder)
at = next((i for i, r in enumerate(doc["줄"]) if r.get("키") == key), None)
if at is None:
raise store.StoreError(404, f"없는 내 재료 「{key}」")
row = _checked(body, [r for i, r in enumerate(doc["줄"]) if i != at])
doc["줄"][at] = got = {"키": key, **row}
atomic_write_json(Path(folder) / FILE, doc)
return got
def _aside(path: Path, folder: str | Path) -> bool:
"""밑줄 · 점 폴더(「_합친것」 등 파생 · 보관) — 쓰는 곳 아님."""
return any(x.startswith(("_", ".")) for x in path.relative_to(folder).parts[:-1])
def usage(folder: str | Path, keys: list[str]) -> dict[str, list[dict[str, Any]]]:
"""그 층에서 키마다 쓰는 문서(단가산출 · 일위대가 …) {키: [{종류, 키, 이름}]} — 파일은 한 번씩 읽음."""
out: dict[str, list[dict[str, Any]]] = {k: [] for k in keys}
for path in sorted(Path(folder).rglob("*.json")): # 종류 폴더 · 그 밑 폴더 — 내 목록 파일 뺌
if path.name == FILE or _aside(path, folder):
continue
try:
text = path.read_text(encoding="utf-8")
except OSError:
continue
hit = [k for k in keys if k in text]
if not hit:
continue
try:
doc = json.loads(text)
except ValueError:
continue
name = (doc.get("이름") if isinstance(doc, dict) else None) or path.stem
for k in hit:
out[k].append({"종류": path.parent.name, "키": path.stem, "이름": name})
return out
def uses(folder: str | Path, key: str) -> list[dict[str, Any]]:
return usage(folder, [key])[key]
def remove(folder: str | Path, key: str) -> None:
"""내 재료 지움 — 쓰는 문서가 있으면 409(그 줄을 먼저 바꿈)."""
with store._LOCK:
doc = read(folder)
if not any(r.get("키") == key for r in doc["줄"]):
raise store.StoreError(404, f"없는 내 재료 「{key}」")
if used := uses(folder, key):
names = " · ".join(str(u["이름"]) for u in used[:3])
raise store.StoreError(409, f"쓰는 곳 {len(used)} — {names} · 그 줄을 먼저 바꿈")
doc["줄"] = [r for r in doc["줄"] if r.get("키") != key]
atomic_write_json(Path(folder) / FILE, doc)
# ── 840-4 셈 색인(단가산출이 M01 재료처럼 읽음) ─────────────────────────
_MEMO: dict[str, tuple] = {}
def whole(base: Any) -> Any:
"""셈 색인 + 지금 층(개인) 내 재료 줄 — 파일 · 바탕이 그대로면 같은 객체 · 개인 층 아님 = 바탕 그대로."""
from decimal import Decimal
from M02_MasterTemplete import M02_Sangeun_Copy as skc
folder = store.root()
path = folder / FILE
try:
st = path.stat()
except OSError:
return base
if not _personal(folder):
return base
sig = (st.st_mtime_ns, st.st_size)
got = _MEMO.get(str(path))
if got and got[0] == sig and got[1] is base:
return got[2]
raw = json.dumps(rows(folder), ensure_ascii=False)
mine = [
r
for r in json.loads(raw, parse_float=Decimal, parse_int=Decimal)
if is_own(str(r.get("키")))
]
out = skc.Copy(base, mine, ("내재료", sig)) if mine else base
if len(_MEMO) > 16: # ponytail: 통째 비움 · 층이 많아지면 LRU 로
_MEMO.clear()
_MEMO[str(path)] = (sig, base, out)
return out
def keys_in(doc: Any) -> list[str]:
"""문서 안 내 재료 키(요소 이음 「PM…」 · 사본 빈틈 찍기)."""
return sorted(set(FIND.findall(json.dumps(doc, ensure_ascii=False, default=str))))
def added(index: Any) -> list[dict]:
"""`whole` 이 얹은 내 재료 줄(사본 모으기 `collect` 가 마스터 밖 줄로 담음)."""
return list((getattr(index, "index", {}).get(PREFIX) or {}).values())
# ── 148-3 — 저장 검사 · 셈 · 사본 · 층 사이 ─────────────────────────────
BUNDLE = "재료_개인자재.json" # 사본 `단가.json` 안 이름
+3
View File
@@ -4,6 +4,7 @@
* 줄 = 그 층 단가산출 줄에 값을 바로 적은 재료(우리 자재에 안 이어진 것 · 서버 `M02_MyMachine_Look.items`)
* 칸 = 이름 · 규격 · 단위 · 값 · 쓰는 단가산출 수 · 같은 이름 수(같은 이름 묶음 = 이름 차례로 붙어 보임)
* 줄 누름 = 아래 쓰는 단가산출 목록 → 누르면 그 단가산출로(고치기는 거기서 · 여기선 저장 없음)
* 위 = 「내 재료」 등록 칸(840-4 · `M02_MyMaterial_View` — 재료 DB 에 없는 자재 등록) · 이 모아 보기는 그 아래 읽기
* ========================================================================== */
import { createDataTable } from "@ui/ui_template_data_table";
@@ -11,6 +12,7 @@ import { createInputField, el } from "@ui/ui_template_elements";
import { createFindList } from "@ui/ui_template_find_list";
import { createText } from "@ui/ui_template_text";
import { listMyItems, type MyItem, type Use } from "./M02_MyMachine_Api";
import { buildMyMaterialBlock } from "./M02_MyMaterial_View";
import { mt } from "./M02_MyMachine_Text";
export interface MyItemsViewOptions {
@@ -85,6 +87,7 @@ export function buildMyItemsView(opt: MyItemsViewOptions): HTMLElement {
className: "m02-mymach-view",
attrs: { "data-my-items": "" },
children: [
buildMyMaterialBlock({ owner: opt.owner }),
el("div", { className: "ui-toolbar", children: [search.root, hint] }),
createText(mt("Items_Note"), "muted"),
fail,
+1 -1
View File
@@ -75,7 +75,7 @@ const TEXT = {
Why_Company: "개인용으로 복사해서 씀",
// 내 품목
Items_Note:
"단가산출 줄에 값을 바로 적은 재료(우리 자재에 안 이어진 것) — 고치기는 그 단가산출에서 · 줄 누르면 쓰는 단가산출",
"단가산출 줄에 값을 바로 적은 재료(재료 DB · 내 재료에 안 이어진 것 · 읽기만) — 고치기는 그 단가산출에서 · 줄 누르면 쓰는 단가산출",
Items_None: "내 품목 없음",
Value: "값(원)",
Unit: "단위",
+45
View File
@@ -0,0 +1,45 @@
/* =============================================================================
* M02_MyMaterial_Api.ts
* M02 내 재료(개인 자재 PM · PLAN 840-4) 서버 호출 — 개인 층만 · 서버 `M02_Labor_Router` 의 /layers/personal/materials
* 목록(줄마다 쓰는 곳) · 만들기 · 고치기 · 지우기(쓰는 곳 있으면 409) · M01 재료 DB 와 같은 이름 · 규격 · 단위 = 409
* ========================================================================== */
import { call } from "./M02_MasterTemplete_Api_Fetch";
export interface MyMaterialUse {
종류: string;
키: string;
이름: string;
}
export interface MyMaterial {
키: string;
이름: string;
규격: string;
단위: string;
값: number | null;
쓰는곳?: MyMaterialUse[];
}
export type MyMaterialBody = Pick<MyMaterial, "이름" | "규격" | "단위" | "값">;
const path = (owner: string | null, key = ""): string =>
`/layers/personal/materials${key ? `/${encodeURIComponent(key)}` : ""}${
owner ? `?owner=${encodeURIComponent(owner)}` : ""
}`;
export const listMyMaterials = (owner: string | null): Promise<MyMaterial[]> =>
call<{ 줄: MyMaterial[] }>(path(owner)).then((d) => d.줄);
export const addMyMaterial = (owner: string | null, body: MyMaterialBody): Promise<MyMaterial> =>
call<MyMaterial>(path(owner), { method: "POST", body: JSON.stringify(body) });
export const editMyMaterial = (
owner: string | null,
key: string,
body: MyMaterialBody,
): Promise<MyMaterial> =>
call<MyMaterial>(path(owner, key), { method: "PUT", body: JSON.stringify(body) });
export const dropMyMaterial = (owner: string | null, key: string): Promise<unknown> =>
call(path(owner, key), { method: "DELETE" });
+185
View File
@@ -0,0 +1,185 @@
/* =============================================================================
* M02_MyMaterial_View.ts
* M02 개인관리 › 자재 위 「내 재료」 등록 칸(PLAN 840-4 · 요구 854 · 862) — 개인 층
* 내 재료 = 재료 DB(M01)에 없는 자재를 등록하는 곳 · M01 재료 값 바꿈은 단가산출 안 재료 줄에서
* 표 = 이름 · 규격 · 단위 · 값 · 쓰는 곳 · 키 · 줄 누름 = 아래 칸에서 고치기 · [새 자재] = 빈 칸
* [저장] = 서버(M01 과 이름 · 규격 · 단위 같으면 서버가 막음 — 까닭 그대로 알림) · [지우기] = 쓰는 곳 있으면 서버가 막음
* 값을 고치면 그 재료를 쓰는 개인 층 단가산출이 따라옴(836-2 자동 따라옴 · 프로젝트 층 = 사본 값)
* 남의 층(owner 있음) = 읽기만
* ========================================================================== */
import { createButton } from "@ui/ui_template_button";
import { createDataTable } from "@ui/ui_template_data_table";
import { createInputField, el, showConfirmDialog, showToast } from "@ui/ui_template_elements";
import { createText } from "@ui/ui_template_text";
import { createUnitPick, NO_UNIT } from "./DataFlow/M02_DF_UnitPick";
import {
addMyMaterial,
dropMyMaterial,
editMyMaterial,
listMyMaterials,
type MyMaterial,
} from "./M02_MyMaterial_Api";
const TEXT = {
title: "내 재료",
note: "재료 DB(M01)에 없는 자재를 등록하는 곳 — 단가산출 재료 고르기 「내 재료」 로 씀 · M01 재료 값 바꿈은 단가산출 안 재료 줄에서",
none: "내 재료 없음",
add: "새 자재",
name: "품명",
spec: "규격",
unit: "단위",
value: "값(원)",
uses: "쓰는 곳",
key: "키",
save: "저장",
drop: "지우기",
cancel: "취소",
need: "품명 · 단위는 꼭 적음",
saved: "저장함 — 쓰는 단가산출이 새 값으로 셈",
dropped: "지움",
dropAsk: "「{name}」 을 지움",
readOnly: "남의 층 — 읽기만",
} as const;
export interface MyMaterialBlockOptions {
owner: string | null;
}
export function buildMyMaterialBlock(opt: MyMaterialBlockOptions): HTMLElement {
const canWrite = opt.owner === null;
let rows: MyMaterial[] = [];
let editing: MyMaterial | null = null;
let unit = "";
const table = createDataTable({
caption: TEXT.title,
columns: [
{ key: "이름", label: TEXT.name, width: 200 },
{ key: "규격", label: TEXT.spec, width: 140 },
{ key: "단위", label: TEXT.unit, width: 60 },
{ key: "값", label: TEXT.value, kind: "number", decimals: 2, trim: true, width: 100 },
{ key: "쓰는곳", label: TEXT.uses, kind: "number", decimals: 0, width: 70 },
{ key: "키", label: TEXT.key, width: 90 },
],
rows: [],
empty: TEXT.none,
onRowClick: (i) => canWrite && open(rows[i]),
});
const name = createInputField({ label: TEXT.name, required: true });
const spec = createInputField({ label: TEXT.spec });
const price = createInputField({ label: TEXT.value, type: "number", min: 0 });
const unitHost = el("span");
const drawUnit = (): void =>
unitHost.replaceChildren(
createUnitPick({
value: unit || NO_UNIT,
ariaLabel: TEXT.unit,
onPick: (u) => {
unit = u === NO_UNIT ? "" : u;
drawUnit();
},
}),
);
const head = createText("");
const saveBtn = createButton({ label: TEXT.save, variant: "filled", onClick: () => void save() });
const dropBtn = createButton({
label: TEXT.drop,
variant: "danger-ghost",
onClick: () => void drop(),
});
const form = el("div", {
className: "m02-pick__new",
attrs: { "data-my-material-form": "" },
children: [
head,
name.root,
spec.root,
el("div", {
className: "ui-field",
children: [el("label", { className: "ui-field__label", text: TEXT.unit }), unitHost],
}),
price.root,
el("div", {
className: "ui-btn-group",
children: [
createButton({ label: TEXT.cancel, variant: "ghost", onClick: () => close() }),
dropBtn,
saveBtn,
],
}),
],
});
form.hidden = true;
function open(row: MyMaterial | null): void {
editing = row;
name.input.value = row?.이름 ?? "";
spec.input.value = row?.규격 ?? "";
price.input.value = row?.값 === null || row?.값 === undefined ? "" : String(row.값);
unit = row?.단위 ?? "";
drawUnit();
head.textContent = row ? `${row.키} ${row.이름}` : TEXT.add;
dropBtn.hidden = !row;
form.hidden = false;
name.input.focus();
}
function close(): void {
editing = null;
form.hidden = true;
}
async function load(): Promise<void> {
rows = await listMyMaterials(opt.owner).catch((e) => {
showToast(e instanceof Error ? e.message : String(e), "error");
return [];
});
table.setRows(rows.map((r) => ({ ...r, 쓰는곳: r.쓰는곳?.length ?? 0 })));
}
async function save(): Promise<void> {
const 이름 = name.input.value.trim();
if (!이름 || !unit) return showToast(TEXT.need, "error");
const raw = price.input.value.trim();
const body = {
이름,
규격: spec.input.value.trim(),
단위: unit,
값: raw === "" ? null : Number(raw),
};
saveBtn.disabled = true;
try {
if (editing) await editMyMaterial(opt.owner, editing.키, body);
else await addMyMaterial(opt.owner, body);
showToast(TEXT.saved, "success");
close();
await load();
} catch (e) {
showToast(e instanceof Error ? e.message : String(e), "error");
} finally {
saveBtn.disabled = false;
}
}
async function drop(): Promise<void> {
if (!editing) return;
if (!(await showConfirmDialog(TEXT.dropAsk.replace("{name}", editing.이름), TEXT.drop))) return;
try {
await dropMyMaterial(opt.owner, editing.키);
showToast(TEXT.dropped, "success");
close();
await load();
} catch (e) {
showToast(e instanceof Error ? e.message : String(e), "error");
}
}
const addBtn = createButton({ label: TEXT.add, variant: "filled", onClick: () => open(null) });
addBtn.hidden = !canWrite;
void load();
return el("div", {
attrs: { "data-my-materials": "" },
children: [
el("div", { className: "ui-toolbar", children: [addBtn] }),
createText(canWrite ? TEXT.note : TEXT.readOnly, "muted"),
table.root,
form,
],
});
}
+3 -2
View File
@@ -45,10 +45,11 @@ READS: ContextVar[dict | None] = ContextVar("읽은줄", default=None)
def whole_() -> Any:
"""M01 색인 + 지금 층 내 기계 줄(821-1 · `M02_MyMachine.whole`)."""
"""M01 색인 + 지금 층 내 기계 줄(821-1 · `M02_MyMachine.whole`) + 내 재료 줄(840-4 · `M02_Material_Own.whole`)."""
from M02_MasterTemplete import M02_Material_Own as own
from M02_MasterTemplete import M02_MyMachine as mym
return mym.whole()
return own.whole(mym.whole())
def _fp(rows: Any) -> str:
+21 -2
View File
@@ -24,7 +24,7 @@ export const COVER = "기계덮음";
/** 값 칸에서 빼는 기계 칸 — 줄(조종원 · 잡품)로 다룸 */
export const NOT_VALUE = ["조종원", "조종원직종", "잡재료율"];
const HOUR = "Q_시간환산";
/** 조종원 줄을 새로 넣을 때(조종원 없는 식) 시간환산 — GC000267 과 같은 꼴(건설품셈 공통 1-1-3 2) */
/** 조종원 줄을 새로 넣을 때(조종원 없는 식) 시간환산 — GC000267 과 같은 꼴(1/8 × 16/12 × 25/20 · 건협기술-2230) */
const HOUR_VARS: DocVar[] = [
{
열쇠: "Q_분자^표", 기호: "Q", 아래: "분자", 위: "표", 이름: "건설기계 조종원 노임 시간 환산 계수.분자", 단위: "",
@@ -34,9 +34,28 @@ const HOUR_VARS: DocVar[] = [
열쇠: "Q_분모^표", 기호: "Q", 아래: "분모", 위: "표", 이름: "건설기계 조종원 노임 시간 환산 계수.분모", 단위: "",
연결: { 갈래: "표", 표: "CC000336", 조건: { 구분: "'시간환산'" }, 칸: "분모" },
},
{
열쇠: "Q_분자2^표", 기호: "Q", 아래: "분자2", 위: "표", 이름: "건설기계 조종원 노임 시간 환산 계수.분자", 단위: "",
연결: { 갈래: "표", 표: "CC000336", 조건: { 구분: "'상여계수'" }, 칸: "분자" },
},
{
열쇠: "Q_분모2^표", 기호: "Q", 아래: "분모2", 위: "표", 이름: "건설기계 조종원 노임 시간 환산 계수.분모", 단위: "",
연결: { 갈래: "표", 표: "CC000336", 조건: { 구분: "'상여계수'" }, 칸: "분모" },
},
{
열쇠: "Q_분자3^표", 기호: "Q", 아래: "분자3", 위: "표", 이름: "건설기계 조종원 노임 시간 환산 계수.분자", 단위: "",
연결: { 갈래: "표", 표: "CC000336", 조건: { 구분: "'휴지계수'" }, 칸: "분자" },
},
{
열쇠: "Q_분모3^표", 기호: "Q", 아래: "분모3", 위: "표", 이름: "건설기계 조종원 노임 시간 환산 계수.분모", 단위: "",
연결: { 갈래: "표", 표: "CC000336", 조건: { 구분: "'휴지계수'" }, 칸: "분모" },
},
{ 열쇠: "시간환산", 기호: "Q", 아래: "시간환산", 위: "", 이름: "시간환산", 단위: "", 연결: { 갈래: "식" } },
]; // prettier-ignore
const HOUR_LINE = { 기호: HOUR, 식: "Q_분자^표 ÷ Q_분모^표" };
const HOUR_LINE = {
기호: HOUR,
식: "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표",
};
export interface CrewRow {
키: string;
+3 -1
View File
@@ -20,6 +20,8 @@ export const MACHINE_COEFS = ["상각비계수", "정비비계수", "관리비
export type MachineCoefs = Record<(typeof MACHINE_COEFS)[number], number>;
const E = 1e-6; // 끊는 경계 부동소수 흔들림 막음
/** 조종원 하루 → 시간(CC000336 시간환산 · 상여 · 휴지 = 1/8 × 16/12 × 25/20 · 840-5) */
export const MACHINE_HOUR = ((((1 / 8) * 16) / 12) * 25) / 20; // 파이썬 짝과 같은 차례
const num = (v: unknown): number => (typeof v === "number" && Number.isFinite(v) ? v : 0);
const halfUp = (x: number): number => Math.floor(x + 0.5 + E);
@@ -69,7 +71,7 @@ export function machineHourly(
fuel: number,
wage: number,
power = 0,
hour = 1 / 8,
hour = MACHINE_HOUR,
): MachineHourly {
const loss = Math.floor((num(values["가격"]) * 1000 * num(values["손료계수"])) / 1e7 + E);
const oil = tenth(num(values["주연료"]) * num(fuel));
@@ -34,6 +34,10 @@ const NAME: Record<string, string> = {
Q_시간환산: "환산",
"Q_분자^표": "환산분자",
"Q_분모^표": "환산분모",
"Q_분자2^표": "상여분자",
"Q_분모2^표": "상여분모",
"Q_분자3^표": "휴지분자",
"Q_분모3^표": "휴지분모",
"Q_주연료^표": "휘발유량",
"Q_주연료2^표": "오일량",
"Q_잡^표": "잡품",
@@ -47,7 +47,7 @@ RAW_SUB = (
"(옛 엔진 = 끝수 전 날 값 · `master_formula.run` 결과를 식에 씀)"
)
# 채택된 차이 — (로직, 옵션) · 요구 714-3
ADOPTED = {("GC000100", "지역=경북")}
ADOPTED = {("GC000091", "지역=울산"), ("GC000093", "지역=경북"), ("GC000100", "지역=전북")}
def rows_of(files: dict) -> list[tuple[str, dict]]:
@@ -30,9 +30,20 @@ _HOUR_VARS = [
"단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모",
"단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자",
"단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모",
"단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자",
"단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모",
"단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "연결": {"갈래": "식"}},
] # fmt: skip
_HOUR_LINE = {"기호": HOUR, "식": "Q_분자^표 ÷ Q_분모^표"}
_HOUR_LINE = {
"기호": HOUR,
"식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표",
}
MAX_ROWS = 30
@@ -22,6 +22,7 @@ import math
INPUTS = ("내용시간", "연간표준가동시간", "상각비율", "정비비율", "연간관리비율")
COEFS = ("상각비계수", "정비비계수", "관리비계수", "손료계수")
_E = 1e-6 # 끊는 경계 부동소수 흔들림 막음
HOUR = 1 / 8 * 16 / 12 * 25 / 20 # 조종원 하루 → 시간(CC000336 시간환산 · 상여 · 휴지 · 840-5)
def _num(v) -> float:
@@ -56,9 +57,7 @@ def coef_of(values: dict) -> dict | None:
return coef(*(values[k] for k in INPUTS))
def preview(
values: dict, fuel: float, wage: float, power: float = 0.0, hour: float = 1 / 8
) -> dict:
def preview(values: dict, fuel: float, wage: float, power: float = 0.0, hour: float = HOUR) -> dict:
"""값 묶음 + 유가(원/ℓ) · 노임(원/일) · 전력(원/kWh) · 시간환산 → 시간당 줄 · 비목 · 계."""
loss = math.floor(_num(values.get("가격")) * 1000 * _num(values.get("손료계수")) / 1e7 + _E)
oil = _tenth(_num(values.get("주연료")) * _num(fuel))
@@ -33,7 +33,11 @@
},
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1" },
@@ -45,7 +49,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [{ "이름": "잡재료비", "식": "재료비 * EQ:{기계}.잡재료율 / 100", "비목": "재료비", "출처": "건설품셈 공통 8-4 주②" }, { "이름": "기계손료", "식": "손료", "비목": "경비", "출처": "건설품셈 공통 8-1-6 2" }],
@@ -303,7 +307,11 @@
{ "이름": "손료", "식": "버림(EQ:{기계}.가격 * 1000 * ((EQ:{기계}.상각비계수 + EQ:{기계}.정비비계수) + EQ:{기계}.관리비계수) / 10000000, 0)", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4" },
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1" },
@@ -315,7 +323,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [{ "이름": "잡재료비", "식": "재료비 * EQ:{기계}.잡재료율 / 100", "비목": "재료비", "출처": "건설품셈 공통 8-4 주②" }, { "이름": "기계손료", "식": "손료", "비목": "경비", "출처": "건설품셈 공통 8-1-6 2" }],
@@ -496,7 +504,11 @@
},
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1" },
@@ -508,7 +520,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [{ "이름": "잡재료비", "식": "재료비 * EQ:{기계}.잡재료율 / 100", "비목": "재료비", "출처": "건설품셈 공통 8-4 주②" }, { "이름": "기계손료", "식": "손료", "비목": "경비", "출처": "건설품셈 공통 8-1-6 2" }],
@@ -557,7 +569,11 @@
{ "이름": "조합잡재료율", "식": "찾기(CC000074, 구분='불도저 및 굴착기 잡재료 비율').적용", "출처": "건설품셈 공통 8-4-8 주⑤" },
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1" },
@@ -569,7 +585,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [
@@ -628,7 +644,11 @@
{ "이름": "조합잡재료율", "식": "찾기(CC000074, 구분='불도저 및 굴착기 잡재료 비율').적용", "출처": "건설품셈 공통 8-4-8 주⑤" },
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1" },
@@ -640,7 +660,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [
@@ -1318,7 +1338,11 @@
"중간": [
{ "이름": "손료", "식": "버림(EQ:{기계}.가격 * 1000 * ((EQ:{기계}.상각비계수 + EQ:{기계}.정비비계수) + EQ:{기계}.관리비계수) / 10000000, 0)", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4" },
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-1" },
@@ -1330,7 +1354,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [{ "이름": "잡재료비", "식": "재료비 * EQ:{기계}.잡재료율 / 100", "비목": "재료비", "출처": "건설품셈 공통 8-4 주②" }, { "이름": "기계손료", "식": "손료", "비목": "경비", "출처": "건설품셈 공통 8-1-6 2" }],
@@ -1389,7 +1413,11 @@
"중간": [
{ "이름": "손료", "식": "버림(EQ:{기계}.가격 * 1000 * ((EQ:{기계}.상각비계수 + EQ:{기계}.정비비계수) + EQ:{기계}.관리비계수) / 10000000, 0)", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{
@@ -1400,7 +1428,7 @@
"수량": "EQ:{기계}.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [{ "이름": "기계손료", "식": "손료", "비목": "경비", "출처": "건설품셈 공통 8-1-6 2" }],
@@ -3516,7 +3544,11 @@
"중간": [
{ "이름": "손료", "식": "버림(EQ:{기계}.가격 * 1000 * EQ:{기계}.손료계수 / 10000000, 0)", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{
@@ -3671,7 +3703,11 @@
{ "이름": "손료", "식": "버림(EQ:{기계}.가격 * 1000 * EQ:{기계}.손료계수 / 10000000, 0)", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4" },
{ "이름": "연료", "식": "EQ:{기계}.주연료종류", "출처": "건설품셈 공통 8-4 주①㉰" },
{ "이름": "직종", "식": "EQ:{기계}.조종원직종", "출처": "건설품셈 공통 8-1-3 5" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:{연료}:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ:{기계}.주연료", "비목": "재료비", "출처": "건설품셈 공통 8-4-8" },
@@ -534,7 +534,11 @@
{ "이름": "손료", "식": "버림(EQ000655.가격 * 1000 * (EQ000069.상각비계수 + EQ000069.정비비계수 + EQ000069.관리비계수) / 10000000, 0)", "출처": "산림품셈 10-9 · 건설품셈 공통 8-1-5 12" },
{ "이름": "비율", "식": "찾기(QF000330, 구분='2.5톤 덤프 주 연료 대비').비율", "출처": "산림품셈 10-9" },
{ "이름": "직종", "식": "EQ000069.조종원직종" },
{ "이름": "시간환산", "식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)" }
{
"이름": "시간환산",
"식": "찾기(CC000336, 구분='시간환산').분자 / 찾기(CC000336, 구분='시간환산').분모 * 찾기(CC000336, 구분='상여계수').분자 / 찾기(CC000336, 구분='상여계수').분모 * 찾기(CC000336, 구분='휴지계수').분자 / 찾기(CC000336, 구분='휴지계수').분모",
"출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)"
}
],
"호표": [
{ "종류": "재료", "요소": "MO:경유:{지역}", "이름": "주연료", "단위": "ℓ", "수량": "EQ000069.주연료 * 비율 / 100", "비목": "재료비", "출처": "산림품셈 10-9" },
@@ -546,7 +550,7 @@
"수량": "EQ000069.조종원 * 시간환산",
"비목": "노무비",
"출처": "건설품셈 공통 8-1-3 6",
"비고": "하루 노임 × 1/8(1일 8시간 · 건설품셈 공통 1-1-3 2) — 질의회신 건협기술-2230 의 상여 16/12 · 휴지 25/20 뺌(내역 15 · 품셈 본문대로)"
"비고": "하루 노임 × 1/8 × 16/12 × 25/20(1일 8시간 · 상여 300 % + 퇴직 100 % · 월 25 일 중 20 일 가동 — 질의회신 건협기술-2230 · 실무 · 경쟁사와 같음)"
}
],
"덧줄": [
@@ -20,7 +20,7 @@
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4 · 8-1-7 1", "연결": {"갈래": "식"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "r_가산^표", "기호": "r", "아래": "가산", "위": "표", "이름": "기계손료의 보정.가산비율", "단위": "%", "연결": {"갈래": "표", "표": "CC000034", "조건": {"기종": "'굴착기(무한궤도) 및 로더(무한궤도)'", "작업": "S_보정작업"}, "칸": "가산비율"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
@@ -28,6 +28,10 @@
{"열쇠": "k_기계관리비", "기호": "k", "아래": "기계관리비", "위": "", "이름": "EQ:{기계}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계주연료", "기호": "P", "아래": "기계주연료", "위": "", "이름": "EQ:{기계}.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료"}},
{"열쇠": "P_자동차용경유", "기호": "P", "아래": "자동차용경유", "위": "", "이름": "자동차용경유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
@@ -37,7 +41,7 @@
"식": [
{"기호": "r_가산", "식": "만약(S_보정작업 == '해당 없음', 0, r_가산^표)"},
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × ((k_기계상각비 + k_기계정비비) × (1 + r_가산 ÷ 100) + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_기계주연료", "단가": "P_자동차용경유", "출처": "건설품셈 공통 8-4-1"},
@@ -67,13 +71,17 @@
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
{"열쇠": "k_기계정비비", "기호": "k", "아래": "기계정비비", "위": "", "이름": "EQ:{기계}.정비비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "정비비계수"}},
{"열쇠": "k_기계관리비", "기호": "k", "아래": "기계관리비", "위": "", "이름": "EQ:{기계}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계주연료", "기호": "P", "아래": "기계주연료", "위": "", "이름": "EQ:{기계}.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료"}},
{"열쇠": "P_휘발유", "기호": "P", "아래": "휘발유", "위": "", "이름": "휘발유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
@@ -82,7 +90,7 @@
],
"식": [
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × (k_기계상각비 + k_기계정비비 + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_기계주연료", "단가": "P_휘발유", "출처": "건설품셈 공통 8-4-1"},
@@ -115,7 +123,7 @@
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4 · 8-1-7 1", "연결": {"갈래": "식"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "r_가산^표", "기호": "r", "아래": "가산", "위": "표", "이름": "기계손료의 보정.가산비율", "단위": "%", "연결": {"갈래": "표", "표": "CC000034", "조건": {"기종": "S_보정기종", "작업": "S_보정작업"}, "칸": "가산비율"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
@@ -123,6 +131,10 @@
{"열쇠": "k_기계관리비", "기호": "k", "아래": "기계관리비", "위": "", "이름": "EQ:{기계}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계주연료", "기호": "P", "아래": "기계주연료", "위": "", "이름": "EQ:{기계}.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료"}},
{"열쇠": "P_휘발유", "기호": "P", "아래": "휘발유", "위": "", "이름": "휘발유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
@@ -133,7 +145,7 @@
{"기호": "S_보정기종", "식": "만약(S_기계 == '0101-0007' 또는 S_기계 == '0101-0010' 또는 S_기계 == '0101-0012' 또는 S_기계 == '0102-0015' 또는 S_기계 == '0102-0028' 또는 S_기계 == '0102-0033' 또는 S_기계 == '0121-0004' 또는 S_기계 == '0121-0013', '불도저(19톤이상 제외)', 만약(S_기계 == '0602-0025' 또는 S_기계 == '0602-0045' 또는 S_기계 == '0602-0060' 또는 S_기계 == '0602-0080' 또는 S_기계 == '0602-0105' 또는 S_기계 == '0602-0150', '덤프트럭', 만약(S_기계 == '0301-0057' 또는 S_기계 == '0301-0076' 또는 S_기계 == '0301-0095' 또는 S_기계 == '0301-0115' 또는 S_기계 == '0301-0134' 또는 S_기계 == '0301-0153' 또는 S_기계 == '0301-0172' 또는 S_기계 == '0301-0287', '굴착기(무한궤도) 및 로더(무한궤도)', '없음')))"},
{"기호": "r_가산", "식": "만약(S_보정작업 == '해당 없음' 또는 S_보정기종 == '없음', 0, r_가산^표)"},
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × ((k_기계상각비 + k_기계정비비) × (1 + r_가산 ÷ 100) + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_기계주연료", "단가": "P_휘발유", "출처": "건설품셈 공통 8-4-1"},
@@ -168,7 +180,7 @@
{"열쇠": "조합잡재료율", "기호": "r", "아래": "조합잡재료", "위": "", "이름": "조합잡재료율", "단위": "", "출처": "건설품셈 공통 8-4-8 주⑤", "연결": {"갈래": "표", "표": "CC000074", "조건": {"구분": "'불도저 및 굴착기 잡재료 비율'"}, "칸": "적용"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "r_가산^표", "기호": "r", "아래": "가산", "위": "표", "이름": "기계손료의 보정.가산비율", "단위": "%", "연결": {"갈래": "표", "표": "CC000034", "조건": {"기종": "'굴착기(무한궤도) 및 로더(무한궤도)'", "작업": "S_보정작업"}, "칸": "가산비율"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
@@ -180,6 +192,10 @@
{"열쇠": "k_집게관리비", "기호": "k", "아래": "집게관리비", "위": "", "이름": "EQ:{집게}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_집게}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계주연료", "기호": "P", "아래": "기계주연료", "위": "", "이름": "EQ:{기계}.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료"}},
{"열쇠": "P_자동차용경유", "기호": "P", "아래": "자동차용경유", "위": "", "이름": "자동차용경유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
@@ -189,7 +205,7 @@
{"기호": "r_가산", "식": "만약(S_보정작업 == '해당 없음', 0, r_가산^표)"},
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × ((k_기계상각비 + k_기계정비비) × (1 + r_가산 ÷ 100) + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "C_집게", "식": "버림(P_집게 × 1000 × (k_집게상각비 + k_집게정비비 + k_집게관리비) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_기계주연료", "단가": "P_자동차용경유", "출처": "건설품셈 공통 8-4-1"},
@@ -225,7 +241,7 @@
{"열쇠": "조합잡재료율", "기호": "r", "아래": "조합잡재료", "위": "", "이름": "조합잡재료율", "단위": "", "출처": "건설품셈 공통 8-4-8 주⑤", "연결": {"갈래": "표", "표": "CC000074", "조건": {"구분": "'불도저 및 굴착기 잡재료 비율'"}, "칸": "적용"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "r_가산^표", "기호": "r", "아래": "가산", "위": "표", "이름": "기계손료의 보정.가산비율", "단위": "%", "연결": {"갈래": "표", "표": "CC000034", "조건": {"기종": "'굴착기(무한궤도) 및 로더(무한궤도)'", "작업": "S_보정작업"}, "칸": "가산비율"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
@@ -237,6 +253,10 @@
{"열쇠": "k_브레이커관리", "기호": "k", "아래": "브레이커관리", "위": "", "이름": "EQ:{브레이커}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_브레이커}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계주연료", "기호": "P", "아래": "기계주연료", "위": "", "이름": "EQ:{기계}.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료"}},
{"열쇠": "P_자동차용경유", "기호": "P", "아래": "자동차용경유", "위": "", "이름": "자동차용경유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
@@ -246,7 +266,7 @@
{"기호": "r_가산", "식": "만약(S_보정작업 == '해당 없음', 0, r_가산^표)"},
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × ((k_기계상각비 + k_기계정비비) × (1 + r_가산 ÷ 100) + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "C_브레이커", "식": "버림(P_브레이커 × 1000 × (k_브레이커상각 + k_브레이커정비 + k_브레이커관리) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_기계주연료", "단가": "P_자동차용경유", "출처": "건설품셈 공통 8-4-1"},
@@ -372,13 +392,17 @@
{"열쇠": "조종원직종", "기호": "S", "아래": "조종원직종", "위": "", "이름": "조종원직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "선택", "목록": ["1048", "1049", "1050"], "값": "1048"}},
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
{"열쇠": "k_기계정비비", "기호": "k", "아래": "기계정비비", "위": "", "이름": "EQ:{기계}.정비비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "정비비계수"}},
{"열쇠": "k_기계관리비", "기호": "k", "아래": "기계관리비", "위": "", "이름": "EQ:{기계}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계주연료", "기호": "P", "아래": "기계주연료", "위": "", "이름": "EQ:{기계}.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료"}},
{"열쇠": "P_자동차용경유", "기호": "P", "아래": "자동차용경유", "위": "", "이름": "자동차용경유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
@@ -387,7 +411,7 @@
],
"식": [
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × (k_기계상각비 + k_기계정비비 + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_기계주연료", "단가": "P_자동차용경유", "출처": "건설품셈 공통 8-4-1"},
@@ -416,19 +440,23 @@
{"열쇠": "지역", "기호": "S", "아래": "지역", "위": "", "이름": "지역", "단위": "", "출처": "건설품셈 공통 8-1-7 5", "연결": {"갈래": "선택", "목록": ["전국평균", "전국", "서울", "경기", "강원", "충북", "충남", "전북", "경북", "경남", "부산", "제주", "대구", "인천", "대전", "울산", "세종", "전남광주"], "값": "전국평균"}},
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
{"열쇠": "k_기계상각비", "기호": "k", "아래": "기계상각비", "위": "", "이름": "EQ:{기계}.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "상각비계수"}},
{"열쇠": "k_기계정비비", "기호": "k", "아래": "기계정비비", "위": "", "이름": "EQ:{기계}.정비비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "정비비계수"}},
{"열쇠": "k_기계관리비", "기호": "k", "아래": "기계관리비", "위": "", "이름": "EQ:{기계}.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원"}},
{"열쇠": "w_기계운전사", "기호": "w", "아래": "기계운전사", "위": "", "이름": "건설기계운전사노임", "단위": "", "연결": {"갈래": "요소", "키": "LB:{S_직종}"}}
],
"식": [
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × (k_기계상각비 + k_기계정비비 + k_기계관리비) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "조종원", "단위": "인", "비목": "노무비", "수량": "Q_기계조종원 × Q_시간환산", "단가": "w_기계운전사", "출처": "건설품셈 공통 8-1-3 6"},
@@ -2263,11 +2291,15 @@
{"열쇠": "전력 계약종별", "기호": "S", "아래": "전력계약종별", "위": "", "이름": "전력 계약종별", "단위": "", "출처": "유가전력 한전 전기요금표 2025-01-01", "연결": {"갈래": "선택", "목록": ["일반용(갑)Ⅰ 저압", "주택용 저압"], "값": "일반용(갑)Ⅰ 저압"}},
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종", "계약종별": "S_전력계약종별"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "P_기계", "기호": "P", "아래": "기계", "위": "", "이름": "EQ:{기계}.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격", "계약종별": "S_전력계약종별"}},
{"열쇠": "k_기계손료", "기호": "k", "아래": "기계손료", "위": "", "이름": "EQ:{기계}.손료계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "손료계수", "계약종별": "S_전력계약종별"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_기계전력", "기호": "P", "아래": "기계전력", "위": "", "이름": "EQ:{기계}.전력", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "전력", "계약종별": "S_전력계약종별"}},
{"열쇠": "P_전력", "기호": "P", "아래": "전력", "위": "", "이름": "전력단가", "단위": "", "연결": {"갈래": "요소", "재료": {"이름": "전력량요금", "계약종별": "입력"}, "단위": "㎾h", "계약종별": "S_전력계약종별"}},
{"열쇠": "Q_기계조종원", "기호": "Q", "아래": "기계조종원", "위": "", "이름": "EQ:{기계}.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원", "계약종별": "S_전력계약종별"}},
@@ -2276,7 +2308,7 @@
],
"식": [
{"기호": "C_손료", "식": "버림(P_기계 × 1000 × k_기계손료 ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "전력", "단위": "㎾h", "비목": "재료비", "수량": "P_기계전력", "단가": "P_전력", "출처": "건설품셈 공통 8-1-6 3 가"},
@@ -2409,11 +2441,15 @@
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4", "연결": {"갈래": "식"}},
{"열쇠": "연료", "기호": "S", "아래": "연료", "위": "", "이름": "연료", "단위": "", "출처": "건설품셈 공통 8-4 주①㉰", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료종류", "계약종별": "S_전력계약종별"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "출처": "건설품셈 공통 8-1-3 5", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "조종원직종", "계약종별": "S_전력계약종별"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "P_EQ기계", "기호": "P", "아래": "EQ기계", "위": "", "이름": "EQ:{기계}", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격", "계약종별": "S_전력계약종별"}},
{"열쇠": "P_EQ기계2", "기호": "P", "아래": "EQ기계2", "위": "", "이름": "EQ:{기계}", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "손료계수", "계약종별": "S_전력계약종별"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_EQ기계3", "기호": "P", "아래": "EQ기계3", "위": "", "이름": "EQ:{기계}", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "주연료", "계약종별": "S_전력계약종별"}},
{"열쇠": "P_MO연료지역", "기호": "P", "아래": "MO연료지역", "위": "", "이름": "MO:{연료}:{지역}", "단위": "", "연결": {"갈래": "요소", "키": "MO:{S_연료}:{S_지역}", "계약종별": "S_전력계약종별"}},
{"열쇠": "P_EQ기계4", "기호": "P", "아래": "EQ기계4", "위": "", "이름": "EQ:{기계}", "단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "전력", "계약종별": "S_전력계약종별"}},
@@ -2424,7 +2460,7 @@
],
"식": [
{"기호": "C_손료", "식": "버림(P_EQ기계 × 1000 × P_EQ기계2 ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_EQ기계3", "단가": "P_MO연료지역", "출처": "건설품셈 공통 8-4-8"},
@@ -481,13 +481,17 @@
{"열쇠": "손료", "기호": "C", "아래": "손료", "위": "", "이름": "손료", "단위": "", "출처": "산림품셈 10-9 · 건설품셈 공통 8-1-5 12", "연결": {"갈래": "식"}},
{"열쇠": "비율", "기호": "r", "아래": "비율", "위": "", "이름": "비율", "단위": "", "출처": "산림품셈 10-9", "연결": {"갈래": "표", "표": "QF000330", "조건": {"구분": "'2.5톤 덤프 주 연료 대비'"}, "칸": "비율"}},
{"열쇠": "직종", "기호": "S", "아래": "직종", "위": "", "이름": "직종", "단위": "", "연결": {"갈래": "요소", "키": "EQ000069", "칸": "조종원직종"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "건설품셈 공통 1-1-3 2(일일 작업시간 8시간)", "연결": {"갈래": "식"}},
{"열쇠": "시간환산", "기호": "Q", "아래": "시간환산", "위": "", "이름": "시간환산", "단위": "", "출처": "질의회신 건협기술-2230(1일 8시간 · 상여 · 휴지)", "연결": {"갈래": "식"}},
{"열쇠": "P_덤프트럭", "기호": "P", "아래": "덤프트럭", "위": "", "이름": "EQ000655.가격", "단위": "", "연결": {"갈래": "요소", "키": "EQ000655", "칸": "가격"}},
{"열쇠": "k_덤프트럭", "기호": "k", "아래": "덤프트럭", "위": "", "이름": "EQ000069.상각비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ000069", "칸": "상각비계수"}},
{"열쇠": "k_덤프트럭2", "기호": "k", "아래": "덤프트럭2", "위": "", "이름": "EQ000069.정비비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ000069", "칸": "정비비계수"}},
{"열쇠": "k_덤프트럭3", "기호": "k", "아래": "덤프트럭3", "위": "", "이름": "EQ000069.관리비계수", "단위": "", "연결": {"갈래": "요소", "키": "EQ000069", "칸": "관리비계수"}},
{"열쇠": "Q_분자^표", "기호": "Q", "아래": "분자", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분자"}},
{"열쇠": "Q_분모^표", "기호": "Q", "아래": "분모", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'시간환산'"}, "칸": "분모"}},
{"열쇠": "Q_분자2^표", "기호": "Q", "아래": "분자2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모2^표", "기호": "Q", "아래": "분모2", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'상여계수'"}, "칸": "분모"}},
{"열쇠": "Q_분자3^표", "기호": "Q", "아래": "분자3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분자", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분자"}},
{"열쇠": "Q_분모3^표", "기호": "Q", "아래": "분모3", "위": "표", "이름": "건설기계 조종원 노임 시간 환산 계수.분모", "단위": "", "연결": {"갈래": "표", "표": "CC000336", "조건": {"구분": "'휴지계수'"}, "칸": "분모"}},
{"열쇠": "P_덤프트럭2", "기호": "P", "아래": "덤프트럭2", "위": "", "이름": "EQ000069.주연료", "단위": "", "연결": {"갈래": "요소", "키": "EQ000069", "칸": "주연료"}},
{"열쇠": "P_자동차용경유", "기호": "P", "아래": "자동차용경유", "위": "", "이름": "자동차용경유단가", "단위": "", "연결": {"갈래": "요소", "키": "MO:경유:{S_지역}"}},
{"열쇠": "Q_덤프트럭", "기호": "Q", "아래": "덤프트럭", "위": "", "이름": "EQ000069.조종원", "단위": "", "연결": {"갈래": "요소", "키": "EQ000069", "칸": "조종원"}},
@@ -496,7 +500,7 @@
],
"식": [
{"기호": "C_손료", "식": "버림(P_덤프트럭 × 1000 × (k_덤프트럭 + k_덤프트럭2 + k_덤프트럭3) ÷ 10000000, 0)"},
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표"}
{"기호": "Q_시간환산", "식": "Q_분자^표 ÷ Q_분모^표 × Q_분자2^표 ÷ Q_분모2^표 × Q_분자3^표 ÷ Q_분모3^표"}
],
"금액": [
{"이름": "주연료", "단위": "ℓ", "비목": "재료비", "수량": "P_덤프트럭2 × r_비율 ÷ 100", "단가": "P_자동차용경유", "출처": "산림품셈 10-9"},
+3 -3
View File
@@ -1,6 +1,6 @@
"""713-4 지킴 — 정본 로직 원문 대조 정리(내역 15) 뒤 꼴.
조종원 = 하루 노임 × 1/8(질의회신 상여 · 휴지계수 없음) ·
조종원 = 하루 노임 × 1/8 × 16/12 × 25/20(840-5 · 요구 864 경쟁사와 같게 — 713-4 의 1/8 만 꼴을 되돌림) ·
지운 키(쪼갠 로직 · 쪽 표 · 터파기 작업량)를
쓰는 곳 0 · 방제 8-3 열 여덟 모두 로직 · 플랜트 13-1-1 표 하나.
"""
@@ -57,11 +57,11 @@ def test_지운_키는_어디에도_없음() -> None:
assert not pattern.search(path.read_text(encoding="utf-8", errors="ignore")), path.name
def test_조종원_시간환산_본문대로() -> None:
def test_조종원_시간환산_세_계수() -> None:
rows = _rows(cm.load())
for key in MACHINE:
text = str(rows[key]["중간"])
assert "상여계수" not in text and "휴지계수" not in text, key
assert "'시간환산'" in text and "상여계수" in text and "휴지계수" in text, key
def test_방제_열_여덟_플랜트_한_표() -> None:
+1 -1
View File
@@ -93,7 +93,7 @@ def test_굴착기_블록_Q_노재경():
assert item["이름식"]["우"]["꼴"] == "분수" # 1 / 작업량
cut = mcut.engine(whole(), EXCAVATOR, raw(EXCAVATOR))
assert eq["합계"] == {k: cut[k] for k in mf.BUNDLE}
assert eq["합계"]["계"] == D("2190.0")
assert eq["합계"]["계"] == D("2791.0") # 조종원 1/8 × 16/12 × 25/20(840-5 · 옛 2190)
def test_지게_N_M_42917():
+7 -3
View File
@@ -57,8 +57,8 @@ def test_옵션_표본_모든_갈래_한_번_이상(result):
info = result["요약"]
assert info["옵션 표본"] == want == info["옵션 같음"] + info["옵션 다름"]
assert (
info["옵션 같음"] >= 18400 and info["옵션 다름"] == info["채택된 차이"] == 1
) # 813-2: 지운 6 문서 표본 빠져 18,438
info["옵션 같음"] >= 18400 and info["옵션 다름"] == info["채택된 차이"] == 3
) # 813-2: 지운 6 문서 표본 빠져 18,438 · 840-5 조종원 환산 뒤 채택 셋
def _whole():
@@ -72,7 +72,11 @@ def test_다름_목록_까닭(result):
diff = [x for x in result["대조"] if not x["같음"]]
assert all(x["까닭"] != "까닭 모름" for x in diff)
# 채택된 차이(요구 714-3) — 식 속 단가산출 부름 값 = 끝수 뒤 · 재료비 1 원 · 저장은 함
assert [(x["로직"], x["옵션"], x["채택"]) for x in diff] == [("GC000100", "지역=경북", True)]
assert [(x["로직"], x["옵션"], x["채택"]) for x in diff] == [
("GC000091", "지역=울산", True),
("GC000093", "지역=경북", True),
("GC000100", "지역=전북", True),
] # 840-5 조종원 1/8 × 16/12 × 25/20 뒤 — 같은 까닭 1 원 셋(옛 GC000100 경북 = 같아짐)
assert diff[0]["까닭"].startswith(build.RAW_SUB)
assert diff[0]["옛"]["재료비"] != diff[0]["새"]["재료비"]
assert abs(diff[0]["새"]["재료비"] - diff[0]["옛"]["재료비"]) == 1
+3 -3
View File
@@ -191,9 +191,9 @@ def test_틀풀기_전수_금액같음_Cm고침(world):
"펼침",
[{**world["cases"]["GF000099"], "기호": "Q_작업", "고침": [{"기호": "Cm", "글": "20"}]}],
)[0][0]
assert one["전"]["계"] == 5286 and one["후"]["계"] == 5286
assert one["전"]["계"] == 5651 and one["후"]["계"] == 5651 # 840-5 조종원 환산(옛 5286)
assert one["옮김"][-1] == "Q_작업" and {"q", "K", "f", "E", "Cm"} <= set(one["옮김"])
assert one["고친"]["계"] == 5434 # Cm 18 → 20 = Q 58.212 → 52.391
assert one["고친"]["계"] == 5840 # Cm 18 → 20 = Q 58.212 → 52.391(840-5 · 옛 5434)
gone = _ts("펼침", [{**world["cases"]["GF000099"], "기호": "Q_작업", "지움": ["Cm"]}])[0][0]
assert gone["고친"]["계"] is None and "정의 필요" in gone["표지"] # 지워도 오류 없음
@@ -217,7 +217,7 @@ def test_저장_쌓기_다시읽어같음(client, tmp_path):
laid = got["차림문서"]
res = client.post("/api/m01/logic/doc/save", json={"문서": laid})
assert res.status_code == 200, res.text
assert res.json()["셈"]["계"] == read["셈"]["계"] == 5286
assert res.json()["셈"]["계"] == read["셈"]["계"] == 5651 # 840-5(옛 5286)
again = client.get("/api/m01/logic/doc", params={"key": "GF000099"}).json()
assert (
again["문서"]["쌓기"] == laid["쌓기"] and _ts("왕복", [{"문서": again["문서"]}])[0]["같음"]
+3 -1
View File
@@ -82,7 +82,9 @@ def test_새_기계_단위_출처_자동_계수_서버_재계산(copy: Path) ->
client = _app()
lists = client.get("/api/m01/machine/lists").json()
assert {"경유", "휘발유"} <= {f["value"] for f in lists["fuels"]}
assert any(j["value"] == "1048" for j in lists["jobs"]) and lists["hour"] == 0.125
assert (
any(j["value"] == "1048" for j in lists["jobs"]) and abs(lists["hour"] - 5 / 24) < 1e-12
) # 840-5
found = client.get("/api/m01/machine/find", params={"q": "굴착기 1.0㎥"}).json()["rows"]
seed = next(r for r in found if r["키"] == "EQ000022")
before = _files(copy)
@@ -42,7 +42,9 @@ def test_lists_same_as_m01():
assert set(got) == {"fuels", "jobs", "power", "hour"}
for k in got:
assert got[k] == want[k], k
assert got["fuels"] and got["jobs"] and got["hour"] == 0.125
assert (
got["fuels"] and got["jobs"] and abs(got["hour"] - 5 / 24) < 1e-12
) # 1/8 × 16/12 × 25/20(840-5)
def test_find_mine_first_and_number(world):
@@ -137,7 +139,7 @@ def test_stack_line_copy(world):
assert job["바뀐자원"] == [] and job["후"]["계"] == now["셈"]["계"]
_at(me, mym.delete, key)
gone = _at(me, path.read, sk)
assert gone["셈"]["계"] == was and gone["사본"]["지운키"] == [key]
assert gone["셈"]["계"] == was # 지운 키 = 저장한 사본 줄 값
def _mine_row():
@@ -124,7 +124,8 @@ WANT = ("파워트로웰", "3.73kW")
def test_generator_ours_formula(world) -> None:
"""발전기 5.5kW 내 기계 시간당 노무비 = 우리 노임 ÷ 8 × 1 인(EST 의 ×16/12 ×25/20 안 씀)."""
"""발전기 5.5kW 내 기계 시간당 노무비 = 우리 노임 × 1/8 × 16/12 × 25/20 × 1 인(우리 식이 한 번 · 840-5 —
EST 구성의 환산을 가져와 또 곱하지 않음 = 0.347 아님)."""
me = world["personal"]
me.mkdir(parents=True, exist_ok=True)
body = mm.body(_main()["기계구성"][GEN], 0, _line("발전기", "5.5kW"), "main.estx")
@@ -133,7 +134,7 @@ def test_generator_ours_formula(world) -> None:
hour = mh.hourly(key)
lb = m01.loaded()[1].numbers["LB"][_labor("일반기계운전사")]
assert hour["ok"] and hour["로직"] == "GC000268"
assert abs(hour["노무비"] - float(lb["값"]) / 8) < 1
assert abs(hour["노무비"] - float(lb["값"]) * 5 / 24) < 1
def test_make_flow(world) -> None:
@@ -39,7 +39,10 @@ POWER, POWER_CREW, ONE_FUEL, DIRECT = "GC001196", "GC001197", "GC001198", "GC001
FUEL_POWER, FUEL_POWER_CREW = "GC001200", "GC001201"
NAME = "sub1임시기계822"
# 안 옮긴 기계 — 822-2 전 금액(전국평균 · 기본 옵션)
KEEP = {"EQ000001": 68550, "EQ000022": 108958}
KEEP = {
"EQ000001": 92158,
"EQ000022": 132566,
} # 840-5 조종원 1/8 × 16/12 × 25/20(옛 68550 · 108958)
def _rows() -> dict[str, dict]:
@@ -196,7 +199,7 @@ def test_power_line_jumbo_drill():
elec = Decimal("135") * Decimal("114.4")
misc = int(elec * 6) / Decimal(100)
assert h["경비"] == loss and h["재료비"] == int(elec + misc)
assert h["노무비"] == int(_wage("1048") / 8)
assert h["노무비"] == int(_wage("1048") * 5 / 24) # 1/8 × 16/12 × 25/20(840-5)
p = _preview("EQ000347")
assert (p["노무비"], p["재료비"], p["경비"], p["계"]) == (
h["노무비"],
@@ -237,10 +240,10 @@ def test_power_my_machine(world):
# ⑥ · ⑦ 옮긴 기계 견본 ─────────────────────────────────────────────────
def test_moved_samples():
plant = mh.hourly("EQ000188") # 아스팔트 믹싱플랜트 60t — 연료 + 조종원 2 인
assert plant["로직"] == "GC000268" and plant["노무비"] == int(_wage("1048") * 2 / 8)
assert plant["로직"] == "GC000268" and plant["노무비"] == int(_wage("1048") * 2 * 5 / 24)
assert plant["재료비"] > 0
tower = mh.hourly("EQ000165") # 타워크레인 — 건설기계운전사 조종원 줄(요구 799)
assert tower["로직"] == "GC000276" and tower["노무비"] == int(_wage("1048") / 8)
assert tower["로직"] == "GC000276" and tower["노무비"] == int(_wage("1048") * 5 / 24)
spray = m01.loaded()[1].get("EQ000198") # 아스팔트 스프레어 — 직종 빈 칸 = 직종 입력 식
assert mh.pick(spray)["키"] == "GC000275" and "조종원직종" in json.dumps(
mh.pick(spray)["입력"], ensure_ascii=False
+2 -2
View File
@@ -89,7 +89,7 @@ def test_굴착기_덮음_손셈(links):
return {"노무비": int(labor), "재료비": int(mats), "경비": int(exp)}
fuel_amt = _cut1(fuel * oil)
crew1 = _cut1(D(1) / 8 * wage)
crew1 = _cut1(D(1) / 8 * 16 / 12 * 25 / 20 * wage) # 840-5
misc = _cut1(fuel_amt * rate / 100)
want = total(crew1, fuel_amt + misc, loss(price))
got = mc.calc(_one("GC000267", NO), links)
@@ -104,7 +104,7 @@ def test_굴착기_덮음_손셈(links):
f20 = _cut1(20 * oil)
assert run({"값": {"주연료": 20}}) == total(crew1, f20 + _cut1(f20 * rate / 100), loss(price))
assert run({"조종원": [{"키": "LB:1048", "인": 2}]}) == total(
_cut1(D(2) / 8 * wage), fuel_amt + misc, loss(price)
_cut1(D(2) / 8 * 16 / 12 * 25 / 20 * wage), fuel_amt + misc, loss(price)
)
assert run({"조종원": []}) == total(0, fuel_amt + misc, loss(price))
assert run({"잡품": [{"줄": "주연료", "율": 30}]}) == total(
@@ -53,7 +53,9 @@ def test_16_문서_이름_전수_겹침_없음():
assert all("_" not in v and "^" not in v for v in alias.values()), (k, alias)
forms |= {i for i in ids if not i.startswith("P_EQ기계")}
assert not g["틀림"], (k, g["틀림"][:3]) # 식 글 왕복 = 같은 식
assert len(forms) == 58 # 64 꼴 = 사전 58 + 「P_EQ기계~6」 읽는 칸 이름 6
assert (
len(forms) == 62
) # 68 꼴 = 사전 62(840-5 상여 · 휴지 분자 · 분모 넷 더함) + 「P_EQ기계~6」 6
def test_대표_이름():
@@ -0,0 +1,78 @@
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
"""840-4 내 재료(개인 자재 PM) = M01 재료 DB 에 없는 자재 등록 자리 — 임시 storage.
① M01 재료 DB 와 이름 · 규격 · 단위가 같으면 만들기 · 고치기 막음(409) · 품명 · 단위 빈 = 400
② 단가산출 재료 줄이 내 재료를 M01 재료처럼 읽음(미리 셈 · 저장)
③ 내 재료 값을 고치면 개인 층 단가산출 금액이 따라옴(836-2 자동 따라옴 길)
④ 쓰는 곳 있으면 지움 막음(409) · 쓰는 곳 없으면 지움 · 없는 키 = 404.
"""
from __future__ import annotations
import pytest
from M01_MasterData import M01_MasterData_Store as m01
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_Material_Own as own
from resources.tester.test_m02_labor_ref import world # noqa: F401 — 같은 임시 층
NAME = "sub4임시자재"
def _at(folder, fn, *args):
with store.at(folder):
return fn(*args)
def _code(fn, *args) -> int:
with pytest.raises(store.StoreError) as e:
fn(*args)
return e.value.status
def _doc(key: str, code: str) -> dict:
"""줄 쌓기 재료 줄 하나(화면이 저장하는 꼴) — 단가 = 요소 이음(내 재료)."""
var = {"기호": "P", "아래": "재", "위": "", "이름": NAME, "단위": "",
"연결": {"갈래": "요소", "키": code, "단위": "kg"}} # fmt: skip
line = {"이름": NAME, "단위": "kg", "비목": "재료비", "수량": "2", "단가": "P_재"}
return {"꼴": "수식문서", "판": 1, "키": key, "이름": NAME, "결과단위": "원",
"변수": [var], "식": [], "금액": [line]} # fmt: skip
def test_m01_same_blocked(world):
me = world["personal"]
mt = next(r for r in m01.loaded()[1].index["MT"].values() if r.get("이름") and r.get("단위"))
same = {"이름": f" {mt['이름']} ", "규격": mt.get("규격") or "", "단위": mt["단위"], "값": 1}
assert _at(me, _code, own.add, me, same) == 409
assert _at(me, _code, own.add, me, {"이름": NAME, "단위": ""}) == 400
row = _at(me, own.add, me, {"이름": NAME, "규격": "x", "단위": "kg", "값": 1000})
assert own.is_own(row["키"]) and own.m01_same(row) is None
assert _at(me, _code, own.update, me, row["키"], same) == 409
assert _at(me, _code, own.update, me, "PM999999", {"이름": NAME, "단위": "kg"}) == 404
assert (
_at(me, _code, own.add, me, {"이름": NAME, "규격": "X", "단위": "㎏"}) == 409
) # 내 목록 같음
def test_sk_reads_and_follows(world):
from M02_MasterTemplete import M02_Doc_Sk_Path as path
from M02_MasterTemplete import M02_Labor_Ref as refs
me = world["personal"]
code = _at(me, own.add, me, {"이름": NAME, "규격": "y", "단위": "kg", "값": 1000})["키"]
sk = _at(me, lambda: refs.create("sangeun", {"이름": NAME, "단위": "식", "더한줄": []})["이름"])
doc = _doc(sk, code)
assert _at(me, path.preview, sk, {"문서": doc})["셈"]["계"] == 2000 # 저장 전 미리 셈
_at(me, path.save, sk, {"문서": doc, "판": _at(me, path.read, sk)["판"]})
assert _at(me, path.read, sk)["셈"]["계"] == 2000
_at(me, own.update, me, code, {"이름": NAME, "규격": "y", "단위": "kg", "값": 1500})
assert _at(me, path.read, sk)["셈"]["계"] == 3000 # 값 바꿈 → 따라옴
assert [u["키"] for u in _at(me, own.uses, me, code)] == [sk]
assert _at(me, _code, own.remove, me, code) == 409 # 쓰는 곳 있음
_at(me, store.delete, "sangeun", sk)
aside = me / "_합친것" / f"{sk}.json" # 파생 · 보관 폴더 = 쓰는 곳 아님
aside.parent.mkdir(parents=True, exist_ok=True)
aside.write_text(f'{{"이름": "x", "키": "{code}"}}', encoding="utf-8")
_at(me, own.remove, me, code)
assert all(r["키"] != code for r in own.rows(me))
assert _at(me, _code, own.remove, me, code) == 404
+1 -1
View File
@@ -55,7 +55,7 @@ def test_추가하면_PM_6자리_키_목록에_보임_화면_키_무시(world):
assert got.status_code == 200, got.text
row = got.json()
assert row == {"키": "PM000001", "이름": "앵커볼트", "규격": "M16", "단위": "EA", "값": 1200}
assert c.get(URL.format("personal")).json()["줄"] == [row]
assert c.get(URL.format("personal")).json()["줄"] == [{**row, "쓰는곳": []}] # 840-4 쓰는 곳
path = layers.personal_dir(7, 42) / own.FILE
assert path.is_file()
assert own.read(path.parent)["그룹"] == "재료"
+6 -6
View File
@@ -89,10 +89,10 @@ def test_굴착기(whole):
whole, EXCAVATOR, {"기계": "0201-0070", "지역": "전국평균", "보정작업": "해당 없음"}
)
assert [cents(got[k]) for k in ("노무비", "재료비", "경비", "계")] == [
"35412.13", # 조종원 = 하루 노임 × 1/8(713-4 · 질의회신 상여 · 휴지계수 뺌)
"59020.21", # 조종원 = 하루 노임 × 1/8 × 16/12 × 25/20(840-5 · 옛 1/8 = 35412.13)
"26130.11",
"24554.00",
"86096.24",
"109704.32",
]
@@ -103,7 +103,7 @@ def test_굴착기_암석_보정(whole):
{"기계": "0201-0070", "지역": "전국평균", "보정작업": "암석작업(연암・보통암・경암)"},
)
assert got["중간"]["손료"] == 28322
assert cents(got["계"]) == "89864.24"
assert cents(got["계"]) == "113472.32" # 840-5 조종원 환산
def test_불도저_덤프_로더_손료_보정(whole):
@@ -148,10 +148,10 @@ def test_노체포설(whole):
assert mf.run(whole, "GF000118", {})["결과"] == Decimal("24.255")
got = mf.run(whole, "GF000119", {"지역": "전국평균", "보정작업": "해당 없음"})
assert [cents(got[k]) for k in ("노무비", "재료비", "경비", "계")] == [
"1459.99", # 조종원 = 하루 노임 × 1/8(713-4)
"2433.32", # 조종원 = 하루 노임 × 1/8 × 16/12 × 25/20(840-5)
"1077.31",
"1012.33",
"3549.63",
"4522.96",
]
@@ -191,7 +191,7 @@ def test_굴착기_부착용_집게(whole):
{"기계": "0201-0060", "집게": "7206-0070", "지역": "전국평균", "보정작업": "해당 없음"},
)
assert got["중간"]["집게손료"] == 5786
assert cents(got["계"]) == "86467.61"
assert cents(got["계"]) == "110075.69" # 840-5 조종원 환산
def test_불도저_운반_작업량(whole):
+1
View File
@@ -235,6 +235,7 @@ export const ui_locales_m2 = {
M02_FindClass: ["구분", "Class"],
M02_FindLogic: ["단가산출 기초", "Unit-cost logic"],
M02_FindNewMaterial: ["신규 자재", "New material"],
M02_FindMyMaterial: ["내 재료", "My material"],
M02_FindElementLater: ["일위대가 표 개편 뒤", "After the unit-cost table rework"],
M02_FindOptions: ["옵션 {n}", "{n} options"],
// 729-3 불러오기 — 안 이은 줄 · 일위대가표 띠