Energyco KPI Dashboard
`; openPrint(html); } function exportIndividualExcel(){ const u=app.user;const per=curPeriod(); const deptsToShow=u.isSuperAdmin?DEPTS:u.depts; let csv=`KPI Report — ${u.name} — ${per}\n\nDepartment,KPI,Value,Target,Attainment\n`; deptsToShow.forEach(dept=>{ (db.templates[dept]||[]).forEach(t=>{ const val=gv(u.id,t.id+dept,per);const tgt=getTarget(dept,t.id); const p=(t.type==='number'||t.type==='percent')?pctOf(val,tgt):null; csv+=`"${dept}","${t.name}","${fmtVal(val,t.type)}","${tgt}","${p!==null?p+'%':'—'}"\n`; }); }); csv+=`\nGenerated: ${new Date().toLocaleDateString('en-MY')}`; dlFile(csv,`KPI_${u.name.replace(/ /g,'_')}_${per.replace(/[ /]/g,'_')}.csv`,'text/csv'); } function exportTeamPDF(){ const per=curPeriod(); const sections=DEPTS.map(dept=>{ const members=db.members.filter(m=>!m.isSuperAdmin&&m.depts.includes(dept)); if(!members.length)return''; const dc2=DC[dept]||{bg:'#eee',tx:'#333'}; const blocks=members.map(m=>{ const ts=db.templates[dept]||[]; const rows=ts.map(t=>{ const val=gv(m.id,t.id+dept,per);const tgt=getTarget(dept,t.id); const p=(t.type==='number'||t.type==='percent')?pctOf(val,tgt):null; const col=barColorHex(p); return `${t.name} ${fmtVal(val,t.type)} ${tgt} ${p!==null?p+'%':'—'}`; }).join(''); const pcts=ts.filter(t=>t.type!=='status'&&t.type!=='time').map(t=>pctOf(gv(m.id,t.id+dept,per),getTarget(dept,t.id))).filter(x=>x!==null); const avg=pcts.length?Math.round(pcts.reduce((a,b)=>a+b,0)/pcts.length):null; return `
${m.name} ${avg!==null?`${avg}%`:''}
${['KPI','Value','Target','Att.'].map(h=>``).join('')}${rows}
${h}
`; }).join(''); return `
${dept}
${blocks}
`; }).join(''); const html=`Team KPI — ${per}
Team KPI Report
Energyco — All departments
${per}
${sections}
Generated ${new Date().toLocaleDateString('en-MY',{day:'numeric',month:'long',year:'numeric'})} · Energyco KPI Dashboard
`; openPrint(html); } function exportTeamExcel(){ const per=curPeriod(); let csv=`Team KPI Report — ${per}\n\nDepartment,Name,KPI,Value,Target,Attainment\n`; DEPTS.forEach(dept=>{ db.members.filter(m=>!m.isSuperAdmin&&m.depts.includes(dept)).forEach(m=>{ (db.templates[dept]||[]).forEach(t=>{ const val=gv(m.id,t.id+dept,per);const tgt=getTarget(dept,t.id); const p=(t.type==='number'||t.type==='percent')?pctOf(val,tgt):null; csv+=`"${dept}","${m.name}","${t.name}","${fmtVal(val,t.type)}","${tgt}","${p!==null?p+'%':'—'}"\n`; }); }); }); csv+=`\nGenerated: ${new Date().toLocaleDateString('en-MY')}`; dlFile(csv,`Team_KPI_${per.replace(/[ /]/g,'_')}.csv`,'text/csv'); } function openPrint(html){const w=window.open('','_blank','width=900,height=700');w.document.write(html);w.document.close();w.focus();setTimeout(()=>w.print(),600);} function dlFile(content,name,mime){const b=new Blob([content],{type:mime+';charset=utf-8;'});const u=URL.createObjectURL(b);const a=document.createElement('a');a.href=u;a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(u),1000);} render();