Merge pull request #884 from twetech/0.1.8.4

0.1.8.4
This commit is contained in:
Johnny 2024-02-15 17:56:04 -05:00 committed by GitHub
commit 8e3c490092
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 460 additions and 237 deletions

153
admin_bulk_mail.php Normal file
View File

@ -0,0 +1,153 @@
<?php
require_once "inc_all_admin.php";
$sql = mysqli_query($mysqli, "SELECT * FROM contacts
WHERE contact_archived_at IS NULL
AND contact_email != ''
AND (contact_primary = 1 OR
contact_important = 1 OR
contact_billing = 1 OR
contact_technical = 1)
ORDER BY contact_primary DESC,
contact_important DESC"
);
?>
<form action="post.php" method="post">
<div class="card">
<div class="card-header">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-envelope-open mr-2"></i>Bulk Mail</h3>
<div class="card-tools">
<button type="submit" class="btn btn-primary" name="send_bulk_mail_now">
<i class="fas fa-paper-plane mr-2"></i>Send Now
</button>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<h5>Email Message</h5>
<hr>
<div class="form-group">
<select type="text" class="form-control select2" name="mail_from" >
<option value="<?php echo $config_mail_from_email; ?>"><?php echo $config_mail_from_email; ?></option>
<option value="<?php echo $config_invoice_from_email; ?>"><?php echo $config_invoice_from_email; ?></option>
<option value="<?php echo $config_quote_from_email; ?>"><?php echo $config_quote_from_email; ?></option>
<option value="<?php echo $config_ticket_from_email; ?>"><?php echo $config_ticket_from_email; ?></option>
</select>
</div>
<div class="form-group">
<input type="text" class="form-control" name="mail_from_name" placeholder="From Name" value="<?php echo nullable_htmlentities($config_mail_from_name); ?>" required>
</div>
<div class="form-group">
<input type="text" class="form-control" name="subject" placeholder="Subject" required>
</div>
<div class="form-group">
<textarea class="form-control tinymce" name="body" placeholder="Type an email in here"></textarea>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="datetime-local" class="form-control" name="queued_at">
</div>
</div>
</div>
<div class="col">
<h5>Select Contacts</h5>
<hr>
<div class="card">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="selectAllCheckbox" onchange="toggleCheckboxes()">
</div>
</td>
<th>Name</th>
<th>Title</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']);
if (empty($contact_title)) {
$contact_title_display = "-";
} else {
$contact_title_display = "$contact_title";
}
$contact_email = nullable_htmlentities($row['contact_email']);
$contact_primary = intval($row['contact_primary']);
$contact_important = intval($row['contact_important']);
$contact_billing = intval($row['contact_billing']);
$contact_technical = intval($row['contact_technical']);
$contact_client_id = intval($row['contact_client_id']);
?>
<tr>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" name="contact[]" value="<?php echo $contact_id; ?>">
</div>
</td>
<td>
<a href="client_contact_details.php?client_id=<?php echo $contact_client_id; ?>&contact_id=<?php echo $contact_id; ?>" target="_blank">
<?php echo $contact_name; ?>
</a>
</td>
<td><?php echo $contact_title_display; ?></td>
<td><?php echo $contact_email; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<script>
function toggleCheckboxes() {
// Get the state of the 'selectAllCheckbox'
var selectAllChecked = document.getElementById('selectAllCheckbox').checked;
// Find all checkboxes with the name 'contact[]' and set their state
var checkboxes = document.querySelectorAll('input[type="checkbox"][name="contact[]"]');
checkboxes.forEach(function(checkbox) {
checkbox.checked = selectAllChecked;
});
}
</script>
<?php
require_once "footer.php";

View File

@ -1,141 +1,177 @@
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none">
<a class="brand-link pb-1 mt-1" href="clients.php">
<p class="h6"><i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i> Back | <strong>Administration</strong></p>
</a>
<a class="brand-link pb-1 mt-1" href="clients.php">
<p class="h6"><i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i> Back | <strong>Administration</strong></p>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar Menu -->
<nav>
<!-- Sidebar Menu -->
<nav>
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" data-accordion="false">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" data-accordion="false">
<li class="nav-header">ACCESS</li>
<li class="nav-header">ACCESS</li>
<li class="nav-item">
<a href="admin_users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_users.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-users"></i>
<p>Users</p>
</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_api.php") {
echo "active";
} ?>" href="admin_api.php">
<i class="nav-icon fas fa-key"></i>
<p>API Keys</p>
</a>
</li>
<li class="nav-header mt-3">TAGS & CATEGORIES</li>
<li class="nav-item">
<a href="admin_tags.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_tags.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-tags"></i>
<p>Tags</p>
</a>
</li>
<li class="nav-item">
<a href="admin_categories.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_categories.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-list-ul"></i>
<p>Categories</p>
</a>
</li>
<!-- ---------------------- TODO: Custom Fields ----------------------
<li class="nav-item">
<a href="admin_users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_users.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-users"></i>
<p>Users</p>
</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_api.php") { echo "active"; } ?>"
href="admin_api.php">
<i class="nav-icon fas fa-key"></i>
<p>API Keys</p>
</a>
</li>
<li class="nav-header mt-3">TAGS & CATEGORIES</li>
<li class="nav-item">
<a href="admin_tags.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_tags.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-tags"></i>
<p>Tags</p>
</a>
</li>
<li class="nav-item">
<a href="admin_categories.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_categories.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-list-ul"></i>
<p>Categories</p>
</a>
</li>
<!-- ---------------------- TODO: Custom Fields ----------------------
<li class="nav-item">
<a href="settings_custom_fields.php" class="nav-link <?php //if (basename($_SERVER["PHP_SELF"]) == "settings_custom_fields.php") { echo "active"; } ?>">
<a href="settings_custom_fields.php" class="nav-link <?php //if (basename($_SERVER["PHP_SELF"]) == "settings_custom_fields.php") { echo "active"; }
?>">
<i class="nav-icon fas fa-th-list"></i>
<p>Custom Fields</p>
</a>
</li>
-->
<li class="nav-item">
<a href="admin_taxes.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_taxes.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-balance-scale"></i>
<p>Taxes</p>
</a>
</li>
<li class="nav-item">
<a href="admin_account_types.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_account_types.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-money-bill-wave"></i>
<p>Account Types</p>
</a>
</li>
<li class="nav-item">
<a href="admin_taxes.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_taxes.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-balance-scale"></i>
<p>Taxes</p>
</a>
</li>
<li class="nav-header mt-3">TEMPLATES</li>
<li class="nav-item">
<a href="admin_account_types.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_account_types.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-money-bill-wave"></i>
<p>Account Types</p>
</a>
</li>
<li class="nav-item">
<a href="admin_vendor_templates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_vendor_templates.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-building"></i>
<p>Vendor Templates</p>
</a>
</li>
<li class="nav-header mt-3">TEMPLATES</li>
<li class="nav-item">
<a href="admin_software_templates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_software_templates.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-rocket"></i>
<p>License Templates</p>
</a>
</li>
<li class="nav-item">
<a href="admin_vendor_templates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_vendor_templates.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-building"></i>
<p>Vendor Templates</p>
</a>
</li>
<li class="nav-item">
<a href="admin_document_templates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_document_templates.php" || basename($_SERVER["PHP_SELF"]) == "admin_document_template_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-file"></i>
<p>Document Templates</p>
</a>
</li>
<li class="nav-item">
<a href="admin_software_templates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_software_templates.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-rocket"></i>
<p>License Templates</p>
</a>
</li>
<li class="nav-header mt-3">MAINTENANCE</li>
<li class="nav-item">
<a href="admin_document_templates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_document_templates.php" || basename($_SERVER["PHP_SELF"]) == "admin_document_template_details.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-file"></i>
<p>Document Templates</p>
</a>
</li>
<li class="nav-item">
<a href="admin_mail_queue.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_mail_queue.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-mail-bulk"></i>
<p>Mail Queue</p>
</a>
</li>
<li class="nav-header mt-3">MAINTENANCE</li>
<li class="nav-item">
<a href="admin_logs.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_logs.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-history"></i>
<p>Audit Logs</p>
</a>
</li>
<li class="nav-item">
<a href="admin_mail_queue.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_mail_queue.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-mail-bulk"></i>
<p>Mail Queue</p>
</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_backup.php") { echo "active"; } ?>"
href="admin_backup.php">
<i class="nav-icon fas fa-cloud-upload-alt"></i>
<p>Backup</p>
</a>
</li>
<li class="nav-item">
<a href="admin_logs.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_logs.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-history"></i>
<p>Audit Logs</p>
</a>
</li>
<li class="nav-item">
<a href="admin_debug.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_debug.php") { echo "active"; } ?>">
<i class="nav-icon fa fa-bug"></i>
<p>Debug</p>
</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_backup.php") {
echo "active";
} ?>" href="admin_backup.php">
<i class="nav-icon fas fa-cloud-upload-alt"></i>
<p>Backup</p>
</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_update.php") { echo "active"; } ?>"
href="admin_update.php">
<i class="nav-icon fas fa-download"></i>
<p>Update</p>
</a>
</li>
<li class="nav-item">
<a href="admin_debug.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_debug.php") {
echo "active";
} ?>">
<i class="nav-icon fa fa-bug"></i>
<p>Debug</p>
</a>
</li>
</ul>
</nav>
<!-- /.sidebar-menu -->
<li class="nav-item">
<a class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_update.php") {
echo "active";
} ?>" href="admin_update.php">
<i class="nav-icon fas fa-download"></i>
<p>Update</p>
</a>
</li>
<div class="mb-3"></div>
<li class="nav-header"> Other</li>
</div>
<!-- /.sidebar -->
</aside>
<li class="nav-item">
<a href="admin_bulk_mail.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "admin_bulk_mail.php") {
echo "active";
} ?>">
<i class="nav-icon fas fa-envelope"></i>
<p>Bulk Mail</p>
</a>
</ul>
</nav>
<!-- /.sidebar-menu -->
<div class="mb-3"></div>
</div>
<!-- /.sidebar -->
</aside>

View File

@ -10,12 +10,12 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
);
?>
<form action="post.php" method="post">
<form action="post.php" method="post">
<div class="card">
<div class="card-header">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-envelope-open mr-2"></i>Bulk Mail</h3>
<h3 class="card-title mt-2"><i class="fa fa-fw fa-envelope-open mr-2"></i>Bulk Mail to Special Contacts</h3>
<div class="card-tools">
<button type="submit" class="btn btn-primary" name="send_bulk_mail_now">
<i class="fas fa-paper-plane mr-2"></i>Send Now
@ -25,19 +25,29 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
<div class="card-body">
<div class="row">
<div class="col">
<h5>Email Message</h5>
<hr>
<div class="form-group">
<input type="text" class="form-control" name="mail_from" placeholder="Email From" value="<?php echo nullable_htmlentities($config_mail_from_email); ?>" required>
<select type="text" class="form-control select2" name="mail_from">
<option value="<?php echo $config_mail_from_email; ?>">
<?php echo $config_mail_from_email; ?></option>
<option value="<?php echo $config_invoice_from_email; ?>">
<?php echo $config_invoice_from_email; ?></option>
<option value="<?php echo $config_quote_from_email; ?>">
<?php echo $config_quote_from_email; ?></option>
<option value="<?php echo $config_ticket_from_email; ?>">
<?php echo $config_ticket_from_email; ?></option>
</select>
</div>
<div class="form-group">
<input type="text" class="form-control" name="mail_from_name" placeholder="From Name" value="<?php echo nullable_htmlentities($config_mail_from_name); ?>" required>
<input type="text" class="form-control" name="mail_from_name" placeholder="From Name"
value="<?php echo nullable_htmlentities($config_mail_from_name); ?>" required>
</div>
<div class="form-group">
@ -45,7 +55,8 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
</div>
<div class="form-group">
<textarea class="form-control tinymce" name="body" placeholder="Type an email in here"></textarea>
<textarea class="form-control tinymce" name="body"
placeholder="Type an email in here"></textarea>
</div>
<div class="form-group">
@ -70,7 +81,8 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
<tr>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="selectAllCheckbox" onchange="toggleCheckboxes()">
<input type="checkbox" class="form-check-input" id="selectAllCheckbox"
onchange="toggleCheckboxes()">
</div>
</td>
<th>Name</th>
@ -80,7 +92,7 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
</thead>
<tbody>
<?php
<?php
while ($row = mysqli_fetch_array($sql)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
@ -96,27 +108,29 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
$contact_billing = intval($row['contact_billing']);
$contact_technical = intval($row['contact_technical']);
?>
<tr>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" name="contact[]" value="<?php echo $contact_id; ?>">
</div>
</td>
<td>
<a href="client_contact_details.php?client_id=<?php echo $client_id; ?>&contact_id=<?php echo $contact_id; ?>" target="_blank">
<?php echo $contact_name; ?>
</a>
</td>
<td><?php echo $contact_title_display; ?></td>
<td><?php echo $contact_email; ?></td>
</tr>
<?php } ?>
<tr>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" name="contact[]"
value="<?php echo $contact_id; ?>">
</div>
</td>
<td>
<a href="client_contact_details.php?client_id=<?php echo $client_id; ?>&contact_id=<?php echo $contact_id; ?>"
target="_blank">
<?php echo $contact_name; ?>
</a>
</td>
<td><?php echo $contact_title_display; ?></td>
<td><?php echo $contact_email; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
@ -129,7 +143,7 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
function toggleCheckboxes() {
// Get the state of the 'selectAllCheckbox'
var selectAllChecked = document.getElementById('selectAllCheckbox').checked;
// Find all checkboxes with the name 'contact[]' and set their state
var checkboxes = document.querySelectorAll('input[type="checkbox"][name="contact[]"]');
checkboxes.forEach(function(checkbox) {
@ -140,4 +154,4 @@ function toggleCheckboxes() {
<?php
require_once "footer.php";
require_once "footer.php";

View File

@ -21,51 +21,61 @@ $sql = mysqli_query(
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_id') AS num FROM recurring WHERE recurring_archived_at IS NULL AND recurring_client_id = $client_id"));
$recurring_invoice_count = $row['num'];
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-invoice mr-2"></i>Invoices</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addInvoiceModal"><i class="fas fa-plus mr-2"></i>New Invoice</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportInvoiceModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-invoice mr-2"></i>Invoices</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addInvoiceModal"><i class="fas fa-plus mr-2"></i>New Invoice</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportInvoiceModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="row">
</div>
<div class="card-body">
<form autocomplete="off">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Invoices">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {
echo stripslashes(nullable_htmlentities($q));
} ?>" placeholder="Search Invoices">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-md-8">
<div class="float-right">
<?php if($balance > 0) { ?>
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#addBulkPaymentModal"><i class="fa fa-credit-card mr-2"></i>Batch Payment</button>
<div class="col-md-8">
<div class="float-right">
<div class="btn-group float-right">
<a href="client_recurring_invoices.php?client_id=<?php echo $client_id; ?>" class="btn btn-outline-primary"><i class="fa fa-fw fa-redo-alt mr-2"></i>Recurring | <b><?php echo $recurring_invoice_count; ?></b></a>
<?php if ($balance > 0) { ?>
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#addBulkPaymentModal"><i class="fa fa-credit-card mr-2"></i>Batch Payment</button>
<?php } ?>
</div>
</div>
</div>
</form>
<hr>
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
</div>
</form>
<hr>
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) {
echo "d-none";
} ?>">
<tr>
<th><a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_number&order=<?php echo $disp; ?>">Number</a></th>
<th><a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_scope&order=<?php echo $disp; ?>">Scope</a></th>
@ -76,8 +86,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<th><a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_status&order=<?php echo $disp; ?>">Status</a></th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
@ -121,14 +131,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$invoice_badge_color = "secondary";
}
?>
?>
<tr>
<td class="text-bold"><a href="invoice.php?invoice_id=<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number"; ?></a></td>
<td><?php echo $invoice_scope_display; ?></td>
<td class="text-bold text-right"><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td>
<td><?php echo $invoice_date; ?></td>
<td><div class="<?php echo $overdue_color; ?>"><?php echo $invoice_due; ?></div></td>
<td>
<div class="<?php echo $overdue_color; ?>"><?php echo $invoice_due; ?></div>
</td>
<td><?php echo $category_name; ?></td>
<td>
<span class="p-2 badge badge-<?php echo $invoice_badge_color; ?>">
@ -162,23 +174,22 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</td>
</tr>
<?php
<?php
require "invoice_copy_modal.php";
require "invoice_edit_modal.php";
}
?>
</tbody>
</table>
</div>
<?php require_once "pagination.php";
?>
</tbody>
</table>
</div>
<?php require_once "pagination.php";
?>
</div>
</div>
<?php
require_once "invoice_add_modal.php";
@ -188,4 +199,3 @@ require_once "invoice_payment_add_bulk_modal.php";
require_once "client_invoice_export_modal.php";
require_once "footer.php";

View File

@ -53,6 +53,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="col-md-8">
<div class="float-right">
<div class="btn-group float-right">
<a href="client_invoices.php?client_id=<?php echo $client_id; ?>" class="btn btn-outline-primary"><i class="fa fa-fw fa-file-invoice mr-2"></i>Back to Invoices</a>
</div>
</div>
</div>

View File

@ -51,7 +51,7 @@
<li class="nav-header mt-3">SUPPORT</li>
<li class="nav-item">
<a href="client_tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_tickets.php") { echo "active"; } ?>">
<a href="client_tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_tickets.php" || basename($_SERVER["PHP_SELF"]) == "client_recurring_tickets.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-life-ring"></i>
<p>
Tickets
@ -64,19 +64,6 @@
</a>
</li>
<li class="nav-item">
<a href="client_recurring_tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_recurring_tickets.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-calendar-check"></i>
<p>
Recurring Tickets
<?php
if ($num_scheduled_tickets > 0) { ?>
<span class="right badge text-light"><?php echo $num_scheduled_tickets; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
@ -237,7 +224,7 @@
<li class="nav-header mt-3">FINANCE</li>
<li class="nav-item">
<a href="client_invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_invoices.php") { echo "active"; } ?>">
<a href="client_invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_invoices.php" || basename($_SERVER["PHP_SELF"]) == "client_recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "client_recurring_invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-file-invoice"></i>
<p>
Invoices
@ -249,18 +236,6 @@
</a>
</li>
<li class="nav-item">
<a href="client_recurring_invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_recurring_invoices.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Invoices
<?php
if ($num_recurring > 0) { ?>
<span class="right badge text-light"><?php echo $num_recurring; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="client_quotes.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_quotes.php") { echo "active"; } ?>">

View File

@ -137,13 +137,14 @@ if (isset($_GET['client_id'])) {
payments.payment_amount,
payments.payment_reference,
invoices.invoice_number,
invoices.invoice_prefix
invoices.invoice_prefix,
invoices.invoice_client_id
FROM
payments
LEFT JOIN
invoices ON payments.payment_invoice_id = invoices.invoice_id
WHERE
payment_account_id = $client_id
invoice_client_id = $client_id
AND payment_archived_at IS NULL
ORDER BY
payment_date DESC";

View File

@ -59,6 +59,11 @@ $sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS to
$row = mysqli_fetch_array($sql_total_tickets_closed);
$total_tickets_closed = intval($row['total_tickets_closed']);
//Get Total Scheduled tickets
$sql_total_scheduled_tickets = mysqli_query($mysqli, "SELECT COUNT(scheduled_ticket_id) AS total_scheduled_tickets FROM scheduled_tickets WHERE scheduled_ticket_client_id = $client_id");
$row = mysqli_fetch_array($sql_total_scheduled_tickets);
$total_scheduled_tickets = intval($row['total_scheduled_tickets']);
?>
<div class="card card-dark">
@ -97,8 +102,13 @@ $total_tickets_closed = intval($row['total_tickets_closed']);
</div>
</div>
<div class="col-md-8">
<div class="float-right">
<a href="client_recurring_tickets.php?client_id=<?php echo $client_id; ?>" class="btn btn-outline-info">
<i class="fa fa-fw fa-redo-alt mr-2"></i>Recurring Tickets | <strong> <?php echo $total_scheduled_tickets; ?></strong>
</a>
</div>
</div>

View File

@ -956,7 +956,12 @@ function calculateAccountBalance($mysqli, $account_id)
function generateReadablePassword($security_level)
{
// Cap security level at 5
$security_level = intval($security_level);
$security_level = min($security_level, 5);
// Arrays of words
$articles = ['The', 'A'];
$adjectives = ['Smart', 'Swift', 'Secure', 'Stable', 'Digital', 'Virtual', 'Active', 'Dynamic', 'Innovative', 'Efficient', 'Portable', 'Wireless', 'Rapid', 'Intuitive', 'Automated', 'Robust', 'Reliable', 'Sleek', 'Modern', 'Happy', 'Funny', 'Quick', 'Bright', 'Clever', 'Gentle', 'Brave', 'Calm', 'Eager', 'Fierce', 'Kind', 'Lucky', 'Proud', 'Silly', 'Witty', 'Bold', 'Curious', 'Elated', 'Gracious', 'Honest', 'Jolly', 'Merry', 'Noble', 'Optimistic', 'Playful', 'Quirky', 'Rustic', 'Steady', 'Tranquil', 'Upbeat'];
$nouns = ['Computer', 'Laptop', 'Tablet', 'Server', 'Router', 'Software', 'Hardware', 'Pixel', 'Byte', 'App', 'Network', 'Cloud', 'Firewall', 'Email', 'Database', 'Folder', 'Document', 'Interface', 'Program', 'Gadget', 'Dinosaur', 'Tiger', 'Elephant', 'Kangaroo', 'Monkey', 'Unicorn', 'Dragon', 'Puppy', 'Kitten', 'Parrot', 'Lion', 'Bear', 'Fox', 'Wolf', 'Rabbit', 'Deer', 'Owl', 'Hedgehog', 'Turtle', 'Frog', 'Butterfly', 'Panda', 'Giraffe', 'Zebra', 'Peacock', 'Koala', 'Raccoon', 'Squirrel', 'Hippo', 'Rhino', 'Book', "Monitor"];
$verbs = ['Connects', 'Runs', 'Processes', 'Secures', 'Encrypts', 'Saves', 'Updates', 'Boots', 'Scans', 'Compiles', 'Executes', 'Restores', 'Installs', 'Configures', 'Downloads', 'Streams', 'BacksUp', 'Syncs', 'Browses', 'Navigates', 'Runs', 'Jumps', 'Flies', 'Swims', 'Dances', 'Sings', 'Hops', 'Skips', 'Races', 'Climbs', 'Crawls', 'Glides', 'Twirls', 'Swings', 'Sprints', 'Gallops', 'Trots', 'Wanders', 'Strolls', 'Marches'];
@ -968,40 +973,48 @@ function generateReadablePassword($security_level)
$verb = $verbs[array_rand($verbs)];
$adv = $adverbs[array_rand($adverbs)];
// Combine to create a base password
if ($security_level > 2) {
$password = "The" . $adj . $noun . $adv . $verb;
} else {
$password = $adj . $noun . $verb;
$password = $adj . $noun . $verb . $adv;
// Select an article randomly
$article = $articles[array_rand($articles)];
// Determine if we should use 'An' instead of 'A'
if ($article == 'A' && preg_match('/^[aeiouAEIOU]/', $adj)) {
$article = 'An';
}
// Add the article to the password
$password = $article . $password;
// Mapping of letters to special characters and numbers
$mappings = [
'A' => '@', 'a' => '@',
'E' => '3', 'e' => '3',
'I' => '!', 'i' => '!',
'O' => '0', 'o' => '0',
'S' => '$', 's' => '$'
'S' => '$', 's' => '$',
'T' => '+', 't' => '+',
'B' => '8', 'b' => '8'
];
// Replace characters based on mappings
if ($security_level > 4) {
$password = strtr($password, $mappings);
} else {
// Randomly replace characters based on mappings
for ($i = 0; $i < strlen($password); $i++) {
if (array_key_exists($password[$i], $mappings) && rand(0, 1)) {
$password[$i] = $mappings[$password[$i]];
}
// Generate an array of indices based on the password length
$indices = range(0, strlen($password) - 1);
// Randomly shuffle the indices
shuffle($indices);
// Iterate through the shuffled indices and replace characters based on the security level
for ($i = 0; $i < min($security_level, strlen($password)); $i++) {
$index = $indices[$i]; // Get a random index
$currentChar = $password[$index]; // Get the character at this index
// Check if the current character has a mapping and replace it
if (array_key_exists($currentChar, $mappings)) {
$password[$index] = $mappings[$currentChar];
}
}
if ($security_level > 3) {
// Add a random number at the end
$password .= rand(0, 99);
}
// Add as many random numbers as the security level
$password .= rand(pow(10, $security_level - 1), pow(10, $security_level) - 1);
return $password;
}

View File

@ -66,7 +66,7 @@ validateAccountantRole();
?>
<tr>
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<td><a href="client_statement.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

View File

@ -85,8 +85,16 @@
</thead>
<tbody>
<?php
$processed_clients = []; // Array to keep track of processed client IDs
while ($row = mysqli_fetch_assoc($result_client_balance_report)) {
$client_id = intval($row['client_id']);
// Skip this row if we've already processed this client ID
if (in_array($client_id, $processed_clients)) {
continue; // Skip to the next iteration of the loop
} // Add the client ID to the array of processed clients
$processed_clients[] = $client_id;
$client_name = nullable_htmlentities($row['client_name']);
$balance = floatval($row['balance']);
$billing_contact_phone = formatPhoneNumber($row['billing_contact_phone']);

View File

@ -77,7 +77,7 @@ $sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS to
$row = mysqli_fetch_array($sql_total_tickets_closed);
$total_tickets_closed = intval($row['total_tickets_closed']);
//Get Total Scheduled tickets
//Get Total Recurring (scheduled) tickets
$sql_total_scheduled_tickets = mysqli_query($mysqli, "SELECT COUNT(scheduled_ticket_id) AS total_scheduled_tickets FROM scheduled_tickets");
$row = mysqli_fetch_array($sql_total_scheduled_tickets);
$total_scheduled_tickets = intval($row['total_scheduled_tickets']);