From 209443657753e0c898fc2784aba598a909baed61 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 9 Nov 2026 13:19:17 +0900 Subject: [PATCH] =?UTF-8?q?feat(802-2a):=20GC000100=20=EC=95=94=ED=8C=8C?= =?UTF-8?q?=EC=87=84(=EC=9C=A0=EC=95=95=EC=8B=9D=20=ED=95=A0=EC=95=94?= =?UTF-8?q?=EA=B3=B5=EB=B2=95)=20=EC=88=98=EC=8B=9D=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EB=84=A3=EC=9D=8C=20=E2=80=94=20=EB=8B=A8=EA=B0=80=EC=82=B0?= =?UTF-8?q?=EC=B6=9C=20=EB=B6=80=EB=A6=84=20=EA=B0=92=20=3D=20=EB=81=9D?= =?UTF-8?q?=EC=88=98=20=EB=92=A4=20=EC=B1=84=ED=83=9D(=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=20714-3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 빌더 ADOPTED(채택된 차이) — GC000100 지역=경북 재료비 1 원 · 목록에 남기고 저장은 막지 않음 · 요약에 「채택된 차이」 - 수식 문서 1,518 → 1,519(건설품셈 03장 토공사 파일에 GC000100 49 줄 더함 · 다른 문서 그대로) - test_802_2 기대 바꿈(채택 차이 · 저장 1,519) · test_802_3 「빈 문서」 길은 임시 사본에서 GC000100 문서를 지워 봄(낡은 기대: GC000100 문서 없음) Co-Authored-By: Claude Sonnet 5.5 --- docs/raw/요구_1104/_목록_802-2_변환대조.xlsx | Bin 13055 -> 13010 bytes .../scripts/build_수식문서_802_2.py | 12 +++-- .../수식문서/수식_건설품셈_03장_토공사.json | 49 ++++++++++++++++++ resources/tester/test_802_2_convert.py | 22 +++++--- resources/tester/test_802_3_doc_screen.py | 6 ++- 5 files changed, 79 insertions(+), 10 deletions(-) diff --git a/docs/raw/요구_1104/_목록_802-2_변환대조.xlsx b/docs/raw/요구_1104/_목록_802-2_변환대조.xlsx index 1aef7d64c9d307ce13ff6545caad7ffa4748dc7d..ab3b94924dfa8efe810eecf696c525003472afa9 100644 GIT binary patch delta 2090 zcmY*ac|4Tu8h(edOp#{Bh{l!}V{P6klwBEQj}~LeQlkh{Bc*lnCCLzaZ{n>v`_$cmM9+b6=N`(oK=~bdiKB0stTj z_=kq2%NNo`OF%4Qef)$7Y=Z#+QnVhW9`U46PeyM$LZwlRVRE{Gm(_D6Pt2If3;Kc|t5p?Kq zp5rW#Qn0i+M4|Hwr%KRr@i->sb!>bVeU4|YbvyY@Q2OnCxk0FrU@&yk{VoRaVq=t& zvb=ypazw<|4>h42?yf}Kfv%}~@jNdLY`SC;{n0`7u!hFH(ND8{9WVDIe5agiHy^Y# zhgRd6*WDYq+0WWn^s~q*XgEtUs`SJ+uYT$R@39`4JjxvX67^cYBs3(T)~!fGW7&-J zJ}Nfu3u-K^-5Un|>3nd7b%annhD*V3*WtN2v8tH9YQ(mAs~1oJMz;zoF9 z@ODakgk^cd{(c~XMmuduPh-n}JJ#oC>hELA-&$t> zaF^cJIFunahGCf16rlX+wj7+%Lc1E+DSP!mg=fiE)KSMBWsyCI+NLr)&_Ol;xzX4D zxEaDoM{_Q*lZrwh(-RXLZP2ZWPAeq_Znn8vS}~9lgXrOCZyw?6Gn_@*E)9MoCvOI3 zPvV+op7H39b@QIT{-{;oP9^>}yu5H>F37|Ho!4MR1GVx<@JZGZ+Yhw2bNX_xC#7FG z#KHAh3ZizaT;M=5f{jU7P#~kgMrPu)ao-AmW-7it+|sbz)UX_vcEdtVPQUu>%u)hSl#BJHZ}L&X8dMz4BZZYrZd-~dDql1kB;n}RzZ$YFV3cR z{AyFG%y_Ad9&A2jJD|3t@$UWo(0}c}#j7;t##qVCxc|YS%$2M6wh9j$%=A7juRNk@ z*y0(xTkV1CgHz4BAJqM@3w$QA!sql-yPsOu2qafX(6Wu~hQ&u#)m7_%O{UgOP*Y2` z%a76Bud64wcP%ST_s%a_4%DMAgv&OjE^YVbChzq>o9R<}X=?7J@U)bGc6!t#i!~DK zd1qVU#P<)%mwIM8Qf+W@tbmzB1NV{qUA!=V??K zmWd2D^B_Df&EF8BUN_Pvo6f0!!XBFVLx}Li{=b$4)Z#oEKv91rNdMIz#MS<|mN7u> zA#7|GVhreY%(=7q+9q>ydmaPJr6+@)NP)NoxW&4f!uoR@^Yf#;%&#KK(`$gs`%(Yt{+Zy%bwz|`3YbWSR zR*WYM5@nF=L&cK8c<&othl@%#pLn=G>fPCK4UCND=Ltyh4E^|`mNIPsG?(7|n`6_K zfgGs0IQ(Ii@ywQ?#-}PQO&l*~GH!>qSA<;1Ip?3u8?l;B?_U{*E^)c0BiYg_^;a{p z^SyoC9{m(vHaxzL?A`JYT>Y!>TD)opGe+6P%U%wA#MG8vOx0nx4(p4p#;Gq`%sJ$^ zNPNVeoR0k3*^hKR-+LYK8o5VkUslDNhqh*zYH|vn{nQ=b^=jQ|7mnYXl$Y?ICA^Sg*gA52};xG!qdc#^# zhe`-LHCLgv|5)UP{~Z-^ChJ#KA5sUA8mkYh`kuEBC<6cv2NM~>-=iXq3Auy1VlwU~ zMgdvms*a+@So@{~Cni(Sm4cpta^j@^31VTk&^u67d|Cpr<~8~N5J;m$L~k=*ojqM( z5{kfI_8q|EHRvUX*yly;3V$a6T!H05?nHGl4V8$6ks$_APn>fPR6C3pMbM-G0KF!{ O8|oqAq#tiv1^*3Wwunjq delta 2107 zcmZ8ic{CLI7oWuzMvSqGAv3l&GlsE5#T$E4RJ1VJNny$sSq2GNvW&I&s4PX1F$USw z%p>GsR7TcHXe41sW%&)i(>tfWe|+!#e!lmfd(S=h-Vf7j+Y4f61LlDN00031HOD6t zQbpnlLb_hn$~+hB1p)wKT*^tFe`{o8!loNlPT-W;c#)xC-8vZKq4t^G!@y`=!=OK%Gn@A&Q zI8by|tT5SJ`3>xI^AxPi#~|i3={sSc=#fsxsf=vg{hOq9^ zbCtiu(Q^>O=&cbggw6poqmxmSQc=2BeD{k~r|<0_T5j~;U*YKCXj5`Sq`X{cH7wH@ zk`_-i4=>tuFsZc?=P5iGK($#uF+RRnf0jTE%n2&0UA;A){2{IUHL+w~(Q?~i&d}rQ znqp_l-P|wplkDTal&E$Xc$iOQr$|W#;0Y5j0ARa^Y%3%~!tT_iHTU@OQ7zch_T(IK zdAKjrShy~SPq?10!t*9n{$9vvlFDcKJgSqMm+5tDfjW?{7S`WR1n#gQXZ4AiPWA9_ zqkqCJ2&RlM-10j6quak0O-9re{;~hytOQ)ewWEfBDT4{9i#&Rmr*6{4;jfQ|fbM)GTw10`EArWJSU?ALSclJDr&geE z&s%G~vJ1+{3v^*I&e0& zkvU-^IrAdR_P*UWtneCa1>&8t@U8vsnB%R>mIYas8R7%Zp?@@N>Pi`Q&nXGp;^%<( zCXt*c@mio~Pi)P+%y97H?V}8k@|xwTruZa&vkkq>jD>?@qBlba-&n8N;Jl$ag^Y4x zirp+}hGB9lZ~JL2$b)KK01WDxLZk z34Chz&2%MpdMTUeh=18t#_j{R-4u1lThP$MbL>G|{D%Xdk>?hX=koINrC;Gt#lCJ8 zx!B6{&F7sw79U3WMdZDj_Y2{79{yJT+VB9Wq-%AHqVYVn4t<+5tz0Rn9fx)qpr5>U zmUr(v(;Bt)B?#qsBB%FuezNdK3;fZ#TkSunZZwB;s?Gz6#e-+g?Ab10FZmR}1T^qRQ$T~qTB(8{nIDvV(uRHpWK*k11 zauyBxsS%un)W*|9t2A8=zZEqEGeRL$I<@<0do~K1K5nnK-z~oGd25vUBBv~|E(xbZ zpo24S<-}UCGL`C{&UZ{iKN-|9p)sQ+N&$p1H%+IQfJok|84E?@MZjofjYYrgXcef5 zruo{OM`uF@506$af+I%d8HlS1MECj;!^Yx>(=p8+f6d3d(%5vXDqkCeyen9G$q4UV zje!ImyymaffzcdmYZwLnX}(=wU>-ktc#HD%j*+MkZ(EURQZVlo-VhhNk1oFq9HI15 z(-J*1uK9BIEFSspPgz%|IzD= zR4}zzmqfwyNXk9h%B8)M`BK7GtRyPzt6xOCPS&*JlrE`;AQ={{&QwVxB&=)q3PkAK z$j)v1aOP@ktEX5BG6q}?7h>@*Rc3%bx)W57YCjLh2QlEwRs8?11vAxdr_S!lj-*>$ z%$F(S?+J%~&#k%^2b;m?z?WA9L*cd#h>`Bz5c_$BhuMFv5x!aWZBScf-cn45q^#B4 zCj(J1JjpD#f>rXt<4ixUg}9_7rt(D^C3cd|H{mQJs4h-+KE!Nu)h@Ei5_nkcvzp$Z zAW7wy=vb+9zj(sH)MuG^I2V`p$=9>rZt6R`xTys{EcIaZ!FxTb^}1r93;DLRNLN3l8V;DIDTJ2v5&fYW918dlbIxA> z%?1m3Zzy)(rB5u{fGR}X!I)I?eJ)Clr4sV}x(Myj;A7u+n8elDMSn9gK7ckF`}c)u z25#ZQ+rE#2uN2cCtr+`zk|`l2OP##-Qp@UYDJrvSH>@OU8ae}=SPR{aAv~ztDTXC@ z<$+49M|eeS14B#_T*tM7(N)|LaspvgqE1i3|9ly3yHWA{Ic<*V@k diff --git a/resources/master_data/scripts/build_수식문서_802_2.py b/resources/master_data/scripts/build_수식문서_802_2.py index 4356a8ed0..5d32c7cf5 100644 --- a/resources/master_data/scripts/build_수식문서_802_2.py +++ b/resources/master_data/scripts/build_수식문서_802_2.py @@ -12,7 +12,9 @@ · 계(돈 아닌 로직 = 결과) 원 단위 — 기본 옵션 전부 + 옵션 표본(로직마다 고르기 입력의 다른 갈래 하나씩 · 나머지 기본). 둘 다 못 셈 = 같음(따로 셈). 보정 없음 — 다르면 목록에 까닭. -- 저장 = 같은 것만(요구서_664 1 장 3) — 모든 대조가 같고 부르는 단가산출도 저장되는 문서 · +- 채택된 차이(`ADOPTED`) = 사용자 요구 714-3 「1원 차이는 로직만 맞다면 문제 없음」 — 식 속 단가산출 + 부름 값 = 끝수 뒤(새 계산기 그대로) · 목록에 남기고 저장은 막지 않음. +- 저장 = 같은 것만(요구서_664 1 장 3) — 모든 대조가 같고(채택된 차이 빼고) 부르는 단가산출도 저장되는 문서 · `resources/master_data/수식문서/수식_<옛 로직 파일 꼬리>.json`(로직 파일마다 · 옛 로직 JSON 은 안 씀). - 목록 = `docs/raw/요구_1104/_목록_802-2_변환대조.xlsx`(로직 · 옵션 · 옛 · 새 · 차이 · 까닭 + 요약). @@ -44,6 +46,8 @@ RAW_SUB = ( "식 속 단가산출 부름 = 끝수 뒤 값" "(옛 엔진 = 끝수 전 날 값 · `master_formula.run` 결과를 식에 씀)" ) +# 채택된 차이 — (로직, 옵션) · 요구 714-3 +ADOPTED = {("GC000100", "지역=경북")} def rows_of(files: dict) -> list[tuple[str, dict]]: @@ -108,7 +112,7 @@ def why(doc: dict, old, new) -> str: if isinstance(new, str) and not isinstance(old, str): return f"새 계산기 못 셈 — {new}" if _uses_raw_sub(doc): - return RAW_SUB + return RAW_SUB + " · 채택(요구 714-3)" return "까닭 모름" @@ -151,6 +155,7 @@ def build(log=print) -> dict: ) for one in runs: if not one["같음"]: + one["채택"] = (one["로직"], one["옵션"]) in ADOPTED one["까닭"] = why(docs[one["로직"]], one["옛"], one["새"]) keep = _keep(docs, runs) for one in runs: # 같아도 못 넣는 것 — 부르는 단가산출이 빠짐 @@ -165,6 +170,7 @@ def build(log=print) -> dict: "옵션 표본": sum(1 for x in runs if x["옵션"]), "옵션 같음": sum(1 for x in runs if x["옵션"] and x["같음"]), "옵션 다름": sum(1 for x in runs if x["옵션"] and not x["같음"]), + "채택된 차이": sum(1 for x in runs if x.get("채택")), "둘 다 못 셈": both_out, "저장": len(keep), "변환 알림": sum(1 for v in notes.values() if v), @@ -192,7 +198,7 @@ def _calls(doc: dict) -> set[str]: def _keep(docs: dict, runs: list[dict]) -> set[str]: """저장할 문서 — 모든 대조 같음 + 부르는 단가산출도 저장(닫힘). 키 구멍 부름은 그 로직 대조로 판정.""" - keep = set(docs) - {x["로직"] for x in runs if not x["같음"]} + keep = set(docs) - {x["로직"] for x in runs if not x["같음"] and not x.get("채택")} while True: drop = {k for k in keep if not _calls(docs[k]) <= keep} if not drop: diff --git a/resources/master_data/수식문서/수식_건설품셈_03장_토공사.json b/resources/master_data/수식문서/수식_건설품셈_03장_토공사.json index 1e2796a26..fb90d4e9a 100644 --- a/resources/master_data/수식문서/수식_건설품셈_03장_토공사.json +++ b/resources/master_data/수식문서/수식_건설품셈_03장_토공사.json @@ -641,6 +641,55 @@ "끝전": "비목버림" } }, + { + "꼴": "수식문서", + "판": 1, + "키": "GC000100", + "이름": "암파쇄(유압식 할암공법)", + "결과단위": "원/㎥", + "출처": "건설품셈 공통 3-3-8", + "변수": [ + {"열쇠": "지역", "기호": "S", "아래": "지역", "위": "", "이름": "지역", "단위": "", "출처": "건설품셈 공통 8-1-7 5", "연결": {"갈래": "선택", "목록": ["전국평균", "전국", "서울", "경기", "강원", "충북", "충남", "전북", "경북", "경남", "부산", "제주", "대구", "인천", "대전", "울산", "세종", "전남광주"], "값": "전국평균"}}, + {"열쇠": "보정작업", "기호": "S", "아래": "보정작업", "위": "", "이름": "보정작업", "단위": "", "출처": "건설품셈 공통 8-1-7 1", "연결": {"갈래": "선택", "목록": ["해당 없음", "암석작업(연암・보통암・경암)", "전석섞인토사"], "값": "해당 없음"}}, + {"열쇠": "드릴경비", "기호": "C", "아래": "드릴", "위": "", "이름": "드릴경비", "단위": "", "연결": {"갈래": "식"}}, + {"열쇠": "브레이커경비", "기호": "C", "아래": "브레이커", "위": "", "이름": "브레이커경비", "단위": "", "연결": {"갈래": "식"}}, + {"열쇠": "P_기계시간당", "기호": "P", "아래": "기계시간당", "위": "", "이름": "기계 시간당 기계경비(손료 보정 없는 기종)", "단위": "원/시간", "연결": {"갈래": "단가산출", "키": "GC000268", "입력": {"기계": "'5405-0110'", "지역": "S_지역"}, "칸": "계"}}, + {"열쇠": "Q_유압식크롤드^표", "기호": "Q", "아래": "유압식크롤드", "위": "표", "이름": "암파쇄(유압식 할암공법).유압식크롤러드릴", "단위": "hr", "연결": {"갈래": "표", "표": "QC000201", "조건": {}, "칸": "유압식크롤러드릴"}}, + {"열쇠": "P_굴착기무한궤", "기호": "P", "아래": "굴착기무한궤", "위": "", "이름": "굴착기(무한궤도)+대형브레이커 시간당 기계경비", "단위": "원/시간", "연결": {"갈래": "단가산출", "키": "GC000271", "입력": {"기계": "'0201-0100'", "브레이커": "'0230-0010'", "지역": "S_지역", "보정작업": "S_보정작업"}, "칸": "계"}}, + {"열쇠": "Q_굴착기대형브^표", "기호": "Q", "아래": "굴착기대형브", "위": "표", "이름": "암파쇄(유압식 할암공법).굴착기_대형브레이커", "단위": "hr", "연결": {"갈래": "표", "표": "QC000201", "조건": {}, "칸": "굴착기_대형브레이커"}}, + {"열쇠": "Q_기계설비공^표", "기호": "Q", "아래": "기계설비공", "위": "표", "이름": "암파쇄(유압식 할암공법).기계설비공", "단위": "인", "연결": {"갈래": "표", "표": "QC000201", "조건": {}, "칸": "기계설비공"}}, + {"열쇠": "w_기계설비공", "기호": "w", "아래": "기계설비공", "위": "", "이름": "기계설비공노임", "단위": "", "연결": {"갈래": "요소", "키": "LB000051"}}, + {"열쇠": "Q_특별인부^표", "기호": "Q", "아래": "특별인부", "위": "표", "이름": "암파쇄(유압식 할암공법).특별인부", "단위": "인", "연결": {"갈래": "표", "표": "QC000201", "조건": {}, "칸": "특별인부"}}, + {"열쇠": "w_특별인부", "기호": "w", "아래": "특별인부", "위": "", "이름": "특별인부노임", "단위": "", "연결": {"갈래": "요소", "키": "LB000003"}}, + {"열쇠": "P_기계시간당2", "기호": "P", "아래": "기계시간당2", "위": "", "이름": "기계 시간당 기계경비(손료 보정 없는 기종)", "단위": "원/시간", "연결": {"갈래": "단가산출", "키": "GC000268", "입력": {"기계": "'5405-0110'", "지역": "S_지역"}}}, + {"열쇠": "Q_발전기^표", "기호": "Q", "아래": "발전기", "위": "표", "이름": "암파쇄(유압식 할암공법).발전기", "단위": "hr", "연결": {"갈래": "표", "표": "QC000201", "조건": {}, "칸": "발전기"}}, + {"열쇠": "P_기계시간당3", "기호": "P", "아래": "기계시간당3", "위": "", "이름": "기계 시간당 기계경비(손료 보정 없는 기종)", "단위": "원/시간", "연결": {"갈래": "단가산출", "키": "GC000268", "입력": {"기계": "'7505-0025'", "지역": "S_지역"}}}, + {"열쇠": "Q_유압식할암기^표", "기호": "Q", "아래": "유압식할암기", "위": "표", "이름": "암파쇄(유압식 할암공법).유압식할암기", "단위": "hr", "연결": {"갈래": "표", "표": "QC000201", "조건": {}, "칸": "유압식할암기"}}, + {"열쇠": "P_기계시간당4", "기호": "P", "아래": "기계시간당4", "위": "", "이름": "기계 시간당 손료(연료·조종원 없는 기종)", "단위": "원/시간", "연결": {"갈래": "단가산출", "키": "GC000273", "입력": {"기계": "'5501-0080'"}}}, + {"열쇠": "P_굴착기무한2", "기호": "P", "아래": "굴착기무한2", "위": "", "이름": "굴착기(무한궤도)+대형브레이커 시간당 기계경비", "단위": "원/시간", "연결": {"갈래": "단가산출", "키": "GC000271", "입력": {"기계": "'0201-0100'", "브레이커": "'0230-0010'", "지역": "S_지역", "보정작업": "S_보정작업"}}}, + {"열쇠": "Q_기계경비의^표", "기호": "Q", "아래": "기계경비의", "위": "표", "이름": "소모자재 요율.기계경비의", "단위": "%", "연결": {"갈래": "표", "표": "QC000202", "조건": {"장비": "'유압식 크롤러드릴'"}, "칸": "기계경비의"}}, + {"열쇠": "Q_기계경비의2^표", "기호": "Q", "아래": "기계경비의2", "위": "표", "이름": "소모자재 요율.기계경비의", "단위": "%", "연결": {"갈래": "표", "표": "QC000202", "조건": {"장비": "'굴착기+대형브레이커'"}, "칸": "기계경비의"}} + ], + "식": [ + {"기호": "C_드릴", "식": "P_기계시간당 × Q_유압식크롤드^표"}, + {"기호": "C_브레이커", "식": "P_굴착기무한궤 × Q_굴착기대형브^표"} + ], + "금액": [ + {"이름": "기계설비공", "단위": "인", "비목": "노무비", "수량": "Q_기계설비공^표", "단가": "w_기계설비공", "묶음": "인력"}, + {"이름": "특별인부", "단위": "인", "비목": "노무비", "수량": "Q_특별인부^표", "단가": "w_특별인부", "묶음": "인력"}, + {"이름": "유압식 크롤러드릴 110㎾", "단위": "시간", "비목": "묶음", "수량": "Q_유압식크롤드^표", "단가": "P_기계시간당2", "묶음": "유압식 크롤러드릴 110㎾"}, + {"이름": "발전기 25㎾", "단위": "시간", "비목": "묶음", "수량": "Q_발전기^표", "단가": "P_기계시간당3", "묶음": "발전기 25㎾"}, + {"이름": "유압식할암기 ∅80", "단위": "시간", "비목": "묶음", "수량": "Q_유압식할암기^표", "단가": "P_기계시간당4", "묶음": "유압식할암기 ∅80"}, + {"이름": "굴착기+대형브레이커 1.0㎥", "단위": "시간", "비목": "묶음", "수량": "Q_굴착기대형브^표", "단가": "P_굴착기무한2", "묶음": "굴착기+대형브레이커 1.0㎥"}, + {"이름": "소모자재(크롤러드릴)", "단위": "식", "비목": "재료비", "단가": "C_드릴 × Q_기계경비의^표 ÷ 100", "출처": "건설품셈 공통 3-3-8 주④", "묶음": "소모자재(크롤러드릴) · 소모자재(대형브레이커)"}, + {"이름": "소모자재(대형브레이커)", "단위": "식", "비목": "재료비", "단가": "C_브레이커 × Q_기계경비의2^표 ÷ 100", "출처": "건설품셈 공통 3-3-8 주④", "묶음": "소모자재(크롤러드릴) · 소모자재(대형브레이커)"} + ], + "끝수": { + "줄": {"방법": "버림", "자리": 1}, + "비목": {"방법": "버림", "자리": 0}, + "끝전": "비목버림" + } + }, { "꼴": "수식문서", "판": 1, diff --git a/resources/tester/test_802_2_convert.py b/resources/tester/test_802_2_convert.py index 90cb4af63..3b999d9d7 100644 --- a/resources/tester/test_802_2_convert.py +++ b/resources/tester/test_802_2_convert.py @@ -4,7 +4,7 @@ ① --check — 다시 돌린 결과 = 저장본(`resources/master_data/수식문서/`) · 목록 xlsx. ② 로직 1,519 전수 기본 옵션 = 옛 엔진 노 · 재 · 경 · 계(결과) 원 단위 같음. ③ 옵션 표본 — 로직마다 고르기 입력의 모든 갈래 한 번 이상 · 같음 수 · 다름 = 목록 · 까닭 모름 0. -④ 저장 = 같은 것만(부르는 단가산출까지) · 저장본을 읽어 다시 셈해도 같음. +④ 저장 = 같은 것만(부르는 단가산출까지 · 채택된 차이 GC000100 지역=경북 재료비 1 원 빼고) · 저장본을 읽어 다시 셈해도 같음. ⑤ 791 실무 손 옮김 견본 넷(번지 · 단계 · 합밖 · 줄 자리 · 끝전 · 조정 · 값묶음)도 변환 셈 = 엑셀 금액. """ @@ -56,7 +56,7 @@ def test_옵션_표본_모든_갈래_한_번_이상(result): assert (row["키"], f"{spec['이름']}={opt}") in seen info = result["요약"] assert info["옵션 표본"] == want == info["옵션 같음"] + info["옵션 다름"] - assert info["옵션 같음"] >= 18700 and info["옵션 다름"] <= 1 + assert info["옵션 같음"] >= 18700 and info["옵션 다름"] == info["채택된 차이"] == 1 def _whole(): @@ -69,15 +69,25 @@ def test_다름_목록_까닭(result): assert sheet[0] == list(build.HEAD) and sheet[1:] == rows diff = [x for x in result["대조"] if not x["같음"]] assert all(x["까닭"] != "까닭 모름" for x in diff) - assert [(x["로직"], x["옵션"], x["까닭"]) for x in diff] == [ - ("GC000100", "지역=경북", build.RAW_SUB) - ] + # 채택된 차이(요구 714-3) — 식 속 단가산출 부름 값 = 끝수 뒤 · 재료비 1 원 · 저장은 함 + assert [(x["로직"], x["옵션"], x["채택"]) for x in diff] == [("GC000100", "지역=경북", True)] + assert diff[0]["까닭"].startswith(build.RAW_SUB) + assert diff[0]["옛"]["재료비"] != diff[0]["새"]["재료비"] + assert abs(diff[0]["새"]["재료비"] - diff[0]["옛"]["재료비"]) == 1 + assert {k: diff[0]["옛"][k] for k in ("노무비", "경비")} == { + k: diff[0]["새"][k] for k in ("노무비", "경비") + } def test_저장_같은_것만_다시_셈(result): saved = ml.load_all() assert set(saved) == result["저장"] - assert "GC000100" not in saved and len(saved) == result["요약"]["저장"] >= 1518 + assert "GC000100" in saved and len(saved) == result["요약"]["저장"] >= 1519 + base = next(x for x in result["대조"] if x["로직"] == "GC000100" and not x["옵션"]) + assert ( + base["같음"] + and build.new_answer(ml.Links(_whole(), saved), saved["GC000100"]) == base["옛"] + ) for key in ("GC000211", "GC001147", "GF000294", "GC000087"): doc = saved[key] got = build.new_answer(ml.Links(_whole(), saved), doc) diff --git a/resources/tester/test_802_3_doc_screen.py b/resources/tester/test_802_3_doc_screen.py index 3f9018658..6675897f1 100644 --- a/resources/tester/test_802_3_doc_screen.py +++ b/resources/tester/test_802_3_doc_screen.py @@ -67,7 +67,11 @@ def test_읽기_미리셈_연결기록(client): def test_없는문서_빈문서_없는키_404(client): - fresh = _read(client, "GC000100") # 802-2a 로 문서 안 넣음 + assert ( + _read(client, "GC000100")["새"] is False + ) # 802-2a 로 문서 넣음 — 임시 사본에서 지워 빈 문서 길을 봄 + doc_screen.drop("GC000100") + fresh = _read(client, "GC000100") assert fresh["새"] is True and fresh["문서"]["식"] == [] and fresh["문서"]["금액"] == [] assert fresh["셈"]["셈됨"] is False and fresh["셈"]["계"] is None assert client.get("/api/m01/logic/doc", params={"key": "GX999999"}).status_code == 404