- JDL 줄 = 탭 구분 + \x05/\x07 덧붙임(검사기 0x504d20 · 고정폭 표는 죽은 고리 — 34 §17.9 바로잡음) · 단가 목록 7종·Main·GongJong 머리·Global.Ini 상수 키 · zip 받기 - 구버전 판 가리기(Chk_Data 0x459280) · 7.x/DOS 표별 필드 대응 · B→X 조건 = 단위 X - 엑셀 역등록 PRPT「속성」·PRIN「대상」·PROUT「저장」 = PR/RR 줄만 · 원본 BDQTY 4건 일치 - 자재 = 재료비 수량집계표 엑셀 내보내기(주요건설자재현황 시트) - 그림 코드 = COSTN I 코드 IFORM · SIZE = 그림 클래스 이름 - 지식DB 37번 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
"""STMATE 재현 앱 — 재료비 수량집계표 → 엑셀(wM_JajeXLS · 원본은 내보내기만) 지킴 시험.
|
||
|
||
근거: 지식DB REA 분석/37 §3 — STmate.Cpm TWM_JAJEXLS · ActMkJaje 0x5658bc · ST_P_XLS Prn_Col_M_EXL 0x4eb4d0 ·
|
||
머리 0x4ea93c(2~5줄 공사 정보 · 7줄 머리글 CAP_* 기본 글 · 열 너비) · 수량 소수 2자리 사사오입(0x4eba91) ·
|
||
금액 = 수량 × 단가 사사오입
|
||
"""
|
||
|
||
import io
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
sys.path.insert(0, str(ROOT / "tools/stmate-test"))
|
||
from conv_jaje import CAPS, SHEET, WIDTHS, amount, build_jaje_xlsx, caps_from_ini # noqa: E402
|
||
|
||
|
||
def test_layout_and_rounding():
|
||
import openpyxl
|
||
|
||
head = {
|
||
"PNAME": "임도 공사",
|
||
"PNUM": "A-1",
|
||
"BUDGET": "₩1,000원",
|
||
"수요기관": "국유림",
|
||
"계약일자": "2026.11.14",
|
||
}
|
||
rows = [
|
||
{
|
||
"NAME": "레미콘",
|
||
"NAME2": "25-21-120",
|
||
"SIZE": "",
|
||
"UNIT": "M3",
|
||
"QTY": 12.345,
|
||
"PRICE": 93000,
|
||
},
|
||
{"NAME": "철근", "SIZE": "D13", "UNIT": "TON", "QTY": 0.125, "PRICE": 850001},
|
||
]
|
||
wb = openpyxl.load_workbook(io.BytesIO(build_jaje_xlsx(head, rows)))
|
||
ws = wb[SHEET]
|
||
assert ws["A2"].value.endswith("임도 공사") and ws["G2"].value.endswith("A-1")
|
||
assert (
|
||
ws["A3"].value == "수 요 기 관"
|
||
and ws["B3"].value == "국유림"
|
||
and ws["C4"].value == "₩1,000원"
|
||
)
|
||
assert ws["F5"].value == "2026.11.14"
|
||
assert [ws.cell(7, j).value for j in range(1, 8)] == [d for _k, d in CAPS]
|
||
assert [ws.column_dimensions[c].width for c in "ABCDEFG"] == WIDTHS
|
||
assert (
|
||
ws["A8"].value == "레미콘\n25-21-120" and ws["C8"].value == 12.35 and ws["D8"].value == "M3"
|
||
)
|
||
assert ws["F8"].value == amount(rows[0]) == round(12.35 * 93000)
|
||
assert (
|
||
ws["C9"].value == 0.13 and ws["F9"].value == 110500
|
||
) # 0.125 → 0.13(사사오입) · 0.13×850001=110500.13
|
||
assert ws.max_row == 9
|
||
|
||
|
||
def test_caps_from_print_section():
|
||
caps = caps_from_ini({"PRINT": {"CAP_NAME": "품명", "cap_bigo": "참고"}})
|
||
assert caps[0] == "품명" and caps[-1] == "참고" and caps[1] == "규 격"
|