- 새 M02_Hopyo_SkUnit: 줄 판정(Units 잇기 + 매개값 · 사용자 고름 {차례: 노임|기계|자재|기준|뺌} · 꼬리표 「내가 고름」) · 단가 = M01 지금 값으로 다시 셈(우리금액) · 엑셀 금액 차 = 참고 · 블록 판정 「옮길 수 있음」 | 「고를 줄 n」 · 단위 SK 더한줄 = 인력 · 기계경비 로직 줄 · 재료(손료율 든 수량 · 별도계상) · 율 줄(778-4 꼴 · 줄 목록 = 그 행 add:#k) · 하위 참조 · 값 고정 줄 · 저장 꼴로 다듬어 같은 내용 SK 지문 같음
- Sangeun: 기초 · SK · 고름 대기 갈림(SkPatch.plan) 걷고 단위 SK 하나 · 확인 [{번, 고름?}] 에 든 블록만 만듦 · 하위 단산 먼저 · 고를 줄 남으면 못만듦 · 일위대가 만들기가 부르는 Maker.plan(번) = 「확인 전」 고름 대기(자동 없음) · 별칭 제안 걷음(바탕 기초 없음)
- Router: sangeun 몸 바탕 → 확인(줄 수 그대로)
- 시험 새 뜻: test_729(기초 · SK · 고름 대기 · 계수 · 못옮김 잇기 · 729-5 차이 SK 바탕 길 = 바탕 없는 단위 SK 로 사라짐 → 확인 블록 단위 SK · 줄 고름 · 뺌으로 갈음) · test_718_1 · test_572 · test_779_2 · test_m02_hopyo_flow(확인 목록을 보내야 SK 생김 · 같은 파일 안 같은 내용 단위 SK 없을 수 있음 · 바탕 없는 SK = SC 에 참조 그대로)
- 새 test_778_5: 작업반장 = 건설업 · 규격 차례 무관 · 글자 규격 = 후보 · 손료율 · 설치비 · 제경비 율 줄 · 여덟 파일 줄 연결 표 · 확인 안 한 블록 안 만듦 · 고름 · 400 · 404 · 다시 올림 같은 SK 재사용 · 일위대가 확인 전 못 이음
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
117 lines
5.9 KiB
Python
117 lines
5.9 KiB
Python
"""불러오기 [단가산출 만들기] 같은 내용 SK 씀(PLAN 733-1b · 요구서_572 3장 2).
|
|
|
|
북부청 임도(실물)를 임시 층에 → 같은 파일 안 같은 내용 SK 한 벌 · 바이트만 다른 사본 다시 = 새 SK 0 ·
|
|
뒤 출처 = `본뜬.또` · 다시 = 그대로 · 위 층(회사) 같은 것 = `위층같음` 알림 ·
|
|
출처마다 못옮김 · 다른 출처가 쓰는 SK 내용은 안 바꿈(떼어 냄 · 넘겨줌).
|
|
"""
|
|
|
|
import io
|
|
import json
|
|
import zipfile
|
|
|
|
from M02_MasterTemplete import M02_Hopyo_Fit as fit
|
|
from M02_MasterTemplete import M02_Hopyo_Sangeun as sangeun
|
|
from M02_MasterTemplete import M02_Library_Same as same
|
|
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
|
from M02_MasterTemplete import M02_Template_Layers as layers
|
|
from resources.tester.test_572_library_same import _put
|
|
from resources.tester.test_m02_hopyo_excel import NORTH, URL, _post, client # noqa: F401
|
|
|
|
|
|
def _rezip(data: bytes) -> bytes:
|
|
"""내용 같고 바이트 다른 사본 — xlsx = 다시 묶음 · xls = 끝에 빈 칸 한 벌(512 바이트)."""
|
|
if not zipfile.is_zipfile(io.BytesIO(data)):
|
|
return data + bytes(512)
|
|
src, buf = zipfile.ZipFile(io.BytesIO(data)), io.BytesIO()
|
|
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED, compresslevel=1) as z:
|
|
for info in src.infolist():
|
|
z.writestr(
|
|
zipfile.ZipInfo(info.filename, (2026, 1, 1, 0, 0, 0)), src.read(info.filename)
|
|
)
|
|
return buf.getvalue()
|
|
|
|
|
|
def _sks(folder) -> dict[str, dict]:
|
|
paths = sorted((folder / "sangeun").glob("SK-*.json"))
|
|
return {p.stem: json.loads(p.read_bytes()) for p in paths}
|
|
|
|
|
|
def _make(client, folder, data, name):
|
|
res = _post(client, data=data, name=name)
|
|
assert res.status_code == 200, res.text
|
|
key = res.json()["키"]
|
|
fit.run_job(folder, key)
|
|
url = f"{URL.format('personal')}/{key}/sangeun"
|
|
rows = client.post(url).json()["판정"] # 778-5 — 확인한 블록만(옮길 수 있음 모두 확인)
|
|
got = client.post(url, json={"확인": [{"번": r["번"]} for r in rows if not r["고를줄"]]})
|
|
assert got.status_code == 200, got.text
|
|
return key, got.json()
|
|
|
|
|
|
def test_불러오기_같은내용_SK_씀_바이트만_다른_사본_새_SK_0(client):
|
|
folder = layers.personal_dir(7, 42)
|
|
data = NORTH.read_bytes()
|
|
hp1, one = _make(client, folder, data, NORTH.name)
|
|
docs = _sks(folder)
|
|
fingers = [same.finger("sangeun", d) for d in docs.values()]
|
|
assert len(fingers) == len(set(fingers)) # 같은 내용 SK 한 벌
|
|
assert one["만듦"] and len(docs) + len(one["같은것씀"]) == len(one["만듦"])
|
|
assert one["위층같음"] == []
|
|
again = client.post(f"{URL.format('personal')}/{hp1}/sangeun").json()
|
|
assert again["만듦"] == [] and again["그대로"] == len(one["만듦"])
|
|
# 위 층(회사)에 같은 것 = 알림만
|
|
firm = layers.company_dir(7)
|
|
first = next(iter(docs))
|
|
_put(firm, "sangeun", "SK-000001", docs[first])
|
|
# 바이트만 다른 사본 = 새 HP · 새 SK 0 · 뒤 출처 = 본뜬.또
|
|
hp2, two = _make(client, folder, _rezip(data), "사본_" + NORTH.name)
|
|
assert hp2 != hp1 and _sks(folder).keys() == docs.keys()
|
|
assert len(two["만듦"]) == len(one["만듦"]) == len(two["같은것씀"])
|
|
assert {"층": "company", "주인": "7", "키": "SK-000001"} in [
|
|
{k: x[k] for k in ("층", "주인", "키")} for x in two["위층같음"]
|
|
]
|
|
also = {x["키"].split(" ")[0] for d in _sks(folder).values() for x in d["본뜬"].get("또", [])}
|
|
assert also == (
|
|
{hp1, hp2} if one["같은것씀"] else {hp2}
|
|
) # 778-5 단위 SK = 파일 안 겹침 없을 수 있음
|
|
again = client.post(f"{URL.format('personal')}/{hp2}/sangeun").json()
|
|
assert again["만듦"] == [] and again["그대로"] == len(one["만듦"])
|
|
|
|
|
|
def _maker(hp: str) -> sangeun.Maker:
|
|
"""블록 하나짜리 만들기(파일 · 맞춤셈 없이) — 쓰기 규칙만 봄."""
|
|
m = object.__new__(sangeun.Maker)
|
|
m.first, m.blocks = {1: {"이름": "줄", "단위": "㎥"}}, {1: {"이름": "블록"}}
|
|
m.hp, m.sure = {"키": hp, "파일": f"{hp}.xls"}, {"원본": ["personal", "7/42"]}
|
|
m.same, m.reused, m.above = same.Same(), [], []
|
|
return m
|
|
|
|
|
|
def _plan(code: str, lost: list) -> dict:
|
|
keep = {"갈래": "기초", "엑셀품": {}, "못옮김": lost, "바탕": {"로직": code}, "입력값": {}}
|
|
return {**keep, "자재표시": {}, "덮개": {}, "더한줄": [], "뺀줄": []}
|
|
|
|
|
|
def test_같은내용_SK_출처마다_못옮김_떼어냄_넘겨줌(client):
|
|
folder, at = layers.personal_dir(7, 42), ("personal", "7/42")
|
|
one, two = _maker("HP-000001"), _maker("HP-000002")
|
|
with store.at(folder):
|
|
key = one.write(1, _plan("GF000113", []), None)
|
|
assert two.write(1, _plan("GF000113", [{"id": "x"}]), None) == key # 같은 것 씀
|
|
assert two.reused == [{"번": 1, "키": key}]
|
|
doc = _sks(folder)[key]
|
|
assert sangeun.origin_of(doc, "HP-000002 단산1", at)["못옮김"] == [{"id": "x"}]
|
|
assert sangeun.origin_of(doc, "HP-000001 단산1", at)["못옮김"] == []
|
|
assert sangeun.made(folder, "HP-000002", at) == {"HP-000002 단산1": key}
|
|
# 뒤 출처가 바탕을 바꿈 = 떼어 냄 · 남의 SK 내용 그대로
|
|
moved = _maker("HP-000002").write(1, _plan("GF000114", []), key)
|
|
assert moved != key and "또" not in _sks(folder)[key]["본뜬"]
|
|
assert _sks(folder)[key]["바탕"]["로직"] == "GF000113"
|
|
# 앞 출처가 바탕을 바꿈 = 뒤 출처에게 넘겨줌
|
|
assert _maker("HP-000003").write(1, _plan("GF000113", []), None) == key
|
|
back = _maker("HP-000001").write(1, _plan("GF000114", []), key)
|
|
assert back == moved # 바꾼 내용 = 이미 있는 같은 것
|
|
left = _sks(folder)[key]
|
|
assert left["바탕"]["로직"] == "GF000113" and left["본뜬"]["키"] == "HP-000003 단산1"
|
|
assert "또" not in left["본뜬"] and len(_sks(folder)) == 2
|