- 까닭: 요구 776 별칭 여덟(덤프자동덮개 · 크레인(트럭) · 엔진톱 등)이 마스터 기계.json 에 들어감 · 앞으로도 늘어남 - test_815_1: 별칭 칸 비우는 `no_aliases` 추가 · test_alias_machine 별칭 전/후를 비운 사본에서 - test_812_9 · test_816_2: 별칭 없는 사본(autouse)에서 봄 · 816_2 에 「별칭이 있으면 별칭 먼저」 한 줄 추가 - test_815_2: 별칭 다섯 = 부분집합 확인(더 있어도 통과) - test_816_1 · test_816_3: 별칭 있든 없든 통과하게 비움 - 제품 코드 · 마스터 자료 그대로 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
72 lines
3.6 KiB
Python
72 lines
3.6 KiB
Python
"""816-3 지킴 — 가져온 「엔진톱」 = 우리 체인톱 EQ000620(요구 771 · 방향 장부 N2).
|
|
|
|
(a) 별칭 길 — 사용자가 EQ000620 「별칭」 칸에 「엔진톱 18", 엔진톱」 을 넣으면(시험 = 임시 별칭 · 진짜 마스터
|
|
별칭은 시험 안에서 비움) 인치 따옴표가 깨지지 않고 「엔진톱 18"」 · 「엔진톱」(규격 빔) → EQ000620 · 다른 톱 · 다른 규격은 안 이음
|
|
(b) 시간당 = GF000337 「체인톱 시간당 기계경비」 = 산림품셈 1 일 1 대당(2-1-1 휘발유 · 체인오일 · 잡품 ·
|
|
2-2-1 손료) ÷ 8 — GF000076 체인톱 줄(1 일 1 대당) 단가 그대로 · 수량 × 시간환산
|
|
(c) 이음 한 길 — `M02_Machine_Hourly.hourly` · `M02_Doc_Import.hourly_link` = GF000337(기계 입력 없음)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
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 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
|
|
from test_815_1_import_link import aliases, no_aliases # noqa: E402 — M01 별칭 칸 임시
|
|
|
|
ml = importlib.import_module("master_doc_link")
|
|
mc = importlib.import_module("master_doc_calc")
|
|
SAW = "EQ000620"
|
|
|
|
|
|
def _calc(key: str) -> dict:
|
|
docs = ml.load_all()
|
|
return mc.calc(docs[key], ml.Links(m01.loaded()[1], docs))
|
|
|
|
|
|
def test_alias() -> None:
|
|
am = importlib.import_module("master_alias")
|
|
with no_aliases("EQ"): # 진짜 마스터 별칭 있든 없든 — 별칭 전 = 못 이음
|
|
assert mf.find("엔진톱", '18"')["키"] is None
|
|
for text in ('엔진톱 18", 엔진톱', '"엔진톱 18"", 엔진톱'):
|
|
assert am.names(text) == ['엔진톱 18"', "엔진톱"], text
|
|
with no_aliases("EQ"), aliases("EQ", {SAW: '엔진톱 18", 엔진톱'}):
|
|
for name, spec in (("엔진톱", '18"'), ("엔진톱", ""), ("엔진톱", '18 "')):
|
|
got = mf.find(name, spec)
|
|
assert (got["판정"], got["키"]) == (mf.ALIAS, SAW), (name, spec)
|
|
for name, spec in (("엔진톱", '24"'), ("체인톱", '18"')):
|
|
assert mf.find(name, spec)["키"] is None, (name, spec)
|
|
|
|
|
|
def test_hourly_is_day_over_8() -> None:
|
|
hour = _calc("GF000337")
|
|
day = {x["이름"]: x for x in _calc("GF000076")["줄"]} # 같은 체인톱 줄(1 일 1 대당 × 벌목부수)
|
|
lines = {x["이름"]: x for x in hour["줄"]}
|
|
assert set(lines) == {"휘발유(체인톱)", "체인오일", "체인톱 손료", "잡품"}
|
|
for name in ("휘발유(체인톱)", "체인오일", "체인톱 손료"):
|
|
assert lines[name]["단가"] == day[name]["단가"], name
|
|
assert lines["휘발유(체인톱)"]["수량"] == Decimal("5.6") / 8
|
|
assert lines["체인톱 손료"]["수량"] == Decimal("0.0084") / 8
|
|
assert hour["셈됨"] and hour["노무비"] == 0 and hour["계"] > 0
|
|
|
|
|
|
def test_one_way() -> None:
|
|
got = mh.hourly(SAW)
|
|
doc = _calc("GF000337")
|
|
assert got["ok"] and got["로직"] == "GF000337"
|
|
assert [got[k] for k in ("재료비", "경비", "계")] == [float(doc[k]) for k in ("재료비", "경비", "계")] # fmt: skip
|
|
link = di.hourly_link(SAW, "재료비")
|
|
assert link["키"] == "GF000337" and "기계" not in link["입력"]
|
|
assert mh.hourly("EQ000621")["ok"] is False # 예취기 = 시간당 식 없음 그대로
|