Jump to content

WHMCS Admin Widget: UK TAX Year Income/Profit/Loss


ConorBradley

Recommended Posts

Hi All,

put together a small WHMCS Admin Home Widget that summarises profit/loss from your WHMCS transactions and presents it in your base currency, including UK tax-year reporting and a simple toggle for invoice-only vs all transactions. I noticed that there was no way to do this in WHMCS as it uses January-December as the year.

 

What it shows

The widget displays totals (base currency) for:

  • This Month (month-to-date)

  • Previous Month (full month)

  • Tax Year to Date (UK tax year: 6 Apr → 5 Apr)

  • Last Year’s Tax YTD (same “elapsed point” comparison)

It also shows an “Average per month” row for Income / Expenses / Profit:

  • This Month: month-to-date totals (shown as “per month” for consistency; updates daily)

  • Previous Month: totals for the full month

  • Tax YTD: divided by tax months elapsed (UK tax months run 6th → 5th)

  • Last Year’s Tax YTD: calculated as a full-year average (÷ 12) (so you get a completed-year monthly average)

How the numbers are calculated

It pulls data from tblaccounts and uses:

  • Income = Amount In

  • Expenses = Fees + Amount Out

  • Profit = Amount In − Fees − Amount Out

Important: This is based on what’s recorded in WHMCS transactions. If your real business expenses live in Xero/QuickBooks/bank statements and aren’t entered into WHMCS as “Amount Out”, they won’t appear here.

Multi-currency handling

WHMCS stores transactions per client currency; the widget groups by currency and converts everything back into your base currency using tblcurrencies.rate, then displays base totals.

Mode toggle (Invoice-linked vs All transactions)

At the top of the widget there’s a mode toggle:

  • Invoice-linked: includes only transactions linked to an invoice (invoiceid > 0)

    • Usually represents customer payments/refunds + gateway fees.

  • All transactions: includes everything in tblaccounts (including manual entries / “Amount Out” etc.)

The selection persists via a cookie/session (pl_mode) and the widget is set to no cache so switching updates instantly.

UK tax year behaviour

  • UK tax year is 6 April to 5 April

  • The widget calculates Tax YTD from the current tax-year start to “now”

  • For comparison, “Last Year’s Tax YTD” uses the same elapsed point into the previous tax year (e.g., if we’re 10 tax months into the current year, it compares the first 10 tax months of last year)

  • The “tax months elapsed” counter follows UK tax-month boundaries (6th → 5th), so the elapsed count can change on the 6th of each month

Installation

  1. Create a file like:

    whmcs/includes/hooks/profit_loss_widget.php

  2. Paste the code in.

  3. Visit the WHMCS admin dashboard (Home).

    You can drag/reorder widgets as normal.

 

Code Is Below:

 

<?php
if (!defined("WHMCS")) { die("No direct access"); }

use WHMCS\Database\Capsule;
use Carbon\Carbon;

