155 lines
4.6 KiB
PHP
155 lines
4.6 KiB
PHP
<?php
|
|
/**
|
|
* Monthly Tax Report API
|
|
* GET /v1/reports/tax-summary
|
|
* Returns monthly summary of tax, revenue, and invoice statistics
|
|
*/
|
|
|
|
use App\Core\Database;
|
|
use App\Middleware\AuthMiddleware;
|
|
|
|
$decoded = AuthMiddleware::check();
|
|
$db = Database::getInstance();
|
|
|
|
$tenantId = $decoded['tenant_id'];
|
|
$role = $decoded['role'];
|
|
$companyId = $_GET['company_id'] ?? null;
|
|
$month = $_GET['month'] ?? date('m');
|
|
$year = $_GET['year'] ?? date('Y');
|
|
|
|
$where = ["MONTH(i.created_at) = ? AND YEAR(i.created_at) = ?"];
|
|
$params = [$month, $year];
|
|
|
|
if ($role !== 'super_admin') {
|
|
$where[] = 'i.tenant_id = ?';
|
|
$params[] = $tenantId;
|
|
}
|
|
|
|
if ($companyId) {
|
|
$where[] = 'i.company_id = ?';
|
|
$params[] = $companyId;
|
|
}
|
|
|
|
$whereClause = 'WHERE ' . implode(' AND ', $where);
|
|
|
|
// 1. Main aggregation
|
|
$stmt = $db->prepare("
|
|
SELECT
|
|
COUNT(*) as total_invoices,
|
|
SUM(CASE WHEN status = 'approved' OR status = 'submitted' THEN 1 ELSE 0 END) as approved_count,
|
|
SUM(CASE WHEN status = 'extracted' THEN 1 ELSE 0 END) as pending_count,
|
|
SUM(CASE WHEN status = 'submitted' THEN 1 ELSE 0 END) as submitted_count,
|
|
COALESCE(SUM(subtotal), 0) as total_subtotal,
|
|
COALESCE(SUM(tax_amount), 0) as total_tax,
|
|
COALESCE(SUM(discount_total), 0) as total_discount,
|
|
COALESCE(SUM(grand_total), 0) as total_grand,
|
|
COALESCE(AVG(grand_total), 0) as avg_invoice_amount,
|
|
COALESCE(MAX(grand_total), 0) as max_invoice_amount,
|
|
COALESCE(MIN(grand_total), 0) as min_invoice_amount
|
|
FROM invoices i
|
|
$whereClause
|
|
");
|
|
$stmt->execute($params);
|
|
$summary = $stmt->fetch();
|
|
|
|
// 2. Daily breakdown for chart
|
|
$stmtDaily = $db->prepare("
|
|
SELECT
|
|
DAY(i.created_at) as day_num,
|
|
COUNT(*) as count,
|
|
COALESCE(SUM(grand_total), 0) as daily_total,
|
|
COALESCE(SUM(tax_amount), 0) as daily_tax
|
|
FROM invoices i
|
|
$whereClause
|
|
GROUP BY DAY(i.created_at)
|
|
ORDER BY day_num
|
|
");
|
|
$stmtDaily->execute($params);
|
|
$dailyBreakdown = $stmtDaily->fetchAll();
|
|
|
|
// 3. Invoice type breakdown
|
|
$stmtType = $db->prepare("
|
|
SELECT
|
|
invoice_type,
|
|
COUNT(*) as count,
|
|
COALESCE(SUM(grand_total), 0) as total
|
|
FROM invoices i
|
|
$whereClause
|
|
GROUP BY invoice_type
|
|
");
|
|
$stmtType->execute($params);
|
|
$typeBreakdown = $stmtType->fetchAll();
|
|
|
|
// 4. Top 5 suppliers
|
|
$stmtSuppliers = $db->prepare("
|
|
SELECT
|
|
supplier_name,
|
|
COUNT(*) as invoice_count,
|
|
COALESCE(SUM(grand_total), 0) as total_amount
|
|
FROM invoices i
|
|
$whereClause
|
|
GROUP BY supplier_name
|
|
ORDER BY total_amount DESC
|
|
LIMIT 5
|
|
");
|
|
$stmtSuppliers->execute($params);
|
|
$topSuppliers = $stmtSuppliers->fetchAll();
|
|
|
|
// Decrypt supplier names
|
|
foreach ($topSuppliers as &$s) {
|
|
$decrypted = \App\Core\Encryption::decrypt($s['supplier_name']);
|
|
$s['supplier_name'] = ($decrypted !== false && $decrypted !== null) ? $decrypted : $s['supplier_name'];
|
|
}
|
|
unset($s);
|
|
|
|
// 5. Comparison with previous month
|
|
$prevMonth = $month == 1 ? 12 : $month - 1;
|
|
$prevYear = $month == 1 ? $year - 1 : $year;
|
|
|
|
$prevWhere = str_replace(
|
|
"MONTH(i.created_at) = ? AND YEAR(i.created_at) = ?",
|
|
"MONTH(i.created_at) = ? AND YEAR(i.created_at) = ?",
|
|
implode(' AND ', $where)
|
|
);
|
|
|
|
$prevParams = [$prevMonth, $prevYear];
|
|
if ($role !== 'super_admin') $prevParams[] = $tenantId;
|
|
if ($companyId) $prevParams[] = $companyId;
|
|
|
|
$stmtPrev = $db->prepare("
|
|
SELECT
|
|
COUNT(*) as total_invoices,
|
|
COALESCE(SUM(grand_total), 0) as total_grand,
|
|
COALESCE(SUM(tax_amount), 0) as total_tax
|
|
FROM invoices i
|
|
WHERE MONTH(i.created_at) = ? AND YEAR(i.created_at) = ?
|
|
" . ($role !== 'super_admin' ? " AND i.tenant_id = ?" : "")
|
|
. ($companyId ? " AND i.company_id = ?" : "")
|
|
);
|
|
$stmtPrev->execute($prevParams);
|
|
$previous = $stmtPrev->fetch();
|
|
|
|
// Calculate growth
|
|
$growth = [
|
|
'invoices' => $previous['total_invoices'] > 0
|
|
? round((($summary['total_invoices'] - $previous['total_invoices']) / $previous['total_invoices']) * 100, 1)
|
|
: 0,
|
|
'revenue' => $previous['total_grand'] > 0
|
|
? round((($summary['total_grand'] - $previous['total_grand']) / $previous['total_grand']) * 100, 1)
|
|
: 0,
|
|
'tax' => $previous['total_tax'] > 0
|
|
? round((($summary['total_tax'] - $previous['total_tax']) / $previous['total_tax']) * 100, 1)
|
|
: 0,
|
|
];
|
|
|
|
json_success([
|
|
'month' => (int)$month,
|
|
'year' => (int)$year,
|
|
'summary' => $summary,
|
|
'daily_breakdown' => $dailyBreakdown,
|
|
'type_breakdown' => $typeBreakdown,
|
|
'top_suppliers' => $topSuppliers,
|
|
'previous_month' => $previous,
|
|
'growth' => $growth,
|
|
], 'تقرير ضريبة المبيعات الشهري');
|