ACP ERP  ·  Analytics
Inspire Africa Coffee Park  ·  Ntungamo, Uganda
🔔 0
Notifications
No new notifications
?
← Dashboard
📈
DepartmentAnalytics & Reporting
👤
Module ManagerKubariho Venture
🏢
LocationRwashameire, Ntungamo
SystemChecking...
📅
Date
Time
📆
Fiscal YearFY 2025/2026
Cross-Module KPIs — Live from ERP
Production Output (Last 7 Runs)
Programme of Works Progress
Quality Snapshot
Inventory Alerts
Open Issues Across ERP
All Department Scorecards
Production Runs — Output (kg)
Line Utilisation
Waste by Type (kg)
Downtime Events
Budget vs Actual (by Category)
Invoice Status
Recent Ledger Transactions
Staff by Department
Leave Status Today
Training Completion
Performance Ratings
QC Check Pass/Fail Rate
Cupping Scores
Active Certifications
Zone Progress
Equipment Status
Snag List by Priority
Active Contractors
Period Comparison — Month vs Month
Trend Charts
Production Output (kg)
Export Orders
System-wide Activity Log
Export Reports: Download CSV files from ERP data or generate print-ready PDF reports. CSV exports use current localStorage data.
How to Use — Executive Analytics
Step-by-step guidance for Management, Department Heads, and Data Coordinators
Overview Dashboard

The Overview tab aggregates live KPIs from all ERP modules including Revenue YTD, Employees, Production Output, Export Orders, Asset Value, Farm Harvest, Tourism Bookings, and Open Purchase Orders.

Tip: The Overview should be the first screen Nelson Tugume and Kubariho Venture check each morning. Data is pulled from localStorage in real time from all ERP modules.
  1. KPI cards at the top show headline numbers from all modules simultaneously.
  2. Charts show the most recent 7 days of production data and POW phase progress.
  3. The cross-module grid gives a single-screen CEO summary without navigating modules.
🏢 Department Analytics

The Departments tab shows per-department performance summaries: headcount, budget utilisation, open tasks, and risk indicators.

Tip: Use this view in the weekly management meeting. Departments showing amber or red status need a verbal update from their head before the meeting closes.
  1. Each department card shows live KPIs pulled from that module's localStorage.
  2. Click a department card to drill into that department's ERP module.
  3. Department heads should ensure their module data is current before Monday management reviews.
Production & Quality Analytics

The Production and Quality tabs visualise trends in coffee processing output, rejection rates, cupping scores, and batch yield.

Tip: Track cupping score trends weekly. If the rolling average drops below 78, initiate a process review with the Quality and Production teams immediately.
  1. Charts auto-populate from the Production and Quality ERP modules.
  2. Use the Export Reports tab to generate a CSV or print-ready summary.
  3. Waste and downtime charts identify the highest-impact problem categories.
📈 Period Comparison

The Comparison tab lets you select two months (Jan–Mar 2026) and compare KPIs side by side including production output, export orders, staff count, revenue, and harvest volumes.

Tip: Use the Comparison tab for board-level reporting to show month-on-month growth. Green arrows indicate improvement; red arrows indicate decline.
  1. Select Month 1 and Month 2 from the dropdowns.
  2. Click Compare to generate the side-by-side table with change percentage and trend arrows.
  3. Trend charts below show bar visualisations for each period.
📄 Export Reports

The Export Reports tab provides ready-made data exports for all key operational datasets. Each report can be downloaded as a CSV or printed as a formal PDF report.

Tip: Run the Payroll Summary and Asset Register monthly for Finance and Audit. Export orders CSV is required for UCDA compliance reporting.
  1. Click Export CSV to download a comma-separated file of the dataset.
  2. Click Print Report to open a formatted print view with the IACP letterhead.
  3. All CSV exports use current localStorage data — ensure modules are up to date before exporting.
👤 People Analytics & Activity Feed

The People tab shows workforce metrics: headcount by department, attendance, leave, and training. The Activity Feed provides a unified audit log across all modules including payroll runs, new hires, harvest records, export orders, work orders, and procurement approvals.

Tip: Filter the Activity Feed by module to trace specific events. The feed pulls from payroll, HR, harvest, export, maintenance, and procurement localStorage keys.
  1. Use the module filter dropdown to narrow the feed to a specific department.
  2. Each feed item shows a module badge, user avatar, description, and timestamp.
  3. Export activity logs monthly for compliance archiving using the Export Reports tab.
