= 1; $can_edit_payments = incomeCanEditPayments(); $can_delete_payments = incomeCanDeletePayments(); $client_filter = $client_page ? intval($client_id) : intval($_GET['client'] ?? 0); $category_filter = intval($_GET['category'] ?? 0); $account_filter = intval($_GET['account'] ?? 0); $method_filter = (string) ($_GET['method'] ?? ''); $shows = incomeShows(); $show = incomeShowFrom($_GET); $more_filters = $account_filter || $method_filter !== ''; // Only these sort - filter_header.php hands through any lowercase word $sortable_columns = ['income_date' => 'income.income_date', 'income_amount' => 'income.income_amount', 'client_name' => 'income.client_name', 'category_name' => 'income.category_name', 'account_name' => 'income.account_name', 'income_type' => 'income.income_type']; if (!isset($sortable_columns[$sort])) { $sort = 'income_date'; } // Everything but the pill, then the pill - the pill counts are over what the rest leave $filter_src = array_merge($_GET, ['dtf' => $dtf, 'dtt' => $dtt, 'client' => $client_filter, 'show' => $show, 'type' => '']); $where = incomeFiltersSql($filter_src, $summary, false); $show_query = $show !== '' ? 'AND ' . $shows[$show]['where'] : ''; $union = incomeUnionSql(); $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS income.* FROM ($union) AS income WHERE $where $show_query ORDER BY {$sortable_columns[$sort]} $order, income.income_created_at DESC, income.income_id DESC LIMIT $record_from, $record_to"); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $rows = []; while ($row = mysqli_fetch_assoc($sql)) { $rows[] = $row; } // The pills, and the total of what is listed $count_sql = []; foreach ($shows as $key => $s) { $count_sql[] = $key === '' ? 'COUNT(*)' : "COALESCE(SUM({$s['where']}), 0)"; } $row = mysqli_fetch_row(mysqli_query($mysqli, "SELECT " . implode(', ', $count_sql) . ", COALESCE(SUM(CASE WHEN 1 $show_query THEN income.income_amount END), 0) FROM ($union) AS income WHERE $where")); $counts = []; foreach (array_keys($shows) as $i => $key) { $counts[$key] = intval($row[$i]); } $listed_total = floatval($row[count($shows)]); $stats = incomeStats($client_page ? $client_id : 0); $money = function ($amount, $currency = '') { return escapeHtml(billingMoney($amount, $currency)); }; $filter_url = function ($changes) use ($client_page, $client_id) { $params = array_merge($_GET, $changes); unset($params['page'], $params['type']); if ($client_page) { $params['client_id'] = $client_id; } return '?' . http_build_query(array_filter($params, function ($v) { return $v !== '' && $v !== null; })); }; $date_url = function ($from, $to, $changes = []) use ($filter_url) { return $filter_url(array_merge(['canned_date' => 'custom', 'dtf' => $from, 'dtt' => $to], $changes)); }; $any_filter = $q || ($client_filter && !$client_page) || $category_filter || $account_filter || $method_filter !== '' || $show !== '' || $dtf !== '1970-01-01'; $add_url = 'modals/revenue/revenue_add.php' . ($client_page ? "?client_id=$client_id" : ''); $invoices_url = 'invoices.php?' . ($client_page ? "client_id=$client_id&" : '') . 'status=Unpaid'; ?>
This month
% on the same days of Nothing in by now last month
so far
a month on average
">
Recurring
a month
Still owed
0 ? ' · ' . $money($stats['overdue']) . ' late' : '' ?>

Income

Date From Category Client Paid into Amount
>
- An invoice since deleted
Online
No category
-
Archived
count($rows) ? ' - the total is for all of them, not just this page' : '' ?>
'income', 'icon' => 'fa-hand-holding-usd', 'filtered' => $q || ($client_filter && !$client_page) || $category_filter || $account_filter || $method_filter !== '' || $dtf !== '1970-01-01', 'views' => ['show'], 'view' => emptyStatePill($shows, $show, '', ['uncategorised']), 'match_title' => 'No income matches', 'text' => "A payment is added on its invoice. Money in that isn't for an invoice is New Income here.", 'actions' => $can_edit ? [ ['label' => 'New Income', 'modal' => $add_url, 'size' => 'lg'], ['label' => 'Import Deposits', 'href' => 'income_import.php', 'icon' => 'fa-file-import'], ] : [], ]; require_once "../includes/filter_footer.php"; ?>