Plugin Directory

Changeset 3446582


Ignore:
Timestamp:
01/25/2026 03:43:15 PM (4 weeks ago)
Author:
dbee78
Message:

Tagging version 1.0.25

Location:
keiste-solar-report
Files:
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • keiste-solar-report/tags/1.0.25/assets/js/charts.js

    r3415762 r3446582  
    2424    // ===== BREAK-EVEN CHART =====
    2525    function calculateBreakEvenDataSimple(config) {
     26        console.log('[CHART] calculateBreakEvenDataSimple called with config:', config);
     27       
    2628        const yearlyEnergy = config.yearlyEnergyDcKwh;
    2729        const panelCount = config.panelsCount;
    28         const electricityRate = parseFloat(document.getElementById('electricityRate')?.value) || 0.45;
    29 
    30         const exportRate = (() => {
    31             const v = document.getElementById('exportRate')?.value;
    32             const p = parseFloat(String(v || '').replace(/[^0-9.\-]/g, ''));
    33             return Number.isFinite(p) ? (p / 100) : 0.4;
    34         })();
     30       
     31        // Get values from config or inputs
     32        const cfg = window.KSRAD_CalcConfig || {};
     33        const electricityRate = parseFloat(document.getElementById('electricityRate')?.value) || 0.36;
     34        const feedInTariff = 0.21; // Standard FIT rate
     35        const billMonthly = parseFloat(document.getElementById('electricityBill')?.value) || 0;
     36
     37        const exportRatePercent = cfg.defaultExportRate || 0.05;
    3538
    3639        const inclGrant = document.getElementById('inclGrant')?.checked;
    37         const inclACA = document.getElementById('inclACA')?.checked;
    3840        const inclLoan = document.getElementById('inclLoan')?.checked;
    3941        const degradation = 0.005;
    40 
    41         // Compute installation cost
    42         const installedCapacityKwp = yearlyEnergy / 1000;
    43         let computedInstallCost = 0;
    44         if (installedCapacityKwp <= 100) {
    45             computedInstallCost = installedCapacityKwp * 1500;
    46         } else if (installedCapacityKwp <= 250) {
    47             computedInstallCost = (100 * 1500) + ((installedCapacityKwp - 100) * 1300);
    48         } else {
    49             computedInstallCost = (100 * 1500) + (150 * 1300) + ((installedCapacityKwp - 250) * 1100);
    50         }
    51 
    52         const seaiGrant = inclGrant ? Math.min(computedInstallCost * 0.3, 162000) : 0;
    53         const acaGrant = inclACA ? (computedInstallCost * 0.125) : 0;
    54         const totalGrant = seaiGrant + acaGrant;
    55         const totalCost = computedInstallCost - totalGrant;
     42        const annualIncrease = 0.05; // 5% bill increase per year
     43
     44        // Get actual net install cost from the calculator
     45        // We need to recalculate it here to match what keyFigures does
     46        const baseCost = config.installCost || 0;
     47       
     48        console.log('[CHART] baseCost:', baseCost);
     49        console.log('[CHART] billMonthly:', billMonthly);
     50        console.log('[CHART] inclGrant:', inclGrant);
     51        console.log('[CHART] inclLoan:', inclLoan);
     52       
     53        // Get grant settings based on building type
     54        const getGrantAmount = () => {
     55            try {
     56                const grants = cfg.grantSettings || {};
     57                const btEl = document.getElementById('userBuildingType');
     58                const selected = (btEl && btEl.value) ? btEl.value.trim() : 'Residential';
     59                const isResidential = (selected === 'Residential');
     60                const category = isResidential ? 'Residential' : 'Non-Residential';
     61                const grantSettings = grants[category] || { rate: 0.30, cap: 162000 };
     62                return inclGrant ? Math.min(baseCost * grantSettings.rate, grantSettings.cap) : 0;
     63            } catch (e) {
     64                return inclGrant ? Math.min(baseCost * 0.30, 162000) : 0;
     65            }
     66        };
     67       
     68        const seaiGrant = getGrantAmount();
     69        const principal = Math.max(0, baseCost - seaiGrant);
     70       
     71        console.log('[CHART] seaiGrant:', seaiGrant);
     72        console.log('[CHART] principal:', principal);
     73       
     74        // Calculate loan payments if applicable
     75        const loanAPR = 0.07; // 7% APR
     76        const loanYears = 7;
     77        let yearlyLoanCost = 0;
     78        let totalCost = principal;
     79       
     80        if (inclLoan) {
     81            const m = 12;
     82            const n = loanYears * m;
     83            const r = loanAPR / m;
     84            const monthlyRepay = principal * (r / (1 - Math.pow(1 + r, -n)));
     85            yearlyLoanCost = monthlyRepay * 12;
     86            totalCost = yearlyLoanCost * loanYears;
     87        }
     88       
     89        console.log('[CHART] yearlyLoanCost:', yearlyLoanCost);
     90        console.log('[CHART] totalCost (investment):', totalCost);
     91
     92        // Calculate annual usage from bill
     93        const annualUsageKwh = (billMonthly * 12) / electricityRate;
     94       
     95        console.log('[CHART] annualUsageKwh:', annualUsageKwh);
    5696
    5797        const years = Array.from({ length: 25 }, (_, i) => i);
     
    5999            const yearDegradation = Math.pow(1 - degradation, year);
    60100            const yearlyEnergyProduction = yearlyEnergy * yearDegradation;
    61             const selfConsumedEnergy = yearlyEnergyProduction * (1 - exportRate);
    62             const exportedEnergy = yearlyEnergyProduction * exportRate;
    63             const yearlySaving = (selfConsumedEnergy * electricityRate) + (exportedEnergy * exportRate);
    64 
    65             const totalSaving = year === 0 ? 0 : years
     101           
     102            // Calculate self-consumption and export (same logic as main calculator)
     103            const maxSelfConsumption = yearlyEnergyProduction * (1 - exportRatePercent);
     104            const actualSelfConsumption = Math.min(maxSelfConsumption, annualUsageKwh);
     105            const exportedEnergy = yearlyEnergyProduction - actualSelfConsumption;
     106           
     107            // Apply escalating electricity rate
     108            const escalatedRate = electricityRate * Math.pow(1 + annualIncrease, year);
     109           
     110            // Year's savings
     111            const yearlySaving = (actualSelfConsumption * escalatedRate) + (exportedEnergy * feedInTariff);
     112           
     113            // Year's loan cost (only for first 7 years if loan)
     114            const yearLoanCost = (inclLoan && year < loanYears) ? yearlyLoanCost : 0;
     115           
     116            // Net saving for this year
     117            const netYearlySaving = yearlySaving - yearLoanCost;
     118
     119            // Cumulative savings up to this year
     120            const totalSaving = year === 0 ? -totalCost : years
    66121                .slice(1, year + 1)
    67122                .reduce((acc, y) => {
    68123                    const yDegradation = Math.pow(1 - degradation, y);
    69124                    const yEnergyProduction = yearlyEnergy * yDegradation;
    70                     const ySelfConsumed = yEnergyProduction * (1 - exportRate);
    71                     const yExported = yEnergyProduction * exportRate;
    72                     return acc + (ySelfConsumed * electricityRate) + (yExported * exportRate);
    73                 }, 0);
    74 
    75             return totalSaving - totalCost;
     125                    const yMaxSelfConsumption = yEnergyProduction * (1 - exportRatePercent);
     126                    const yActualSelfConsumption = Math.min(yMaxSelfConsumption, annualUsageKwh);
     127                    const yExported = yEnergyProduction - yActualSelfConsumption;
     128                    const yEscalatedRate = electricityRate * Math.pow(1 + annualIncrease, y);
     129                    const ySaving = (yActualSelfConsumption * yEscalatedRate) + (yExported * feedInTariff);
     130                    const yLoanCost = (inclLoan && y < loanYears) ? yearlyLoanCost : 0;
     131                    return acc + (ySaving - yLoanCost);
     132                }, -totalCost);
     133
     134            return totalSaving;
    76135        });
     136       
     137        const breakEvenYear = savings.findIndex(saving => saving >= 0);
     138        console.log('[CHART] Break-even year:', breakEvenYear);
     139        console.log('[CHART] First 5 years cumulative savings:', savings.slice(0, 5));
    77140
    78141        return {
    79142            cost: totalCost,
    80143            savings: savings,
    81             breakEvenYear: savings.findIndex(saving => saving >= 0)
     144            breakEvenYear: breakEvenYear
    82145        };
    83146    }
  • keiste-solar-report/tags/1.0.25/assets/js/solar-calculator-main.js

    r3419489 r3446582  
    302302        console.log('install_cost', install_cost);
    303303
    304         const net_install_cost = Math.round(Number(baseCost - seaiGrant + (inclLoan ? (baseCost - seaiGrant) * interest : 0)));
    305         console.log('net_install_cost', net_install_cost);
    306 
    307304        // Production
    308305        const yearlyEnergyKWhYr0 = yearlyEnergy; // year 0 nominal from config
     
    315312        const monthlyRepay = Math.round(inclLoan ? principal * (r / (1 - Math.pow(1 + r, -n))) : 0);
    316313        const yearlyLoanCost = Math.round(inclLoan ? monthlyRepay * 12 : 0);
     314
     315        // Net install cost: if loan, show total loan payments; otherwise show upfront cost after grant
     316        const net_install_cost = inclLoan ? Math.round(yearlyLoanCost * LENGTH_OF_PAYBACK) : Math.round(baseCost - seaiGrant);
     317        console.log('net_install_cost', net_install_cost);
    317318
    318319        // Total 25-year savings (benefits - cost + ACA if included)
     
    341342
    342343        // First-year annual saving (calculate this BEFORE payback so we can use it)
    343         const savings_year0 = (() => {
    344             // Current electricity usage based on their bill
    345             const current_usage_kwh = (billMonthly * 12) / RETAIL;
    346             console.log('Bill calculation - billMonthly:', billMonthly, 'RETAIL:', RETAIL, 'current_usage_kwh:', current_usage_kwh);
    347            
    348             // Total solar production (use actual config data, not formula)
    349             const annual_solar_kwh = yearlyEnergy > 0 ? yearlyEnergy : (panels * DAY_POWER_AVG * DAYS_IN_YR);
    350             console.log('Annual solar production:', annual_solar_kwh, 'kWh (from yearlyEnergy:', yearlyEnergy, ')');
    351            
    352             // Self-consumption: what they can use themselves (capped by their actual usage)
    353             const max_self_consumption_kwh = annual_solar_kwh * (1 - exportRate);
    354             const actual_self_consumption_kwh = Math.min(max_self_consumption_kwh, current_usage_kwh);
    355             console.log('Export rate:', exportRate, 'Max self:', max_self_consumption_kwh, 'Actual self:', actual_self_consumption_kwh, 'Current usage:', current_usage_kwh);
    356            
    357             // Export: everything not self-consumed
    358             const export_kwh = annual_solar_kwh - actual_self_consumption_kwh;
    359             console.log('Export kWh:', export_kwh);
    360            
    361             // Financial benefits
    362             const bill_savings = actual_self_consumption_kwh * RETAIL;  // Avoided electricity cost
    363             const export_income = export_kwh * FIT;                     // Export income
    364             console.log('Bill savings:', bill_savings, '(', actual_self_consumption_kwh, '*', RETAIL, ')');
    365             console.log('Export income:', export_income, '(', export_kwh, '*', FIT, ')');
    366 
    367             const loan_cost = inclLoan ? yearlyLoanCost : 0;
    368             const acaBump = (inclACA ? acaAllowance : 0);
    369            
    370             return bill_savings + export_income - loan_cost + acaBump;
    371         })();
     344        // ===== FIXED PRODUCTION & SAVINGS MODEL =====
     345
     346        // Annual usage derived from bill
     347        const current_usage_kwh = (billMonthly * MONTHS_IN_YR) / RETAIL;
     348
     349        // Total solar production
     350        const annual_solar_kwh =
     351            panels *
     352            PANEL_POWER_W / 1000 *
     353            DAY_POWER_AVG *
     354            DAYS_IN_YR;
     355
     356        // Self-consumption is limited by actual usage
     357        const max_self_consumption_kwh = annual_solar_kwh * (1 - exportRate);
     358        const actual_self_consumption_kwh = Math.min(max_self_consumption_kwh, current_usage_kwh);
     359
     360        // Export is what's left after self-consumption
     361        const export_kwh = annual_solar_kwh - actual_self_consumption_kwh;
     362
     363        // --- FINANCIALS ---
     364        const bill_savings = actual_self_consumption_kwh * RETAIL;
     365        const export_income = export_kwh * FIT;
     366
     367        // Total benefit (before loan / adjustments)
     368        const savings_year0 = bill_savings + export_income - yearlyLoanCost;
     369
     370        console.log(
     371            'YEAR 0 BREAKDOWN:\n' +
     372            '  annual_solar_kwh: ' + annual_solar_kwh + '\n' +
     373            '  current_usage_kwh: ' + current_usage_kwh + '\n' +
     374            '  exportRate: ' + exportRate + '\n' +
     375            '  max_self_consumption_kwh: ' + max_self_consumption_kwh + '\n' +
     376            '  actual_self_consumption_kwh: ' + actual_self_consumption_kwh + '\n' +
     377            '  export_kwh: ' + export_kwh + '\n' +
     378            '  RETAIL: ' + RETAIL + '\n' +
     379            '  FIT: ' + FIT + '\n' +
     380            '  bill_savings: ' + bill_savings + '\n' +
     381            '  export_income: ' + export_income + '\n' +
     382            '  yearlyLoanCost: ' + yearlyLoanCost + '\n' +
     383            '  savings_year0: ' + savings_year0
     384        );
    372385
    373386        // Monthly charge (Year 0) - based on actual savings
    374         const monthly_charge = (savings_year0 / 12) - billMonthly;
    375 
     387        // Only show meaningful net income when there's a bill to offset
     388        const monthly_charge = billMonthly > 0 ? (savings_year0 / 12) - billMonthly : 0;
     389   
    376390        // Payback period (years) - uses actual net annual savings
    377         const payback_period = (() => {
    378             // Investment amount to pay back
    379             const investment = inclLoan ? loanCost25 : net_install_cost;
    380            
    381             // Net annual savings (year 0) - this is what actually goes back into your pocket
    382             const annualSavings = savings_year0;
    383            
    384             // Payback = Investment / Annual Savings
    385             return annualSavings > 0 ? investment / annualSavings : 0;
    386         })();
     391        // Investment amount to pay back
     392        const investment = inclLoan ? loanCost25 : net_install_cost;
     393        // Payback = Investment / Annual Savings
     394        const payback_period = savings_year0 > 0 ? investment / savings_year0 : 0;
    387395
    388396        // ROI over 25 years (%)
     
    394402        // CO2 reduction over life
    395403        const co2_reduction = CO2_COEFFICIENT_TONNES *
    396             Array.from({ length: YRS_OF_SYSTEM }, (_, y) =>
     404        Array.from({ length: YRS_OF_SYSTEM }, (_, y) =>
    397405                panels * DAY_POWER_AVG * Math.pow(1 - SOLAR_PANEL_DEGRADATION, y) * DAYS_IN_YR
    398406            ).reduce((a, b) => a + b, 0);
     
    407415
    408416    // ========= 5) GUI UPDATES =========
     417    function updateGrantDescription() {
     418        // Update the grant description text based on current building type
     419        try {
     420            const cfg = window.KSRAD_CalcConfig || {};
     421            const grants = cfg.grantSettings || {};
     422            const btEl = document.getElementById('userBuildingType');
     423            const selected = (btEl && btEl.value) ? btEl.value.trim() : 'Residential';
     424           
     425            const isResidential = (selected === 'Residential');
     426            const category = isResidential ? 'Residential' : 'Non-Residential';
     427           
     428            const grantRate = grants[category] ? (grants[category].rate || 0.30) : 0.30;
     429            const grantCap = grants[category] ? (grants[category].cap || 162000) : 162000;
     430           
     431            // Find and update grant description elements
     432            const grantDescElements = document.querySelectorAll('.grant-description, [data-grant-description]');
     433            grantDescElements.forEach(el => {
     434                const percentDisplay = Math.round(grantRate * 100);
     435                const capDisplay = CURRENCY_SYMBOL + grantCap.toLocaleString('en-IE');
     436                el.textContent = `${percentDisplay}% Grant (max ${capDisplay})`;
     437            });
     438        } catch (e) {
     439            console.error('Error updating grant description:', e);
     440        }
     441    }
     442   
    409443    function updateResults(state, figs) {
    410444        const setTxt = (id, txt) => {
     
    419453        setTxt('installationCost', fmtEuro(figs.install_cost));
    420454        setTxt('grant', fmtEuro(figs.seaiGrant));
     455       
     456        // Update grant description text dynamically
     457        updateGrantDescription();
     458       
    421459        setTxt('panelCount', fmtNum(state.panels, 0));
    422460        // Annual energy production display: support both legacy `yearlyEnergy` and current `yearlyEnergyValue` IDs
     
    453491            });
    454492        };
     493       
     494        // Only show meaningful figures when there's a bill
     495        if (!state.billMonthly || state.billMonthly === 0) {
     496            setTxt('netCost', CURRENCY_SYMBOL + '0');
     497            setTxt('totalSavings', CURRENCY_SYMBOL + '0');
     498            setTxt('roi', '0%');
     499            setTxt('co2Reduction', '0 t');
     500            setTxt('annualSavings', CURRENCY_SYMBOL + '0');
     501            setTxt('paybackPeriod', '0 years');
     502            return;
     503        }
     504       
    455505        // #installation-details
    456506        setTxt('netCost', fmtEuro(figs.net_install_cost));
     
    478528        if (window.breakEvenChart && window.breakEvenChart.data && typeof window.calculateBreakEvenDataSimple === 'function') {
    479529            try {
     530                console.log('[updateBreakEvenChart] Inside try block, billMonthly:', state.billMonthly);
     531               
    480532                // On page load with no bill, show zero baseline
    481533                if (!state.billMonthly || state.billMonthly === 0) {
     
    487539                }
    488540               
    489                 const cfg = { panelsCount: state.panels, yearlyEnergyDcKwh: figs.yearlyEnergyKWh || (state.panels * DAY_POWER_AVG * DAYS_IN_YR) };
     541                console.log('[updateBreakEvenChart] About to create config object');
     542                console.log('[updateBreakEvenChart] figs.yearlyEnergyKWh:', figs.yearlyEnergyKWh);
     543                console.log('[updateBreakEvenChart] figs.baseCost:', figs.baseCost);
     544               
     545                const cfg = {
     546                    panelsCount: state.panels,
     547                    yearlyEnergyDcKwh: figs.yearlyEnergyKWh || (state.panels * DAY_POWER_AVG * DAYS_IN_YR),
     548                    installCost: figs.baseCost
     549                };
    490550                console.log('Calling calculateBreakEvenDataSimple with:', cfg);
    491551                const be = window.calculateBreakEvenDataSimple(cfg);
     
    713773        console.log('[INIT] solar-calculator-main.js initializing...');
    714774        console.log('[INIT] document.readyState:', document.readyState);
    715         // Apply configuration from PHP if available
     775       
     776        // Apply configuration from PHP if available (don't wait, just use defaults if not ready)
    716777        if (window.KSRAD_CalcConfig) {
    717778            console.log('[INIT] KSRAD_CalcConfig found:', window.KSRAD_CalcConfig);
    718779            CURRENCY_SYMBOL = window.KSRAD_CalcConfig.currencySymbol || CURRENCY_SYMBOL;
    719            
    720             // Also expose globally for consistency with other scripts
    721780            window.CURRENCY_SYMBOL = CURRENCY_SYMBOL;
    722781        } else {
    723             console.warn('[INIT] KSRAD_CalcConfig not found');
     782            console.warn('[INIT] KSRAD_CalcConfig not found - using defaults');
    724783        }
    725784       
  • keiste-solar-report/tags/1.0.25/includes/class-ksrad-calculator.php

    r3415762 r3446582  
    33 * Solar Calculator class for Keiste Solar Report
    44 *
     5<<<<<<< HEAD
     6=======
     7 * This code is just the placeholder code.
     8>>>>>>> fed100d (added UK no solar. grant % defaults to zero now. the math is still off though.)
    59 * Handles solar panel calculations and renders the calculator frontend.
    610 *
  • keiste-solar-report/tags/1.0.25/includes/plugin-init.php

    r3420871 r3446582  
    217217            'googleSolarApiKey' => ksrad_get_option('google_solar_api_key', ''),
    218218            'reportKey' => ksrad_get_option('report_key', ''),
    219             'defaultElectricityRate' => ksrad_get_option('default_electricity_rate', '0.17'),
    220             'defaultExportRate' => ksrad_get_option('default_export_rate', '10'),
    221             'defaultFeedInTariff' => ksrad_get_option('default_feed_in_tariff', '0.15'),
     219            'defaultElectricityRate' => ksrad_get_option('default_electricity_rate', '0.36'),
     220            'defaultExportRate' => ksrad_get_option('default_export_rate', '5'),
     221            'defaultFeedInTariff' => ksrad_get_option('default_feed_in_tariff', '0.20'),
    222222            'defaultLoanApr' => ksrad_get_option('default_loan_apr', '5'),
    223223            'loanTerm' => ksrad_get_option('loan_term', '7'),
    224224            'annualPriceIncrease' => ksrad_get_option('annual_price_increase', '5'),
    225             'currency' => ksrad_get_option('currency', '$'),
    226             'country' => ksrad_get_option('country', 'United States'),
    227             'systemCostRatio' => ksrad_get_option('system_cost_ratio', '650'),
     225            'currency' => ksrad_get_option('currency', ''),
     226            'country' => ksrad_get_option('country', 'Republic of Ireland'),
     227            'systemCostRatio' => ksrad_get_option('system_cost_ratio', '1600'),
    228228            'grantRateDomestic' => ksrad_get_option('grant_rate_domestic', '30'),
    229229            'grantCapDomestic' => ksrad_get_option('grant_cap_domestic', '7500'),
     
    311311            'report_key' => '',
    312312            'logo_url' => '',
    313             'default_electricity_rate' => '0.17',
    314             'default_export_rate' => '10',
    315             'default_feed_in_tariff' => '0.14',
     313            'default_electricity_rate' => '0.34',
     314            'default_export_rate' => '5',
     315            'default_feed_in_tariff' => '0.20',
    316316            'default_loan_apr' => '5',
    317317            'loan_term' => '7',
    318318            'annual_price_increase' => '5',
    319             'currency' => '$',
    320             'country' => 'United States',
    321             'system_cost_ratio' => '650',
    322             'cost_domestic' => '650',
    323             'cost_small' => '600',
    324             'cost_medium' => '500',
    325             'cost_large' => '425',
     319            'currency' => '',
     320            'country' => 'Republic of Ireland',
     321            'system_cost_ratio' => '1800',
     322            'cost_domestic' => '1800',
     323            'cost_small' => '1600',
     324            'cost_medium' => '1200',
     325            'cost_large' => '1000',
    326326            'grant_rate_domestic' => '30',
    327327            'grant_cap_domestic' => '7500',
  • keiste-solar-report/tags/1.0.25/keiste-solar-report.php

    r3420878 r3446582  
    55 * Plugin URI: https://keiste.com/keiste-solar-report
    66 * Description: Comprehensive solar panel analysis tool with ROI calculations, Google Solar API integration, interactive charts, and PDF report generation.
    7  * Version: 1.0.24
     7 * Version: 1.0.25
    88 * Author: Dara Burke, Keiste
    99 * Author URI: https://keiste.com
     
    3434// Define plugin constants (only once) with ksrad_ namespace
    3535if (!defined('KSRAD_VERSION')) {
    36     define('KSRAD_VERSION', '1.0.24');
     36    define('KSRAD_VERSION', '1.0.25');
    3737}
    3838if (!defined('KSRAD_PLUGIN_DIR')) {
     
    325325    <div class="container">
    326326
    327         <div class="text-center mt-4">
     327        <div class="text-center">
    328328            <?php
    329329            $ksrad_logo_url = ksrad_get_option('logo_url', '');
     
    333333            }
    334334            ?>
    335             <a href="<?php echo esc_url(home_url('/')); ?>">
     335            <a href="<?php echo esc_url(home_url('/keiste-solar-report/')); ?>">
    336336                <img src="<?php echo esc_url($ksrad_logo_url); ?>" alt="Company Logo"
    337337                    class="img-fluid logo-image" style="max-width: 130px; width: 100%;">
     
    359359            ?>
    360360            <h1>Solar Report<sup style="color: red;font-size: 16px;vertical-align: middle;top: -14px;"> <?php echo esc_html($ksrad_country_code); ?></sup></h1>
     361            <div style="text-align: center; margin: 30px 0;">
     362                <a href="<?php echo esc_url(remove_query_arg(['lat', 'lng', 'business_name'])); ?>"
     363                   class="btn btn-secondary"
     364                   style="display: inline-block; padding: 8px 16px; background: #6c757d; color: white; text-decoration: none; border-radius: 8px; font-size: 14px; transition: background 0.3s;"
     365                   onmouseover="this.style.background='#5a6268';"
     366                   onmouseout="this.style.background='#6c757d';">
     367                   🔄 Start Again
     368                </a>
     369            </div>
    361370        </div>
    362371
    363372
    364         <!-- Initial Page (when NOT an AJAX request) -->
    365         <?php if (!$ksrad_isAjaxRequest): ?>
    366             <div id="ajaxHeader" class="alert alert-info" role="alert"
     373        <!-- Initial Page Header -->
     374        <div id="ajaxHeader" class="alert alert-info" role="alert"
    367375                style="text-align: center; background: #FDFDFB; border: 2px solid #E8E8E6; border-radius: 12px; padding: 2rem; margin: 2rem auto; max-width: 600px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);">
    368376                <h3 style="color: #2A2A28; margin-bottom: 1rem; font-size: 1.3em; font-weight: 600;">🔍 How Much Can You Save With Solar?
     
    451459
    452460            </div>
    453 
    454         <?php endif; ?>
    455461
    456462        <?php if (empty(ksrad_get_option('google_solar_api_key', ''))): ?>
     
    704710                                <div class="results-section" id="results">
    705711                                    <h4 class="text-center">Your Return on Investment (ROI)</h4>
     712                                    <span class="text-center">enter your electricity bill (above)</span>
    706713                                    <!-- END .section.site-overview -->
    707714                                    <div class="row mt-4">
     
    713720                                                    <div class="resultsCol" style="border-left: unset;">
    714721                                                        <span class="highlight" id="netIncome">0</span>
    715                                                         <div class="ms-2 underWrite">MONTHLY INC/EXP</div>
     722                                                        <div class="ms-2 underWrite">MONTHLY PROFIT/LOSS</div>
    716723                                                    </div>
    717724                                                </div>
     
    775782                                           
    776783                                        <?php if (!apply_filters('ksrad_is_premium', false)): ?>
    777                                         <p class="mt-3 align-center"><a href="https://keiste.com/how-is-our-math/" style="color: #5A5A58;font-size: 0.9rem;" >How is our math?</a></p>
     784                                        <p class="mt-3 align-center" style="visibility: hidden;"><a href="https://keiste.com/how-is-our-math/" style="color: #5A5A58;font-size: 0.9rem;" >How is our math?</a></p>
    778785                                        <?php endif; ?>
    779786                                   
     
    846853                                                // Display grant help with correct percent and currency formatting
    847854                                                $ksrad_currency_symbol = ksrad_get_option('currency', '€');
    848                                                 $ksrad_grant_rate = floatval(ksrad_get_option('seai_grant_rate', '30')); // default 30%
    849                                                 $ksrad_grant_cap = floatval(ksrad_get_option('seai_grant_cap', '162000')); // sensible numeric default
     855                                                $ksrad_grant_rate = floatval(ksrad_get_option('grant_rate_domestic', '0')); // default 30%
     856                                                $ksrad_grant_cap = floatval(ksrad_get_option('grant_cap_domestic', '0')); // sensible numeric default
    850857                                            ?>
    851                                             <div class="input-help-right"><?php echo esc_html($ksrad_grant_rate); ?>% Grant (max <?php echo esc_html($ksrad_currency_symbol); ?><?php echo number_format($ksrad_grant_cap, 0); ?>)</div>
     858                                            <div class="input-help-right">                                           
     859                                                <span class="grant-description"><?php echo esc_html($ksrad_grant_rate); ?>% Grant (max <?php echo esc_html($ksrad_currency_symbol); ?><?php echo number_format($ksrad_grant_cap, 0); ?>)</span>
     860                                            </div>                                       
    852861                                        </div>
    853862                                    </div>
     
    927936                                // Currency symbol and getPanelCount - expose globally for external scripts
    928937                                window.CURRENCY_SYMBOL = '<?php echo esc_js(ksrad_get_option('currency', '€')); ?>';
    929 
     938                                // if it's the UK, the remove include grant setting
     939                                if (window.CURRENCY_SYMBOL == '£') {
     940                                    document.getElementById("inclGrant").disabled = true;
     941                                }
    930942                                window.getPanelCount = function getPanelCount() {
    931943                                    const range = document.querySelector('input[type="range"]#panelCount');
     
    11331145    <?php endif; ?>
    11341146
     1147    </div><!-- End .middle-column -->
     1148
    11351149<?php endif; ?>
    11361150    </div><!-- End .newContainer -->
     
    11511165        window.KSRAD_CalcConfig = Object.assign({}, window.KSRAD_CalcConfig || {}, {
    11521166            currencySymbol: '<?php echo esc_js(ksrad_get_option('currency', '€')); ?>',
    1153             defaultExportRate: <?php echo esc_js(floatval(ksrad_get_option('default_export_rate', '10')) / 100); ?>,
     1167            defaultExportRate: <?php echo esc_js(floatval(ksrad_get_option('default_export_rate', '5')) / 100); ?>,
    11541168            // Grant settings by building type
    11551169            grantSettings: {
     
    11791193        <h6 style="color: #2a2a28; text-align: center;font-family: 'Brush Script MT', cursive;margin-top: 2rem;"><a href="https://keiste.com" target="_blank" rel="noopener noreferrer" class="bad-script-regular">Get Your Keiste Solar Report</a></h6>
    11801194    <?php endif; ?>
    1181 
    1182 </div><!-- #keiste-solar-report-wrapper -->
     1195</div>
     1196<!-- #keiste-solar-report-wrapper -->
    11831197<?php
    11841198// Return the buffered content to shortcode handler
  • keiste-solar-report/tags/1.0.25/readme.txt

    r3420878 r3446582  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.24
     7Stable tag: 1.0.25
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
  • keiste-solar-report/trunk/assets/js/charts.js

    r3415762 r3446582  
    2424    // ===== BREAK-EVEN CHART =====
    2525    function calculateBreakEvenDataSimple(config) {
     26        console.log('[CHART] calculateBreakEvenDataSimple called with config:', config);
     27       
    2628        const yearlyEnergy = config.yearlyEnergyDcKwh;
    2729        const panelCount = config.panelsCount;
    28         const electricityRate = parseFloat(document.getElementById('electricityRate')?.value) || 0.45;
    29 
    30         const exportRate = (() => {
    31             const v = document.getElementById('exportRate')?.value;
    32             const p = parseFloat(String(v || '').replace(/[^0-9.\-]/g, ''));
    33             return Number.isFinite(p) ? (p / 100) : 0.4;
    34         })();
     30       
     31        // Get values from config or inputs
     32        const cfg = window.KSRAD_CalcConfig || {};
     33        const electricityRate = parseFloat(document.getElementById('electricityRate')?.value) || 0.36;
     34        const feedInTariff = 0.21; // Standard FIT rate
     35        const billMonthly = parseFloat(document.getElementById('electricityBill')?.value) || 0;
     36
     37        const exportRatePercent = cfg.defaultExportRate || 0.05;
    3538
    3639        const inclGrant = document.getElementById('inclGrant')?.checked;
    37         const inclACA = document.getElementById('inclACA')?.checked;
    3840        const inclLoan = document.getElementById('inclLoan')?.checked;
    3941        const degradation = 0.005;
    40 
    41         // Compute installation cost
    42         const installedCapacityKwp = yearlyEnergy / 1000;
    43         let computedInstallCost = 0;
    44         if (installedCapacityKwp <= 100) {
    45             computedInstallCost = installedCapacityKwp * 1500;
    46         } else if (installedCapacityKwp <= 250) {
    47             computedInstallCost = (100 * 1500) + ((installedCapacityKwp - 100) * 1300);
    48         } else {
    49             computedInstallCost = (100 * 1500) + (150 * 1300) + ((installedCapacityKwp - 250) * 1100);
    50         }
    51 
    52         const seaiGrant = inclGrant ? Math.min(computedInstallCost * 0.3, 162000) : 0;
    53         const acaGrant = inclACA ? (computedInstallCost * 0.125) : 0;
    54         const totalGrant = seaiGrant + acaGrant;
    55         const totalCost = computedInstallCost - totalGrant;
     42        const annualIncrease = 0.05; // 5% bill increase per year
     43
     44        // Get actual net install cost from the calculator
     45        // We need to recalculate it here to match what keyFigures does
     46        const baseCost = config.installCost || 0;
     47       
     48        console.log('[CHART] baseCost:', baseCost);
     49        console.log('[CHART] billMonthly:', billMonthly);
     50        console.log('[CHART] inclGrant:', inclGrant);
     51        console.log('[CHART] inclLoan:', inclLoan);
     52       
     53        // Get grant settings based on building type
     54        const getGrantAmount = () => {
     55            try {
     56                const grants = cfg.grantSettings || {};
     57                const btEl = document.getElementById('userBuildingType');
     58                const selected = (btEl && btEl.value) ? btEl.value.trim() : 'Residential';
     59                const isResidential = (selected === 'Residential');
     60                const category = isResidential ? 'Residential' : 'Non-Residential';
     61                const grantSettings = grants[category] || { rate: 0.30, cap: 162000 };
     62                return inclGrant ? Math.min(baseCost * grantSettings.rate, grantSettings.cap) : 0;
     63            } catch (e) {
     64                return inclGrant ? Math.min(baseCost * 0.30, 162000) : 0;
     65            }
     66        };
     67       
     68        const seaiGrant = getGrantAmount();
     69        const principal = Math.max(0, baseCost - seaiGrant);
     70       
     71        console.log('[CHART] seaiGrant:', seaiGrant);
     72        console.log('[CHART] principal:', principal);
     73       
     74        // Calculate loan payments if applicable
     75        const loanAPR = 0.07; // 7% APR
     76        const loanYears = 7;
     77        let yearlyLoanCost = 0;
     78        let totalCost = principal;
     79       
     80        if (inclLoan) {
     81            const m = 12;
     82            const n = loanYears * m;
     83            const r = loanAPR / m;
     84            const monthlyRepay = principal * (r / (1 - Math.pow(1 + r, -n)));
     85            yearlyLoanCost = monthlyRepay * 12;
     86            totalCost = yearlyLoanCost * loanYears;
     87        }
     88       
     89        console.log('[CHART] yearlyLoanCost:', yearlyLoanCost);
     90        console.log('[CHART] totalCost (investment):', totalCost);
     91
     92        // Calculate annual usage from bill
     93        const annualUsageKwh = (billMonthly * 12) / electricityRate;
     94       
     95        console.log('[CHART] annualUsageKwh:', annualUsageKwh);
    5696
    5797        const years = Array.from({ length: 25 }, (_, i) => i);
     
    5999            const yearDegradation = Math.pow(1 - degradation, year);
    60100            const yearlyEnergyProduction = yearlyEnergy * yearDegradation;
    61             const selfConsumedEnergy = yearlyEnergyProduction * (1 - exportRate);
    62             const exportedEnergy = yearlyEnergyProduction * exportRate;
    63             const yearlySaving = (selfConsumedEnergy * electricityRate) + (exportedEnergy * exportRate);
    64 
    65             const totalSaving = year === 0 ? 0 : years
     101           
     102            // Calculate self-consumption and export (same logic as main calculator)
     103            const maxSelfConsumption = yearlyEnergyProduction * (1 - exportRatePercent);
     104            const actualSelfConsumption = Math.min(maxSelfConsumption, annualUsageKwh);
     105            const exportedEnergy = yearlyEnergyProduction - actualSelfConsumption;
     106           
     107            // Apply escalating electricity rate
     108            const escalatedRate = electricityRate * Math.pow(1 + annualIncrease, year);
     109           
     110            // Year's savings
     111            const yearlySaving = (actualSelfConsumption * escalatedRate) + (exportedEnergy * feedInTariff);
     112           
     113            // Year's loan cost (only for first 7 years if loan)
     114            const yearLoanCost = (inclLoan && year < loanYears) ? yearlyLoanCost : 0;
     115           
     116            // Net saving for this year
     117            const netYearlySaving = yearlySaving - yearLoanCost;
     118
     119            // Cumulative savings up to this year
     120            const totalSaving = year === 0 ? -totalCost : years
    66121                .slice(1, year + 1)
    67122                .reduce((acc, y) => {
    68123                    const yDegradation = Math.pow(1 - degradation, y);
    69124                    const yEnergyProduction = yearlyEnergy * yDegradation;
    70                     const ySelfConsumed = yEnergyProduction * (1 - exportRate);
    71                     const yExported = yEnergyProduction * exportRate;
    72                     return acc + (ySelfConsumed * electricityRate) + (yExported * exportRate);
    73                 }, 0);
    74 
    75             return totalSaving - totalCost;
     125                    const yMaxSelfConsumption = yEnergyProduction * (1 - exportRatePercent);
     126                    const yActualSelfConsumption = Math.min(yMaxSelfConsumption, annualUsageKwh);
     127                    const yExported = yEnergyProduction - yActualSelfConsumption;
     128                    const yEscalatedRate = electricityRate * Math.pow(1 + annualIncrease, y);
     129                    const ySaving = (yActualSelfConsumption * yEscalatedRate) + (yExported * feedInTariff);
     130                    const yLoanCost = (inclLoan && y < loanYears) ? yearlyLoanCost : 0;
     131                    return acc + (ySaving - yLoanCost);
     132                }, -totalCost);
     133
     134            return totalSaving;
    76135        });
     136       
     137        const breakEvenYear = savings.findIndex(saving => saving >= 0);
     138        console.log('[CHART] Break-even year:', breakEvenYear);
     139        console.log('[CHART] First 5 years cumulative savings:', savings.slice(0, 5));
    77140
    78141        return {
    79142            cost: totalCost,
    80143            savings: savings,
    81             breakEvenYear: savings.findIndex(saving => saving >= 0)
     144            breakEvenYear: breakEvenYear
    82145        };
    83146    }
  • keiste-solar-report/trunk/assets/js/solar-calculator-main.js

    r3419489 r3446582  
    302302        console.log('install_cost', install_cost);
    303303
    304         const net_install_cost = Math.round(Number(baseCost - seaiGrant + (inclLoan ? (baseCost - seaiGrant) * interest : 0)));
    305         console.log('net_install_cost', net_install_cost);
    306 
    307304        // Production
    308305        const yearlyEnergyKWhYr0 = yearlyEnergy; // year 0 nominal from config
     
    315312        const monthlyRepay = Math.round(inclLoan ? principal * (r / (1 - Math.pow(1 + r, -n))) : 0);
    316313        const yearlyLoanCost = Math.round(inclLoan ? monthlyRepay * 12 : 0);
     314
     315        // Net install cost: if loan, show total loan payments; otherwise show upfront cost after grant
     316        const net_install_cost = inclLoan ? Math.round(yearlyLoanCost * LENGTH_OF_PAYBACK) : Math.round(baseCost - seaiGrant);
     317        console.log('net_install_cost', net_install_cost);
    317318
    318319        // Total 25-year savings (benefits - cost + ACA if included)
     
    341342
    342343        // First-year annual saving (calculate this BEFORE payback so we can use it)
    343         const savings_year0 = (() => {
    344             // Current electricity usage based on their bill
    345             const current_usage_kwh = (billMonthly * 12) / RETAIL;
    346             console.log('Bill calculation - billMonthly:', billMonthly, 'RETAIL:', RETAIL, 'current_usage_kwh:', current_usage_kwh);
    347            
    348             // Total solar production (use actual config data, not formula)
    349             const annual_solar_kwh = yearlyEnergy > 0 ? yearlyEnergy : (panels * DAY_POWER_AVG * DAYS_IN_YR);
    350             console.log('Annual solar production:', annual_solar_kwh, 'kWh (from yearlyEnergy:', yearlyEnergy, ')');
    351            
    352             // Self-consumption: what they can use themselves (capped by their actual usage)
    353             const max_self_consumption_kwh = annual_solar_kwh * (1 - exportRate);
    354             const actual_self_consumption_kwh = Math.min(max_self_consumption_kwh, current_usage_kwh);
    355             console.log('Export rate:', exportRate, 'Max self:', max_self_consumption_kwh, 'Actual self:', actual_self_consumption_kwh, 'Current usage:', current_usage_kwh);
    356            
    357             // Export: everything not self-consumed
    358             const export_kwh = annual_solar_kwh - actual_self_consumption_kwh;
    359             console.log('Export kWh:', export_kwh);
    360            
    361             // Financial benefits
    362             const bill_savings = actual_self_consumption_kwh * RETAIL;  // Avoided electricity cost
    363             const export_income = export_kwh * FIT;                     // Export income
    364             console.log('Bill savings:', bill_savings, '(', actual_self_consumption_kwh, '*', RETAIL, ')');
    365             console.log('Export income:', export_income, '(', export_kwh, '*', FIT, ')');
    366 
    367             const loan_cost = inclLoan ? yearlyLoanCost : 0;
    368             const acaBump = (inclACA ? acaAllowance : 0);
    369            
    370             return bill_savings + export_income - loan_cost + acaBump;
    371         })();
     344        // ===== FIXED PRODUCTION & SAVINGS MODEL =====
     345
     346        // Annual usage derived from bill
     347        const current_usage_kwh = (billMonthly * MONTHS_IN_YR) / RETAIL;
     348
     349        // Total solar production
     350        const annual_solar_kwh =
     351            panels *
     352            PANEL_POWER_W / 1000 *
     353            DAY_POWER_AVG *
     354            DAYS_IN_YR;
     355
     356        // Self-consumption is limited by actual usage
     357        const max_self_consumption_kwh = annual_solar_kwh * (1 - exportRate);
     358        const actual_self_consumption_kwh = Math.min(max_self_consumption_kwh, current_usage_kwh);
     359
     360        // Export is what's left after self-consumption
     361        const export_kwh = annual_solar_kwh - actual_self_consumption_kwh;
     362
     363        // --- FINANCIALS ---
     364        const bill_savings = actual_self_consumption_kwh * RETAIL;
     365        const export_income = export_kwh * FIT;
     366
     367        // Total benefit (before loan / adjustments)
     368        const savings_year0 = bill_savings + export_income - yearlyLoanCost;
     369
     370        console.log(
     371            'YEAR 0 BREAKDOWN:\n' +
     372            '  annual_solar_kwh: ' + annual_solar_kwh + '\n' +
     373            '  current_usage_kwh: ' + current_usage_kwh + '\n' +
     374            '  exportRate: ' + exportRate + '\n' +
     375            '  max_self_consumption_kwh: ' + max_self_consumption_kwh + '\n' +
     376            '  actual_self_consumption_kwh: ' + actual_self_consumption_kwh + '\n' +
     377            '  export_kwh: ' + export_kwh + '\n' +
     378            '  RETAIL: ' + RETAIL + '\n' +
     379            '  FIT: ' + FIT + '\n' +
     380            '  bill_savings: ' + bill_savings + '\n' +
     381            '  export_income: ' + export_income + '\n' +
     382            '  yearlyLoanCost: ' + yearlyLoanCost + '\n' +
     383            '  savings_year0: ' + savings_year0
     384        );
    372385
    373386        // Monthly charge (Year 0) - based on actual savings
    374         const monthly_charge = (savings_year0 / 12) - billMonthly;
    375 
     387        // Only show meaningful net income when there's a bill to offset
     388        const monthly_charge = billMonthly > 0 ? (savings_year0 / 12) - billMonthly : 0;
     389   
    376390        // Payback period (years) - uses actual net annual savings
    377         const payback_period = (() => {
    378             // Investment amount to pay back
    379             const investment = inclLoan ? loanCost25 : net_install_cost;
    380            
    381             // Net annual savings (year 0) - this is what actually goes back into your pocket
    382             const annualSavings = savings_year0;
    383            
    384             // Payback = Investment / Annual Savings
    385             return annualSavings > 0 ? investment / annualSavings : 0;
    386         })();
     391        // Investment amount to pay back
     392        const investment = inclLoan ? loanCost25 : net_install_cost;
     393        // Payback = Investment / Annual Savings
     394        const payback_period = savings_year0 > 0 ? investment / savings_year0 : 0;
    387395
    388396        // ROI over 25 years (%)
     
    394402        // CO2 reduction over life
    395403        const co2_reduction = CO2_COEFFICIENT_TONNES *
    396             Array.from({ length: YRS_OF_SYSTEM }, (_, y) =>
     404        Array.from({ length: YRS_OF_SYSTEM }, (_, y) =>
    397405                panels * DAY_POWER_AVG * Math.pow(1 - SOLAR_PANEL_DEGRADATION, y) * DAYS_IN_YR
    398406            ).reduce((a, b) => a + b, 0);
     
    407415
    408416    // ========= 5) GUI UPDATES =========
     417    function updateGrantDescription() {
     418        // Update the grant description text based on current building type
     419        try {
     420            const cfg = window.KSRAD_CalcConfig || {};
     421            const grants = cfg.grantSettings || {};
     422            const btEl = document.getElementById('userBuildingType');
     423            const selected = (btEl && btEl.value) ? btEl.value.trim() : 'Residential';
     424           
     425            const isResidential = (selected === 'Residential');
     426            const category = isResidential ? 'Residential' : 'Non-Residential';
     427           
     428            const grantRate = grants[category] ? (grants[category].rate || 0.30) : 0.30;
     429            const grantCap = grants[category] ? (grants[category].cap || 162000) : 162000;
     430           
     431            // Find and update grant description elements
     432            const grantDescElements = document.querySelectorAll('.grant-description, [data-grant-description]');
     433            grantDescElements.forEach(el => {
     434                const percentDisplay = Math.round(grantRate * 100);
     435                const capDisplay = CURRENCY_SYMBOL + grantCap.toLocaleString('en-IE');
     436                el.textContent = `${percentDisplay}% Grant (max ${capDisplay})`;
     437            });
     438        } catch (e) {
     439            console.error('Error updating grant description:', e);
     440        }
     441    }
     442   
    409443    function updateResults(state, figs) {
    410444        const setTxt = (id, txt) => {
     
    419453        setTxt('installationCost', fmtEuro(figs.install_cost));
    420454        setTxt('grant', fmtEuro(figs.seaiGrant));
     455       
     456        // Update grant description text dynamically
     457        updateGrantDescription();
     458       
    421459        setTxt('panelCount', fmtNum(state.panels, 0));
    422460        // Annual energy production display: support both legacy `yearlyEnergy` and current `yearlyEnergyValue` IDs
     
    453491            });
    454492        };
     493       
     494        // Only show meaningful figures when there's a bill
     495        if (!state.billMonthly || state.billMonthly === 0) {
     496            setTxt('netCost', CURRENCY_SYMBOL + '0');
     497            setTxt('totalSavings', CURRENCY_SYMBOL + '0');
     498            setTxt('roi', '0%');
     499            setTxt('co2Reduction', '0 t');
     500            setTxt('annualSavings', CURRENCY_SYMBOL + '0');
     501            setTxt('paybackPeriod', '0 years');
     502            return;
     503        }
     504       
    455505        // #installation-details
    456506        setTxt('netCost', fmtEuro(figs.net_install_cost));
     
    478528        if (window.breakEvenChart && window.breakEvenChart.data && typeof window.calculateBreakEvenDataSimple === 'function') {
    479529            try {
     530                console.log('[updateBreakEvenChart] Inside try block, billMonthly:', state.billMonthly);
     531               
    480532                // On page load with no bill, show zero baseline
    481533                if (!state.billMonthly || state.billMonthly === 0) {
     
    487539                }
    488540               
    489                 const cfg = { panelsCount: state.panels, yearlyEnergyDcKwh: figs.yearlyEnergyKWh || (state.panels * DAY_POWER_AVG * DAYS_IN_YR) };
     541                console.log('[updateBreakEvenChart] About to create config object');
     542                console.log('[updateBreakEvenChart] figs.yearlyEnergyKWh:', figs.yearlyEnergyKWh);
     543                console.log('[updateBreakEvenChart] figs.baseCost:', figs.baseCost);
     544               
     545                const cfg = {
     546                    panelsCount: state.panels,
     547                    yearlyEnergyDcKwh: figs.yearlyEnergyKWh || (state.panels * DAY_POWER_AVG * DAYS_IN_YR),
     548                    installCost: figs.baseCost
     549                };
    490550                console.log('Calling calculateBreakEvenDataSimple with:', cfg);
    491551                const be = window.calculateBreakEvenDataSimple(cfg);
     
    713773        console.log('[INIT] solar-calculator-main.js initializing...');
    714774        console.log('[INIT] document.readyState:', document.readyState);
    715         // Apply configuration from PHP if available
     775       
     776        // Apply configuration from PHP if available (don't wait, just use defaults if not ready)
    716777        if (window.KSRAD_CalcConfig) {
    717778            console.log('[INIT] KSRAD_CalcConfig found:', window.KSRAD_CalcConfig);
    718779            CURRENCY_SYMBOL = window.KSRAD_CalcConfig.currencySymbol || CURRENCY_SYMBOL;
    719            
    720             // Also expose globally for consistency with other scripts
    721780            window.CURRENCY_SYMBOL = CURRENCY_SYMBOL;
    722781        } else {
    723             console.warn('[INIT] KSRAD_CalcConfig not found');
     782            console.warn('[INIT] KSRAD_CalcConfig not found - using defaults');
    724783        }
    725784       
  • keiste-solar-report/trunk/includes/class-ksrad-calculator.php

    r3415762 r3446582  
    33 * Solar Calculator class for Keiste Solar Report
    44 *
     5<<<<<<< HEAD
     6=======
     7 * This code is just the placeholder code.
     8>>>>>>> fed100d (added UK no solar. grant % defaults to zero now. the math is still off though.)
    59 * Handles solar panel calculations and renders the calculator frontend.
    610 *
  • keiste-solar-report/trunk/includes/plugin-init.php

    r3420871 r3446582  
    217217            'googleSolarApiKey' => ksrad_get_option('google_solar_api_key', ''),
    218218            'reportKey' => ksrad_get_option('report_key', ''),
    219             'defaultElectricityRate' => ksrad_get_option('default_electricity_rate', '0.17'),
    220             'defaultExportRate' => ksrad_get_option('default_export_rate', '10'),
    221             'defaultFeedInTariff' => ksrad_get_option('default_feed_in_tariff', '0.15'),
     219            'defaultElectricityRate' => ksrad_get_option('default_electricity_rate', '0.36'),
     220            'defaultExportRate' => ksrad_get_option('default_export_rate', '5'),
     221            'defaultFeedInTariff' => ksrad_get_option('default_feed_in_tariff', '0.20'),
    222222            'defaultLoanApr' => ksrad_get_option('default_loan_apr', '5'),
    223223            'loanTerm' => ksrad_get_option('loan_term', '7'),
    224224            'annualPriceIncrease' => ksrad_get_option('annual_price_increase', '5'),
    225             'currency' => ksrad_get_option('currency', '$'),
    226             'country' => ksrad_get_option('country', 'United States'),
    227             'systemCostRatio' => ksrad_get_option('system_cost_ratio', '650'),
     225            'currency' => ksrad_get_option('currency', ''),
     226            'country' => ksrad_get_option('country', 'Republic of Ireland'),
     227            'systemCostRatio' => ksrad_get_option('system_cost_ratio', '1600'),
    228228            'grantRateDomestic' => ksrad_get_option('grant_rate_domestic', '30'),
    229229            'grantCapDomestic' => ksrad_get_option('grant_cap_domestic', '7500'),
     
    311311            'report_key' => '',
    312312            'logo_url' => '',
    313             'default_electricity_rate' => '0.17',
    314             'default_export_rate' => '10',
    315             'default_feed_in_tariff' => '0.14',
     313            'default_electricity_rate' => '0.34',
     314            'default_export_rate' => '5',
     315            'default_feed_in_tariff' => '0.20',
    316316            'default_loan_apr' => '5',
    317317            'loan_term' => '7',
    318318            'annual_price_increase' => '5',
    319             'currency' => '$',
    320             'country' => 'United States',
    321             'system_cost_ratio' => '650',
    322             'cost_domestic' => '650',
    323             'cost_small' => '600',
    324             'cost_medium' => '500',
    325             'cost_large' => '425',
     319            'currency' => '',
     320            'country' => 'Republic of Ireland',
     321            'system_cost_ratio' => '1800',
     322            'cost_domestic' => '1800',
     323            'cost_small' => '1600',
     324            'cost_medium' => '1200',
     325            'cost_large' => '1000',
    326326            'grant_rate_domestic' => '30',
    327327            'grant_cap_domestic' => '7500',
  • keiste-solar-report/trunk/keiste-solar-report.php

    r3420878 r3446582  
    55 * Plugin URI: https://keiste.com/keiste-solar-report
    66 * Description: Comprehensive solar panel analysis tool with ROI calculations, Google Solar API integration, interactive charts, and PDF report generation.
    7  * Version: 1.0.24
     7 * Version: 1.0.25
    88 * Author: Dara Burke, Keiste
    99 * Author URI: https://keiste.com
     
    3434// Define plugin constants (only once) with ksrad_ namespace
    3535if (!defined('KSRAD_VERSION')) {
    36     define('KSRAD_VERSION', '1.0.24');
     36    define('KSRAD_VERSION', '1.0.25');
    3737}
    3838if (!defined('KSRAD_PLUGIN_DIR')) {
     
    325325    <div class="container">
    326326
    327         <div class="text-center mt-4">
     327        <div class="text-center">
    328328            <?php
    329329            $ksrad_logo_url = ksrad_get_option('logo_url', '');
     
    333333            }
    334334            ?>
    335             <a href="<?php echo esc_url(home_url('/')); ?>">
     335            <a href="<?php echo esc_url(home_url('/keiste-solar-report/')); ?>">
    336336                <img src="<?php echo esc_url($ksrad_logo_url); ?>" alt="Company Logo"
    337337                    class="img-fluid logo-image" style="max-width: 130px; width: 100%;">
     
    359359            ?>
    360360            <h1>Solar Report<sup style="color: red;font-size: 16px;vertical-align: middle;top: -14px;"> <?php echo esc_html($ksrad_country_code); ?></sup></h1>
     361            <div style="text-align: center; margin: 30px 0;">
     362                <a href="<?php echo esc_url(remove_query_arg(['lat', 'lng', 'business_name'])); ?>"
     363                   class="btn btn-secondary"
     364                   style="display: inline-block; padding: 8px 16px; background: #6c757d; color: white; text-decoration: none; border-radius: 8px; font-size: 14px; transition: background 0.3s;"
     365                   onmouseover="this.style.background='#5a6268';"
     366                   onmouseout="this.style.background='#6c757d';">
     367                   🔄 Start Again
     368                </a>
     369            </div>
    361370        </div>
    362371
    363372
    364         <!-- Initial Page (when NOT an AJAX request) -->
    365         <?php if (!$ksrad_isAjaxRequest): ?>
    366             <div id="ajaxHeader" class="alert alert-info" role="alert"
     373        <!-- Initial Page Header -->
     374        <div id="ajaxHeader" class="alert alert-info" role="alert"
    367375                style="text-align: center; background: #FDFDFB; border: 2px solid #E8E8E6; border-radius: 12px; padding: 2rem; margin: 2rem auto; max-width: 600px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);">
    368376                <h3 style="color: #2A2A28; margin-bottom: 1rem; font-size: 1.3em; font-weight: 600;">🔍 How Much Can You Save With Solar?
     
    451459
    452460            </div>
    453 
    454         <?php endif; ?>
    455461
    456462        <?php if (empty(ksrad_get_option('google_solar_api_key', ''))): ?>
     
    704710                                <div class="results-section" id="results">
    705711                                    <h4 class="text-center">Your Return on Investment (ROI)</h4>
     712                                    <span class="text-center">enter your electricity bill (above)</span>
    706713                                    <!-- END .section.site-overview -->
    707714                                    <div class="row mt-4">
     
    713720                                                    <div class="resultsCol" style="border-left: unset;">
    714721                                                        <span class="highlight" id="netIncome">0</span>
    715                                                         <div class="ms-2 underWrite">MONTHLY INC/EXP</div>
     722                                                        <div class="ms-2 underWrite">MONTHLY PROFIT/LOSS</div>
    716723                                                    </div>
    717724                                                </div>
     
    775782                                           
    776783                                        <?php if (!apply_filters('ksrad_is_premium', false)): ?>
    777                                         <p class="mt-3 align-center"><a href="https://keiste.com/how-is-our-math/" style="color: #5A5A58;font-size: 0.9rem;" >How is our math?</a></p>
     784                                        <p class="mt-3 align-center" style="visibility: hidden;"><a href="https://keiste.com/how-is-our-math/" style="color: #5A5A58;font-size: 0.9rem;" >How is our math?</a></p>
    778785                                        <?php endif; ?>
    779786                                   
     
    846853                                                // Display grant help with correct percent and currency formatting
    847854                                                $ksrad_currency_symbol = ksrad_get_option('currency', '€');
    848                                                 $ksrad_grant_rate = floatval(ksrad_get_option('seai_grant_rate', '30')); // default 30%
    849                                                 $ksrad_grant_cap = floatval(ksrad_get_option('seai_grant_cap', '162000')); // sensible numeric default
     855                                                $ksrad_grant_rate = floatval(ksrad_get_option('grant_rate_domestic', '0')); // default 30%
     856                                                $ksrad_grant_cap = floatval(ksrad_get_option('grant_cap_domestic', '0')); // sensible numeric default
    850857                                            ?>
    851                                             <div class="input-help-right"><?php echo esc_html($ksrad_grant_rate); ?>% Grant (max <?php echo esc_html($ksrad_currency_symbol); ?><?php echo number_format($ksrad_grant_cap, 0); ?>)</div>
     858                                            <div class="input-help-right">                                           
     859                                                <span class="grant-description"><?php echo esc_html($ksrad_grant_rate); ?>% Grant (max <?php echo esc_html($ksrad_currency_symbol); ?><?php echo number_format($ksrad_grant_cap, 0); ?>)</span>
     860                                            </div>                                       
    852861                                        </div>
    853862                                    </div>
     
    927936                                // Currency symbol and getPanelCount - expose globally for external scripts
    928937                                window.CURRENCY_SYMBOL = '<?php echo esc_js(ksrad_get_option('currency', '€')); ?>';
    929 
     938                                // if it's the UK, the remove include grant setting
     939                                if (window.CURRENCY_SYMBOL == '£') {
     940                                    document.getElementById("inclGrant").disabled = true;
     941                                }
    930942                                window.getPanelCount = function getPanelCount() {
    931943                                    const range = document.querySelector('input[type="range"]#panelCount');
     
    11331145    <?php endif; ?>
    11341146
     1147    </div><!-- End .middle-column -->
     1148
    11351149<?php endif; ?>
    11361150    </div><!-- End .newContainer -->
     
    11511165        window.KSRAD_CalcConfig = Object.assign({}, window.KSRAD_CalcConfig || {}, {
    11521166            currencySymbol: '<?php echo esc_js(ksrad_get_option('currency', '€')); ?>',
    1153             defaultExportRate: <?php echo esc_js(floatval(ksrad_get_option('default_export_rate', '10')) / 100); ?>,
     1167            defaultExportRate: <?php echo esc_js(floatval(ksrad_get_option('default_export_rate', '5')) / 100); ?>,
    11541168            // Grant settings by building type
    11551169            grantSettings: {
     
    11791193        <h6 style="color: #2a2a28; text-align: center;font-family: 'Brush Script MT', cursive;margin-top: 2rem;"><a href="https://keiste.com" target="_blank" rel="noopener noreferrer" class="bad-script-regular">Get Your Keiste Solar Report</a></h6>
    11801194    <?php endif; ?>
    1181 
    1182 </div><!-- #keiste-solar-report-wrapper -->
     1195</div>
     1196<!-- #keiste-solar-report-wrapper -->
    11831197<?php
    11841198// Return the buffered content to shortcode handler
  • keiste-solar-report/trunk/readme.txt

    r3420878 r3446582  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.24
     7Stable tag: 1.0.25
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset for help on using the changeset viewer.