'); win.document.close(); win.focus(); setTimeout(()=>win.print(),400); } function renderExportReports(){ document.getElementById('rpt-grid').innerHTML=REPORTS.map((rpt,i)=>{ const colors=['#2a7a7a','#4a7c59','#c9a227','#2a5298','#d4621a','#2d6a3f']; return `
${rpt.title}
${rpt.desc}
`; }).join(''); } // ── Notification bell ───────────────────────────────────────────────────────── function loadNotifications(){ const notifs=load('acpark_notifications')||[]; const unread=notifs.filter(n=>!n.read).length; const badge=document.getElementById('notif-badge'); if(badge){badge.textContent=unread>0?unread:'';badge.style.display=unread>0?'flex':'none';} const list=document.getElementById('notif-list'); if(list){ list.innerHTML=notifs.length?notifs.slice(0,12).map(n=>`
${n.message||n.text||''}
${n.createdAt?new Date(n.createdAt).toLocaleString('en-UG',{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'}):'—'}
`).join(''):'
No new notifications
'; } } function toggleNotifDropdown(){ const dd=document.getElementById('notif-dropdown'); if(!dd)return; dd.classList.toggle('open'); // Mark all as read when opening if(dd.classList.contains('open')){ const notifs=load('acpark_notifications')||[]; notifs.forEach(n=>n.read=true); save('acpark_notifications',notifs); setTimeout(loadNotifications,300); } } // Close dropdown when clicking outside document.addEventListener('click',function(e){ const bell=document.getElementById('notif-bell'); if(bell&&!bell.contains(e.target)){ const dd=document.getElementById('notif-dropdown'); if(dd)dd.classList.remove('open'); } }); // ── Clock ───────────────────────────────────────────────────────────────────── function tickClock(){ const el=document.getElementById('ana-clock'); if(el){const n=new Date();el.textContent=n.toLocaleDateString('en-UG',{weekday:'short',day:'numeric',month:'short',year:'numeric'})+' '+n.toLocaleTimeString('en-UG',{hour:'2-digit',minute:'2-digit'});} } // ── API hydration — pull backend data into localStorage before first render ──── // allData() reads directly from localStorage; this function pre-fills the keys // that have live API endpoints. Runs once on load; fails silently if offline. async function hydrateFromAPI() { if (!window.api || api.isOnline() === false) return; try { // api.analytics.dashboard() returns aggregated KPI data keyed by module const dash = await api.analytics.dashboard(); if (dash) { // The dashboard endpoint returns top-level arrays for each module. // Map known response fields into the localStorage keys allData() reads. if (dash.staff && dash.staff.length) save('erp_staff', dash.staff); if (dash.payroll && dash.payroll.length) save('erp_payroll', dash.payroll); if (dash.leaves && dash.leaves.length) save('erp_leaves', dash.leaves); if (dash.training && dash.training.length) save('erp_training', dash.training); if (dash.budgets && dash.budgets.length) save('erp_budgets', dash.budgets); if (dash.ledger && dash.ledger.length) save('erp_ledger', dash.ledger); if (dash.invoices && dash.invoices.length) save('erp_invoices', dash.invoices); if (dash.pos && dash.pos.length) save('erp_pos', dash.pos); if (dash.zones && dash.zones.length) save('erp_zones', dash.zones); if (dash.qc && dash.qc.length) save('erp_qc_checks', dash.qc); if (dash.ncrs && dash.ncrs.length) save('erp_ncrs', dash.ncrs); if (dash.certs && dash.certs.length) save('erp_certs', dash.certs); if (dash.inventory && dash.inventory.length) save('erp_inventory', dash.inventory); if (dash.prodRuns && dash.prodRuns.length) save('erp_production_runs', dash.prodRuns); if (dash.prodLines && dash.prodLines.length) save('erp_production_lines', dash.prodLines); if (dash.activity && dash.activity.length) save('erp_activity', dash.activity); } } catch(e) {} try { // api.staff.list() returns the full staff roster const staff = await api.staff.list(); if (staff && staff.length) save('erp_staff', staff); } catch(e) {} try { // api.finance.summary() returns budget, ledger, and invoice data const fin = await api.finance.summary(); if (fin) { if (fin.budgets && fin.budgets.length) save('erp_budgets', fin.budgets); if (fin.ledger && fin.ledger.length) save('erp_ledger', fin.ledger); if (fin.invoices && fin.invoices.length) save('erp_invoices', fin.invoices); } } catch(e) {} } // ── Init ────────────────────────────────────────────────────────────────────── document.addEventListener('DOMContentLoaded', async () => { tickClock(); setInterval(tickClock, 30000); document.querySelectorAll('.mod-tab').forEach(t => { t.addEventListener('click', () => showMod(t.dataset.mod)); }); loadNotifications(); // Hydrate localStorage from API before first render so allData() gets // fresh backend data. Falls back gracefully if server is offline. await hydrateFromAPI(); showMod('overview'); renderComparison(); // pre-render comparison with defaults });