My Company Emissions dashboard
“My Company Emissions” is the Carbon Calculator’s landing page for a logged-in user: this year’s total in tCO2e, the Scope 1/2/3 split, carbon intensity per £1m turnover, a year-over-year chart, and the table of the company’s reports.
Why it exists
Section titled “Why it exists”It is the answer to “what are our emissions?” in one screen, and the entry point to everything else — creating or continuing a report, and sharing with clients. It also has to degrade gracefully for the large fraction of users who arrive with no company link, no reporting years configured, or no calculation run yet.
Entry points
Section titled “Entry points”| Path | What it does |
|---|---|
wp-content/themes/carboncalculator/page-my-company-emissions.php | The page template, /my-company-emissions/ |
wp-content/themes/carboncalculator/assets/js/company-emissions.js | Chart rendering and the scope filter buttons |
wp-content/themes/carboncalculator/partials/components/reports-table.php | The reports table markup |
wp-content/themes/carboncalculator/assets/js/reports-table.js | Table sorting and row actions |
wp-content/themes/carboncalculator/assets/js/create-report-modal.js | “Create report” flow |
wp-content/themes/carboncalculator/functions.php:1413 | carboncalculator_build_company_reports_table_rows() |
wp-content/themes/carboncalculator/functions.php:1481 | carboncalculator_get_company_emissions_chart_series() |
wp-content/themes/carboncalculator/functions.php:1313 | carboncalculator_format_report_intensity_display() |
wp-content/themes/carboncalculator/index.php | Front page; redirects logged-in users here |
How it works
Section titled “How it works”The template runs entirely server-side before get_header()
(page-my-company-emissions.php:1-135):
- Auth. If
carboncalculator_auth_required()and there is no LMS user with an email, redirect tohome_url('/').CARBONCALC_SKIP_AUTHdisables this. - Company.
CarbonCalc\LMS::company_id(). Zero triggerscarboncalculator_log_company_not_linked_dashboard(), which writes acarbon_calculator_company_not_linkedline towp-content/carboncalc-login-denied.log, and the page renders a “Company not linked” notice instead of data. - Year selection.
?reporting_year_id=is validated against the list of real years (in_arrayagainst ids at:29— an unknown value falls back, it does not error). With no param it prefers the year of the company’s most recent report, else the first year in the list. - Report and result.
carboncalculator_get_company_report_for_year()thencarboncalculator_get_report_result_row(). - Totals. Prefer
cc_report_result.total_tco2e; fall back tos1 + s2 + s3.$cc_has_calculationis true if the total column is non-null or the scope sum is greater than zero (:69) — so a genuinely zero-emission report reads as “not calculated yet”. - Intensity.
total ÷ (turnover in £m), fromcarboncalculator_get_report_turnover_gbp()which reads the turnover answer off the report. Displayed astCO2e / £1m. - Chart.
carboncalculator_get_company_emissions_chart_series()builds labels and values across the company’s years. The chart column is hidden unless there are at least two data points (:153,:316). - Buttons. Label depends on report status — “Continue {year} report”
for draft, “Edit Report” for submitted/completed, “Create {year} report”
when none exists (
:107-131). The create/share buttons only render whencarboncalculator_user_can_create_reports()is true, and “Share with clients” additionally requirescarboncalculator_is_sharing_enabled(). - Reports table.
partials/components/reports-table.phpwith rows fromcarboncalculator_build_company_reports_table_rows().
Data is passed to JavaScript through data- attributes on
#company-emissions-dashboard (:151-153) — chart labels, values, and a
show/hide flag — rather than wp_localize_script.
Report URLs use the report UUID, not the numeric id
(add_query_arg('report_id', strtolower($cc_report['uuid']), …) at :108).
UUIDs were added in schema v13 (Migrations.php:300) precisely so report
links are not guessable by incrementing an integer.
Formatting helpers all live in carboncalculator/functions.php:
carboncalculator_format_tco2e_display() (:1291),
carboncalculator_format_compact_tco2e() (:3784),
carboncalculator_format_compact_gbp() (:3751),
carboncalculator_format_dashboard_total_spend_gbp() (:3770).
Configuration
Section titled “Configuration”CARBONCALC_SKIP_AUTH— bypass the login redirect (local only).carboncalc_feature_sharing_enabled— shows the “Share with clients” button.- Reporting years must exist in
cc_reporting_year, or the page renders “No reporting years available”. - Page slugs are hard-coded in the template:
/my-company-emissions/,/my-company-emissions/carbon-emissions-report/,/my-company-emissions/share-carbon-emissions-report/(:101,:102,:223). Renaming the WordPress pages breaks these links.
Invariants and gotchas
Section titled “Invariants and gotchas”- A report with a true zero total shows as “not calculated yet”.
$cc_has_calculation(:69) treats aNULLtotal plus zero scopes as uncalculated, which is correct for a fresh report and wrong for a company with genuinely nil declared emissions. - The page renders for a user with no company rather than redirecting — intentional, so support can see the “Company not linked” state. It also writes a log line on every such page load, so a single stuck user produces a lot of log volume.
- The chart hides below two data points. A company’s first year always shows a full-width summary with no chart; this is by design, not a bug.
- Intensity is
nullunless both a calculation and a turnover answer exist; the UI renders an en dash. Turnover comes from the questionnaire, so a report can be fully calculated and still have no intensity. - Year selection silently falls back on an invalid
reporting_year_id. No 404, no notice. page-my-company-emissions.php.bakexists in the theme directory. It is dead weight and not loaded; do not edit it by accident.
Changing it safely
Section titled “Changing it safely”- Server-side data prep belongs in
carboncalculator/functions.phpas acarboncalculator_*function called from the template’s header block. Keep the template’s top section free of markup — everything aboveget_header()at:136is data assembly. - New dashboard numbers: add a formatter next to the existing
carboncalculator_format_*helpers so rounding and unit display stay consistent, then pass to JS via adata-attribute on the dashboard div. - Changing page slugs requires editing the hard-coded URLs at
:101,:102and:223, plusredirect_targets_carbon_calculator()inthemes/supplychainschool/inc/classes/LMSClient.php:1133, which string-matches those same slugs to decide whether a login is a Carbon login. Missing that second one silently breaks role sync on login. - Assets are built with Gulp + Tailwind. Run
npm run prodinwp-content/themes/carboncalculatorand commitassets/cssandassets/js— the compiled output is tracked. Tailwind scans**/*.php, so a class only used in a JS template literal will be purged. - Verify by hand, in this order, because each is a distinct code path:
- Guest → redirected to
/. - Logged in, no company → “Company not linked”.
- Company, no years → “No reporting years available”.
- Company with a draft → “Continue {year} report”.
- One calculated year → totals, no chart.
- Two calculated years → chart appears.
- Guest → redirected to
None. No PHP or JS test setup in either theme.
Related: [[emissions-calculation-and-submission]], [[carbon-report-questionnaire]], [[report-sharing]], [[supply-chain-emissions]], [[carbon-access-gates]].