= 2; $can_delete = lookupUserPermission('module_financial') >= 3; $vendor_filter = intval($_GET['vendor'] ?? 0); $category_filter = intval($_GET['category'] ?? 0); $client_filter = intval($_GET['client'] ?? 0); $statuses = recurringExpenseShows(); $status = isset($statuses[$_GET['status'] ?? '']) ? (string) $_GET['status'] : 'active'; $status_query = $statuses[$status]['where'] ? 'AND ' . $statuses[$status]['where'] : ''; // Only these sort - filter_header.php hands through any lowercase word $sortable_columns = ['recurring_expense_next_date' => 'recurring_expense_next_date', 'vendor_name' => 'vendor_name', 'category_name' => 'category_name', 'client_name' => 'client_name', 'recurring_expense_amount' => 'recurring_expense_amount', 'monthly' => 'monthly', 'recurring_expense_last_sent' => 'recurring_expense_last_sent']; if (!isset($sortable_columns[$sort])) { $sort = 'recurring_expense_next_date'; } $joins = "LEFT JOIN vendors ON recurring_expense_vendor_id = vendor_id LEFT JOIN categories ON recurring_expense_category_id = category_id LEFT JOIN accounts ON recurring_expense_account_id = account_id LEFT JOIN clients ON recurring_expense_client_id = client_id"; $where = recurringExpenseFiltersSql($_GET); $monthly_sql = expenseRecurringMonthlySql(); $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS recurring_expenses.*, vendor_name, vendor_archived_at, category_name, category_color, category_icon, account_name, client_name, $monthly_sql AS monthly, recurring_invoice_prefix, recurring_invoice_number FROM recurring_expenses $joins LEFT JOIN recurring_invoices ON recurring_invoice_id = recurring_expense_recurring_invoice_id WHERE $where $status_query ORDER BY {$sortable_columns[$sort]} $order, recurring_expense_id ASC LIMIT $record_from, $record_to"); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $recurring_expenses = []; while ($row = mysqli_fetch_assoc($sql)) { $recurring_expenses[] = $row; } // The pills - over what the filters leave $count_sql = []; foreach ($statuses as $key => $s) { $count_sql[] = $s['where'] === '' ? 'COUNT(*)' : "COALESCE(SUM({$s['where']}), 0)"; } $row = mysqli_fetch_row(mysqli_query($mysqli, "SELECT " . implode(', ', $count_sql) . " FROM recurring_expenses $joins WHERE $where")); $counts = []; foreach (array_keys($statuses) as $i => $key) { $counts[$key] = intval($row[$i]); } // The money along the top - every recurring expense the agent can see, not narrowed by search or pill $scope = "recurring_expense_archived_at IS NULL " . clientScopeSql('recurring_expense_client_id'); $money = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COALESCE(SUM(CASE WHEN recurring_expense_status = 1 THEN $monthly_sql END), 0) AS monthly, COALESCE(SUM(recurring_expense_status = 1), 0) AS running, COALESCE(SUM(recurring_expense_status = 0), 0) AS stopped, COALESCE(SUM(recurring_expense_status = 1 AND recurring_expense_next_date < CURDATE()), 0) AS late FROM recurring_expenses WHERE $scope")); $soon_to = date('Y-m-d', strtotime('+30 days')); $soon_amount = 0.0; $soon_runs = 0; $sql_soon = mysqli_query($mysqli, "SELECT recurring_expenses.* FROM recurring_expenses WHERE $scope AND recurring_expense_status = 1 AND recurring_expense_next_date <= '$soon_to'"); while ($soon = mysqli_fetch_assoc($sql_soon)) { $runs = count(recurringExpenseRunsUntil($soon, $soon_to)); $soon_runs += $runs; $soon_amount += $runs * floatval($soon['recurring_expense_amount']); } $filter_url = function ($changes) { $params = array_merge($_GET, $changes); unset($params['page']); return '?' . http_build_query(array_filter($params, function ($v) { return $v !== '' && $v !== null; })); }; $stat_money = function ($amount) use ($session_company_currency) { return escapeHtml(billingMoney($amount, $session_company_currency)); }; $any_filter = $q || $vendor_filter || $category_filter || $client_filter; ?>
| Vendor | Category | Client | Amount | A month | Next | Last | |
|---|---|---|---|---|---|---|---|
|
= vendorTile((string) $row['vendor_name'], 'xs') ?>
>= escapeHtml($row['vendor_name'] ?: 'No vendor') ?>
= escapeHtml((string) $row['recurring_expense_description']) ?: ' ' ?>
|
= expenseCategoryDot($row['category_color'], $row['category_icon'] ?? '') ?>= escapeHtml($row['category_name'] ?: '-') ?> |
Covered by = escapeHtml($row['recurring_invoice_prefix'] . $row['recurring_invoice_number']) ?>
Billed on
-
|
= escapeHtml(billingMoney($row['recurring_expense_amount'], $row_currency)) ?>
= escapeHtml(recurringInvoiceFrequencies()[$row['recurring_expense_frequency']] ?? 'Monthly') ?>
|
= escapeHtml(billingMoney($row['monthly'], $row_currency)) ?> |
= $row_state === 'ended' ? '' : escapeHtml($row_next) ?>
= recurringExpenseNextPill($row) ?>
Ends = escapeHtml($row['recurring_expense_end_date']) ?>
|
= escapeHtml($row['recurring_expense_last_sent']) ?> Not yet |
|