diff --git a/agent/reports/tax_summary.php b/agent/reports/tax_summary.php index 86a302814..5be9f825a 100644 --- a/agent/reports/tax_summary.php +++ b/agent/reports/tax_summary.php @@ -86,21 +86,19 @@ $sql_tax = mysqli_query($mysqli, "SELECT `tax_name` FROM `taxes`"); if ($view == 'monthly') { + // Row total = sum of this tax’s 12 months, accumulated as we go + $row_total = 0.0; for ($i = 1; $i <= 12; $i++) { $monthly_tax = (float) getMonthlyTax($tax_name, $i, $year, $mysqli); // Accumulate totals $monthly_totals[$i] += $monthly_tax; $grand_total += $monthly_tax; + $row_total += $monthly_tax; echo "" . numfmt_format_currency($currency_format, $monthly_tax, $company_currency) . ""; } - // Row total = sum of this tax’s 12 months - $row_total = 0.0; - for ($i = 1; $i <= 12; $i++) { - $row_total += (float) getMonthlyTax($tax_name, $i, $year, $mysqli); - } echo "" . numfmt_format_currency($currency_format, $row_total, $company_currency) . ""; } else { diff --git a/functions/app.php b/functions/app.php index 0b4af1597..651d291b6 100644 --- a/functions/app.php +++ b/functions/app.php @@ -644,12 +644,20 @@ function checkForUpdates() { } function getMonthlyTax($tax_name, $month, $year, $mysqli) { - // SQL to calculate monthly tax - $sql = "SELECT SUM(item_tax) AS monthly_tax FROM invoice_items - LEFT JOIN invoices ON invoice_items.item_invoice_id = invoices.invoice_id - LEFT JOIN payments ON invoices.invoice_id = payments.payment_invoice_id + // Cash basis - tax is booked to the month the money arrived, in proportion to + // how much of the invoice that payment covered. Driving off payments (rather + // than invoice_items) counts each payment exactly once, and pre-aggregating + // the line items stops a multi-payment invoice multiplying its own tax. + $sql = "SELECT SUM(invoice_tax.tax_total * (payments.payment_amount / invoices.invoice_amount)) AS monthly_tax + FROM payments + INNER JOIN invoices ON invoices.invoice_id = payments.payment_invoice_id + INNER JOIN (SELECT item_invoice_id, SUM(item_tax) AS tax_total + FROM invoice_items + WHERE item_tax_id = (SELECT tax_id FROM taxes WHERE tax_name = '$tax_name') + GROUP BY item_invoice_id) AS invoice_tax + ON invoice_tax.item_invoice_id = invoices.invoice_id WHERE YEAR(payments.payment_date) = $year AND MONTH(payments.payment_date) = $month - AND invoice_items.item_tax_id = (SELECT tax_id FROM taxes WHERE tax_name = '$tax_name')"; + AND invoices.invoice_amount > 0"; $result = mysqli_query($mysqli, $sql); $row = mysqli_fetch_assoc($result); return $row['monthly_tax'] ?? 0; @@ -660,12 +668,17 @@ function getQuarterlyTax($tax_name, $quarter, $year, $mysqli) { $start_month = ($quarter - 1) * 3 + 1; $end_month = $start_month + 2; - // SQL to calculate quarterly tax - $sql = "SELECT SUM(item_tax) AS quarterly_tax FROM invoice_items - LEFT JOIN invoices ON invoice_items.item_invoice_id = invoices.invoice_id - LEFT JOIN payments ON invoices.invoice_id = payments.payment_invoice_id + // SQL to calculate quarterly tax - see getMonthlyTax for why it is shaped this way + $sql = "SELECT SUM(invoice_tax.tax_total * (payments.payment_amount / invoices.invoice_amount)) AS quarterly_tax + FROM payments + INNER JOIN invoices ON invoices.invoice_id = payments.payment_invoice_id + INNER JOIN (SELECT item_invoice_id, SUM(item_tax) AS tax_total + FROM invoice_items + WHERE item_tax_id = (SELECT tax_id FROM taxes WHERE tax_name = '$tax_name') + GROUP BY item_invoice_id) AS invoice_tax + ON invoice_tax.item_invoice_id = invoices.invoice_id WHERE YEAR(payments.payment_date) = $year AND MONTH(payments.payment_date) BETWEEN $start_month AND $end_month - AND invoice_items.item_tax_id = (SELECT tax_id FROM taxes WHERE tax_name = '$tax_name')"; + AND invoices.invoice_amount > 0"; $result = mysqli_query($mysqli, $sql); $row = mysqli_fetch_assoc($result); return $row['quarterly_tax'] ?? 0;