add_hook('AdminHomeWidgets', 1, function () {
    return new class extends \WHMCS\Module\AbstractWidget {
        protected $title = 'Profit / Loss (Month, Prev Month, UK Tax Year)';
        protected $description = 'Base-currency totals only. Amount In − Fees − Amount Out. UK tax year 6 Apr – 5 Apr.';
        protected $weight = 150;
        protected $columns = 2;         // wider widget (set 1/2/3 to suit your dashboard)
        protected $cache = false;
        protected $cacheExpiry = 0;
        protected $requiredPermission = '';

        public function getData()
        {
            try {
                $now = Carbon::now();

                // Mode: 'invoice' (payments & refunds only) or 'all' (includes withdrawals/expenditures)
                $mode = $this->getMode();
                $onlyInvoiceLinked = ($mode === 'invoice');
                $opts = ['onlyInvoiceLinked' => $onlyInvoiceLinked];

                // Calendar months
                $startMonth     = $now->copy()->startOfMonth();
                $prevMonthStart = $now->copy()->subMonth()->startOfMonth();
                $prevMonthEnd   = $now->copy()->subMonth()->endOfMonth();

                // UK tax year (6 Apr – 5 Apr)
                $tyStart = $this->ukTaxYearStart($now);
                $tyEnd   = $tyStart->copy()->addYear()->subDay()->endOfDay(); // 5 Apr end-of-day

                // Last tax year (full)
                $lastTyStart = $tyStart->copy()->subYear();
                $lastTyEnd   = $lastTyStart->copy()->addYear()->subDay()->endOfDay(); // 5 Apr end-of-day

                // Query per-currency then convert to base totals
                $monthRows     = $this->sumProfitByCurrency($startMonth, $now, $opts);                // this month-to-date
                $prevMonthRows = $this->sumProfitByCurrency($prevMonthStart, $prevMonthEnd, $opts);  // full previous month

                // Current tax year is "to date" (can’t include future)
                $taxYearToDateRows = $this->sumProfitByCurrency($tyStart, $now, $opts);

                // Last tax year is full 12 months
                $lastTaxYearFullRows = $this->sumProfitByCurrency($lastTyStart, $lastTyEnd, $opts);

                $base = Capsule::table('tblcurrencies')->where('default', 1)->first();

                // --- Averages per month (income, expenses, profit) ---
                // Month periods: treat as 1 month each (this month-to-date still counts as a month per your request)
                $monthTotalsMulti     = $this->toBaseTotalsMulti($monthRows, $base);
                $prevMonthTotalsMulti = $this->toBaseTotalsMulti($prevMonthRows, $base);

                $monthAvg = [
                    'income'   => $this->avgPerMonth($monthTotalsMulti['amount_in'], 1),
                    'expenses' => $this->avgPerMonth($monthTotalsMulti['fees'] + $monthTotalsMulti['amount_out'], 1),
                    'profit'   => $this->avgPerMonth($monthTotalsMulti['profit'], 1),
                    'months'   => 1,
                ];

                $prevMonthAvg = [
                    'income'   => $this->avgPerMonth($prevMonthTotalsMulti['amount_in'], 1),
                    'expenses' => $this->avgPerMonth($prevMonthTotalsMulti['fees'] + $prevMonthTotalsMulti['amount_out'], 1),
                    'profit'   => $this->avgPerMonth($prevMonthTotalsMulti['profit'], 1),
                    'months'   => 1,
                ];

                // Current tax year average uses UK tax-months elapsed (6th → 5th)
                $tyMonths = $this->ukTaxMonthsElapsed($tyStart, $now);

                $taxYearTotalsMulti      = $this->toBaseTotalsMulti($taxYearToDateRows, $base);
                $lastTaxYearTotalsMulti  = $this->toBaseTotalsMulti($lastTaxYearFullRows, $base);

                $taxYearAvg = [
                    'income'   => $this->avgPerMonth($taxYearTotalsMulti['amount_in'], $tyMonths),
                    'expenses' => $this->avgPerMonth($taxYearTotalsMulti['fees'] + $taxYearTotalsMulti['amount_out'], $tyMonths),
                    'profit'   => $this->avgPerMonth($taxYearTotalsMulti['profit'], $tyMonths),
                    'months'   => $tyMonths,
                ];

                // Last tax year is a completed year: always 12 months
                $lastTaxYearAvg = [
                    'income'   => $this->avgPerMonth($lastTaxYearTotalsMulti['amount_in'], 12),
                    'expenses' => $this->avgPerMonth($lastTaxYearTotalsMulti['fees'] + $lastTaxYearTotalsMulti['amount_out'], 12),
                    'profit'   => $this->avgPerMonth($lastTaxYearTotalsMulti['profit'], 12),
                    'months'   => 12,
                ];
                // --- /Averages ---

                return [
                    'totals' => [
                        'month'          => $this->toBaseTotal($monthRows, $base),
                        'prev_month'     => $this->toBaseTotal($prevMonthRows, $base),
                        'tax_year'       => $this->toBaseTotal($taxYearToDateRows, $base),      // current tax year to date
                        'last_tax_year'  => $this->toBaseTotal($lastTaxYearFullRows, $base),   // last tax year full
                        'base'           => $base ? (array)$base : ['code'=>'','prefix'=>'','suffix'=>''],
                    ],
                    'averages' => [
                        'month'          => $monthAvg,
                        'prev_month'     => $prevMonthAvg,
                        'tax_year'       => $taxYearAvg,
                        'last_tax_year'  => $lastTaxYearAvg,
                    ],
                    'meta' => [
                        'month_label'         => $startMonth->format('M Y'),
                        'prev_month_label'    => $prevMonthStart->format('M Y'),

                        'tax_year_label'      => $this->formatTaxYearLabel($tyStart),
                        'tax_year_full_range' => $tyStart->format('j M Y') . ' – ' . $tyEnd->format('j M Y'),
                        'tax_year_asof'       => $now->format('j M Y'),

                        'last_tax_year_label'      => $this->formatTaxYearLabel($lastTyStart),
                        'last_tax_year_full_range' => $lastTyStart->format('j M Y') . ' – ' . $lastTyEnd->format('j M Y'),

                        'generated'           => $now->toDayDateTimeString(),
                        'mode'                => $mode, // 'invoice' or 'all'
                    ],
                ];
            } catch (\Throwable $e) {
                return ['error' => $e->getMessage(), 'meta' => ['generated' => date('r')]];
            }
        }

        /** Persist/return the current mode (invoice|all) using GET → session/cookie. */
        private function getMode()
        {
            $valid = ['invoice', 'all'];
            $get = isset($_GET['pl_mode']) ? strtolower((string)$_GET['pl_mode']) : null;
            if ($get && in_array($get, $valid, true)) {
                if (isset($_SESSION)) { $_SESSION['pl_mode'] = $get; }
                @setcookie('pl_mode', $get, time() + 31536000, '/'); // 1 year
                return $get;
            }
            if (isset($_SESSION['pl_mode']) && in_array($_SESSION['pl_mode'], $valid, true)) {
                return $_SESSION['pl_mode'];
            }
            if (isset($_COOKIE['pl_mode']) && in_array($_COOKIE['pl_mode'], $valid, true)) {
                return $_COOKIE['pl_mode'];
            }
            return 'invoice';
        }

        /** Build a link to switch mode while preserving the current path & query. */
        private function toggleUrl($toMode)
        {
            $uri   = $_SERVER['REQUEST_URI'] ?? 'index.php';
            $parts = parse_url($uri);
            $path  = $parts['path'] ?? 'index.php';
            $q     = [];
            if (!empty($parts['query'])) { parse_str($parts['query'], $q); }
            $q['pl_mode'] = $toMode;
            $qs = http_build_query($q);
            return $path . ($qs ? '?' . $qs : '');
        }

        private function ukTaxYearStart(Carbon $date)
        {
            $tyStart = Carbon::create($date->year, 4, 6, 0, 0, 0, $date->timezone);
            if ($date->lt($tyStart)) { $tyStart->subYear(); }
            return $tyStart->startOfDay();
        }

        private function formatTaxYearLabel(Carbon $tyStart)
        {
            $startYear = (int)$tyStart->format('Y');
            $endYY     = (int)$tyStart->copy()->addYear()->format('y');
            return sprintf('%d/%02d', $startYear, $endYY);
        }

        /**
         * UK tax months elapsed in the tax year (tax months run 6th → 5th).
         * Returns an integer 1..12.
         */
        private function ukTaxMonthsElapsed(Carbon $tyStart, Carbon $to)
        {
            if ($to->lt($tyStart)) {
                return 0;
            }

            $startY = (int)$tyStart->format('Y');
            $startM = 4; // tax year starts in April
            $toY    = (int)$to->format('Y');
            $toM    = (int)$to->format('n');
            $toD    = (int)$to->format('j');

            $diffMonths = (($toY - $startY) * 12) + ($toM - $startM);
            $monthsElapsed = $diffMonths + (($toD >= 6) ? 1 : 0);

            if ($monthsElapsed < 1)  { $monthsElapsed = 1; }
            if ($monthsElapsed > 12) { $monthsElapsed = 12; }

            return $monthsElapsed;
        }

        /** Aggregate per currency for a period; optionally invoice-linked only. */
        private function sumProfitByCurrency(Carbon $from, Carbon $to, array $opts = [])
        {
            $onlyInvoices = !empty($opts['onlyInvoiceLinked']);

            $q = Capsule::table('tblaccounts as a')
                ->leftJoin('tblclients as cl', 'cl.id', '=', 'a.userid')
                ->leftJoin('tblcurrencies as cur', 'cur.id', '=', 'cl.currency')
                ->whereBetween('a.date', [$from->toDateTimeString(), $to->toDateTimeString()]);

            if ($onlyInvoices) {
                $q->where('a.invoiceid', '>', 0);
            }

            $rows = $q->groupBy('cl.currency', 'cur.code', 'cur.prefix', 'cur.suffix', 'cur.rate')
                      ->orderBy('cur.code')
                      ->get([
                          Capsule::raw('cl.currency as currencyId'),
                          Capsule::raw('cur.code as code'),
                          Capsule::raw('cur.prefix as prefix'),
                          Capsule::raw('cur.suffix as suffix'),
                          Capsule::raw('cur.rate as rate'),
                          Capsule::raw('SUM(a.amountin) as amount_in'),
                          Capsule::raw('SUM(a.fees) as fees'),
                          Capsule::raw('SUM(a.amountout) as amount_out'),
                          Capsule::raw('SUM(a.amountin - a.fees - a.amountout) as profit'),
                      ]);

            $defaultCurrency = Capsule::table('tblcurrencies')->where('default', 1)->first();

            return $rows->map(function ($r) use ($defaultCurrency) {
                $code   = $r->code ?? ($defaultCurrency->code ?? 'BASE');
                $prefix = $r->prefix ?? ($defaultCurrency->prefix ?? '');
                $suffix = $r->suffix ?? ($defaultCurrency->suffix ?? '');
                $rate   = isset($r->rate) ? (float)$r->rate : (float)($defaultCurrency->rate ?? 1.0);
                $cid    = isset($r->currencyId) ? (int)$r->currencyId : (int)($defaultCurrency->id ?? 0);

                return [
                    'currencyId' => $cid,
                    'code'       => (string)$code,
                    'prefix'     => (string)$prefix,
                    'suffix'     => (string)$suffix,
                    'rate'       => (float)$rate,
                    'amount_in'  => (float)$r->amount_in,
                    'fees'       => (float)$r->fees,
                    'amount_out' => (float)$r->amount_out,
                    'profit'     => (float)$r->profit,
                ];
            })->all();
        }

        /** Convert to base-currency total (profit only). */
        private function toBaseTotal(array $rows, $baseCurrency)
        {
            if (!$baseCurrency) {
                return ['amount' => 0.0, 'prefix' => '', 'suffix' => '', 'code' => ''];
            }
            $baseId = (int)$baseCurrency->id;
            $sum = 0.0;
            foreach ($rows as $r) {
                $profit = (float)$r['profit'];
                $sum += ((int)$r['currencyId'] === $baseId) ? $profit : ($profit / ((float)$r['rate'] ?: 1.0));
            }
            return [
                'amount' => $sum,
                'prefix' => (string)$baseCurrency->prefix,
                'suffix' => (string)$baseCurrency->suffix,
                'code'   => (string)$baseCurrency->code,
            ];
        }

        /** Convert rows to base totals for multiple fields (amount_in, fees, amount_out, profit). */
        private function toBaseTotalsMulti(array $rows, $baseCurrency)
        {
            if (!$baseCurrency) {
                return [
                    'amount_in'  => 0.0,
                    'fees'       => 0.0,
                    'amount_out' => 0.0,
                    'profit'     => 0.0,
                ];
            }

            $baseId = (int)$baseCurrency->id;

            $totals = [
                'amount_in'  => 0.0,
                'fees'       => 0.0,
                'amount_out' => 0.0,
                'profit'     => 0.0,
            ];

            foreach ($rows as $r) {
                $rate = (float)($r['rate'] ?? 1.0);
                if ($rate == 0.0) { $rate = 1.0; }

                $isBase = ((int)$r['currencyId'] === $baseId);

                $conv = function ($v) use ($isBase, $rate) {
                    $v = (float)$v;
                    return $isBase ? $v : ($v / $rate);
                };

                $totals['amount_in']  += $conv($r['amount_in']  ?? 0);
                $totals['fees']       += $conv($r['fees']       ?? 0);
                $totals['amount_out'] += $conv($r['amount_out'] ?? 0);
                $totals['profit']     += $conv($r['profit']     ?? 0);
            }

            return $totals;
        }

        /** Safe average helper. */
        private function avgPerMonth($total, $months)
        {
            $months = (int)$months;
            if ($months <= 0) { return 0.0; }
            return (float)$total / $months;
        }

        public function generateOutput($data)
        {
            if (!empty($data['error'])) {
                return '<div class="widget-content-padded"><strong>Error:</strong> '
                    . htmlspecialchars($data['error'], ENT_QUOTES, 'UTF-8')
                    . '<br><small>Generated ' . htmlspecialchars($data['meta']['generated'], ENT_QUOTES, 'UTF-8') . '</small></div>';
            }

            $fmt = function ($prefix, $amount, $suffix) {
                return sprintf('%s%s%s',
                    htmlspecialchars($prefix ?? '', ENT_QUOTES, 'UTF-8'),
                    number_format((float)$amount, 2),
                    htmlspecialchars($suffix ?? '', ENT_QUOTES, 'UTF-8')
                );
            };

            $t   = $data['totals'];
            $m   = $data['meta'];
            $avg = $data['averages'] ?? [];

            $monthBase     = $fmt($t['base']['prefix'] ?? '', $t['month']['amount'] ?? 0,         $t['base']['suffix'] ?? '');
            $prevMonthBase = $fmt($t['base']['prefix'] ?? '', $t['prev_month']['amount'] ?? 0,    $t['base']['suffix'] ?? '');
            $tyBase        = $fmt($t['base']['prefix'] ?? '', $t['tax_year']['amount'] ?? 0,      $t['base']['suffix'] ?? '');
            $lastTyBase    = $fmt($t['base']['prefix'] ?? '', $t['last_tax_year']['amount'] ?? 0, $t['base']['suffix'] ?? '');

            $mAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['month']['income'] ?? 0,         $t['base']['suffix'] ?? '');
            $mAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['month']['expenses'] ?? 0,       $t['base']['suffix'] ?? '');
            $mAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['month']['profit'] ?? 0,         $t['base']['suffix'] ?? '');

            $pmAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['prev_month']['income'] ?? 0,   $t['base']['suffix'] ?? '');
            $pmAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['prev_month']['expenses'] ?? 0, $t['base']['suffix'] ?? '');
            $pmAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['prev_month']['profit'] ?? 0,   $t['base']['suffix'] ?? '');

            $tyAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['tax_year']['income'] ?? 0,     $t['base']['suffix'] ?? '');
            $tyAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['tax_year']['expenses'] ?? 0,   $t['base']['suffix'] ?? '');
            $tyAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['tax_year']['profit'] ?? 0,     $t['base']['suffix'] ?? '');

            $lastTyAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['last_tax_year']['income'] ?? 0,   $t['base']['suffix'] ?? '');
            $lastTyAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['last_tax_year']['expenses'] ?? 0, $t['base']['suffix'] ?? '');
            $lastTyAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['last_tax_year']['profit'] ?? 0,   $t['base']['suffix'] ?? '');

            $tyMonths = (int)($avg['tax_year']['months'] ?? 0);

            $isInvoice = ($m['mode'] === 'invoice');
            $modeLabel = $isInvoice ? 'Invoice-linked' : 'All transactions';
            $switchTo  = $isInvoice ? 'all' : 'invoice';
            $switchTxt = $isInvoice ? 'Switch to All transactions' : 'Switch to Invoice-linked';
            $switchUrl = $this->toggleUrl($switchTo);

            return <<<HTML
