Files
itflow/api/v1/taxes/read.php
johnnyq cd565b73c7 Taxes stage 2: Tax Collected report rebuilt for filing with an Invoiced basis (each sent invoice in the month of its date) or Paid basis (each payment carrying its share of its invoice), tax by part of each rate with registration numbers so a state's and a county's parts count apart and parts named alike add up in one row, sales before tax and net of discounts split into taxable, exempt and non-taxable, tax paid on purchases by part and net tax collected less paid, exempt sales by client with certificate and expiry, quarterly or monthly with a chart and CSV export of the tax table or the exempt sales, archived payments left out; expenses and recurring expenses record the tax included in them with a rate worked out from the amount as typed or typed over from the receipt, a tax amount with no rate allowed, refunds giving their tax back, recurring expenses copying it to each expense recorded, vendor defaults filling it in, and the list and quick looks showing it; exports gain invoice subtotal, discount, tax and tax by part, quote and recurring invoice tax, expense before tax, tax and tax rate, and client tax rate and exemption columns; API adds a taxes read endpoint with each rate's parts, subtotal, tax, tax by part and registration numbers on invoice and quote reads, and each line's rate on invoice item reads; Admin > Taxes explains naming parts alike and links the report; demo data names Allegheny County's state part PA Sales Tax and taxes the company's own-use purchases; removes the unused getMonthlyTax and getQuarterlyTax; database 3.1.2 adds expense and recurring expense tax rate and amount; changelog updated
2026-10-17 13:27:53 -04:00

63 lines
2.5 KiB
PHP

<?php
/*
* API - Taxes - Read
* GET /api/v1/taxes/read.php
*
* The tax rates, each with the parts it is made of.
*
* Parameters (GET):
* api_key required - Your API key
* tax_id optional - One rate (archived or not)
* archived optional - 1 to include archived rates in the list
* limit optional - Max rows to return (default 50)
* offset optional - Offset for pagination (default 0)
*
* Each rate: tax_id, tax_name, tax_percent (the whole rate), tax_description,
* tax_registration_number, tax_archived_at, tax_replaced_by (the rate a
* changed rate was replaced by, else 0), tax_default (the default for new
* lines) and tax_components - name, percent, compound (charged on top of the
* parts above) and registration_number - one for a rate without parts.
*
* Rates aren't client-scoped; access is gated by module_sales in enforce_api_rbac.php.
*/
require_once '../validate_api_key.php';
require_once '../require_get_method.php';
if (isset($_GET['tax_id'])) {
$id = intval($_GET['tax_id']);
$sql = mysqli_query($mysqli, "SELECT tax_id FROM taxes WHERE tax_id = $id");
} else {
$archived = intval($_GET['archived'] ?? 0) === 1 ? '' : 'WHERE tax_archived_at IS NULL';
$sql = mysqli_query($mysqli, "SELECT tax_id FROM taxes $archived ORDER BY tax_name ASC, tax_id ASC LIMIT $limit OFFSET $offset");
}
if ($sql && mysqli_num_rows($sql) > 0) {
$default_id = taxSettings()['default_id'];
$rows = [];
while ($id_row = mysqli_fetch_row($sql)) {
$tax = taxRow($id_row[0]);
$rows[] = [
'tax_id' => intval($tax['tax_id']),
'tax_name' => $tax['tax_name'],
'tax_percent' => floatval($tax['tax_percent']),
'tax_description' => $tax['tax_description'],
'tax_registration_number' => $tax['tax_registration_number'],
'tax_archived_at' => $tax['tax_archived_at'],
'tax_replaced_by' => intval($tax['tax_replaced_by']),
'tax_default' => intval($tax['tax_id']) === $default_id,
'tax_components' => array_map(function ($part) use ($tax) {
return ['name' => $part['name'], 'percent' => $part['percent'], 'compound' => $part['compound'],
'registration_number' => $part['registration'] !== '' ? $part['registration'] : (string) $tax['tax_registration_number']];
}, $tax['components']),
];
}
echo json_encode(['success' => 'True', 'count' => count($rows), 'data' => $rows]);
exit();
}
// Output
require_once "../read_output.php";