';
window.modelResult={...result,origin,inputs:v,empiricalVerified:false};
}
names.forEach(k=>document.getElementById(k).addEventListener('input',()=>{origin='user-unverified';delete window.modelResult;update();}));
document.getElementById('example').onclick=()=>{
const v={R0:20,V0:15,Rn:21,Vn:15.5,F:1000,Qn:100,Qc:1000};
names.forEach(k=>document.getElementById(k).value=v[k]);origin='synthetic';update();
};
document.getElementById('reset').onclick=()=>{names.forEach(k=>document.getElementById(k).value='');origin='blank';delete window.modelResult;update();};
update();
})();'''
def build_model(out,shell):
model={'schema':'ksf.incremental-feasibility.v1','unit':'元/统一销售单位,销量为同一分析期',
'empiricalCompanyData':False,'fields':{k:{'label':label,'value':None,'unit':unit,'sourceNeeded':source} for k,label,unit,source in FIELDS},
'formulas':{'u0':'R0-V0','un':'Rn-Vn','deltaUnit':'un-u0','incrementalContribution':'Qn*un+Qc*(un-u0)-F',
'sameVolumeBreakEven':'ceil(F/(un-u0)) only when un-u0>0; Qn=0'},
'limitations':['不以零售价代净实现收入','费用口径互斥,不能重复计税/运费/报损','新销量与旧品转移销量分开','仅单期贡献模型,未含资金时间价值和额外固定运营变化']}
(out/'商业回推模型.json').write_text(json.dumps(model,ensure_ascii=False,indent=2)+'\n',encoding='utf8')
with (out/'商业回推输入模板.csv').open('w',encoding='utf-8-sig',newline='') as f:
w=csv.writer(f);w.writerow(['变量','含义','实际值(留空待核)','单位','需要的依据'])
for k,label,unit,source in FIELDS:w.writerow([k,label,'',unit,source])
inputs=''.join(f'' for k,label,unit,_ in FIELDS)
body='''