<div class="widget-content-padded">
  <div class="clearfix">
    <div class="pull-left">
      <strong>Totals in Base ({$t['base']['code']})</strong>
      <span class="label label-info" style="margin-left:8px;">Mode: {$modeLabel}</span>
      <a href="{$switchUrl}" style="margin-left:8px;">{$switchTxt}</a>
    </div>
    <div class="pull-right text-muted" style="font-size:12px">
      Generated {$m['generated']}
    </div>
  </div>

  <table class="table table-condensed" style="margin-top:10px">
    <thead>
      <tr>
        <th></th>
        <th class="text-right">This Month<br><small>({$m['month_label']})</small></th>
        <th class="text-right">Previous Month<br><small>({$m['prev_month_label']})</small></th>
        <th class="text-right">
          Current Tax Year (to date)
          <br><small>({$m['tax_year_label']}: {$m['tax_year_full_range']})</small>
          <br><small class="text-muted">As of {$m['tax_year_asof']}</small>
        </th>
        <th class="text-right">
          Last Tax Year (full)
          <br><small>({$m['last_tax_year_label']}: {$m['last_tax_year_full_range']})</small>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th>Total (Base {$t['base']['code']})</th>
        <td class="text-right">{$monthBase}</td>
        <td class="text-right">{$prevMonthBase}</td>
        <td class="text-right">{$tyBase}</td>
        <td class="text-right">{$lastTyBase}</td>
      </tr>

      <tr>
        <th>
          Average per month (Income, Expenses, Profit)
          <br><small class="text-muted">Current tax year: {$tyMonths}/12 tax months elapsed; last tax year: 12/12</small>
        </th>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$mAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$mAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$mAvgProfit}</div>
        </td>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$pmAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$pmAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$pmAvgProfit}</div>
        </td>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$tyAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$tyAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$tyAvgProfit}</div>
        </td>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$lastTyAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$lastTyAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$lastTyAvgProfit}</div>
        </td>
      </tr>
    </tbody>
  </table>

  <p class="text-muted" style="font-size:12px;margin-top:8px;">
    Formula: <code>Amount In  Fees  Amount Out</code>. UK tax year runs 6 Apr  5 Apr.
    <br>Average per month uses: <code>Income = Amount In</code>, <code>Expenses = Fees + Amount Out</code>, <code>Profit = Amount In  Fees  Amount Out</code>.
    <br><small>Note: This Month is month-to-date, so it updates daily.</small>
  </p>
