- 요구 834 · 835 · 836 · 837 — 보기 · 관리 방식(열 구성 · 조달청 0 · 일반가격 · 상하차 고르기 · 가장 낮은 값 규칙) 그대로 · 항목 목록만 EST 그대로 - 빌더 통합 단계 걷음 — material_merge = 열 한 벌 · 상하차 판독(split_load) · place 만 남김(지역 · 관급/사급 묶기 걷음) - 재료_자재품목 17,692 → 24,027 줄 = 830-1 24,092 − 재료 아닌 줄 65 · 키 = 830-1 키 · 새 키 0 · 키대장 = 830-1 대장 − 65 · 「다음」 그대로 - 830-1 대조: 키 · 구분 · 상세구분 · 단위 · 물가지 넷 · 출처 · 면수 같음 · 다른 것 = 열 구성 · 조달청 값 0 · 비고(조달 4,552 · 가격정보 2) · 상하차 글 뺌 384(이름 297 · 규격 87 — 요구 836) - 상하차 = 이름 · 규격 끝 인도 조건 글(도착도 259 = 하차 · 상차도 류 125 = 상차)을 칸으로 옮기고 글은 뺌 · 나머지 - - 빌더가 손 값(상하차 · 일반가격)을 원문번호로 이어 받음 · 빌더 두 번 = 같은 파일 - 사급/관급 열은 두지 않음(요구 837 — 단가산출 쪽 몫) - 품셈재료 옮긴 줄 2(모래 · 자갈 건조상태 전국)의 830-2 통합 이름 · 비고를 830-1 글로 되살림 - 시험: test_830_2 를 이번 상태로(통합 규칙 시험 지움 · 상하차 글 뺌 · 줄 = EST 그대로 · 24,027) · 830-2 가 통합에 맞춰 바꾼 기대를 830-1 판으로 되돌림(814_1 · 815_1 · 827_2 · 827_3 · m02_hopyo_match · m01_pick · m01_api 「시멘트 전국」 xfail 걷음 · masterdata_check 자재지역) · 울진 레미콘 = 관급 줄뿐 → 「지역 값 없음」 · check_links 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
3.0 KiB
Python
68 lines
3.0 KiB
Python
"""재료 자재품목 열 한 벌 · 상하차(요구 828 · 830 · 831 · 834 · 836 · 837 · PLAN 830-9).
|
|
build_재료_자재품목 이 부름 · 시험 = test_830_2_material_merge.
|
|
|
|
줄 목록 = EST 그대로(지역 · 관급 · 사급 · 제조사 · 조합 글이 든 원래 이름 · 줄마다 따로) — 합치지 않음.
|
|
열 한 벌 = COLUMNS — 상하차 = 단위 바로 뒤 · 가격 열 = 조달청(관급) · 물가지 넷 · 일반가격(사급).
|
|
사급 / 관급 고르기는 재료 표 열이 아님 — 단가산출 쪽 몫(요구 837).
|
|
상하차 칸 = 상차 · 하차 · -(기본 · 모름) — 이름 · 규격 끝 인도 조건 글로 채우고 그 글은 이름 · 규격에서 뺌(요구 836)
|
|
「도착도」 · 「하차도」 = 하차 · 「채취장상차(도)」 · 「하치장 · 생산공장 상차도」 · 「(상차도)」 = 상차
|
|
조달청 칸 값은 모두 비움(EST 「가격정보」 — 요구 827 · 831) · 일반가격 = 시스템 관리자가 넣는 칸.
|
|
상하차 · 일반가격 손 값은 빌더가 이어 받음.
|
|
"""
|
|
|
|
import re
|
|
|
|
MARKET = ("물가자료", "유통물가", "물가정보", "거래가격")
|
|
LOAD = "상하차" # 표지 칸(값 칸 아님)
|
|
LOADS = ("-", "상차", "하차") # 첫째 = 기본(모름)
|
|
GOVT = "조달청" # 관급 가격 칸 — 가장 낮은 값 고르기에 안 넣음(요구 826 · 830)
|
|
OWN = "일반가격" # 시스템 관리자 손 입력 칸(사급)
|
|
HAND = (LOAD, OWN) # 빌더가 이어 받는 손 값 칸
|
|
COLUMNS = ( # 열 한 벌 · 차례(요구 830 · 831)
|
|
"키",
|
|
"구분",
|
|
"상세구분",
|
|
"이름",
|
|
"규격",
|
|
"단위",
|
|
LOAD,
|
|
GOVT,
|
|
*MARKET,
|
|
OWN,
|
|
"출처",
|
|
"비고",
|
|
"면수",
|
|
)
|
|
NAME_LOAD = re.compile(r",\s*(도착도|하차도|채취장상차도|채취장상차)$") # 모 래, 서울, 도착도
|
|
SPEC_LOAD = re.compile(
|
|
r"\s*(?:\((상차도)\)|((?:하치장|생산공장)\s*상차도))$"
|
|
) # HD=10mm 하치장 상차도
|
|
|
|
|
|
def split_load(row: dict) -> tuple[str, str, str, str | None]:
|
|
"""(인도 조건 글을 뺀 이름, 규격, 상하차 값, 뺀 글) — 도착 · 하차 = 하차 · 상차 = 상차 · 글 없음 = -."""
|
|
name, spec = row.get("이름") or "", row.get("규격") or ""
|
|
m = NAME_LOAD.search(name)
|
|
if m:
|
|
name, text = name[: m.start()], m[1]
|
|
else:
|
|
m = SPEC_LOAD.search(spec)
|
|
if not m:
|
|
return name, spec, LOADS[0], None
|
|
spec, text = spec[: m.start()], m[1] or m[2]
|
|
return name, spec, "하차" if text.startswith(("도착", "하차")) else "상차", text
|
|
|
|
|
|
def place(row: dict) -> dict:
|
|
"""COLUMNS 차례의 줄 — 첫 칸(열쇠 · 키)은 그대로 · 인도 조건 글은 상하차 칸으로 ·
|
|
손 값(상하차)이 있으면 그 값 · 조달청 = 빔 · 옛 칸(관급)은 뺌."""
|
|
name, spec, load, _ = split_load(row)
|
|
first = next(iter(row))
|
|
fix = {
|
|
"이름": name,
|
|
"규격": spec,
|
|
LOAD: row.get(LOAD) or load,
|
|
GOVT: None,
|
|
}
|
|
return {first: row[first], **{c: fix[c] if c in fix else row.get(c) for c in COLUMNS[1:]}}
|