Files
itflow/agent/includes/side_nav.php
johnnyq a2a0823163 Trips stage 2: mileage money - Trips and Mileage in Admin > Settings > Invoice with miles or kilometers, the rate an agent is paid back for their own vehicle and the expense category it goes under, and what a trip bills a client as a trip charge, a rate a mile beyond the distance the charge covers and the invoice line name; the trip form has In their own vehicle starting as the driver's latest trip and Bill the client starting as the ticket is billable, each showing what it pays back or bills; the list gets To pay back and To bill pills, an owed card (Owed to you for agents without financial access), who is owed what and marks on each row; Pay Mileage pays one driver for the ticked trips at the usual or a past rate as a mileage expense per client paid personally by them under the mileage category to a Mileage vendor made on first use, paid back there and then from an account or later with Reimburse; Unbilled Time has Travel to bill beside the expenses at an editable price going on the client's invoice with their tickets and expenses, billing every client includes trips and Not billable writes them off; the invoice gets a Travel card with Add Trips and Take off Invoice, and deleting the line or invoice makes a trip to bill again; paid back and billed trips keep their distance, driver, vehicle, client and billable and can't be deleted, and deleting the mileage expense puts its trips back to pay; bulk Set Vehicle, Set Billable and Pay Mileage; the trip quick look shows what it pays back and bills and the mileage expense lists its trips; dashboard Trips to bill and Mileage to pay back, client overview Trips to bill and the Unbilled Time count include trips; export Vehicle, Paid Back and Billing columns; the Mileage report and dashboard chart follow the unit and the report rate starts at the mileage rate; demo data with recent trips in own vehicles and billable when trips bill; database 3.0.4 with trip_own_vehicle, trip_expense_id, trip_billable, trip_invoice_id, trip_invoice_item_id and the mileage and trip billing settings; CHANGELOG updated
2026-10-16 20:35:51 -04:00

303 lines
18 KiB
PHP

