fix(재료): 품셈재료 고르기 단위 거름 — 단위·이름 같은 줄을 대표로, 없으면 비움
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V1MKKZKpUHTPKb513FneU8
This commit is contained in:
@@ -65,6 +65,9 @@ OVERRIDE = {
|
||||
}
|
||||
NO_GROUP = "자재품목 묶음에 짝이 없음 — 관리자가 화면에서 이음"
|
||||
NO_ROW = "자재품목에 그 묶음 줄이 없음"
|
||||
NO_UNIT = "자재품목 그 묶음에 같은 단위·이름 줄이 없음"
|
||||
UNIT = {"㎏": "kg", "톤": "ton", "Ton": "ton", "M": "m", "m²": "㎡", "L": "ℓ", "EA": "개", "set": "SET", "Set": "SET"}
|
||||
PRICE = ("물가자료", "유통물가", "물가정보", "거래가격", "관급")
|
||||
NOTE = re.compile(r"\s*·?\s*고르기 없음\([^)]*\)")
|
||||
FIELD = re.compile(r'("연결": (?:null|"[^"]*"|\{[^{}]*\}))(, "고르기": (?:null|\{[^{}]*\}))?')
|
||||
NOTE_FIELD = re.compile(r'(, "비고": )(null|"(?:[^"\\]|\\.)*")')
|
||||
@@ -90,9 +93,32 @@ def 고르기(row: dict, market: list[dict]) -> tuple[dict | None, str]:
|
||||
return None, NO_ROW
|
||||
대표 = {"대표": rep[0]} if rep else {}
|
||||
want = [mm.plain_spec(w) for w in str(row.get("규격") or "").replace(",", " ").split()]
|
||||
cond = {"구분": sub, "상세구분": detail, **대표}
|
||||
if want and any(all(w in mm.plain_spec(r.get("규격")) for w in want) for r in hits):
|
||||
return {"구분": sub, "상세구분": detail, "규격": row["규격"], **대표}, ""
|
||||
return {"구분": sub, "상세구분": detail, **대표}, ""
|
||||
cond = {"구분": sub, "상세구분": detail, "규격": row["규격"], **대표}
|
||||
hits = [r for r in hits if all(w in mm.plain_spec(r.get("규격")) for w in want)]
|
||||
return _단위(row, cond, hits, market)
|
||||
|
||||
|
||||
def _단위(row: dict, cond: dict, hits: list[dict], market: list[dict]) -> tuple[dict | None, str]:
|
||||
"""후보 첫 줄의 단위가 원문 단위와 다르면 — 단위·이름이 같은 줄을 대표로, 없으면 비움."""
|
||||
u = lambda x: UNIT.get(x, x) # noqa: E731
|
||||
want = u(str(row.get("단위") or ""))
|
||||
val = lambda r: [r[k] for k in PRICE if r.get(k) is not None] # noqa: E731
|
||||
if not want:
|
||||
return cond, ""
|
||||
if cond.get("대표"):
|
||||
rep = next(r for r in market if r["키"] == cond["대표"])
|
||||
return (cond, "") if u(rep["단위"]) == want else (None, NO_UNIT)
|
||||
first = next((r for r in hits if val(r)), hits[0])
|
||||
if u(first["단위"]) == want:
|
||||
return cond, ""
|
||||
root = re.sub(r"\s+", "", re.split(r"[(,\-]", str(row["이름"]))[0])
|
||||
same = [r for r in hits if u(r["단위"]) == want and val(r) and root in re.sub(r"\s+", "", r["이름"])]
|
||||
if not same:
|
||||
return None, NO_UNIT
|
||||
best = min(same, key=lambda r: (min(val(r)), r["키"]))
|
||||
return {**cond, "대표": best["키"]}, ""
|
||||
|
||||
|
||||
def main(show: bool) -> int:
|
||||
|
||||
Reference in New Issue
Block a user