mirror of
https://github.com/itflow-org/itflow
synced 2026-02-28 19:04:52 +00:00
rename /user/ to /agent/ and update links to use agent/ instead
This commit is contained in:
107
agent/reports/budget.php
Normal file
107
agent/reports/budget.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_expense_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(expense_date) AS expense_year FROM expenses WHERE expense_category_id > 0 ORDER BY expense_year DESC");
|
||||
|
||||
$categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Expense' ORDER BY category_name ASC");
|
||||
$monthlyTotals = array_fill(1, 12, 0); // Initialize monthly totals for each month
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Annual Budget</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_expense_years)) {
|
||||
$expense_year = $row['expense_year'];
|
||||
?>
|
||||
<option <?php if ($year == $expense_year) { ?> selected <?php } ?> > <?php echo $expense_year; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<canvas id="cashFlow" width="100%" height="20"></canvas>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead class="text-dark">
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-right">January</th>
|
||||
<th class="text-right">February</th>
|
||||
<th class="text-right">March</th>
|
||||
<th class="text-right">April</th>
|
||||
<th class="text-right">May</th>
|
||||
<th class="text-right">June</th>
|
||||
<th class="text-right">July</th>
|
||||
<th class="text-right">August</th>
|
||||
<th class="text-right">September</th>
|
||||
<th class="text-right">October</th>
|
||||
<th class="text-right">November</th>
|
||||
<th class="text-right">December</th>
|
||||
<th class="text-right">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if ($categories->num_rows > 0) {
|
||||
while($category = $categories->fetch_assoc()) {
|
||||
echo "<tr>";
|
||||
echo "<td>" . nullable_htmlentities($category['category_name']) . "</td>";
|
||||
$categoryTotal = 0;
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
// Fetch the monthly budget for this category for 2022
|
||||
$sql = "SELECT budget_amount FROM budget WHERE budget_category_id = " . $category['category_id'] . " AND budget_month = $month AND budget_year = $year";
|
||||
$result = $mysqli->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$budget = $result->fetch_assoc();
|
||||
$amount = $budget['budget_amount'];
|
||||
$categoryTotal += $amount;
|
||||
$monthlyTotals[$month] += $amount;
|
||||
echo "<td class='text-right'>" . $amount . "</td>";
|
||||
} else {
|
||||
echo "<td class='text-right'>0</td>";
|
||||
}
|
||||
}
|
||||
echo "<td class='text-right'>" . $categoryTotal . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
|
||||
// Displaying the monthly totals row
|
||||
echo "<tr><td><strong>Total</strong></td>";
|
||||
$grandTotal = 0;
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$grandTotal += $monthlyTotals[$month];
|
||||
echo "<td class='text-right'>" . $monthlyTotals[$month] . "</td>";
|
||||
}
|
||||
echo "<td class='text-right'>" . $grandTotal . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php";
|
||||
?>
|
||||
85
agent/reports/clients_with_balance.php
Normal file
85
agent/reports/clients_with_balance.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-exclamation-triangle mr-2"></i>Clients with a Balance</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<?php
|
||||
$sql_clients = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
clients.client_id,
|
||||
clients.client_name,
|
||||
IFNULL(SUM(invoices.invoice_amount), 0) - IFNULL(SUM(payments.payment_amount), 0) AS balance
|
||||
FROM
|
||||
clients
|
||||
LEFT JOIN
|
||||
invoices
|
||||
ON
|
||||
clients.client_id = invoices.invoice_client_id
|
||||
AND invoices.invoice_status != 'Draft'
|
||||
AND invoices.invoice_status != 'Cancelled'
|
||||
AND invoice_status != 'Non-Billable'
|
||||
LEFT JOIN
|
||||
(SELECT
|
||||
payment_invoice_id,
|
||||
SUM(payment_amount) as payment_amount
|
||||
FROM payments
|
||||
GROUP BY payment_invoice_id) as payments
|
||||
ON
|
||||
invoices.invoice_id = payments.payment_invoice_id
|
||||
GROUP BY
|
||||
clients.client_id,
|
||||
clients.client_name
|
||||
HAVING
|
||||
balance > 0
|
||||
ORDER BY
|
||||
balance DESC
|
||||
");
|
||||
|
||||
?>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Balance</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
$balance = floatval($row['balance']);
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><a href="../../agent/invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../includes/footer.php";
|
||||
|
||||
75
agent/reports/credential_rotation.php
Normal file
75
agent/reports/credential_rotation.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_credential');
|
||||
|
||||
// TODO: Default to 90 but allow input field to change this
|
||||
if (isset($_GET['days'])) {
|
||||
$days = intval($_GET['days']);
|
||||
} else {
|
||||
$days = 90;
|
||||
}
|
||||
|
||||
$passwords_not_rotated_sql = mysqli_query($mysqli,
|
||||
"SELECT credential_id, credential_name, credential_description, credential_password_changed_at, credential_client_id, client_id, client_name
|
||||
FROM credentials
|
||||
LEFT JOIN clients ON credential_client_id = client_id
|
||||
WHERE DATE(credential_password_changed_at) < DATE_SUB(CURDATE(), INTERVAL $days DAY)
|
||||
ORDER BY client_name"
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Client credentials not changed/rotated in the last 90 days</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Credential Name</th>
|
||||
<th class="text-right">Credential Description</th>
|
||||
<th class="text-right">Credential Password Last Changed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($passwords_not_rotated_sql)) {
|
||||
|
||||
$credential_id = intval($row['credential_id']);
|
||||
$credential_name = nullable_htmlentities($row['credential_name']);
|
||||
$credential_description = nullable_htmlentities($row['credential_description']);
|
||||
$credential_password_changed = nullable_htmlentities($row['credential_password_changed_at']);
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $client_name; ?></td>
|
||||
<td class="text-right"><?php echo $credential_name; ?></td>
|
||||
<td class="text-right"><?php echo $credential_description; ?></td>
|
||||
<td class="text-right"><?php echo timeAgo($credential_password_changed) . " (" . $credential_password_changed . ")" ?></td>
|
||||
</tr>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../includes/footer.php";
|
||||
|
||||
97
agent/reports/expense_by_vendor.php
Normal file
97
agent/reports/expense_by_vendor.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
if ($_GET['year'] === 'all') {
|
||||
$year = 'all';
|
||||
} else {
|
||||
$year = intval($_GET['year']);
|
||||
}
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_payment_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(payment_date) AS payment_year FROM payments
|
||||
UNION SELECT DISTINCT YEAR(revenue_date) AS payment_year FROM revenues
|
||||
ORDER BY payment_year DESC"
|
||||
);
|
||||
|
||||
$year_condition = ($year == 'all') ? "" : "AND YEAR(expense_date) = $year";
|
||||
|
||||
$sql_vendor_expenses = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
vendors.*,
|
||||
SUM(expenses.expense_amount) AS amount_paid
|
||||
FROM
|
||||
vendors
|
||||
LEFT JOIN
|
||||
expenses ON vendors.vendor_id = expenses.expense_vendor_id $year_condition
|
||||
GROUP BY
|
||||
vendors.vendor_id
|
||||
HAVING
|
||||
amount_paid > 599
|
||||
ORDER BY
|
||||
amount_paid DESC
|
||||
");
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-building mr-2"></i>Expense By Vendor <small>(With expense amounts of 600 or more)</small></h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<option value="all" <?php if ($year == 'all') { ?> selected <?php } ?> >All Years</option>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_payment_years)) {
|
||||
$payment_year = intval($row['payment_year']);
|
||||
?>
|
||||
<option <?php if ($year == $payment_year) { ?> selected <?php } ?> > <?php echo $payment_year; ?></option>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Vendor</th>
|
||||
<th class="text-right">Paid</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_vendor_expenses)) {
|
||||
$vendor_id = intval($row['vendor_id']);
|
||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
||||
$amount_paid = floatval($row['amount_paid']); ?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $vendor_name; ?></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $amount_paid, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php";
|
||||
?>
|
||||
195
agent/reports/expense_summary.php
Normal file
195
agent/reports/expense_summary.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_expense_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(expense_date) AS expense_year FROM expenses WHERE expense_category_id > 0 ORDER BY expense_year DESC");
|
||||
|
||||
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Expense' ORDER BY category_name ASC");
|
||||
|
||||
// For chart Y-axis max
|
||||
$largest_expense_month = 0;
|
||||
|
||||
?>
|
||||
|
||||
<!-- Responsive chart helpers -->
|
||||
<style>
|
||||
.chart-h-320 { position: relative; height: 320px; }
|
||||
@media (max-width: 576px) { .chart-h-320 { height: 260px; } }
|
||||
</style>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-coins mr-2"></i>Expense Summary</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php while ($row = mysqli_fetch_array($sql_expense_years)) {
|
||||
$expense_year = intval($row['expense_year']); ?>
|
||||
<option <?php if ($year == $expense_year) { ?> selected <?php } ?>><?php echo $expense_year; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="chart-h-320 mb-3">
|
||||
<canvas id="cashFlow"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead class="text-dark">
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-right">January</th>
|
||||
<th class="text-right">February</th>
|
||||
<th class="text-right">March</th>
|
||||
<th class="text-right">April</th>
|
||||
<th class="text-right">May</th>
|
||||
<th class="text-right">June</th>
|
||||
<th class="text-right">July</th>
|
||||
<th class="text-right">August</th>
|
||||
<th class="text-right">September</th>
|
||||
<th class="text-right">October</th>
|
||||
<th class="text-right">November</th>
|
||||
<th class="text-right">December</th>
|
||||
<th class="text-right">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($row = mysqli_fetch_array($sql_categories)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']); ?>
|
||||
<tr>
|
||||
<td><?php echo $category_name; ?></td>
|
||||
<?php
|
||||
$total_expense_for_all_months = 0;
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE expense_category_id = $category_id AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month");
|
||||
$rowm = mysqli_fetch_array($sql_expenses);
|
||||
$expense_amount_for_month = floatval($rowm['expense_amount_for_month']);
|
||||
$total_expense_for_all_months += $expense_amount_for_month;
|
||||
?>
|
||||
<td class="text-right">
|
||||
<a class="text-dark" href="expenses.php?q=<?php echo $category_name; ?>&dtf=<?php echo "$year-$month"; ?>-01&dtt=<?php echo "$year-$month"; ?>-31">
|
||||
<?php echo numfmt_format_currency($currency_format, $expense_amount_for_month, $session_company_currency); ?>
|
||||
</a>
|
||||
</td>
|
||||
<?php } ?>
|
||||
<th class="text-right">
|
||||
<a class="text-dark" href="expenses.php?q=<?php echo $category_name; ?>&dtf=<?php echo $year; ?>-01-01&dtt=<?php echo $year; ?>-12-31">
|
||||
<?php echo numfmt_format_currency($currency_format, $total_expense_for_all_months, $session_company_currency); ?>
|
||||
</a>
|
||||
</th>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<?php
|
||||
$grand_total_all_months = 0;
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_total_amount_for_month FROM expenses WHERE YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
|
||||
$rowt = mysqli_fetch_array($sql_expenses);
|
||||
$expense_total_amount_for_month = floatval($rowt['expense_total_amount_for_month']);
|
||||
$grand_total_all_months += $expense_total_amount_for_month;
|
||||
?>
|
||||
<th class="text-right">
|
||||
<a class="text-dark" href="expenses.php?dtf=<?php echo "$year-$month"; ?>-01&dtt=<?php echo "$year-$month"; ?>-31">
|
||||
<?php echo numfmt_format_currency($currency_format, $expense_total_amount_for_month, $session_company_currency); ?>
|
||||
</a>
|
||||
</th>
|
||||
<?php } ?>
|
||||
<th class="text-right">
|
||||
<a class="text-dark" href="expenses.php?dtf=<?php echo $year; ?>-01-01&dtt=<?php echo $year; ?>-12-31">
|
||||
<?php echo numfmt_format_currency($currency_format, $grand_total_all_months, $session_company_currency); ?>
|
||||
</a>
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php"; ?>
|
||||
|
||||
<script>
|
||||
// Bootstrap-like defaults for Chart.js v4
|
||||
Chart.defaults.font.family = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||
Chart.defaults.color = '#292b2c';
|
||||
|
||||
// EXPENSES LINE CHART
|
||||
(function () {
|
||||
var ctx = document.getElementById("cashFlow");
|
||||
if (!ctx) return;
|
||||
|
||||
var dataPoints = [
|
||||
<?php
|
||||
// Build series and track the largest month for axis max
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
|
||||
$rowm = mysqli_fetch_array($sql_expenses);
|
||||
$expenses_for_month = floatval($rowm['expense_amount_for_month']);
|
||||
|
||||
if ($expenses_for_month > 0 && $expenses_for_month > $largest_expense_month) {
|
||||
$largest_expense_month = $expenses_for_month;
|
||||
}
|
||||
echo "$expenses_for_month,";
|
||||
}
|
||||
?>
|
||||
];
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
|
||||
datasets: [{
|
||||
label: "Expense",
|
||||
tension: 0.3, // v4 name (v2: lineTension)
|
||||
fill: false,
|
||||
borderColor: "#dc3545",
|
||||
pointBackgroundColor: "#dc3545",
|
||||
pointBorderColor: "#dc3545",
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "#dc3545",
|
||||
pointBorderWidth: 2,
|
||||
data: dataPoints
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
grid: { display: false },
|
||||
ticks: { maxTicksLimit: 12 }
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
max: <?php
|
||||
$max = max(1000, $largest_expense_month);
|
||||
echo roundUpToNearestMultiple($max);
|
||||
?>,
|
||||
ticks: { maxTicksLimit: 5 },
|
||||
grid: { color: "rgba(0, 0, 0, .125)" }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: { display: false }
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
20
agent/reports/includes/inc_all_reports.php
Normal file
20
agent/reports/includes/inc_all_reports.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
require_once "../../config.php";
|
||||
require_once "../../functions.php";
|
||||
require_once "../../includes/router.php";
|
||||
require_once "../../includes/check_login.php";
|
||||
require_once "../../includes/page_title.php";
|
||||
// Reporting Perms
|
||||
enforceUserPermission('module_reporting');
|
||||
require_once "../../includes/header.php";
|
||||
require_once "../../includes/top_nav.php";
|
||||
require_once "includes/reports_side_nav.php";
|
||||
require_once "../../includes/inc_wrapper.php";
|
||||
require_once "../../includes/inc_alert_feedback.php";
|
||||
require_once "../../includes/filter_header.php";
|
||||
|
||||
// Set variable default values
|
||||
$largest_income_month = 0;
|
||||
$largest_invoice_month = 0;
|
||||
$recurring_total = 0;
|
||||
121
agent/reports/includes/reports_side_nav.php
Normal file
121
agent/reports/includes/reports_side_nav.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-primary d-print-none">
|
||||
|
||||
<a class="pb-1 mt-1 brand-link" href="../../agent/<?php echo $config_start_page ?>">
|
||||
<p class="h5"><i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
|
||||
<span class="brand-text ">Back | <strong>Reports</strong>
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
|
||||
<!-- Sidebar Menu -->
|
||||
<nav>
|
||||
|
||||
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" data-accordion="false">
|
||||
|
||||
<li class="nav-header">FINANCIAL</li>
|
||||
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_financial") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="income_summary.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "income_summary.php") { echo "active"; } ?>">
|
||||
<i class="far fa-circle nav-icon"></i>
|
||||
<p>Income</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="income_by_client.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "income_by_client.php") { echo "active"; } ?>">
|
||||
<i class="far fa-user nav-icon"></i>
|
||||
<p>Income By Client</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="recurring_by_client.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_by_client.php") { echo "active"; } ?>">
|
||||
<i class="fa fa-sync nav-icon"></i>
|
||||
<p>Recurring Income By Client</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="clients_with_balance.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "clients_with_balance.php") { echo "active"; } ?>">
|
||||
<i class="fa fa-exclamation-triangle nav-icon"></i>
|
||||
<p>Clients with a Balance</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="expense_summary.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "expense_summary.php") { echo "active"; } ?>">
|
||||
<i class="far fa-credit-card nav-icon"></i>
|
||||
<p>Expense</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="expense_by_vendor.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "expense_by_vendor.php") { echo "active"; } ?>">
|
||||
<i class="far fa-building nav-icon"></i>
|
||||
<p>Expense By Vendor</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="tax_summary.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tax_summary.php") { echo "active"; } ?>">
|
||||
<i class="fas fa-percent nav-icon"></i>
|
||||
<p>Tax Summary</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="profit_loss.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "profit_loss.php") { echo "active"; } ?>">
|
||||
<i class="fas fa-file-invoice-dollar nav-icon"></i>
|
||||
<p>Profit & Loss</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="tickets_unbilled.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets_unbilled.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Unbilled Tickets</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php } // End financial reports IF statement ?>
|
||||
|
||||
|
||||
<li class="nav-header">TECHNICAL</li>
|
||||
<?php if ($config_module_enable_ticketing && lookupUserPermission("module_support") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="ticket_summary.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "ticket_summary.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Tickets</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="ticket_by_client.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "ticket_by_client.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Tickets by Client</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="time_by_tech.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "time_by_tech.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Time by Technician</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php if (lookupUserPermission("module_credential") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="credential_rotation.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "credential_rotation.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-key"></i>
|
||||
<p>Credential rotation</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- /.sidebar-menu -->
|
||||
|
||||
<div class="sidebar-custom mb-3">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
95
agent/reports/income_by_client.php
Normal file
95
agent/reports/income_by_client.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
if ($_GET['year'] === 'all') {
|
||||
$year = 'all';
|
||||
} else {
|
||||
$year = intval($_GET['year']);
|
||||
}
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_payment_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(payment_date) AS payment_year FROM payments
|
||||
UNION SELECT DISTINCT YEAR(revenue_date) AS payment_year FROM revenues
|
||||
ORDER BY payment_year DESC"
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-users mr-2"></i>Income By Client <small>(With payments of 600 or more)</small></h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<option value="all" <?php if ($year == 'all') { ?> selected <?php } ?> >All Years</option>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_payment_years)) {
|
||||
$payment_year = intval($row['payment_year']);
|
||||
?>
|
||||
<option <?php if ($year == $payment_year) { ?> selected <?php } ?> > <?php echo $payment_year; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
$sql_clients = "SELECT c.client_id, c.client_name, SUM(p.payment_amount) AS amount_paid
|
||||
FROM clients AS c
|
||||
JOIN invoices AS i ON c.client_id = i.invoice_client_id
|
||||
JOIN payments AS p ON i.invoice_id = p.payment_invoice_id";
|
||||
if ($year != 'all') {
|
||||
$sql_clients .= " WHERE YEAR(p.payment_date) = $year";
|
||||
}
|
||||
$sql_clients .= " GROUP BY c.client_id
|
||||
HAVING amount_paid > 599
|
||||
ORDER BY amount_paid DESC";
|
||||
|
||||
$sql_clients = mysqli_query($mysqli, $sql_clients);
|
||||
?>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Paid</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
$amount_paid = floatval($row['amount_paid']);
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><a href="../../agent/client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $amount_paid, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../includes/footer.php";
|
||||
|
||||
201
agent/reports/income_summary.php
Normal file
201
agent/reports/income_summary.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_payment_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(payment_date) AS payment_year FROM payments
|
||||
UNION SELECT DISTINCT YEAR(revenue_date) AS payment_year FROM revenues
|
||||
ORDER BY payment_year DESC");
|
||||
|
||||
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' ORDER BY category_name ASC");
|
||||
|
||||
// Used for chart y-axis max calculation
|
||||
$largest_income_month = 0;
|
||||
|
||||
?>
|
||||
|
||||
<!-- Responsive chart helpers -->
|
||||
<style>
|
||||
.chart-h-320 { position: relative; height: 320px; }
|
||||
@media (max-width: 576px) { .chart-h-320 { height: 260px; } }
|
||||
</style>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-coins mr-2"></i>Income Summary</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<form class="p-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php while ($row = mysqli_fetch_array($sql_payment_years)) {
|
||||
$payment_year = intval($row['payment_year']); ?>
|
||||
<option <?php if ($year == $payment_year) { ?> selected <?php } ?>><?php echo $payment_year; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="px-3 pb-3">
|
||||
<div class="chart-h-320">
|
||||
<canvas id="cashFlow"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-right">January</th>
|
||||
<th class="text-right">February</th>
|
||||
<th class="text-right">March</th>
|
||||
<th class="text-right">April</th>
|
||||
<th class="text-right">May</th>
|
||||
<th class="text-right">June</th>
|
||||
<th class="text-right">July</th>
|
||||
<th class="text-right">August</th>
|
||||
<th class="text-right">September</th>
|
||||
<th class="text-right">October</th>
|
||||
<th class="text-right">November</th>
|
||||
<th class="text-right">December</th>
|
||||
<th class="text-right">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($row = mysqli_fetch_array($sql_categories)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']); ?>
|
||||
<tr>
|
||||
<td><?php echo $category_name; ?></td>
|
||||
<?php
|
||||
$total_payment_for_all_months = 0;
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
// Payments to Invoices
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_category_id = $category_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row2 = mysqli_fetch_array($sql_payments);
|
||||
$payment_amount_for_month = floatval($row2['payment_amount_for_month']);
|
||||
|
||||
// Revenues
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id = $category_id AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row3 = mysqli_fetch_array($sql_revenues);
|
||||
$revenues_amount_for_month = floatval($row3['revenue_amount_for_month']);
|
||||
|
||||
$payment_amount_for_month = $payment_amount_for_month + $revenues_amount_for_month;
|
||||
$total_payment_for_all_months += $payment_amount_for_month;
|
||||
?>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_amount_for_month, $session_company_currency); ?></td>
|
||||
<?php } ?>
|
||||
<td class="text-right text-bold"><?php echo numfmt_format_currency($currency_format, $total_payment_for_all_months, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<?php
|
||||
$grand_total_all_months = 0;
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_total_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row4 = mysqli_fetch_array($sql_payments);
|
||||
$payment_total_amount_for_month = floatval($row4['payment_total_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row5 = mysqli_fetch_array($sql_revenues);
|
||||
$revenues_total_amount_for_month = floatval($row5['revenue_amount_for_month']);
|
||||
|
||||
$payment_total_amount_for_month += $revenues_total_amount_for_month;
|
||||
$grand_total_all_months += $payment_total_amount_for_month;
|
||||
?>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_total_amount_for_month, $session_company_currency); ?></th>
|
||||
<?php } ?>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $grand_total_all_months, $session_company_currency); ?></th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php"; ?>
|
||||
|
||||
<script>
|
||||
// Bootstrap-like defaults for Chart.js v4
|
||||
Chart.defaults.font.family = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||
Chart.defaults.color = '#292b2c';
|
||||
|
||||
// INCOME (Line)
|
||||
(function () {
|
||||
var ctx = document.getElementById("cashFlow");
|
||||
if (!ctx) return;
|
||||
|
||||
var myLineChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
datasets: [{
|
||||
label: "Income",
|
||||
fill: false,
|
||||
borderColor: "#007bff",
|
||||
pointBackgroundColor: "#007bff",
|
||||
pointBorderColor: "#007bff",
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "#007bff",
|
||||
pointBorderWidth: 2,
|
||||
data: [
|
||||
<?php
|
||||
// Build series and track the largest month for axis max
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$r1 = mysqli_fetch_array($sql_payments);
|
||||
$payments_for_month = floatval($r1['payment_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$r2 = mysqli_fetch_array($sql_revenues);
|
||||
$revenues_for_month = floatval($r2['revenue_amount_for_month']);
|
||||
|
||||
$income_for_month = $payments_for_month + $revenues_for_month;
|
||||
|
||||
if ($income_for_month > 0 && $income_for_month > $largest_income_month) {
|
||||
$largest_income_month = $income_for_month;
|
||||
}
|
||||
|
||||
echo "$income_for_month,";
|
||||
}
|
||||
?>
|
||||
],
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
grid: { display: false },
|
||||
ticks: { maxTicksLimit: 12 }
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
max: <?php
|
||||
$max = max(1000, $largest_income_month);
|
||||
echo roundUpToNearestMultiple($max);
|
||||
?>,
|
||||
ticks: { maxTicksLimit: 5 },
|
||||
grid: { color: "rgba(0, 0, 0, .125)" }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: { display: false }
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
20
agent/reports/index.php
Normal file
20
agent/reports/index.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-coins mr-2"></i>Reports</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<form class="p-3">
|
||||
<h3>Access different reports using the menu on the left</h3>
|
||||
<small class="text-muted">In addition to the general reporting permission, you must have read permissions to the reporting area you wish to view (e.g. support/financial).</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php"; ?>
|
||||
|
||||
437
agent/reports/profit_loss.php
Normal file
437
agent/reports/profit_loss.php
Normal file
@@ -0,0 +1,437 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
//GET unique years from expenses, payments and revenues
|
||||
$sql_all_years = mysqli_query($mysqli, "SELECT YEAR(expense_date) AS all_years FROM expenses
|
||||
UNION DISTINCT SELECT YEAR(payment_date) FROM payments
|
||||
UNION DISTINCT SELECT YEAR(revenue_date) FROM revenues
|
||||
ORDER BY all_years DESC"
|
||||
);
|
||||
|
||||
$sql_categories_income = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' ORDER BY category_name ASC");
|
||||
|
||||
$sql_categories_expense = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Expense' ORDER BY category_name ASC");
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Profit & Loss</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<form class="p-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_all_years)) {
|
||||
$all_years = intval($row['all_years']);
|
||||
?>
|
||||
<option <?php if ($year == $all_years) { ?> selected <?php } ?> > <?php echo $all_years; ?></option>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</select>
|
||||
</form>
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-sm">
|
||||
<thead class="text-dark">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="text-right">Jan-Mar</th>
|
||||
<th class="text-right">Apr-Jun</th>
|
||||
<th class="text-right">Jul-Sep</th>
|
||||
<th class="text-right">Oct-Dec</th>
|
||||
<th class="text-right">Total</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><br><br>Income</th>
|
||||
<th colspan="5"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_categories_income)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $category_name; ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_amount_for_quarter_one = 0;
|
||||
|
||||
for($month = 1; $month<=3; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_category_id = $category_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_amount_for_month = floatval($row['payment_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id = $category_id AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_amount_for_month = floatval($row['revenue_amount_for_month']);
|
||||
|
||||
$payment_amount_for_month = $payment_amount_for_month + $revenue_amount_for_month;
|
||||
|
||||
$payment_amount_for_quarter_one = $payment_amount_for_quarter_one + $payment_amount_for_month;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_amount_for_quarter_one, $session_company_currency); ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_amount_for_quarter_two = 0;
|
||||
|
||||
for($month = 4; $month<=6; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_category_id = $category_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_amount_for_month = floatval($row['payment_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id = $category_id AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_amount_for_month = floatval($row['revenue_amount_for_month']);
|
||||
|
||||
$payment_amount_for_month = $payment_amount_for_month + $revenue_amount_for_month;
|
||||
|
||||
$payment_amount_for_quarter_two = $payment_amount_for_quarter_two + $payment_amount_for_month;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_amount_for_quarter_two, $session_company_currency); ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_amount_for_quarter_three = 0;
|
||||
|
||||
for($month = 7; $month<=9; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_category_id = $category_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_amount_for_month = floatval($row['payment_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id = $category_id AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_amount_for_month = floatval($row['revenue_amount_for_month']);
|
||||
|
||||
$payment_amount_for_month = $payment_amount_for_month + $revenue_amount_for_month;
|
||||
$payment_amount_for_quarter_three = $payment_amount_for_quarter_three + $payment_amount_for_month;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_amount_for_quarter_three, $session_company_currency); ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_amount_for_quarter_four = 0;
|
||||
|
||||
for($month = 10; $month<=12; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_category_id = $category_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_amount_for_month = floatval($row['payment_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id = $category_id AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_amount_for_month = floatval($row['revenue_amount_for_month']);
|
||||
|
||||
$payment_amount_for_month = $payment_amount_for_month + $revenue_amount_for_month;
|
||||
$payment_amount_for_quarter_four = $payment_amount_for_quarter_four + $payment_amount_for_month;
|
||||
}
|
||||
|
||||
$total_payments_for_all_four_quarters = $payment_amount_for_quarter_one + $payment_amount_for_quarter_two + $payment_amount_for_quarter_three + $payment_amount_for_quarter_four;
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_amount_for_quarter_four, $session_company_currency); ?></td>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $total_payments_for_all_four_quarters, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
$total_payment_for_all_months = 0;
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<th>Gross Profit</th>
|
||||
<?php
|
||||
|
||||
$payment_total_amount_for_quarter_one = 0;
|
||||
|
||||
for($month = 1; $month<=3; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_total_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_total_amount_for_month = floatval($row['payment_total_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_total_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_total_amount_for_month = floatval($row['revenue_total_amount_for_month']);
|
||||
|
||||
$payment_total_amount_for_month = $payment_total_amount_for_month + $revenue_total_amount_for_month;
|
||||
|
||||
$payment_total_amount_for_quarter_one = $payment_total_amount_for_quarter_one + $payment_total_amount_for_month;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_total_amount_for_quarter_one, $session_company_currency); ?></th>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_total_amount_for_quarter_two = 0;
|
||||
|
||||
for($month = 4; $month<=6; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_total_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_total_amount_for_month = floatval($row['payment_total_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_total_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_total_amount_for_month = floatval($row['revenue_total_amount_for_month']);
|
||||
|
||||
$payment_total_amount_for_month = $payment_total_amount_for_month + $revenue_total_amount_for_month;
|
||||
|
||||
$payment_total_amount_for_quarter_two = $payment_total_amount_for_quarter_two + $payment_total_amount_for_month;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_total_amount_for_quarter_two, $session_company_currency); ?></th>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_total_amount_for_quarter_three = 0;
|
||||
|
||||
for($month = 7; $month<=9; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_total_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_total_amount_for_month = floatval($row['payment_total_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_total_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_total_amount_for_month = floatval($row['revenue_total_amount_for_month']);
|
||||
|
||||
$payment_total_amount_for_month = $payment_total_amount_for_month + $revenue_total_amount_for_month;
|
||||
|
||||
$payment_total_amount_for_quarter_three = $payment_total_amount_for_quarter_three + $payment_total_amount_for_month;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_total_amount_for_quarter_three, $session_company_currency); ?></th>
|
||||
|
||||
<?php
|
||||
|
||||
$payment_total_amount_for_quarter_four = 0;
|
||||
|
||||
for($month = 10; $month<=12; $month++) {
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_total_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_payments);
|
||||
$payment_total_amount_for_month = floatval($row['payment_total_amount_for_month']);
|
||||
|
||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_total_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_revenues);
|
||||
$revenue_total_amount_for_month = floatval($row['revenue_total_amount_for_month']);
|
||||
|
||||
$payment_total_amount_for_month = $payment_total_amount_for_month + $revenue_total_amount_for_month;
|
||||
|
||||
$payment_total_amount_for_quarter_four = $payment_total_amount_for_quarter_four + $payment_total_amount_for_month;
|
||||
}
|
||||
|
||||
$total_payments_for_all_four_quarters = $payment_total_amount_for_quarter_one + $payment_total_amount_for_quarter_two + $payment_total_amount_for_quarter_three + $payment_total_amount_for_quarter_four;
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_total_amount_for_quarter_four, $session_company_currency); ?></th>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $total_payments_for_all_four_quarters, $session_company_currency); ?></th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><br><br>Expenses</th>
|
||||
<th colspan="5"></th>
|
||||
</tr>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_categories_expense)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $category_name; ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_amount_for_quarter_one = 0;
|
||||
|
||||
for($month = 1; $month<=3; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE expense_category_id = $category_id AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_amount_for_quarter_one = $expense_amount_for_quarter_one + floatval($row['expense_amount_for_month']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_amount_for_quarter_one, $session_company_currency); ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_amount_for_quarter_two = 0;
|
||||
|
||||
for($month = 4; $month<=6; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE expense_category_id = $category_id AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_amount_for_quarter_two = $expense_amount_for_quarter_two + floatval($row['expense_amount_for_month']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_amount_for_quarter_two, $session_company_currency); ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_amount_for_quarter_three = 0;
|
||||
|
||||
for($month = 7; $month<=9; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE expense_category_id = $category_id AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_amount_for_quarter_three = $expense_amount_for_quarter_three + floatval($row['expense_amount_for_month']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_amount_for_quarter_three, $session_company_currency); ?></td>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_amount_for_quarter_four = 0;
|
||||
|
||||
for($month = 10; $month<=12; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE expense_category_id = $category_id AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_amount_for_quarter_four = $expense_amount_for_quarter_four + floatval($row['expense_amount_for_month']);
|
||||
}
|
||||
|
||||
$total_expenses_for_all_four_quarters = $expense_amount_for_quarter_one + $expense_amount_for_quarter_two + $expense_amount_for_quarter_three + $expense_amount_for_quarter_four;
|
||||
|
||||
?>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_amount_for_quarter_four, $session_company_currency); ?></td>
|
||||
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $total_expenses_for_all_four_quarters, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
$total_expense_for_all_months = 0;
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<th>Total Expenses<br><br><br></th>
|
||||
<?php
|
||||
|
||||
$expense_total_amount_for_quarter_one = 0;
|
||||
|
||||
for($month = 1; $month<=3; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_total_amount_for_month FROM expenses WHERE expense_category_id > 0 AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_total_amount_for_quarter_one = $expense_total_amount_for_quarter_one + floatval($row['expense_total_amount_for_month']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_total_amount_for_quarter_one, $session_company_currency); ?></th>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_total_amount_for_quarter_two = 0;
|
||||
|
||||
for($month = 4; $month<=6; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_total_amount_for_month FROM expenses WHERE expense_category_id > 0 AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_total_amount_for_quarter_two = $expense_total_amount_for_quarter_two + floatval($row['expense_total_amount_for_month']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_total_amount_for_quarter_two, $session_company_currency); ?></th>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_total_amount_for_quarter_three = 0;
|
||||
|
||||
for($month = 7; $month<=9; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_total_amount_for_month FROM expenses WHERE expense_category_id > 0 AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_total_amount_for_quarter_three = $expense_total_amount_for_quarter_three + floatval($row['expense_total_amount_for_month']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_total_amount_for_quarter_three, $session_company_currency); ?></th>
|
||||
|
||||
<?php
|
||||
|
||||
$expense_total_amount_for_quarter_four = 0;
|
||||
|
||||
for($month = 10; $month<=12; $month++) {
|
||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_total_amount_for_month FROM expenses WHERE expense_category_id > 0 AND YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
|
||||
$row = mysqli_fetch_array($sql_expenses);
|
||||
$expense_total_amount_for_quarter_four = $expense_total_amount_for_quarter_four + floatval($row['expense_total_amount_for_month']);
|
||||
}
|
||||
|
||||
$total_expenses_for_all_four_quarters = $expense_total_amount_for_quarter_one + $expense_total_amount_for_quarter_two + $expense_total_amount_for_quarter_three + $expense_total_amount_for_quarter_four;
|
||||
|
||||
?>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $expense_total_amount_for_quarter_four, $session_company_currency); ?></th>
|
||||
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $total_expenses_for_all_four_quarters, $session_company_currency); ?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php
|
||||
$net_profit_quarter_one = $payment_total_amount_for_quarter_one - $expense_total_amount_for_quarter_one;
|
||||
$net_profit_quarter_two = $payment_total_amount_for_quarter_two - $expense_total_amount_for_quarter_two;
|
||||
$net_profit_quarter_three = $payment_total_amount_for_quarter_three - $expense_total_amount_for_quarter_three;
|
||||
$net_profit_quarter_four = $payment_total_amount_for_quarter_four - $expense_total_amount_for_quarter_four;
|
||||
$net_profit_year = $total_payments_for_all_four_quarters - $total_expenses_for_all_four_quarters;
|
||||
?>
|
||||
|
||||
<th>Net Profit</th>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $net_profit_quarter_one, $session_company_currency); ?></th>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $net_profit_quarter_two, $session_company_currency); ?></th>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $net_profit_quarter_three, $session_company_currency); ?></th>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $net_profit_quarter_four, $session_company_currency); ?></th>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $net_profit_year, $session_company_currency); ?></th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php";
|
||||
|
||||
67
agent/reports/recurring_by_client.php
Normal file
67
agent/reports/recurring_by_client.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
validateAccountantRole();
|
||||
|
||||
$sql = mysqli_query($mysqli, "
|
||||
SELECT client_id, client_name,
|
||||
SUM(CASE WHEN recurring_invoice_frequency = 'month' THEN recurring_invoice_amount
|
||||
WHEN recurring_invoice_frequency = 'year' THEN recurring_invoice_amount / 12 END) AS recurring_monthly_total
|
||||
FROM clients
|
||||
LEFT JOIN recurring_invoices ON client_id = recurring_invoice_client_id
|
||||
WHERE recurring_invoice_status = 1
|
||||
GROUP BY clients.client_id
|
||||
HAVING recurring_monthly_total > 0
|
||||
ORDER BY recurring_monthly_total DESC
|
||||
");
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-sync mr-2"></i>Recurring Income By Client</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Monthly Recurring</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
$recurring_monthly_total = floatval($row['recurring_monthly_total']);
|
||||
$recurring_total = $recurring_total + $recurring_monthly_total;
|
||||
?>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><a href="../../agent/client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $recurring_monthly_total, $session_company_currency); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th>Total Monthly Income</th>
|
||||
<th class="text-right"><?php echo numfmt_format_currency($currency_format, $recurring_total, $session_company_currency); ?></th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php";
|
||||
?>
|
||||
121
agent/reports/tax_summary.php
Normal file
121
agent/reports/tax_summary.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
$year = isset($_GET['year']) ? intval($_GET['year']) : date('Y');
|
||||
|
||||
$view = isset($_GET['view']) ? $_GET['view'] : 'quarterly';
|
||||
|
||||
$currency_row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT company_currency FROM companies WHERE company_id = 1"));
|
||||
$company_currency = nullable_htmlentities($currency_row['company_currency']);
|
||||
|
||||
// GET unique years from expenses, payments and revenues
|
||||
$sql_all_years = mysqli_query($mysqli, "SELECT DISTINCT(YEAR(item_created_at)) AS all_years FROM invoice_items ORDER BY all_years DESC");
|
||||
|
||||
$sql_tax = mysqli_query($mysqli, "SELECT `tax_name` FROM `taxes`");
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Collected Tax Summary</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<form class="p-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_all_years)) {
|
||||
$all_years = intval($row['all_years']);
|
||||
?>
|
||||
<option <?php if ($year == $all_years) { echo "selected"; } ?> > <?php echo $all_years; ?></option>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</select>
|
||||
|
||||
<!-- View Selection Dropdown -->
|
||||
<select onchange="this.form.submit()" class="form-control" name="view">
|
||||
<option value="monthly" <?php if ($view == 'monthly') echo "selected"; ?>>Monthly</option>
|
||||
<option value="quarterly" <?php if ($view == 'quarterly') echo "selected"; ?>>Quarterly</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-sm">
|
||||
<thead class="text-dark">
|
||||
<tr>
|
||||
<th>Tax</th>
|
||||
<?php
|
||||
if ($view == 'monthly') {
|
||||
for ($i = 1; $i <= 12; $i++) {
|
||||
echo "<th class='text-right'>" . date('M', mktime(0, 0, 0, $i, 10)) . "</th>";
|
||||
}
|
||||
} else {
|
||||
echo "<th class='text-right'>Jan-Mar</th>";
|
||||
echo "<th class='text-right'>Apr-Jun</th>";
|
||||
echo "<th class='text-right'>Jul-Sep</th>";
|
||||
echo "<th class='text-right'>Oct-Dec</th>";
|
||||
}
|
||||
?>
|
||||
<th class="text-right">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_tax)) {
|
||||
$tax_name = sanitizeInput($row['tax_name']);
|
||||
echo "<tr>";
|
||||
echo "<td>" . $row['tax_name'] . "</td>";
|
||||
|
||||
if ($view == 'monthly') {
|
||||
for ($i = 1; $i <= 12; $i++) {
|
||||
$monthly_tax = getMonthlyTax($tax_name, $i, $year, $mysqli);
|
||||
echo "<td class='text-right'>" . numfmt_format_currency($currency_format, $monthly_tax, $company_currency) . "</td>";
|
||||
}
|
||||
} else {
|
||||
for ($q = 1; $q <= 4; $q++) {
|
||||
$quarterly_tax = getQuarterlyTax($tax_name, $q, $year, $mysqli);
|
||||
echo "<td class='text-right'>" . numfmt_format_currency($currency_format, $quarterly_tax, $company_currency) . "</td>";
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total for row and echo bold
|
||||
$total_tax = getTotalTax($tax_name, $year, $mysqli);
|
||||
echo "<td class='text-right text-bold'>" . numfmt_format_currency($currency_format, $total_tax, $company_currency) . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<?php
|
||||
if ($view == 'monthly') {
|
||||
for ($i = 1; $i <= 12; $i++) {
|
||||
$monthly_tax = getMonthlyTax($tax_name, $i, $year, $mysqli);
|
||||
echo "<th class='text-right'>" . numfmt_format_currency($currency_format, $monthly_tax, $company_currency) . "</th>";
|
||||
}
|
||||
} else {
|
||||
for ($q = 1; $q <= 4; $q++) {
|
||||
$quarterly_tax = getQuarterlyTax($tax_name, $q, $year, $mysqli);
|
||||
echo "<th class='text-right'>" . numfmt_format_currency($currency_format, $quarterly_tax, $company_currency) . "</th>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<td class="text-right"></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php";
|
||||
|
||||
343
agent/reports/ticket_by_client.php
Normal file
343
agent/reports/ticket_by_client.php
Normal file
@@ -0,0 +1,343 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_support');
|
||||
|
||||
function secondsToTime($inputSeconds) {
|
||||
$inputSeconds = floor($inputSeconds);
|
||||
|
||||
$secondsInAMinute = 60;
|
||||
$secondsInAnHour = 60 * $secondsInAMinute;
|
||||
$secondsInADay = 24 * $secondsInAnHour;
|
||||
|
||||
// Extract days
|
||||
$days = floor($inputSeconds / $secondsInADay);
|
||||
|
||||
// Extract hours
|
||||
$hourSeconds = $inputSeconds % $secondsInADay;
|
||||
$hours = floor($hourSeconds / $secondsInAnHour);
|
||||
|
||||
// Extract minutes
|
||||
$minuteSeconds = $hourSeconds % $secondsInAnHour;
|
||||
$minutes = floor($minuteSeconds / $secondsInAMinute);
|
||||
|
||||
// Extract the remaining seconds
|
||||
$remainingSeconds = $minuteSeconds % $secondsInAMinute;
|
||||
$seconds = ceil($remainingSeconds);
|
||||
|
||||
// Format and return
|
||||
$timeParts = [];
|
||||
$sections = [
|
||||
'day' => (int)$days,
|
||||
'hour' => (int)$hours,
|
||||
'minute' => (int)$minutes,
|
||||
'second' => (int)$seconds,
|
||||
];
|
||||
|
||||
foreach ($sections as $name => $value){
|
||||
if ($value > 0) {
|
||||
$timeParts[] = $value. ' '.$name.($value == 1 ? '' : 's');
|
||||
}
|
||||
}
|
||||
|
||||
return implode(', ', $timeParts);
|
||||
}
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
if (isset($_GET['month'])) {
|
||||
$month = intval($_GET['month']);
|
||||
} else {
|
||||
$month = date('m');
|
||||
}
|
||||
|
||||
$sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC");
|
||||
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Tickets By Client</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_ticket_years)) {
|
||||
$ticket_year = intval($row['ticket_year']); ?>
|
||||
<option <?php if ($year == $ticket_year) { ?> selected <?php } ?> > <?php echo $ticket_year; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<select onchange="this.form.submit()" class="form-control" name="month">
|
||||
<option <?php if ($month == 1) { echo 'selected'; } ?> value="1">January</option>
|
||||
<option <?php if ($month == 2) { echo 'selected'; } ?> value="2">February</option>
|
||||
<option <?php if ($month == 3) { echo 'selected'; } ?> value="3">March</option>
|
||||
<option <?php if ($month == 4) { echo 'selected'; } ?> value="4">April</option>
|
||||
<option <?php if ($month == 5) { echo 'selected'; } ?> value="5">May</option>
|
||||
<option <?php if ($month == 6) { echo 'selected'; } ?> value="6">June</option>
|
||||
<option <?php if ($month == 7) { echo 'selected'; } ?> value="7">July</option>
|
||||
<option <?php if ($month == 8) { echo 'selected'; } ?> value="8">August</option>
|
||||
<option <?php if ($month == 9) { echo 'selected'; } ?> value="9">September</option>
|
||||
<option <?php if ($month == 10) { echo 'selected'; } ?> value="10">October</option>
|
||||
<option <?php if ($month == 11) { echo 'selected'; } ?> value="11">November</option>
|
||||
<option <?php if ($month == 12) { echo 'selected'; } ?> value="12">December</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="card card-dark mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-chart-area mr-2"></i>Yearly (<?php echo $year; ?>)</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Raised</th>
|
||||
<th class="text-right">Priority: Low</th>
|
||||
<th class="text-right">Priority: Med</th>
|
||||
<th class="text-right">Priority: High</th>
|
||||
<th class="text-right">Resolved</th>
|
||||
<th class="text-right">Total Time worked <i>(H:M:S)</i></th>
|
||||
<th class="text-right">Avg time to respond</th>
|
||||
<th class="text-right">Avg time to resolve</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
// Calculate total tickets raised in period
|
||||
$sql_ticket_raised_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_raised_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id");
|
||||
$row = mysqli_fetch_array($sql_ticket_raised_count);
|
||||
$ticket_raised_count = intval($row['ticket_raised_count']);
|
||||
|
||||
// Calculate total tickets raised in period that are resolved
|
||||
$sql_ticket_resolved_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_resolved_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_resolved_at IS NOT NULL");
|
||||
$row = mysqli_fetch_array($sql_ticket_resolved_count);
|
||||
$ticket_resolved_count = intval($row['ticket_resolved_count']);
|
||||
|
||||
// Breakdown tickets for each priority - Low
|
||||
$sql_low_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS low_ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_priority = 'Low'");
|
||||
$row = mysqli_fetch_array($sql_low_ticket_count);
|
||||
$low_ticket_count = intval($row['low_ticket_count']);
|
||||
|
||||
// Breakdown tickets for each priority - Low
|
||||
$sql_med_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS med_ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_priority = 'Medium'");
|
||||
$row = mysqli_fetch_array($sql_med_ticket_count);
|
||||
$med_ticket_count = intval($row['med_ticket_count']);
|
||||
|
||||
// Breakdown tickets for each priority - Low
|
||||
$sql_high_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS high_ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_priority = 'High'");
|
||||
$row = mysqli_fetch_array($sql_high_ticket_count);
|
||||
$high_ticket_count = intval($row['high_ticket_count']);
|
||||
|
||||
// Used to calculate average time to respond to tickets that were raised in period specified
|
||||
$sql_tickets_respond = mysqli_query($mysqli, "SELECT ticket_created_at, ticket_first_response_at FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id");
|
||||
|
||||
// Used to calculate average time to resolve tickets that were raised in period specified
|
||||
$sql_tickets_resolved = mysqli_query($mysqli, "SELECT ticket_created_at, ticket_resolved_at FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_resolved_at IS NOT NULL");
|
||||
|
||||
// Calculate total time tracked towards tickets in the period
|
||||
$sql_time = mysqli_query($mysqli, "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(ticket_reply_time_worked))) as total_time FROM ticket_replies LEFT JOIN tickets ON tickets.ticket_id = ticket_replies.ticket_reply_ticket_id WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_reply_time_worked IS NOT NULL");
|
||||
$row = mysqli_fetch_array($sql_time);
|
||||
$ticket_total_time_worked = nullable_htmlentities($row['total_time']);
|
||||
|
||||
if ($ticket_raised_count > 0 || $ticket_resolved_count > 0) {
|
||||
|
||||
// Calculate average time to respond
|
||||
$avg_time_to_respond = '-';
|
||||
$count = 0;
|
||||
$total = 0;
|
||||
while ($row = mysqli_fetch_array($sql_tickets_respond)) {
|
||||
if (!empty($row['ticket_first_response_at'])) {
|
||||
$openedTime = new DateTime($row['ticket_created_at']);
|
||||
$respondTime = new DateTime($row['ticket_first_response_at']);
|
||||
$total += ($respondTime->getTimestamp() - $openedTime->getTimestamp());
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count > 0) {
|
||||
$avg_time_to_respond = secondsToTime($total / $count); // Avoids DivisionByZeroError
|
||||
}
|
||||
|
||||
// Calculate average time to solve
|
||||
$avg_time_to_resolve = '-';
|
||||
if ($ticket_resolved_count > 0) {
|
||||
$count = 0;
|
||||
$total = 0;
|
||||
while ($row = mysqli_fetch_array($sql_tickets_resolved)) {
|
||||
$openedTime = new DateTime($row['ticket_created_at']);
|
||||
$resolvedTime = new DateTime($row['ticket_resolved_at']);
|
||||
|
||||
$total += ($resolvedTime->getTimestamp() - $openedTime->getTimestamp());
|
||||
$count++;
|
||||
}
|
||||
$avg_time_to_resolve = secondsToTime($total / $count);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $client_name; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_raised_count; ?></td>
|
||||
<td class="text-right"><?php echo $low_ticket_count; ?></td>
|
||||
<td class="text-right"><?php echo $med_ticket_count; ?></td>
|
||||
<td class="text-right"><?php echo $high_ticket_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_resolved_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_total_time_worked; ?></td>
|
||||
<td class="text-right"><?php echo $avg_time_to_respond; ?></td>
|
||||
<td class="text-right"><?php echo $avg_time_to_resolve; ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="card card-dark mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-chart-area mr-2"></i>Monthly (<?php echo date("F", mktime(1, 1, 1, $month, 1)) . ' ' . $year; ?>)</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Raised</th>
|
||||
<th class="text-right">Priority: Low</th>
|
||||
<th class="text-right">Priority: Med</th>
|
||||
<th class="text-right">Priority: High</th>
|
||||
<th class="text-right">Resolved</th>
|
||||
<th class="text-right">Total Time worked <i>(H:M:S)</i></th>
|
||||
<th class="text-right">Avg time to respond</th>
|
||||
<th class="text-right">Avg time to resolve</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
mysqli_data_seek($sql_clients, 0); // Reset
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
// Calculate total tickets raised in period
|
||||
$sql_ticket_raised_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_raised_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id");
|
||||
$row = mysqli_fetch_array($sql_ticket_raised_count);
|
||||
$ticket_raised_count = intval($row['ticket_raised_count']);
|
||||
|
||||
// Calculate total tickets raised in period that are resolved
|
||||
$sql_ticket_resolved_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_resolved_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id AND ticket_resolved_at IS NOT NULL");
|
||||
$row = mysqli_fetch_array($sql_ticket_resolved_count);
|
||||
$ticket_resolved_count = intval($row['ticket_resolved_count']);
|
||||
|
||||
// Breakdown tickets for each priority - Low
|
||||
$sql_low_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS low_ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id AND ticket_priority = 'Low'");
|
||||
$row = mysqli_fetch_array($sql_low_ticket_count);
|
||||
$low_ticket_count = intval($row['low_ticket_count']);
|
||||
|
||||
// Breakdown tickets for each priority - Low
|
||||
$sql_med_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS med_ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id AND ticket_priority = 'Medium'");
|
||||
$row = mysqli_fetch_array($sql_med_ticket_count);
|
||||
$med_ticket_count = intval($row['med_ticket_count']);
|
||||
|
||||
// Breakdown tickets for each priority - Low
|
||||
$sql_high_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS high_ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id AND ticket_priority = 'High'");
|
||||
$row = mysqli_fetch_array($sql_high_ticket_count);
|
||||
$high_ticket_count = intval($row['high_ticket_count']);
|
||||
|
||||
// Used to calculate average time to respond to tickets that were raised in period specified
|
||||
$sql_tickets_respond = mysqli_query($mysqli, "SELECT ticket_created_at, ticket_first_response_at FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id");
|
||||
|
||||
// Used to calculate average time to resolve tickets that were raised in period specified
|
||||
$sql_tickets_resolved = mysqli_query($mysqli, "SELECT ticket_created_at, ticket_resolved_at FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id AND ticket_resolved_at IS NOT NULL");
|
||||
|
||||
// Calculate total time tracked towards tickets in the period
|
||||
$sql_time = mysqli_query($mysqli, "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(ticket_reply_time_worked))) as total_time FROM ticket_replies LEFT JOIN tickets ON tickets.ticket_id = ticket_replies.ticket_reply_ticket_id WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month AND ticket_client_id = $client_id AND ticket_reply_time_worked IS NOT NULL");
|
||||
$row = mysqli_fetch_array($sql_time);
|
||||
$ticket_total_time_worked = nullable_htmlentities($row['total_time']);
|
||||
|
||||
if ($ticket_raised_count > 0 || $ticket_resolved_count > 0) {
|
||||
|
||||
// Calculate average time to respond
|
||||
$avg_time_to_respond = '-';
|
||||
$count = 0;
|
||||
$total = 0;
|
||||
while ($row = mysqli_fetch_array($sql_tickets_respond)) {
|
||||
if (!empty($row['ticket_first_response_at'])) {
|
||||
$openedTime = new DateTime($row['ticket_created_at']);
|
||||
$respondTime = new DateTime($row['ticket_first_response_at']);
|
||||
$total += ($respondTime->getTimestamp() - $openedTime->getTimestamp());
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count > 0) {
|
||||
$avg_time_to_respond = secondsToTime($total / $count); // Avoids DivisionByZeroError
|
||||
}
|
||||
|
||||
// Calculate average time to solve
|
||||
$avg_time_to_resolve = '-';
|
||||
if ($ticket_resolved_count > 0) {
|
||||
$count = 0;
|
||||
$total = 0;
|
||||
while ($row = mysqli_fetch_array($sql_tickets_resolved)) {
|
||||
$openedTime = new DateTime($row['ticket_created_at']);
|
||||
$resolvedTime = new DateTime($row['ticket_resolved_at']);
|
||||
|
||||
$total += ($resolvedTime->getTimestamp() - $openedTime->getTimestamp());
|
||||
$count++;
|
||||
}
|
||||
$avg_time_to_resolve = secondsToTime($total / $count);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $client_name; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_raised_count; ?></td>
|
||||
<td class="text-right"><?php echo $low_ticket_count; ?></td>
|
||||
<td class="text-right"><?php echo $med_ticket_count; ?></td>
|
||||
<td class="text-right"><?php echo $high_ticket_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_resolved_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_total_time_worked; ?></td>
|
||||
<td class="text-right"><?php echo $avg_time_to_respond; ?></td>
|
||||
<td class="text-right"><?php echo $avg_time_to_resolve; ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../includes/footer.php";
|
||||
|
||||
163
agent/reports/ticket_summary.php
Normal file
163
agent/reports/ticket_summary.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_support');
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC");
|
||||
|
||||
$sql_tickets = mysqli_query($mysqli, "SELECT ticket_id FROM tickets");
|
||||
|
||||
// Track largest month for chart y-axis max
|
||||
$largest_ticket_month = 0;
|
||||
|
||||
?>
|
||||
|
||||
<!-- Responsive chart helpers -->
|
||||
<style>
|
||||
.chart-h-320 { position: relative; height: 320px; }
|
||||
@media (max-width: 576px) { .chart-h-320 { height: 260px; } }
|
||||
</style>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Ticket Summary</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<form class="p-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_ticket_years)) {
|
||||
$ticket_year = intval($row['ticket_year']); ?>
|
||||
<option <?php if ($year == $ticket_year) { ?> selected <?php } ?>><?php echo $ticket_year; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="px-3 pb-3">
|
||||
<div class="chart-h-320">
|
||||
<canvas id="tickets"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-right">January</th>
|
||||
<th class="text-right">February</th>
|
||||
<th class="text-right">March</th>
|
||||
<th class="text-right">April</th>
|
||||
<th class="text-right">May</th>
|
||||
<th class="text-right">June</th>
|
||||
<th class="text-right">July</th>
|
||||
<th class="text-right">August</th>
|
||||
<th class="text-right">September</th>
|
||||
<th class="text-right">October</th>
|
||||
<th class="text-right">November</th>
|
||||
<th class="text-right">December</th>
|
||||
<th class="text-right">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
$total_tickets_for_all_months = 0;
|
||||
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
|
||||
$sql_tickets = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS tickets_for_month FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month");
|
||||
$row = mysqli_fetch_array($sql_tickets);
|
||||
$tickets_for_month = intval($row['tickets_for_month']);
|
||||
|
||||
if ($tickets_for_month > 0 && $tickets_for_month > $largest_ticket_month) {
|
||||
$largest_ticket_month = $tickets_for_month;
|
||||
}
|
||||
|
||||
$total_tickets_for_all_months += $tickets_for_month; ?>
|
||||
<td class="text-right"><?php echo $tickets_for_month; ?></td>
|
||||
<?php } ?>
|
||||
|
||||
<td class="text-right"><b><?php echo $total_tickets_for_all_months; ?></b></td>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../../includes/footer.php"; ?>
|
||||
|
||||
<script>
|
||||
// Bootstrap-like defaults for Chart.js v4
|
||||
Chart.defaults.font.family = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||
Chart.defaults.color = '#292b2c';
|
||||
|
||||
(function () {
|
||||
var ctx = document.getElementById("tickets");
|
||||
if (!ctx) return;
|
||||
|
||||
var dataPoints = [
|
||||
<?php
|
||||
// Recompute for the chart dataset (values already gathered above, but we echo directly again)
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$sql_tickets = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS tickets_for_month FROM tickets WHERE YEAR(ticket_created_at) = $year AND MONTH(ticket_created_at) = $month");
|
||||
$row = mysqli_fetch_array($sql_tickets);
|
||||
$tickets_for_month = intval($row['tickets_for_month']);
|
||||
echo "$tickets_for_month,";
|
||||
}
|
||||
?>
|
||||
];
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
|
||||
datasets: [{
|
||||
label: "Tickets Raised",
|
||||
fill: false,
|
||||
borderColor: "#007bff",
|
||||
pointBackgroundColor: "#007bff",
|
||||
pointBorderColor: "#007bff",
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "#007bff",
|
||||
pointBorderWidth: 2,
|
||||
data: dataPoints
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
grid: { display: false },
|
||||
ticks: { maxTicksLimit: 12 }
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
max: <?php
|
||||
// use your helper if available, otherwise largest_ticket_month as-is
|
||||
$max = max(5, $largest_ticket_month);
|
||||
echo function_exists('roundUpToNearestMultiple') ? roundUpToNearestMultiple($max) : $max;
|
||||
?>,
|
||||
ticks: { maxTicksLimit: 5, precision: 0 },
|
||||
grid: { color: "rgba(0, 0, 0, .125)" }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: { display: false }
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
182
agent/reports/tickets_unbilled.php
Normal file
182
agent/reports/tickets_unbilled.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_sales', 1);
|
||||
|
||||
function secondsToTime($inputSeconds) {
|
||||
$secondsInAMinute = 60;
|
||||
$secondsInAnHour = 60 * $secondsInAMinute;
|
||||
$secondsInADay = 24 * $secondsInAnHour;
|
||||
|
||||
// Extract days
|
||||
$days = floor($inputSeconds / $secondsInADay);
|
||||
|
||||
// Extract hours
|
||||
$hourSeconds = $inputSeconds % $secondsInADay;
|
||||
$hours = floor($hourSeconds / $secondsInAnHour);
|
||||
|
||||
// Extract minutes
|
||||
$minuteSeconds = $hourSeconds % $secondsInAnHour;
|
||||
$minutes = floor($minuteSeconds / $secondsInAMinute);
|
||||
|
||||
// Extract the remaining seconds
|
||||
$remainingSeconds = $minuteSeconds % $secondsInAMinute;
|
||||
$seconds = ceil($remainingSeconds);
|
||||
|
||||
// Format and return
|
||||
$timeParts = [];
|
||||
$sections = [
|
||||
'day' => (int)$days,
|
||||
'hour' => (int)$hours,
|
||||
'minute' => (int)$minutes,
|
||||
'second' => (int)$seconds,
|
||||
];
|
||||
|
||||
foreach ($sections as $name => $value){
|
||||
if ($value > 0){
|
||||
$timeParts[] = $value. ' '.$name.($value == 1 ? '' : 's');
|
||||
}
|
||||
}
|
||||
|
||||
return implode(', ', $timeParts);
|
||||
}
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
$sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC");
|
||||
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients ORDER BY client_name ASC");
|
||||
|
||||
$rows = 0;
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Unbilled Tickets By Client</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_ticket_years)) {
|
||||
$ticket_year = intval($row['ticket_year']); ?>
|
||||
<option <?php if ($year == $ticket_year) { ?> selected <?php } ?> > <?php echo $ticket_year; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th class="text-right">Tickets Raised</th>
|
||||
<th class="text-right">Billable Tickets</th>
|
||||
<th class="text-right">Unbilled Tickets</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
// Calculate total tickets raised in period
|
||||
$sql_ticket_raised_count = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT
|
||||
COUNT(ticket_id) AS ticket_raised_count
|
||||
FROM
|
||||
tickets
|
||||
WHERE
|
||||
YEAR(ticket_created_at) = $year
|
||||
AND
|
||||
ticket_client_id = $client_id"
|
||||
);
|
||||
$row = mysqli_fetch_array($sql_ticket_raised_count);
|
||||
$ticket_raised_count = intval($row['ticket_raised_count']);
|
||||
|
||||
// Calculate total tickets raised in period that are closed and billable
|
||||
$sql_ticket_closed_count = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT
|
||||
COUNT(ticket_id) AS ticket_closed_count
|
||||
FROM
|
||||
tickets
|
||||
WHERE
|
||||
YEAR(ticket_created_at) = $year
|
||||
AND
|
||||
ticket_client_id = $client_id
|
||||
AND
|
||||
ticket_closed_at IS NOT NULL
|
||||
AND
|
||||
ticket_billable = 1
|
||||
");
|
||||
$row = mysqli_fetch_array($sql_ticket_closed_count);
|
||||
$ticket_closed_count = intval($row['ticket_closed_count']);
|
||||
|
||||
// Calculate total tickets raised in period that are closed and billable, but not invoiced
|
||||
$sql_ticket_unbilled_count = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT
|
||||
COUNT(ticket_id) AS ticket_unbilled_count
|
||||
FROM
|
||||
tickets
|
||||
WHERE
|
||||
YEAR(ticket_created_at) = $year
|
||||
AND
|
||||
ticket_client_id = $client_id
|
||||
AND
|
||||
ticket_closed_at IS NOT NULL
|
||||
AND
|
||||
ticket_billable = 1
|
||||
AND
|
||||
ticket_invoice_id = 0");
|
||||
$row = mysqli_fetch_array($sql_ticket_unbilled_count);
|
||||
$ticket_unbilled_count = intval($row['ticket_unbilled_count']);
|
||||
|
||||
if ($ticket_unbilled_count > 0) {
|
||||
$rows = $rows + 1;
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="../../agent/tickets.php?client_id=<?php echo $client_id; ?>&billable=1&unbilled"><?php echo $client_name; ?></a>
|
||||
</td>
|
||||
<td class="text-right"><?php echo $ticket_raised_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_closed_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_unbilled_count; ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ($rows == 0) {
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="4">You are all caught up! There are no unbilled tickets for this year.
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../includes/footer.php";
|
||||
|
||||
181
agent/reports/time_by_tech.php
Normal file
181
agent/reports/time_by_tech.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all_reports.php";
|
||||
|
||||
enforceUserPermission('module_support');
|
||||
|
||||
function secondsToTime($inputSeconds) {
|
||||
$inputSeconds = floor($inputSeconds);
|
||||
|
||||
$secondsInAMinute = 60;
|
||||
$secondsInAnHour = 60 * $secondsInAMinute;
|
||||
$secondsInADay = 24 * $secondsInAnHour;
|
||||
|
||||
// Extract days
|
||||
$days = floor($inputSeconds / $secondsInADay);
|
||||
|
||||
// Extract hours
|
||||
$hourSeconds = $inputSeconds % $secondsInADay;
|
||||
$hours = floor($hourSeconds / $secondsInAnHour);
|
||||
|
||||
// Extract minutes
|
||||
$minuteSeconds = $hourSeconds % $secondsInAnHour;
|
||||
$minutes = floor($minuteSeconds / $secondsInAMinute);
|
||||
|
||||
// Extract the remaining seconds
|
||||
$remainingSeconds = $minuteSeconds % $secondsInAMinute;
|
||||
$seconds = ceil($remainingSeconds);
|
||||
|
||||
// Format and return
|
||||
$timeParts = [];
|
||||
$sections = [
|
||||
'day' => (int)$days,
|
||||
'hour' => (int)$hours,
|
||||
'minute' => (int)$minutes,
|
||||
'second' => (int)$seconds,
|
||||
];
|
||||
|
||||
foreach ($sections as $name => $value){
|
||||
if ($value > 0){
|
||||
$timeParts[] = $value. ' '.$name.($value == 1 ? '' : 's');
|
||||
}
|
||||
}
|
||||
|
||||
return implode(', ', $timeParts);
|
||||
}
|
||||
|
||||
if (isset($_GET['year'])) {
|
||||
$year = intval($_GET['year']);
|
||||
} else {
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
if (isset($_GET['month'])) {
|
||||
$month = intval($_GET['month']);
|
||||
} else {
|
||||
$month = date('m');
|
||||
}
|
||||
|
||||
$sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC");
|
||||
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
|
||||
$sql_users = mysqli_query($mysqli, "
|
||||
SELECT users.user_id, user_name FROM users
|
||||
LEFT JOIN user_settings on users.user_id = user_settings.user_id
|
||||
WHERE user_type = 1
|
||||
AND user_status = 1
|
||||
AND user_archived_at IS NULL
|
||||
ORDER BY user_name DESC"
|
||||
);
|
||||
// TODO: Maybe try and filter this to just users with the support module perm
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Time Logged By Technician</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary d-print-none" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-3">
|
||||
<select onchange="this.form.submit()" class="form-control" name="year">
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql_ticket_years)) {
|
||||
$ticket_year = intval($row['ticket_year']); ?>
|
||||
<option <?php if ($year == $ticket_year) { ?> selected <?php } ?> > <?php echo $ticket_year; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="card card-dark mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-chart-area mr-2"></i>Yearly (<?php echo $year; ?>)</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Technician</th>
|
||||
<th class="text-right">Tickets assigned</th>
|
||||
<th class="text-right">Tickets touched</th>
|
||||
<th class="text-right">Total time worked <i>(H:M:S)</i></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($agent_row = mysqli_fetch_array($sql_users)) {
|
||||
$user_id = intval($agent_row['user_id']);
|
||||
$user_name = nullable_htmlentities($agent_row['user_name']);
|
||||
|
||||
// Get tickets in period that are still assigned to the technician/agent
|
||||
$sql_ticket_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_assigned_to = $user_id");
|
||||
$row = mysqli_fetch_array($sql_ticket_count);
|
||||
$ticket_raised_count = intval($row['ticket_count']);
|
||||
|
||||
// Get unique tickets in period that the agent replied to/touched
|
||||
$sql_tickets_touched = mysqli_query($mysqli, "
|
||||
SELECT COUNT(DISTINCT ticket_id) AS tickets_touched
|
||||
FROM (
|
||||
-- Tickets the agent replied to
|
||||
SELECT ticket_reply_ticket_id AS ticket_id
|
||||
FROM ticket_replies
|
||||
WHERE YEAR(ticket_reply_created_at) = $year AND ticket_reply_by = $user_id
|
||||
|
||||
UNION
|
||||
|
||||
-- Tickets the agent opened
|
||||
SELECT ticket_id
|
||||
FROM tickets
|
||||
WHERE YEAR(ticket_created_at) = $year AND ticket_created_by = $user_id
|
||||
|
||||
UNION
|
||||
|
||||
-- Tickets the agent closed
|
||||
SELECT ticket_id
|
||||
FROM tickets
|
||||
WHERE YEAR(ticket_created_at) = $year AND ticket_closed_by = $user_id
|
||||
)
|
||||
AS tickets_touched
|
||||
");
|
||||
|
||||
$row = mysqli_fetch_array($sql_tickets_touched);
|
||||
$tickets_touched = intval($row['tickets_touched']);
|
||||
|
||||
|
||||
// Calculate total time tracked towards tickets in the period (for this agent)
|
||||
$sql_time = mysqli_query($mysqli, "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(ticket_reply_time_worked))) as total_time FROM ticket_replies LEFT JOIN tickets ON tickets.ticket_id = ticket_replies.ticket_reply_ticket_id WHERE YEAR(ticket_created_at) = $year AND ticket_reply_by = $user_id AND ticket_reply_time_worked IS NOT NULL");
|
||||
$row = mysqli_fetch_array($sql_time);
|
||||
$ticket_total_time_worked = nullable_htmlentities($row['total_time']);
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?php echo $user_name; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_raised_count; ?></td>
|
||||
<td class="text-right"><?php echo $tickets_touched; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_total_time_worked; ?></td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TODO: Monthly version of this report -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../includes/footer.php";
|
||||
|
||||
Reference in New Issue
Block a user