Files
Aislo/resources/tester/test_est_applied_cost.py
T
eomsangdonandClaude Opus 5.5 7b765c2599 feat(est-test): 적용대가 보기 변경·수량불러오기·적용대가집계표
- 물가변동 품목조정 화면을 native-applied-cost.js 로 옮김(native-extra.js 700줄 한계)
- 보기 변경: 단가 밴드 숨기고 계약·구분별 수량 7종만
- 수량불러오기: 고른 내역서 행 i 수량을 구분 칸에, 원가 행 i Cost 를 Es*Cost 에(위치 짝)
- 적용대가집계표: 원가 행마다 계약·적용제외·적용대가 금액

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 18:59:17 +09:00

87 lines
3.5 KiB
Python

"""적용대가 분류 내역서: 수량불러오기(위치 짝)·적용대가집계표·보기 변경."""
from test_est_rea_parity import run
def test_gn_load_copies_quantity_by_position_and_wonga_cost():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.options.SourceRefresh=false;
p.tables.EstMainDat=[{Code:'A',GN:10,GU:80},{Code:'B',GN:20,GU:50},{Code:'C',GN:5,GU:10}];
p.tables.Wonga=[{Name:'재료비',Cost:0},{Name:'노무비',Cost:0}];
const src={tables:{EstMainDat:[{GN:3},{GN:7}],Wonga:[{Cost:111},{Cost:222},{Cost:333}]}};
const n=EstAppliedCost.load(p,3,src);
const q=EstBusiness.baseline(EstNative.calculate(structuredClone(p)));
EstAppliedCost.load(q,0,{tables:{EstMainDat:[{GN:9}],Wonga:[{Cost:500}]}});
const r=structuredClone(p);delete r.baseline;
EstAppliedCost.load(r,0,{tables:{EstMainDat:[{GN:4}]}});
return {n,actual:p.tables.EstMainDat.map(x=>x.EscActual??null),
work:p.tables.Wonga.map(x=>x.EsWorkCost),base:q.baseline.tables.EstMainDat[0].GN,
contract:q.tables.Wonga[0].EsContractCost,old:r.tables.EstMainDat[0].GN_};
})()""",
)
assert result == {
"n": 2,
"actual": [3, 7, None],
"work": [111, 222],
"base": 9,
"contract": 500,
"old": 4,
}
def test_summary_uses_loaded_contract_cost_or_contract_calculation():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.options.SourceRefresh=false;p.options.EscDesignTotal=1000;
p.tables.EstMainDat=[{Code:'A',Name:'a',GN:10,GU:100},{LinkIndex:54}];
p.tables.Wonga=[{Name:'재료비',VSusic:'',BaseField:'GC',LinkIndex:1}];
const q=EstBusiness.baseline(EstNative.calculate(p));
q.tables.EstMainDat[0].EscActual=4;
const a=EstAppliedCost.summary(q).map(x=>[x.contract,x.except,x.apply]);
q.tables.Wonga[0].EsContractCost=2000;
const b=EstAppliedCost.summary(q).map(x=>[x.contract,x.except,x.apply]);
return {a,b};
})()""",
)
contract, except_, apply = result["a"][0]
assert apply == contract - except_
assert result["b"][0][0] == 2000
assert result["b"][0][2] == 2000 - result["b"][0][1]
def test_style_toggle_shows_quantity_band_only():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.options.SourceRefresh=false;
p.tables.EstMainDat=[{Code:'A',Name:'a',GN:10,GU:100,EscPS:2}];
const q=EstBusiness.baseline(EstNative.calculate(p));
const state={project:q,view:'escalation',escalationPage:0,selection:new Set()};
const box=(t,tools,body)=>tools+body,button=(a,t)=>`<button data-action="${a}">${t}</button>`,
table=(h,rows)=>JSON.stringify({h,rows});
const g=globalThis;g.EstApp={...(g.EstApp||{}),esc:String,number:String,render(){}};g.EstViews={cell:(t,i,k,v)=>String(v)};
const plain=EstAppliedCost.view(state,q,{box,button,table});
EstAppliedCost.handle('applied-style-toggle',state);
const band=EstAppliedCost.view(state,q,{box,button,table});
const head=(s)=>JSON.parse(s.slice(s.indexOf('{"h"'))).h;
return {plain:head(plain).length,band:head(band)};
})()""",
)
assert result["plain"] == 18
assert result["band"] == [
"코드",
"품명",
"계약 수량",
"시공중 수량",
"예정공정 수량",
"실행공정 수량",
"기성 수량",
"PS 수량",
"선시공 수량",
"적용제외",
"적용수량",
]