</div>
HTML;
        }
    };
});

This code and guidance are provided as-is for general informational purposes only. I’m not an accountant, tax adviser, or solicitor, and this widget should not be relied on as professional financial, accounting, or tax advice. Use at your own risk. No liability is accepted for any loss, damage, or issues arising from the use of this code.

Edited by ConorBradley
Link to comment
Share on other sites

1 hour ago, pjs32 said:

Great widget - thanks!

Is it possible to show without VAT being included  on the totals? 

 

Hi, Thank you 😄 Try this code. I haven't tested it on my install, as I need it included in my totals, so you'll have to let me know (please test it NOT on a live install). You'll also need to switch to invoice-only mode as WHMCS doesn’t store “VAT” as a field on tblaccounts transactions.

 

<?php
if (!defined("WHMCS")) { die("No direct access"); }

use WHMCS\Database\Capsule;
use Carbon\Carbon;

add_hook('AdminHomeWidgets', 1, function () {
    return new class extends \WHMCS\Module\AbstractWidget {
        protected $title = 'Profit / Loss (Month, Prev Month, UK Tax Year)';
        protected $description = 'Invoice-linked only. Base-currency totals. Optional Excl. VAT. UK tax year 6 Apr – 5 Apr.';
        protected $weight = 150;
        protected $columns = 2;         // set 1/2/3 to suit your dashboard
        protected $cache = false;
        protected $cacheExpiry = 0;
        protected $requiredPermission = '';

        public function getData()
        {
            try {
                $now = Carbon::now();

                // Invoice-linked only (as requested)
                $opts = ['onlyInvoiceLinked' => true];

                // VAT mode: inc|ex
                $vatMode    = $this->getVatMode();
                $excludeVat = ($vatMode === 'ex');

                // Calendar months
                $startMonth     = $now->copy()->startOfMonth();
                $prevMonthStart = $now->copy()->subMonth()->startOfMonth();
                $prevMonthEnd   = $now->copy()->subMonth()->endOfMonth();

                // UK tax year (6 Apr – 5 Apr)
                $tyStart = $this->ukTaxYearStart($now);
                $tyEnd   = $tyStart->copy()->addYear()->subDay()->endOfDay(); // 5 Apr end-of-day

                // Last tax year (full)
                $lastTyStart = $tyStart->copy()->subYear();
                $lastTyEnd   = $lastTyStart->copy()->addYear()->subDay()->endOfDay(); // 5 Apr end-of-day

                // Query per-currency (invoice-linked only)
                $monthRows        = $this->sumProfitByCurrency($startMonth, $now, $opts);               // month-to-date
                $prevMonthRows    = $this->sumProfitByCurrency($prevMonthStart, $prevMonthEnd, $opts); // full prev month
                $taxYearRows      = $this->sumProfitByCurrency($tyStart, $now, $opts);                  // current tax year to date
                $lastTaxYearRows  = $this->sumProfitByCurrency($lastTyStart, $lastTyEnd, $opts);        // last tax year full

                $base = Capsule::table('tblcurrencies')->where('default', 1)->first();

                // VAT totals by period (deduped per invoice)
                $monthVatRows     = $this->sumInvoiceVatByCurrencyDistinctInvoices($startMonth, $now);
                $prevMonthVatRows = $this->sumInvoiceVatByCurrencyDistinctInvoices($prevMonthStart, $prevMonthEnd);
                $taxVatRows       = $this->sumInvoiceVatByCurrencyDistinctInvoices($tyStart, $now);
                $lastTaxVatRows   = $this->sumInvoiceVatByCurrencyDistinctInvoices($lastTyStart, $lastTyEnd);

                $monthVatBase     = $this->toBaseVatTotal($monthVatRows, $base);
                $prevMonthVatBase = $this->toBaseVatTotal($prevMonthVatRows, $base);
                $taxVatBase       = $this->toBaseVatTotal($taxVatRows, $base);
                $lastTaxVatBase   = $this->toBaseVatTotal($lastTaxVatRows, $base);

                // Profit totals (base)
                $monthBaseProfit     = $this->toBaseTotal($monthRows, $base);
                $prevMonthBaseProfit = $this->toBaseTotal($prevMonthRows, $base);
                $taxBaseProfit       = $this->toBaseTotal($taxYearRows, $base);
                $lastTaxBaseProfit   = $this->toBaseTotal($lastTaxYearRows, $base);

                if ($excludeVat) {
                    // VAT is part of gross invoice totals; remove it from profit
                    $monthBaseProfit['amount']     -= $monthVatBase;
                    $prevMonthBaseProfit['amount'] -= $prevMonthVatBase;
                    $taxBaseProfit['amount']       -= $taxVatBase;
                    $lastTaxBaseProfit['amount']   -= $lastTaxVatBase;
                }

                // Multi-field totals (base) for averages row
                $monthTotalsMulti     = $this->toBaseTotalsMulti($monthRows, $base);
                $prevMonthTotalsMulti = $this->toBaseTotalsMulti($prevMonthRows, $base);
                $taxTotalsMulti       = $this->toBaseTotalsMulti($taxYearRows, $base);
                $lastTaxTotalsMulti   = $this->toBaseTotalsMulti($lastTaxYearRows, $base);

                if ($excludeVat) {
                    // Remove VAT from income and profit (leave fees/amount_out untouched)
                    $monthTotalsMulti['amount_in'] -= $monthVatBase;
                    $monthTotalsMulti['profit']    -= $monthVatBase;

                    $prevMonthTotalsMulti['amount_in'] -= $prevMonthVatBase;
                    $prevMonthTotalsMulti['profit']    -= $prevMonthVatBase;

                    $taxTotalsMulti['amount_in'] -= $taxVatBase;
                    $taxTotalsMulti['profit']    -= $taxVatBase;

                    $lastTaxTotalsMulti['amount_in'] -= $lastTaxVatBase;
                    $lastTaxTotalsMulti['profit']    -= $lastTaxVatBase;
                }

                // Averages
                $tyMonths = $this->ukTaxMonthsElapsed($tyStart, $now);

                $monthAvg = [
                    'income'   => $this->avgPerMonth($monthTotalsMulti['amount_in'], 1),
                    'expenses' => $this->avgPerMonth($monthTotalsMulti['fees'] + $monthTotalsMulti['amount_out'], 1),
                    'profit'   => $this->avgPerMonth($monthTotalsMulti['profit'], 1),
                    'months'   => 1,
                ];

                $prevMonthAvg = [
                    'income'   => $this->avgPerMonth($prevMonthTotalsMulti['amount_in'], 1),
                    'expenses' => $this->avgPerMonth($prevMonthTotalsMulti['fees'] + $prevMonthTotalsMulti['amount_out'], 1),
                    'profit'   => $this->avgPerMonth($prevMonthTotalsMulti['profit'], 1),
                    'months'   => 1,
                ];

                $taxYearAvg = [
                    'income'   => $this->avgPerMonth($taxTotalsMulti['amount_in'], $tyMonths),
                    'expenses' => $this->avgPerMonth($taxTotalsMulti['fees'] + $taxTotalsMulti['amount_out'], $tyMonths),
                    'profit'   => $this->avgPerMonth($taxTotalsMulti['profit'], $tyMonths),
                    'months'   => $tyMonths,
                ];

                $lastTaxYearAvg = [
                    'income'   => $this->avgPerMonth($lastTaxTotalsMulti['amount_in'], 12),
                    'expenses' => $this->avgPerMonth($lastTaxTotalsMulti['fees'] + $lastTaxTotalsMulti['amount_out'], 12),
                    'profit'   => $this->avgPerMonth($lastTaxTotalsMulti['profit'], 12),
                    'months'   => 12,
                ];

                return [
                    'totals' => [
                        'month'         => $monthBaseProfit,
                        'prev_month'    => $prevMonthBaseProfit,
                        'tax_year'      => $taxBaseProfit,      // current tax year to date
                        'last_tax_year' => $lastTaxBaseProfit,  // last tax year full
                        'base'          => $base ? (array)$base : ['code'=>'','prefix'=>'','suffix'=>''],
                    ],
                    'averages' => [
                        'month'         => $monthAvg,
                        'prev_month'    => $prevMonthAvg,
                        'tax_year'      => $taxYearAvg,
                        'last_tax_year' => $lastTaxYearAvg,
                    ],
                    'meta' => [
                        'month_label'         => $startMonth->format('M Y'),
                        'prev_month_label'    => $prevMonthStart->format('M Y'),

                        'tax_year_label'      => $this->formatTaxYearLabel($tyStart),
                        'tax_year_full_range' => $tyStart->format('j M Y') . ' – ' . $tyEnd->format('j M Y'),
                        'tax_year_asof'       => $now->format('j M Y'),

                        'last_tax_year_label'      => $this->formatTaxYearLabel($lastTyStart),
                        'last_tax_year_full_range' => $lastTyStart->format('j M Y') . ' – ' . $lastTyEnd->format('j M Y'),

                        'generated' => $now->toDayDateTimeString(),
                        'vat_mode'  => $vatMode, // inc|ex
                    ],
                ];
            } catch (\Throwable $e) {
                return ['error' => $e->getMessage(), 'meta' => ['generated' => date('r')]];
            }
        }

        /** VAT mode toggle: inc|ex using GET → session/cookie. */
        private function getVatMode()
        {
            $valid = ['inc', 'ex'];
            $get = isset($_GET['pl_vat']) ? strtolower((string)$_GET['pl_vat']) : null;

            if ($get && in_array($get, $valid, true)) {
                if (isset($_SESSION)) { $_SESSION['pl_vat'] = $get; }
                @setcookie('pl_vat', $get, time() + 31536000, '/'); // 1 year
                return $get;
            }
            if (isset($_SESSION['pl_vat']) && in_array($_SESSION['pl_vat'], $valid, true)) {
                return $_SESSION['pl_vat'];
            }
            if (isset($_COOKIE['pl_vat']) && in_array($_COOKIE['pl_vat'], $valid, true)) {
                return $_COOKIE['pl_vat'];
            }
            return 'inc';
        }

        /** Build a link to set query params while preserving the current path & query. */
        private function toggleUrl(array $set)
        {
            $uri   = $_SERVER['REQUEST_URI'] ?? 'index.php';
            $parts = parse_url($uri);
            $path  = $parts['path'] ?? 'index.php';
            $q     = [];
            if (!empty($parts['query'])) { parse_str($parts['query'], $q); }

            foreach ($set as $k => $v) {
                $q[$k] = $v;
            }

            $qs = http_build_query($q);
            return $path . ($qs ? '?' . $qs : '');
        }

        private function ukTaxYearStart(Carbon $date)
        {
            $tyStart = Carbon::create($date->year, 4, 6, 0, 0, 0, $date->timezone);
            if ($date->lt($tyStart)) { $tyStart->subYear(); }
            return $tyStart->startOfDay();
        }

        private function formatTaxYearLabel(Carbon $tyStart)
        {
            $startYear = (int)$tyStart->format('Y');
            $endYY     = (int)$tyStart->copy()->addYear()->format('y');
            return sprintf('%d/%02d', $startYear, $endYY);
        }

        /**
         * UK tax months elapsed in the tax year (tax months run 6th → 5th).
         * Returns an integer 1..12.
         */
        private function ukTaxMonthsElapsed(Carbon $tyStart, Carbon $to)
        {
            if ($to->lt($tyStart)) {
                return 0;
            }

            $startY = (int)$tyStart->format('Y');
            $startM = 4; // tax year starts in April
            $toY    = (int)$to->format('Y');
            $toM    = (int)$to->format('n');
            $toD    = (int)$to->format('j');

            $diffMonths = (($toY - $startY) * 12) + ($toM - $startM);
            $monthsElapsed = $diffMonths + (($toD >= 6) ? 1 : 0);

            if ($monthsElapsed < 1)  { $monthsElapsed = 1; }
            if ($monthsElapsed > 12) { $monthsElapsed = 12; }

            return $monthsElapsed;
        }

        /** Aggregate per currency for a period; invoice-linked only in this widget. */
        private function sumProfitByCurrency(Carbon $from, Carbon $to, array $opts = [])
        {
            $q = Capsule::table('tblaccounts as a')
                ->leftJoin('tblclients as cl', 'cl.id', '=', 'a.userid')
                ->leftJoin('tblcurrencies as cur', 'cur.id', '=', 'cl.currency')
                ->whereBetween('a.date', [$from->toDateTimeString(), $to->toDateTimeString()])
                ->where('a.invoiceid', '>', 0); // invoice-linked only

            $rows = $q->groupBy('cl.currency', 'cur.code', 'cur.prefix', 'cur.suffix', 'cur.rate')
                      ->orderBy('cur.code')
                      ->get([
                          Capsule::raw('cl.currency as currencyId'),
                          Capsule::raw('cur.code as code'),
                          Capsule::raw('cur.prefix as prefix'),
                          Capsule::raw('cur.suffix as suffix'),
                          Capsule::raw('cur.rate as rate'),
                          Capsule::raw('SUM(a.amountin) as amount_in'),
                          Capsule::raw('SUM(a.fees) as fees'),
                          Capsule::raw('SUM(a.amountout) as amount_out'),
                          Capsule::raw('SUM(a.amountin - a.fees - a.amountout) as profit'),
                      ]);

            $defaultCurrency = Capsule::table('tblcurrencies')->where('default', 1)->first();

            return $rows->map(function ($r) use ($defaultCurrency) {
                $rate   = isset($r->rate) ? (float)$r->rate : (float)($defaultCurrency->rate ?? 1.0);
                $cid    = isset($r->currencyId) ? (int)$r->currencyId : (int)($defaultCurrency->id ?? 0);

                return [
                    'currencyId' => $cid,
                    'rate'       => (float)$rate,
                    'amount_in'  => (float)$r->amount_in,
                    'fees'       => (float)$r->fees,
                    'amount_out' => (float)$r->amount_out,
                    'profit'     => (float)$r->profit,
                ];
            })->all();
        }

        /**
         * Sum VAT (tax+tax2) from invoices linked to tblaccounts in date range,
         * counting each invoice once (prevents double-counting on partial/multiple payments).
         */
        private function sumInvoiceVatByCurrencyDistinctInvoices(Carbon $from, Carbon $to)
        {
            $q = Capsule::table('tblaccounts as a')
                ->join('tblinvoices as i', 'i.id', '=', 'a.invoiceid')
                ->leftJoin('tblclients as cl', 'cl.id', '=', 'a.userid')
                ->leftJoin('tblcurrencies as cur', 'cur.id', '=', 'cl.currency')
                ->whereBetween('a.date', [$from->toDateTimeString(), $to->toDateTimeString()])
                ->where('a.invoiceid', '>', 0)
                ->groupBy('a.invoiceid', 'cl.currency', 'cur.rate');

            // One row per invoice per currency
            $invoiceRows = $q->get([
                Capsule::raw('a.invoiceid as invoiceId'),
                Capsule::raw('cl.currency as currencyId'),
                Capsule::raw('cur.rate as rate'),
                Capsule::raw('MAX(COALESCE(i.tax,0) + COALESCE(i.tax2,0)) as vat_total'),
            ]);

            $defaultCurrency = Capsule::table('tblcurrencies')->where('default', 1)->first();

            // Reduce to per-currency totals in PHP
            $byCurrency = [];
            foreach ($invoiceRows as $r) {
                $cid  = isset($r->currencyId) ? (int)$r->currencyId : (int)($defaultCurrency->id ?? 0);
                $rate = isset($r->rate) ? (float)$r->rate : (float)($defaultCurrency->rate ?? 1.0);
                $vat  = (float)$r->vat_total;

                if (!isset($byCurrency[$cid])) {
                    $byCurrency[$cid] = ['currencyId' => $cid, 'rate' => $rate, 'vat_total' => 0.0];
                }
                $byCurrency[$cid]['vat_total'] += $vat;
            }

            return array_values($byCurrency);
        }

        /** Convert VAT rows to base-currency total. */
        private function toBaseVatTotal(array $rows, $baseCurrency)
        {
            if (!$baseCurrency) { return 0.0; }
            $baseId = (int)$baseCurrency->id;
            $sum = 0.0;

            foreach ($rows as $r) {
                $vat  = (float)($r['vat_total'] ?? 0);
                $rate = (float)($r['rate'] ?? 1.0);
                if ($rate == 0.0) { $rate = 1.0; }

                $sum += ((int)$r['currencyId'] === $baseId) ? $vat : ($vat / $rate);
            }
            return $sum;
        }

        /** Convert to base-currency total (profit only). */
        private function toBaseTotal(array $rows, $baseCurrency)
        {
            if (!$baseCurrency) {
                return ['amount' => 0.0, 'prefix' => '', 'suffix' => '', 'code' => ''];
            }
            $baseId = (int)$baseCurrency->id;
            $sum = 0.0;
            foreach ($rows as $r) {
                $profit = (float)$r['profit'];
                $rate   = (float)($r['rate'] ?? 1.0);
                if ($rate == 0.0) { $rate = 1.0; }
                $sum += ((int)$r['currencyId'] === $baseId) ? $profit : ($profit / $rate);
            }
            return [
                'amount' => $sum,
                'prefix' => (string)$baseCurrency->prefix,
                'suffix' => (string)$baseCurrency->suffix,
                'code'   => (string)$baseCurrency->code,
            ];
        }

        /** Convert rows to base totals for multiple fields (amount_in, fees, amount_out, profit). */
        private function toBaseTotalsMulti(array $rows, $baseCurrency)
        {
            if (!$baseCurrency) {
                return [
                    'amount_in'  => 0.0,
                    'fees'       => 0.0,
                    'amount_out' => 0.0,
                    'profit'     => 0.0,
                ];
            }

            $baseId = (int)$baseCurrency->id;

            $totals = [
                'amount_in'  => 0.0,
                'fees'       => 0.0,
                'amount_out' => 0.0,
                'profit'     => 0.0,
            ];

            foreach ($rows as $r) {
                $rate = (float)($r['rate'] ?? 1.0);
                if ($rate == 0.0) { $rate = 1.0; }

                $isBase = ((int)$r['currencyId'] === $baseId);

                $conv = function ($v) use ($isBase, $rate) {
                    $v = (float)$v;
                    return $isBase ? $v : ($v / $rate);
                };

                $totals['amount_in']  += $conv($r['amount_in']  ?? 0);
                $totals['fees']       += $conv($r['fees']       ?? 0);
                $totals['amount_out'] += $conv($r['amount_out'] ?? 0);
                $totals['profit']     += $conv($r['profit']     ?? 0);
            }

            return $totals;
        }

        /** Safe average helper. */
        private function avgPerMonth($total, $months)
        {
            $months = (int)$months;
            if ($months <= 0) { return 0.0; }
            return (float)$total / $months;
        }

        public function generateOutput($data)
        {
            if (!empty($data['error'])) {
                return '<div class="widget-content-padded"><strong>Error:</strong> '
                    . htmlspecialchars($data['error'], ENT_QUOTES, 'UTF-8')
                    . '<br><small>Generated ' . htmlspecialchars($data['meta']['generated'], ENT_QUOTES, 'UTF-8') . '</small></div>';
            }

            $fmt = function ($prefix, $amount, $suffix) {
                return sprintf('%s%s%s',
                    htmlspecialchars($prefix ?? '', ENT_QUOTES, 'UTF-8'),
                    number_format((float)$amount, 2),
                    htmlspecialchars($suffix ?? '', ENT_QUOTES, 'UTF-8')
                );
            };

            $t   = $data['totals'];
            $m   = $data['meta'];
            $avg = $data['averages'] ?? [];

            $monthBase     = $fmt($t['base']['prefix'] ?? '', $t['month']['amount'] ?? 0,         $t['base']['suffix'] ?? '');
            $prevMonthBase = $fmt($t['base']['prefix'] ?? '', $t['prev_month']['amount'] ?? 0,    $t['base']['suffix'] ?? '');
            $tyBase        = $fmt($t['base']['prefix'] ?? '', $t['tax_year']['amount'] ?? 0,      $t['base']['suffix'] ?? '');
            $lastTyBase    = $fmt($t['base']['prefix'] ?? '', $t['last_tax_year']['amount'] ?? 0, $t['base']['suffix'] ?? '');

            $mAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['month']['income'] ?? 0,          $t['base']['suffix'] ?? '');
            $mAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['month']['expenses'] ?? 0,        $t['base']['suffix'] ?? '');
            $mAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['month']['profit'] ?? 0,          $t['base']['suffix'] ?? '');

            $pmAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['prev_month']['income'] ?? 0,    $t['base']['suffix'] ?? '');
            $pmAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['prev_month']['expenses'] ?? 0,  $t['base']['suffix'] ?? '');
            $pmAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['prev_month']['profit'] ?? 0,    $t['base']['suffix'] ?? '');

            $tyAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['tax_year']['income'] ?? 0,      $t['base']['suffix'] ?? '');
            $tyAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['tax_year']['expenses'] ?? 0,    $t['base']['suffix'] ?? '');
            $tyAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['tax_year']['profit'] ?? 0,      $t['base']['suffix'] ?? '');

            $lastTyAvgIncome   = $fmt($t['base']['prefix'] ?? '', $avg['last_tax_year']['income'] ?? 0,   $t['base']['suffix'] ?? '');
            $lastTyAvgExpenses = $fmt($t['base']['prefix'] ?? '', $avg['last_tax_year']['expenses'] ?? 0, $t['base']['suffix'] ?? '');
            $lastTyAvgProfit   = $fmt($t['base']['prefix'] ?? '', $avg['last_tax_year']['profit'] ?? 0,   $t['base']['suffix'] ?? '');

            $tyMonths = (int)($avg['tax_year']['months'] ?? 0);

            // VAT toggle UI
            $isVatEx   = (($m['vat_mode'] ?? 'inc') === 'ex');
            $vatLabel  = $isVatEx ? 'Excl. VAT' : 'Incl. VAT';
            $vatTo     = $isVatEx ? 'inc' : 'ex';
            $vatTxt    = $isVatEx ? 'Switch to Incl. VAT' : 'Switch to Excl. VAT';
            $vatUrl    = $this->toggleUrl(['pl_vat' => $vatTo]);

            return <<<HTML
