- 지움(git rm) 10 파일 3,374 줄: M02_Hopyo_Finger · Ours · Option · Fit · Combine · Verdict · Line · SkLink · SkPatch · Basis
- Match: 흐름 몫(candidates · name_cands · fix_typo · clause · b_order · _logic_specs · _line_mod · units_of · _state · view · guess · picks · chain) 지움 · 이름 도구 몫 · line_key 남김
- Words: conds · cond_score · close · cosine · jacc 지움 / Shares: sections 지움(trade · eq_key 남김)
- 옮김: Finger.kind_of → Fixed.kind_of · SkLink(sk_line · kept · left · LEFT · WHY) → Sangeun · SkPatch 기계 몫(MACH_IN · MACHINE · SOLO · _mach_logics) → Units.mach_logics
- Sangeun: 옛 /sangeun 몸(build · _sure · Maker.basis · judge · plan · make) 지움 · Kids: first · proposal · order 지움 · Build: build() · unlinked() 지움(모두 고정 Builder · build_all · _order · _origins 남김)
- Router: 옛 길 지움(GET hopyo/{키}/{번} · guess · hopyo-picks · hopyo-build · hopyo-unlinked · hopyo/{키}/sangeun) · GET hopyo/{키} = Judge.view(1차 줄 판정 줄상태 · 만든 · 블록 풀이 셈)
- Marks: 칠 = Judge.judged 만 · Forget: 맞춤 캐시 지움 줄 걷음 · Ledger: Ours.version 판 칸 걷음 · Item: Kids.first 걷음
- Row(덧): 단산 줄 = 장부 짝이 있어도 늘 「2차 필요」(장부 = 1차 후보 힌트만)
시험 정리(까닭 = 지운 길 · 모듈만 시험함):
- 지움 11 파일: test_m02_hopyo_finger · fit · golden · option · ours · basis · seam · flow · draft_calc · test_635 · test_628(지문 · 순위 · 옵션 거꾸로 · 맡은 절 · 옛 확인 흐름)
- 함수 지움: /sangeun · /hopyo-build · /hopyo-unlinked · hopyo-picks · 옛 줄 맞춤 보기를 부르던 것(572 · 718_1 · 729 · 739_1 · 777_1 · 778_5 · 780_1 · labor_national · 705_3 · m02_hopyo_match · 746_1)
- test_621 S2(지문 해시) 지움 · S1 남김 · test_m02_hopyo_build = 장부 길 시험만(PUT 으로 심음)
- 새 길로: 779_2(줄상태 = 1차 판정 · 칠 셈 전 None) · grid · stmate(hopyo-judge 줄 판) · 778_1 · 778_2(Units.mach_logics) · 642_6(Marks 원문) · 642_3 장부 짝 단산 줄 2차 지킴
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
152 lines
8.0 KiB
Python
152 lines
8.0 KiB
Python
"""불러오기 엑셀 보관 안 함(PLAN 743-1 · 요구 582-3 · 584-2 · `M02_Hopyo_Forget`).
|
||
|
||
[끝내기] = 남는 파일 0 · 만든 일위대가 · 단가산출 = 출처(파일 · 때 · 누가)만 · 금액 그대로 ·
|
||
엑셀 사본(본뜬 키 · 원본 · 확인 · 품셈 · 줄 메모 「실무 …」) 걷음 ·
|
||
실무수량 = 저장 수량과 같을 때만 걷음 · SK 또 = 그 HP 몫만 ·
|
||
하루 지난 HP = 목록 숨김 → 올림 때 지움 · 옛 파일 정리 미리 보기(쓰기 0) → 고침.
|
||
층 = 임시 폴더.
|
||
"""
|
||
|
||
import json
|
||
from datetime import datetime, timedelta, timezone
|
||
|
||
from M01_MasterData import M01_MasterData_Store as m01
|
||
from M02_MasterTemplete import M02_Hopyo_Forget as forget
|
||
from M02_MasterTemplete import M02_Hopyo_Store as hs
|
||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||
from M02_MasterTemplete import M02_Template_Layers as layers
|
||
from resources.tester.test_m02_hopyo_excel import URL, _post, client # noqa: F401
|
||
|
||
ALL = "/api/m02/layers/personal/hopyo-build-all"
|
||
|
||
|
||
def _files(folder):
|
||
return sorted(p.name for p in (folder / hs.DIRNAME).rglob("HP-*.json"))
|
||
|
||
|
||
def _sums(folder):
|
||
"""문서마다 1 단위 기준 계 — 끝내기 전후 같아야 함."""
|
||
whole = refs.Expand(m01.loaded()[1])
|
||
out = {}
|
||
with store.at(folder):
|
||
for kind in ("precombo", "sangeun"):
|
||
for p in sorted((folder / kind).glob("*.json")):
|
||
out[p.stem] = refs.summary(folder, kind, p.stem, whole).get("기준금액")
|
||
return out
|
||
|
||
|
||
def _docs(folder, kind):
|
||
return {p.stem: json.loads(p.read_bytes()) for p in sorted((folder / kind).glob("*.json"))}
|
||
|
||
|
||
# ── 순수 ──────────────────────────────────────────────────────────────
|
||
SURE = {"누가": {"id": 42, "이름": "갑"}, "때": "2026-11-02T00:00:00Z"}
|
||
HEAD = {"층": "실무자료", "주인": None, "키": "HP-000003 제2호표", "파일": "가.xls"}
|
||
|
||
|
||
def test_SC_사본_걷음_출처만_실무수량은_저장_수량과_같을_때만():
|
||
lines = [
|
||
{"로직": "L1", "메모": "실무 0.3㎥ × 1 · 규격", "수량": {"손": 0.3}, "별칭": "엑셀 품"},
|
||
{"로직": "L2", "메모": "사용자 메모", "수량": {"손": 2}},
|
||
]
|
||
doc = {
|
||
"이름": "가",
|
||
"담은로직": lines,
|
||
"자재": [{"코드": "MT1", "수량": {"손": 5}}],
|
||
"본뜬": {**HEAD, "원본": ["personal", "7/42"], "확인": SURE, "품셈": [0],
|
||
"전국자재": [{"이름": "모래"}], "실무수량": {"줄": {"0": 0.3, "1": 2},
|
||
"자재": {"MT1": 5}}},
|
||
} # fmt: skip
|
||
got = forget.strip_sc(doc)
|
||
assert got["본뜬"] == {
|
||
"층": "실무자료",
|
||
"파일": "가.xls",
|
||
"전국자재": [{"이름": "모래"}],
|
||
"때": SURE["때"],
|
||
"누가": SURE["누가"],
|
||
}
|
||
assert "메모" not in got["담은로직"][0] and got["담은로직"][1]["메모"] == "사용자 메모"
|
||
assert got["담은로직"][0]["별칭"] == "엑셀 품" and got["담은로직"][0]["수량"] == {"손": 0.3}
|
||
assert got["자재"] == doc["자재"]
|
||
# 742 전 저장본(수량 null) = 실무수량이 셈 근거 → 남김
|
||
old = {**doc, "담은로직": [{**x, "수량": None} for x in lines]}
|
||
assert forget.strip_sc(old)["본뜬"]["실무수량"] == doc["본뜬"]["실무수량"]
|
||
|
||
|
||
def test_SK_또_그_HP_몫만_걷음():
|
||
other = {"키": "HP-000004 단산1", "원본": None, "갈래": "SK", "엑셀품": {}, "이름": "나"}
|
||
doc = {"본뜬": {**HEAD, "키": "HP-000003 단산1", "확인": SURE, "갈래": "기초", "엑셀품": {},
|
||
"못옮김": [], "또": [other]}} # fmt: skip
|
||
got = forget.strip_sk(doc, lambda x: str(x.get("키")).startswith("HP-000003 "))
|
||
assert got["본뜬"] == {**{"층": "실무자료", "파일": "가.xls"}, **SURE, "또": [other]}
|
||
both = forget.strip_sk(doc, lambda x: True)
|
||
assert "또" not in both["본뜬"] and "키" not in both["본뜬"]
|
||
|
||
|
||
# ── 길 ───────────────────────────────────────────────────────────────
|
||
def test_끝내기_남는_파일_0_금액_그대로_출처만_다시_올림(client):
|
||
folder = layers.personal_dir(7, 42)
|
||
assert _post(client).json()["키"] == "HP-000001"
|
||
made = client.post(ALL, json={"층": "personal", "키": "HP-000001"}).json()
|
||
assert made["만듦"]
|
||
before = _sums(folder) # 모두 고정 = 메모 없음(메모 걷음은 순수 시험)
|
||
|
||
res = client.delete(URL.format("personal") + "/HP-000001")
|
||
assert res.status_code == 200
|
||
assert _files(folder) == [] # HP · 격자 0
|
||
assert _sums(folder) == before # 금액 그대로
|
||
for kind in ("precombo", "sangeun"):
|
||
for key, doc in _docs(folder, kind).items():
|
||
got = doc["본뜬"]
|
||
assert got["층"] == "실무자료" and got["파일"] and got["때"], key
|
||
assert not {"키", "원본", "확인", "품셈", "갈래", "엑셀품", "못옮김", "또"} & set(got)
|
||
lines = doc.get("담은로직") or []
|
||
assert not any(str(x.get("메모", "")).startswith("실무 ") for x in lines)
|
||
assert hs.done(folder)["지문"] == {} # 끝낸 기록 없음
|
||
again = _post(client) # 같은 엑셀 다시 올림 = 새 키(409 없음)
|
||
assert again.status_code == 200 and again.json()["키"] == "HP-000002"
|
||
|
||
|
||
def test_하루_지난_HP_목록_숨김_올림_때_지움(client):
|
||
folder = layers.personal_dir(7, 42)
|
||
assert _post(client).json()["키"] == "HP-000001"
|
||
path = folder / hs.DIRNAME / "HP-000001.json"
|
||
doc = json.loads(path.read_bytes())
|
||
old = datetime.now(timezone.utc) - timedelta(days=1, minutes=1)
|
||
doc["올린때"] = old.replace(microsecond=0).isoformat().replace("+00:00", "Z")
|
||
path.write_text(json.dumps(doc, ensure_ascii=False), encoding="utf-8")
|
||
assert client.get(URL.format("personal")).json()["줄"] == [] # 숨김
|
||
assert forget.expired(folder) == ["HP-000001"]
|
||
got = _post(client).json() # 같은 엑셀이어도 지난 것 = 지우고 새로(이어서 아님)
|
||
assert got["키"] == "HP-000002" and not got.get("이어서")
|
||
assert _files(folder) == ["HP-000002.json", "HP-000002.json"] # 이번 것 + 격자
|
||
|
||
|
||
def test_옛_파일_정리_미리_보기_쓰기_0_고침(client):
|
||
folder = layers.personal_dir(7, 42)
|
||
assert _post(client).json()["키"] == "HP-000001" # 작업 중 — 그대로
|
||
home = folder / hs.DIRNAME
|
||
(home / "HP-000007.json").write_text(json.dumps({"키": "HP-000007", "호표": []}), "utf-8")
|
||
hs._put_done(folder, {"번": 7, "지문": {"ab": {"파일": "옛.xls", "만든": ["SC-000001"]}}})
|
||
(folder / "precombo").mkdir(exist_ok=True)
|
||
gone = {"이름": "옛", "단위": "개", "담은로직": [{"로직": "L", "메모": "실무 1개 × 1"}],
|
||
"본뜬": {**HEAD, "키": "HP-000005 제1호표", "확인": SURE}} # fmt: skip
|
||
live = {**gone, "본뜬": {**HEAD, "키": "HP-000001 제1호표", "확인": SURE}}
|
||
for key, doc in (("SC-000001", gone), ("SC-000002", live)):
|
||
text = json.dumps(doc, ensure_ascii=False)
|
||
(folder / "precombo" / f"{key}.json").write_text(text, "utf-8")
|
||
snap = {p: p.read_bytes() for p in folder.rglob("*.json")}
|
||
|
||
rows = forget.tidy(folder)
|
||
assert [r["대상"] for r in rows] == ["실무자료/HP-000007", "불러옴.json", "SC-000001"]
|
||
assert {p: p.read_bytes() for p in folder.rglob("*.json")} == snap # 미리 보기 = 쓰기 0
|
||
|
||
assert forget.tidy(folder, apply=True) == rows
|
||
assert _files(folder) == ["HP-000001.json", "HP-000001.json"]
|
||
assert hs.done(folder) == {"번": 7, "지문": {}}
|
||
docs = _docs(folder, "precombo")
|
||
assert "키" not in docs["SC-000001"]["본뜬"] and "메모" not in docs["SC-000001"]["담은로직"][0]
|
||
assert docs["SC-000002"] == live # 작업 중 HP 것 그대로
|
||
assert forget.tidy(folder) == [] # 두 번째 = 할 일 없음
|