<!-- Main Sidebar Container -->
<aside class="app-sidebar shadow d-print-none" data-bs-theme="dark">
<?php
/*
* The company name goes to your own company's client record once one is designated in
* Admin > Settings > Company Details, and falls back to the dashboard otherwise. The
* access check keeps a restricted agent from being sent to a client they would only be
* bounced off, and costs no query - the permission arrays are already in the session.
*/
$brand_link = "/agent/dashboard.php";
if (!empty($config_internal_client_id) && lookupUserPermission("module_client") >= 1 && hasClientAccess($config_internal_client_id)) {
$brand_link = "/agent/client_overview.php?client_id=" . intval($config_internal_client_id);
}
/*
* The company's mark: the logo from Admin > Settings > Company Details on a light
* tile, or the company's initials on the theme colour when there is none (or the
* file has gone missing). The tile grows sideways for a wide logo rather than
* shrinking it to a postage stamp. The name wraps to two lines, then ellipses -
* the full name is in the tooltip.
*/
$brand_logo = basename((string) ($session_company_logo ?? ''));
if ($brand_logo === '' || !is_file(__DIR__ . "/../../uploads/settings/$brand_logo")) {
$brand_logo = '';
}
$brand_name = escapeHtml($session_company_name);
?>
<div class="sidebar-brand itflow-brand">
<a class="brand-link itflow-brand-link" href="<?= $brand_link ?>" title="<?= $brand_name ?>">
<?php if ($brand_logo) { ?>
<span class="itflow-brand-mark itflow-brand-mark-logo">
<img src="/uploads/settings/<?= escapeHtml(rawurlencode($brand_logo)) ?>" alt="" decoding="async">
</span>
<?php } else { ?>
<span class="itflow-brand-mark itflow-brand-mark-initials" aria-hidden="true"><?= escapeHtml(clientInitials('', $session_company_name)) ?></span>
<?php } ?>
<span class="itflow-brand-name"><?= $brand_name ?></span>
</a>
</div>
<!-- Sidebar -->
<div class="sidebar-wrapper">
<!-- Sidebar Menu -->
<nav>
<ul class="nav nav-pills sidebar-menu flex-column mt-3" data-lte-toggle="treeview" data-accordion="false">
<li class="nav-item">
<a href="/agent/dashboard.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "dashboard.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-tachometer-alt"></i>
<p>Dashboard</p>
</a>
</li>
<?php if (lookupUserPermission("module_client") >= 1) { ?>
<li class="nav-item">
<a href="/agent/clients.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "clients.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-users"></i>
<p>
Clients
<?php if ($num_active_clients) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Active Clients"><?= $num_active_clients ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/contacts.php" class="nav-link">
<i class="fas fa-layer-group nav-icon"></i>
<p>All Client Docs</p>
<i class="fas fa-angle-right nav-icon float-end"></i>
</a>
</li>
<?php } ?>
<li class="nav-item">
<a href="/agent/vendors.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php" || basename($_SERVER["PHP_SELF"]) == "vendor.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-building"></i>
<p>Vendors</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/calendar.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-calendar-alt"></i>
<p>Calendar</p>
</a>
</li>
<?php if (lookupUserPermission("module_support") >= 1) { ?>
<?php if ($config_module_enable_ticketing == 1) { ?>
<li class="nav-header mt-3">SUPPORT</li>
<li class="nav-item">
<a href="/agent/tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-life-ring"></i>
<p>
Tickets
<?php if ($num_active_tickets) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Open Tickets"><?= $num_active_tickets ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/recurring_tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Tickets
<?php if ($num_recurring_tickets) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Active Recurring Tickets"><?= $num_recurring_tickets ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/projects.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-project-diagram"></i>
<p>
Projects
<?php if ($num_active_projects) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Open Projects"><?= $num_active_projects ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php } ?>
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_sales") >= 1) { ?>
<li class="nav-header mt-3">BILLING</li>
<li class="nav-item">
<a href="/agent/quotes.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-comment-dollar"></i>
<p>
Quotes
<?php if ($num_open_quotes) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Active Quotes"><?= $num_open_quotes ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-file-invoice"></i>
<p>
Invoices
<?php if ($num_open_invoices) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Open Invoices"><?= $num_open_invoices ?></span>
<?php } ?>
</p>
</a>
</li>
<?php if ($config_module_enable_ticketing == 1 || lookupUserPermission('module_financial') >= 1) { ?>
<li class="nav-item">
<a href="/agent/unbilled_time.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "unbilled_time.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-user-clock"></i>
<p>
Unbilled Time
<?php if ($num_unbilled_tickets || $num_unbilled_expenses || $num_unbilled_trips) {
// "4 billable tickets done, 2 expenses and 1 trip to bill, not invoiced"
$unbilled_parts = array_values(array_filter([
"$num_unbilled_tickets billable ticket" . ($num_unbilled_tickets == 1 ? '' : 's') . ' done',
$num_unbilled_expenses ? "$num_unbilled_expenses expense" . ($num_unbilled_expenses == 1 ? '' : 's') : '',
$num_unbilled_trips ? "$num_unbilled_trips trip" . ($num_unbilled_trips == 1 ? '' : 's') : '',
]));
$unbilled_last = count($unbilled_parts) > 1 ? array_pop($unbilled_parts) : '';
$unbilled_title = $unbilled_last === '' ? 'Billable tickets done, not invoiced' : implode(', ', $unbilled_parts) . " and $unbilled_last to bill, not invoiced"; ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="<?= escapeHtml($unbilled_title) ?>"><?= $num_unbilled_tickets + $num_unbilled_expenses + $num_unbilled_trips ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<li class="nav-item">
<a href="/agent/recurring_invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Invoices
<?php if ($num_recurring_invoices) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Active Recurring Invoices"><?= $num_recurring_invoices ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/products.php" class="nav-link <?php if (in_array(basename($_SERVER["PHP_SELF"]), ['products.php', 'product.php', 'products_count.php'], true)) { echo "active"; } ?>">
<i class="nav-icon fas fa-box-open"></i>
<p>
Products
<?php if (!empty($num_products_reorder)) { ?>
<span class="right badge text-bg-warning" data-bs-toggle="tooltip" title="To reorder"><?= intval($num_products_reorder) ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php if ($config_module_enable_accounting == 1) { ?>
<li class="nav-header mt-3">FINANCE</li>
<?php if (lookupUserPermission("module_financial") >= 1) { ?>
<li class="nav-item">
<a href="/agent/income.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "income.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-hand-holding-usd"></i>
<p>Income</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "expenses.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-shopping-cart"></i>
<p>Expenses</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/recurring_expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_expenses.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Expenses
<?php if ($num_recurring_expenses) { ?>
<span class="right badge text-light" data-bs-toggle="tooltip" title="Recurring Expenses"><?= $num_recurring_expenses ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php // Everyone logs their driving - without Financial access, their own trips ?>
<li class="nav-item">
<a href="/agent/trips.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-route"></i>
<p>Trips</p>
</a>
</li>
<?php if (lookupUserPermission("module_financial") >= 1) { ?>
<li class="nav-item">
<a href="/agent/accounts.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "accounts.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-piggy-bank"></i>
<p>Accounts</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/transactions.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "transactions.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-list-alt"></i>
<p>Transactions</p>
</a>
</li>
<li class="nav-item">
<a href="/agent/transfers.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "transfers.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-exchange-alt"></i>
<p>Transfers</p>
</a>
</li>
<?php } ?>
<?php } ?>
<?php if (lookupUserPermission("module_reporting") >= 1) { ?>
<li class="nav-header mt-3">TOOLS</li>
<li class="nav-item">
<a href="/agent/reports/" class="nav-link">
<i class="fas fa-chart-line nav-icon"></i>
<p>Reports</p>
<i class="fas fa-angle-right nav-icon float-end"></i>
</a>
</li>
<?php } ?>
<?php
$sql_custom_links = mysqli_query($mysqli, "SELECT custom_link_icon, custom_link_name, custom_link_new_tab, custom_link_uri FROM custom_links WHERE custom_link_location = 1 AND custom_link_archived_at IS NULL
ORDER BY custom_link_order ASC, custom_link_name ASC"
);
while ($row = mysqli_fetch_assoc($sql_custom_links)) {
$custom_link_name = escapeHtml($row['custom_link_name']);
$custom_link_uri = escapeUrl($row['custom_link_uri']);
$custom_link_icon = escapeHtml($row['custom_link_icon']);
$custom_link_new_tab = intval($row['custom_link_new_tab']);
if ($custom_link_new_tab == 1) {
$target = "target='_blank' rel='noopener noreferrer'";
} else {
$target = "";
}
?>
<li class="nav-item">
<a href="<?= $custom_link_uri ?>" <?= $target ?> class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == basename($custom_link_uri)) { echo "active"; } ?>">
<i class="fas fa-<?= $custom_link_icon ?> nav-icon"></i>
<p><?= $custom_link_name ?></p>
<i class="fas fa-angle-right nav-icon float-end"></i>
</a>
</li>
<?php } ?>
</ul>
</nav>
<!-- /.sidebar-menu -->
<div class="mb-3"></div>
</div>
<!-- /.sidebar -->
</aside>