<div class="widget-content-padded">
  <div class="clearfix">
    <div class="pull-left">
      <strong>Totals in Base ({$t['base']['code']})</strong>
      <span class="label label-info" style="margin-left:8px;">Mode: Invoice-linked</span>
      <span class="label label-default" style="margin-left:8px;">{$vatLabel}</span>
      <a href="{$vatUrl}" style="margin-left:8px;">{$vatTxt}</a>
    </div>
    <div class="pull-right text-muted" style="font-size:12px">
      Generated {$m['generated']}
    </div>
  </div>

  <table class="table table-condensed" style="margin-top:10px">
    <thead>
      <tr>
        <th></th>
        <th class="text-right">This Month<br><small>({$m['month_label']})</small></th>
        <th class="text-right">Previous Month<br><small>({$m['prev_month_label']})</small></th>
        <th class="text-right">
          Current Tax Year (to date)
          <br><small>({$m['tax_year_label']}: {$m['tax_year_full_range']})</small>
          <br><small class="text-muted">As of {$m['tax_year_asof']}</small>
        </th>
        <th class="text-right">
          Last Tax Year (full)
          <br><small>({$m['last_tax_year_label']}: {$m['last_tax_year_full_range']})</small>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th>Total Profit (Base {$t['base']['code']})</th>
        <td class="text-right">{$monthBase}</td>
        <td class="text-right">{$prevMonthBase}</td>
        <td class="text-right">{$tyBase}</td>
        <td class="text-right">{$lastTyBase}</td>
      </tr>

      <tr>
        <th>
          Average per month (Income, Expenses, Profit)
          <br><small class="text-muted">Current tax year: {$tyMonths}/12 tax months elapsed; last tax year: 12/12</small>
        </th>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$mAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$mAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$mAvgProfit}</div>
        </td>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$pmAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$pmAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$pmAvgProfit}</div>
        </td>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$tyAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$tyAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$tyAvgProfit}</div>
        </td>
        <td class="text-right">
          <div><small class="text-muted">Income</small> {$lastTyAvgIncome}</div>
          <div><small class="text-muted">Expenses</small> {$lastTyAvgExpenses}</div>
          <div><small class="text-muted">Profit</small> {$lastTyAvgProfit}</div>
        </td>
      </tr>
    </tbody>
  </table>

  <p class="text-muted" style="font-size:12px;margin-top:8px;">
    Profit formula: <code>Amount In  Fees  Amount Out</code>.
    UK tax year runs <strong>6 Apr  5 Apr</strong>.
    <br>Average per month uses: <code>Income = Amount In</code>, <code>Expenses = Fees + Amount Out</code>, <code>Profit = Amount In  Fees  Amount Out</code>.
    <br><small>When Excl. VAT is enabled, invoice VAT (tax + tax2) is subtracted from Income and Profit. This is invoice-linked only.</small>
  </p>
</div>
HTML;
        }
    };
});

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated