# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀 """821-3 내 기계 화면 읽기 길(`M02_MyMachine_Look`) — 임시 storage · 쓰기 없음. ① 양식 목록 = M01 기계 화면 목록과 같음(연료 · 직종 · 전력 · 시간환산) ② 비슷한 기계 찾기 = 내 기계(앞) + M01 · 원문번호 = 그 M01 기계 먼저 · 남의 층 내 기계 안 보임 ③ 내 품목 = 값을 바로 적은 재료비 줄만 · 같은 품목 묶음 · 쓰는 단가산출 ④ 개인 층 밖 = 404. """ from __future__ import annotations import json import pytest from fastapi import HTTPException from M01_MasterData import M01_MasterData_Store as m01 from M02_MasterTemplete import M02_MasterTemplete_Store as store from M02_MasterTemplete import M02_MyMachine as mym from M02_MasterTemplete import M02_MyMachine_Look as look from M02_MasterTemplete import M02_Template_Layers as layers from resources.tester.test_m02_labor_ref import world # noqa: F401 — 같은 임시 층 DIG = "EQ000022" # 굴착기(무한궤도) 1.0㎥ NAME = "서브원임시기계" def _at(folder, fn, *args): with store.at(folder): return fn(*args) def _mine(folder): row = {"이름": NAME, "규격": "1㎾", "방식": "바로", "값": {"가격": 1000, "손료계수": 2000}} return _at(folder, mym.create, row)["줄"] def test_lists_same_as_m01(): """① 양식 목록 = M01 기계 화면 값.""" from M01_MasterData import M01_MasterData_Machine as m01m got, want = look.lists(), m01m.lists() 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 def test_find_mine_first_and_number(world): """② 내 기계 앞 · 원문번호 = 그 M01 기계 먼저 · 남의 층 = 내 기계 안 보임.""" me, other = world["personal"], layers.personal_dir(7, 43) key = _mine(me)["키"] rows = _at(me, look.find, NAME) assert rows[0]["키"] == key and rows[0]["출처"] == "개인" and rows[0]["값"]["손료계수"] == 2000 assert all(r["출처"] == "M01" for r in _at(other, look.find, NAME)) no = str(m01.loaded()[1].get(DIG)["원문번호"]) first = _at(me, look.find, no)[0] assert first["키"] == DIG and first["원문번호"] == no and first["출처"] == "M01" assert isinstance(first["값"]["가격"], int | float) and first["구분"] # 수(글이면 미리보기 0) dig = [r for r in _at(me, look.find, "굴착기") if r["출처"] == "M01"] assert dig and len({r["키"] for r in dig}) == len(dig) # 겹침 없음 def _sk(folder, key, name, lines): """수식 문서 재료비 줄 — (이름, 연결) · 숫자 = 바로 적은 값 · 요소 = 우리 자재.""" vars_, money = [], [] for i, (item, link) in enumerate(lines): vars_.append({"열쇠": f"P_x{i}", "기호": "P", "아래": f"x{i}", "위": "", "연결": link}) money.append( {"이름": item, "규격": "10㎜", "단위": "개", "비목": "재료비", "단가": f"P_x{i}"} ) money.append({"이름": "인부", "단위": "인", "비목": "노무비", "단가": "P_x0"}) doc = {"키": key, "이름": name, "수식": {"문서": {"변수": vars_, "금액": money}}} path = folder / "sangeun" / f"{key}.json" path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(doc, ensure_ascii=False), encoding="utf-8") def test_items_direct_only(world): """③ 바로 적은 값 재료만 · 같은 품목 = 한 묶음 · 쓰는 단가산출 · 값 다르면 따로.""" me = world["personal"] _sk(me, "SK-000001", "가", [("볼트", {"갈래": "숫자", "값": 500}), ("시멘트", {"갈래": "요소", "키": "MT004176"})]) # fmt: skip _sk(me, "SK-000002", "나", [("볼트", {"갈래": "숫자", "값": 500}), ("볼트", {"갈래": "입력", "값": 700})]) # fmt: skip got = _at(me, look.items) assert [(r["이름"], r["값"]) for r in got] == [("볼트", 500), ("볼트", 700)] assert [u["키"] for u in got[0]["쓰는곳"]] == ["SK-000001", "SK-000002"] assert got[1]["쓰는곳"] == [{"키": "SK-000002", "이름": "나"}] assert got[0]["규격"] == "10㎜" and got[0]["단위"] == "개" assert _at(layers.personal_dir(7, 43), look.items) == [] def test_personal_only(world): """④ 개인 층 밖 = 404 · 남의 개인 층 = 403(일반).""" user = {"role": "USER", "company_id": 7, "user_id": 42} for layer, owner, code in (("company", None, 404), ("personal", "7/43", 403)): with pytest.raises(HTTPException) as e: look.get_items(layer, owner, user) assert e.value.status_code == code assert look.get_items("personal", None, user) == {"rows": []} def _stack_doc(key, no): """줄 쌓기 기계 줄 하나(화면이 저장하는 꼴) — 기계='개인 …'.""" var = {"기호": "P", "아래": "새", "위": "", "이름": NAME, "단위": "", "연결": {"갈래": "단가산출", "키": "GC000268", "입력": {"기계": f"'{no}'"}}} # fmt: skip line = {"이름": NAME, "단위": "hr", "비목": "묶음", "수량": "1", "단가": "P_새"} return {"꼴": "수식문서", "판": 1, "키": key, "이름": "sub1임시", "결과단위": "원", "변수": [var], "식": [], "금액": [line]} # fmt: skip def test_stack_line_copy(world): """⑤ 줄 쌓기로 고른 내 기계 — 미리 셈 됨 · 저장 때 값 사본에 박힘 → 고쳐도 금액 그대로 + 단가새값 → [단가 갱신] 바뀐 자원 1 → 지워도 마지막 값 + 지운키.""" from M02_MasterTemplete import M02_Doc_Sk_Path as path from M02_MasterTemplete import M02_Labor_Ref as refs me = world["personal"] made = _at(me, mym.create, {**_mine_row(), "값": {**_mine_row()["값"], "주연료": 2, "주연료종류": "경유", "조종원": 1, "조종원직종": "1048"}}) # fmt: skip key, no, was = made["줄"]["키"], made["줄"]["원문번호"], made["시간당"]["계"] sk = _at( me, lambda: refs.create("sangeun", {"이름": "sub1임시", "단위": "시간", "더한줄": []})["이름"], ) doc = _stack_doc(sk, no) look_ = _at(me, path.preview, sk, {"문서": doc}) assert look_["셈"]["계"] == was # 사본에 아직 없는 내 기계도 셈 판 = _at(me, path.read, sk)["판"] _at(me, path.save, sk, {"문서": doc, "판": 판}) copy = _at(me, lambda: store.read("sangeun", sk)["문서"]["수식"]) assert key in [r["키"] for r in copy["단가"]] # 값 사본에 박힘 _at(me, mym.update, key, {**made["줄"], "값": {**made["줄"]["값"], "가격": 3000}}) now = _at(me, path.read, sk) assert now["셈"]["계"] == was and now["사본"]["단가새값"] is True job = _at(me, path.preview, sk, {"할일": "단가갱신"}) assert [x["키"] for x in job["바뀐자원"]] == [key] and job["후"]["계"] > was _at(me, mym.delete, key) gone = _at(me, path.read, sk) assert gone["셈"]["계"] == was and gone["사본"]["지운키"] == [key] def _mine_row(): return {"이름": NAME, "규격": "1㎾", "방식": "바로", "값": {"가격": 1000, "손료계수": 2000}}