Merge pull request #834 from twetech/billable_tickets

Update ticket billing functionality
This commit is contained in:
Johnny 2023-12-20 23:43:51 -05:00 committed by GitHub
commit 8ff6271058
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 310 additions and 79 deletions

View File

@ -336,34 +336,34 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
//Insert queries here required to update to DB version 0.2.1
mysqli_query($mysqli, "ALTER TABLE `vendors`
ADD `vendor_hours` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_website`,
ADD `vendor_sla` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_hours`,
ADD `vendor_code` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_sla`,
ADD `vendor_template_id` INT(11) DEFAULT 0 AFTER `vendor_archived_at`
");
ADD `vendor_hours` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_website`,
ADD `vendor_sla` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_hours`,
ADD `vendor_code` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_sla`,
ADD `vendor_template_id` INT(11) DEFAULT 0 AFTER `vendor_archived_at`
");
mysqli_query($mysqli, "ALTER TABLE `vendors`
DROP `vendor_country`,
DROP `vendor_address`,
DROP `vendor_city`,
DROP `vendor_state`,
DROP `vendor_zip`,
DROP `vendor_global`
");
DROP `vendor_country`,
DROP `vendor_address`,
DROP `vendor_city`,
DROP `vendor_state`,
DROP `vendor_zip`,
DROP `vendor_global`
");
//Create New Vendor Templates Table
mysqli_query($mysqli, "CREATE TABLE `vendor_templates` (`vendor_template_id` int(11) AUTO_INCREMENT PRIMARY KEY,
`vendor_template_name` varchar(200) NOT NULL,
`vendor_template_description` varchar(200) NULL DEFAULT NULL,
`vendor_template_phone` varchar(200) NULL DEFAULT NULL,
`vendor_template_email` varchar(200) NULL DEFAULT NULL,
`vendor_template_website` varchar(200) NULL DEFAULT NULL,
`vendor_template_hours` varchar(200) NULL DEFAULT NULL,
`vendor_template_created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`vendor_template_updated_at` datetime NULL ON UPDATE CURRENT_TIMESTAMP,
`vendor_template_archived_at` datetime NULL DEFAULT NULL,
`company_id` int(11) NOT NULL
)");
`vendor_template_name` varchar(200) NOT NULL,
`vendor_template_description` varchar(200) NULL DEFAULT NULL,
`vendor_template_phone` varchar(200) NULL DEFAULT NULL,
`vendor_template_email` varchar(200) NULL DEFAULT NULL,
`vendor_template_website` varchar(200) NULL DEFAULT NULL,
`vendor_template_hours` varchar(200) NULL DEFAULT NULL,
`vendor_template_created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`vendor_template_updated_at` datetime NULL ON UPDATE CURRENT_TIMESTAMP,
`vendor_template_archived_at` datetime NULL DEFAULT NULL,
`company_id` int(11) NOT NULL
)");
//Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.2.1'");
@ -393,21 +393,20 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
}
if (CURRENT_DATABASE_VERSION == '0.2.3') {
//Create New interfaces Table
mysqli_query($mysqli, "CREATE TABLE `interfaces` (`interface_id` int(11) AUTO_INCREMENT PRIMARY KEY,
`interface_number` int(11) NULL DEFAULT NULL,
`interface_description` varchar(200) NULL DEFAULT NULL,
`interface_connected_asset` varchar(200) NULL DEFAULT NULL,
`interface_ip` varchar(200) NULL DEFAULT NULL,
`interface_created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`interface_updated_at` datetime NULL ON UPDATE CURRENT_TIMESTAMP,
`interface_archived_at` datetime NULL DEFAULT NULL,
`interface_connected_asset_id` int(11) NOT NULL DEFAULT 0,
`interface_network_id` int(11) NOT NULL DEFAULT 0,
`interface_asset_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL
)");
`interface_number` int(11) NULL DEFAULT NULL,
`interface_description` varchar(200) NULL DEFAULT NULL,
`interface_connected_asset` varchar(200) NULL DEFAULT NULL,
`interface_ip` varchar(200) NULL DEFAULT NULL,
`interface_created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`interface_updated_at` datetime NULL ON UPDATE CURRENT_TIMESTAMP,
`interface_archived_at` datetime NULL DEFAULT NULL,
`interface_connected_asset_id` int(11) NOT NULL DEFAULT 0,
`interface_network_id` int(11) NOT NULL DEFAULT 0,
`interface_asset_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL
)");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.2.4'");
@ -1372,12 +1371,12 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
}
if (CURRENT_DATABASE_VERSION == '0.8.6') {
// Insert queries here required to update to DB version 0.8.7
mysqli_query($mysqli, "ALTER TABLE `accounts` ADD `account_type` int(6) DEFAULT NULL AFTER `account_notes`");
mysqli_query($mysqli, "CREATE TABLE `account_types` (`account_type_id` int(11) NOT NULL AUTO_INCREMENT,`account_type_name` varchar(255) NOT NULL,`account_type_description` text DEFAULT NULL,`account_type_created_at` datetime NOT NULL DEFAULT current_timestamp(),`account_type_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),`account_type_archived_at` datetime DEFAULT NULL,PRIMARY KEY (`account_type_id`))");
// Insert queries here required to update to DB version 0.8.7
mysqli_query($mysqli, "ALTER TABLE `accounts` ADD `account_type` int(6) DEFAULT NULL AFTER `account_notes`");
mysqli_query($mysqli, "CREATE TABLE `account_types` (`account_type_id` int(11) NOT NULL AUTO_INCREMENT,`account_type_name` varchar(255) NOT NULL,`account_type_description` text DEFAULT NULL,`account_type_created_at` datetime NOT NULL DEFAULT current_timestamp(),`account_type_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),`account_type_archived_at` datetime DEFAULT NULL,PRIMARY KEY (`account_type_id`))");
// Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.8.7'");
// Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.8.7'");
}
if (CURRENT_DATABASE_VERSION == '0.8.7') {
@ -1398,29 +1397,28 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
if (CURRENT_DATABASE_VERSION == '0.8.8') {
// Insert queries here required to update to DB version 0.8.9
mysqli_query($mysqli, "ALTER TABLE `invoice_items` ADD `item_order` INT(11) NOT NULL DEFAULT 0 AFTER `item_total`");
// Update existing invoices so that item_order is set to item_id
$sql_invoices = mysqli_query($mysqli, "SELECT invoice_id FROM invoices WHERE invoice_id IS NOT NULL");
foreach ($sql_invoices as $row) {
$invoice_id = $row['invoice_id'];
$sql_invoice_items = mysqli_query($mysqli, "SELECT item_id FROM invoice_items WHERE item_invoice_id = '$invoice_id' ORDER BY item_id ASC");
$item_order = 1;
foreach ($sql_invoice_items as $row) {
$item_id = $row['item_id'];
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = '$item_order' WHERE item_id = '$item_id'");
$item_order++;
//Log changes made to invoice
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Invoice', log_action = 'Modify', log_description = 'Updated item_order to item_id: $item_order'");
// Insert queries here required to update to DB version 0.8.9
mysqli_query($mysqli, "ALTER TABLE `invoice_items` ADD `item_order` INT(11) NOT NULL DEFAULT 0 AFTER `item_total`");
// Update existing invoices so that item_order is set to item_id
$sql_invoices = mysqli_query($mysqli, "SELECT invoice_id FROM invoices WHERE invoice_id IS NOT NULL");
foreach ($sql_invoices as $row) {
$invoice_id = $row['invoice_id'];
$sql_invoice_items = mysqli_query($mysqli, "SELECT item_id FROM invoice_items WHERE item_invoice_id = '$invoice_id' ORDER BY item_id ASC");
$item_order = 1;
foreach ($sql_invoice_items as $row) {
$item_id = $row['item_id'];
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = '$item_order' WHERE item_id = '$item_id'");
$item_order++;
//Log changes made to invoice
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Invoice', log_action = 'Modify', log_description = 'Updated item_order to item_id: $item_order'");
}
}
}
//
// Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.8.9'");
}
//
//
// Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.8.9'");
}
if (CURRENT_DATABASE_VERSION == '0.8.9') {
@ -1461,10 +1459,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.9.0'");
}
// Be sure to change database_version.php to reflect the version you are updating to here
// Please add this same comment block to the bottom of this file, and update the version number.
// Uncomment Below Lines, to add additional database updates
//
if (CURRENT_DATABASE_VERSION == '0.9.0') {
//add leads column to clients table
mysqli_query($mysqli, "ALTER TABLE `clients` ADD `client_lead` TINYINT(1) NOT NULL DEFAULT 0 AFTER `client_id`");
@ -1510,6 +1505,26 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
// Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.9.6'");
}
if (CURRENT_DATABASE_VERSION == '0.9.6') {
// Insert queries here required to update to DB version 0.9.7
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_invoice_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_asset_id`");
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_billable` TINYINT(1) NOT NULL DEFAULT 0 AFTER `ticket_status`");
//set all invoice id
// Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.9.7'");
}
// Be sure to change database_version.php to reflect the version you are updating to here
// Please add this same comment block to the bottom of this file, and update the version number.
// Uncomment Below Lines, to add additional database updates
//
// if (CURRENT_DATABASE_VERSION == '0.9.7') {
// // Insert queries here required to update to DB version 0.9.8
// // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.9.8'");
// }
} else {
// Up-to-date
}

View File

@ -5,5 +5,5 @@
* It is used in conjunction with database_updates.php
*/
DEFINE("LATEST_DATABASE_VERSION", "0.9.6");
DEFINE("LATEST_DATABASE_VERSION", "0.9.7");

2
db.sql
View File

@ -1559,6 +1559,7 @@ CREATE TABLE `tickets` (
`ticket_details` longtext NOT NULL,
`ticket_priority` varchar(200) DEFAULT NULL,
`ticket_status` varchar(200) NOT NULL,
`ticket_billable` tinyint(1) NOT NULL DEFAULT 0,
`ticket_vendor_ticket_number` varchar(255) DEFAULT NULL,
`ticket_feedback` varchar(200) DEFAULT NULL,
`ticket_created_at` datetime NOT NULL DEFAULT current_timestamp(),
@ -1573,6 +1574,7 @@ CREATE TABLE `tickets` (
`ticket_contact_id` int(11) NOT NULL DEFAULT 0,
`ticket_location_id` int(11) NOT NULL DEFAULT 0,
`ticket_asset_id` int(11) NOT NULL DEFAULT 0,
`ticket_invoice_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`ticket_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

View File

@ -75,6 +75,29 @@ if (isset($_GET['invoice_id'])) {
$sql_payments = mysqli_query($mysqli, "SELECT * FROM payments, accounts WHERE payment_account_id = account_id AND payment_invoice_id = $invoice_id ORDER BY payments.payment_id DESC");
$sql_tickets = mysqli_query($mysqli, "
SELECT
tickets.*,
SEC_TO_TIME(SUM(TIME_TO_SEC(STR_TO_DATE(ticket_reply_time_worked, '%H:%i:%s')))) AS 'total_time_worked'
FROM
tickets
LEFT JOIN
ticket_replies ON tickets.ticket_id = ticket_replies.ticket_reply_ticket_id
WHERE
ticket_invoice_id = $invoice_id
GROUP BY
tickets.ticket_id
ORDER BY
ticket_id DESC
");
//Get billable, and unbilled tickets to add to invoice
$sql_tickets_billable = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_client_id = $client_id AND ticket_billable = 1 AND ticket_invoice_id = 0;");
//Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id");
$row = mysqli_fetch_array($sql_amount_paid);
@ -546,8 +569,85 @@ if (isset($_GET['invoice_id'])) {
</div>
</div>
</div>
<div class="col-sm d-print-none">
<div class="card">
<div class="card-header text-bold">
<i class="fa fa-cog mr-2"></i>Tickets
<div class="card-tools">
<?php if (mysqli_num_rows($sql_tickets_billable) > 0) { ?>
<a class="btn btn-tool" href="#" data-toggle="modal" data-target="#addTicketModal">
<i class="fas fa-plus"></i>
</a>
<?php } ?>
<a class="btn btn-tool" href="tickets.php?client_id=<?php echo $client_id; ?>">
<i class="fas fa-external-link-alt"></i>
</a>
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
<button type="button" class="btn btn-tool" data-card-widget="remove">
<i class="fas fa-times"></i>
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead class="<?php if (mysqli_num_rows($sql_tickets) == 0) { echo "d-none"; } ?>">
<tr>
<th>Date</th>
<th>Subject</th>
<th>Status</th>
<th>Priority</th>
<th>Assigned To</th>
<th class="text-right">Time Worked</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_tickets)) {
$ticket_id = intval($row['ticket_id']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_status = nullable_htmlentities($row['ticket_status']);
$ticket_priority = nullable_htmlentities($row['ticket_priority']);
$ticket_assigned_to_id = intval($row['ticket_assigned_to']);
$ticket_total_time_worked = floatval($row['total_time_worked']);
$sql_assigned_to = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $ticket_assigned_to_id");
$row = mysqli_fetch_array($sql_assigned_to);
$ticket_assigned_to = nullable_htmlentities($row['user_name']);
?>
<tr>
<td><?php echo $ticket_created_at; ?></td>
<td><?php echo $ticket_subject; ?></td>
<td><?php echo $ticket_status; ?></td>
<td><?php echo $ticket_priority; ?></td>
<td><?php echo $ticket_assigned_to; ?></td>
<td class="text-right"><?php echo $ticket_total_time_worked; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
<?php
include_once "invoice_add_ticket_modal.php";
include_once "invoice_payment_add_modal.php";
include_once "invoice_copy_modal.php";
@ -558,8 +658,6 @@ if (isset($_GET['invoice_id'])) {
include_once "invoice_note_modal.php";
include_once "category_quick_add_modal.php";
}
require_once "footer.php";

View File

@ -0,0 +1,34 @@
<div class="modal" id="addTicketModal">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-fw fa-file-invoice mr-2"></i>Add Unbilled Ticket to Invoice</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal->body bg-white">
<table class="table">
<tr>
<th>Ticket Number</th>
<th>Scope</th>
<th></th>
</tr>
<?php while ($row = mysqli_fetch_array($sql_tickets_billable)) {
$ticket_id = intval($row['ticket_id']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
?>
<tr>
<td><?php echo $ticket_id?></td>
<td><?php echo $ticket_subject ?></td>
<td></td>
<td><a href='ticket.php?ticket_id=<?php echo $ticket_id?>&invoice_id=<?php echo $invoice_id?>#addInvoiceFromTicketModal'>Add</a></td>
</tr>
<?php } ?>
</table>
</div>
</div>
</div>
</div>

8
js/show_modals.js Normal file
View File

@ -0,0 +1,8 @@
$(document).ready(function () {
$('.modal').each(function () {
const modalId = `#${$(this).attr('id')}`;
if (window.location.href.indexOf(modalId) !== -1) {
$(modalId).modal('show');
}
});
});

View File

@ -413,6 +413,9 @@ if (isset($_GET['delete_invoice'])) {
mysqli_query($mysqli,"DELETE FROM payments WHERE payment_id = $payment_id");
}
//unlink tickets from invoice
mysqli_query($mysqli,"UPDATE tickets SET ticket_invoice_id = 0 WHERE ticket_invoice_id = $invoice_id");
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Invoice', log_action = 'Delete', log_description = '$invoice_id', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id");
@ -1353,3 +1356,24 @@ if (isset($_POST['update_invoice_item_order'])) {
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
if (isset($_POST['link_invoice_to_ticket'])) {
$invoice_id = intval($_POST['invoice_id']);
$ticket_id = intval($_POST['ticket_id']);
mysqli_query($mysqli,"UPDATE invoices SET invoice_ticket_id = $ticket_id WHERE invoice_id = $invoice_id");
$_SESSION['alert_message'] = "Invoice linked to ticket";
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
if (isset($_POST['add_ticket_to_invoice'])) {
$invoice_id = intval($_POST['invoice_id']);
$ticket_id = intval($_POST['ticket_id']);
mysqli_query($mysqli,"UPDATE tickets SET ticket_invoice_id = $invoice_id WHERE ticket_id = $ticket_id");
$_SESSION['alert_message'] = "Ticket linked to invoice";
header("Location: post.php?add_ticket_to_invoice=$invoice_id");
}

View File

@ -24,6 +24,7 @@ if (isset($_POST['add_ticket'])) {
$asset_id = intval($_POST['asset']);
$use_primary_contact = intval($_POST['use_primary_contact']);
// Add the primary contact as the ticket contact if "Use primary contact" is checked
if ($use_primary_contact == 1) {
$sql = mysqli_query($mysqli,"SELECT contact_id FROM contacts WHERE contact_client_id = $client_id AND contact_primary = 1");
@ -31,12 +32,18 @@ if (isset($_POST['add_ticket'])) {
$contact = intval($row['contact_id']);
}
if (!isset($_POST['billable'])) {
$billable = 1;
} else {
$billable = intval($_POST['billable']);
}
//Get the next Ticket Number and add 1 for the new ticket number
$ticket_number = $config_ticket_next_number;
$new_config_ticket_next_number = $config_ticket_next_number + 1;
mysqli_query($mysqli,"UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = 1");
mysqli_query($mysqli,"INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = '$ticket_status', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_vendor_id = $vendor_id, ticket_asset_id = $asset_id, ticket_created_by = $session_user_id, ticket_assigned_to = $assigned_to, ticket_contact_id = $contact, ticket_client_id = $client_id");
mysqli_query($mysqli,"INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_billable = '$billable', ticket_status = '$ticket_status', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_vendor_id = $vendor_id, ticket_asset_id = $asset_id, ticket_created_by = $session_user_id, ticket_assigned_to = $assigned_to, ticket_contact_id = $contact, ticket_client_id = $client_id, ticket_invoice_id = 0");
$ticket_id = mysqli_insert_id($mysqli);
@ -145,15 +152,17 @@ if (isset($_POST['edit_ticket'])) {
$ticket_id = intval($_POST['ticket_id']);
$contact_id = intval($_POST['contact']);
$subject = sanitizeInput($_POST['subject']);
$billable = intval($_POST['billable']);
$priority = sanitizeInput($_POST['priority']);
$details = mysqli_real_escape_string($mysqli,$_POST['details']);
$vendor_ticket_number = sanitizeInput($_POST['vendor_ticket_number']);
$vendor_id = intval($_POST['vendor']);
$asset_id = intval($_POST['asset']);
$client_id = intval($_POST['client_id']);
$ticket_number = intval($_POST['ticket_number']);
mysqli_query($mysqli,"UPDATE tickets SET ticket_subject = '$subject', ticket_priority = '$priority', ticket_details = '$details', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_contact_id = $contact_id, ticket_vendor_id = $vendor_id, ticket_asset_id = $asset_id WHERE ticket_id = $ticket_id");
mysqli_query($mysqli,"UPDATE tickets SET ticket_subject = '$subject', ticket_priority = '$priority', ticket_billable = $billable, ticket_details = '$details', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_contact_id = $contact_id, ticket_vendor_id = $vendor_id, ticket_asset_id = $asset_id WHERE ticket_id = $ticket_id");
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Ticket', log_action = 'Modify', log_description = '$session_name modified ticket $ticket_number - $subject', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, log_entity_id = $ticket_id");
@ -870,8 +879,9 @@ if (isset($_POST['add_invoice_from_ticket'])) {
mysqli_query($mysqli,"INSERT INTO history SET history_status = 'Draft', history_description = 'Invoice created from Ticket $ticket_prefix$ticket_number', history_invoice_id = $invoice_id");
// Add internal note to ticket
// Add internal note to ticket, and link to invoice in database
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Created invoice <a href=\"invoice.php?invoice_id=$invoice_id\">$config_invoice_prefix$invoice_number</a> for this ticket.', ticket_reply_type = 'Internal', ticket_reply_time_worked = '00:01:00', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
mysqli_query($mysqli, "UPDATE tickets SET ticket_invoice_id = $invoice_id WHERE ticket_id = $ticket_id");
// Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Invoice', log_action = 'Create', log_description = '$config_invoice_prefix$invoice_number created from Ticket $ticket_prefix$ticket_number', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id");

View File

@ -51,6 +51,8 @@ if (isset($_GET['ticket_id'])) {
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_details = $purifier->purify($row['ticket_details']);
$ticket_priority = nullable_htmlentities($row['ticket_priority']);
$ticket_billable = intval($row['ticket_billable']);
//Set Ticket Bage Color based of priority
if ($ticket_priority == "High") {
$ticket_priority_display = "<span class='p-2 badge badge-danger'>$ticket_priority</span>";
@ -856,6 +858,7 @@ if (isset($_GET['ticket_id'])) {
require_once "footer.php";
?> <script src="js/show_modals.js"></script> <?php
if ($ticket_status !== "Closed") { ?>
<!-- Ticket Time Tracking JS -->
@ -867,3 +870,4 @@ if ($ticket_status !== "Closed") { ?>
<?php } ?>
<script src="js/pretty_content.js"></script>

View File

@ -62,6 +62,20 @@
</div>
</div>
<div class="form-group">
<label>Billable</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-money-bill"></i></span>
</div>
<select class="form-control select2" name="billable">
<option <?php if ($ticket_billable == 1) { echo "selected"; } ?> value="1">Yes</option>
<option <?php if ($ticket_billable == 0) { echo "selected"; } ?> value="0">No</option>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-contacts<?php echo $ticket_id; ?>">

View File

@ -1,3 +1,8 @@
<?php
// Check if ticket_id and invoice_id are set in the URL
$addToExistingInvoice = isset($_GET['ticket_id']) && isset($_GET['invoice_id']);
?>
<div class="modal" id="addInvoiceFromTicketModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
@ -13,10 +18,18 @@
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-create-invoice"><i class="fa fa-fw fa-check mr-2"></i>Create New Invoice</a>
<?php if (!$addToExistingInvoice): ?>
<a class="nav-link active" data-toggle="pill" href="#pills-create-invoice"><i class="fa fa-fw fa-check mr-2"></i>Create New Invoice</a>
<?php else: ?>
<a class="nav-link" data-toggle="pill" href="#pills-create-invoice"><i class="fa fa-fw fa-check mr-2"></i>Create New Invoice</a>
<?php endif; ?>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a>
<?php if ($addToExistingInvoice): ?>
<a class="nav-link active" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a>
<?php else: ?>
<a class="nav-link" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a>
<?php endif; ?>
</li>
</ul>
@ -24,7 +37,11 @@
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-create-invoice">
<?php if (!$addToExistingInvoice): ?>
<div class="tab-pane fade show active" id="pills-create-invoice">
<?php else: ?>
<div class="tab-pane fade" id="pills-create-invoice">
<?php endif; ?>
<div class="form-group">
<label>Invoice Date <strong class="text-danger">*</strong></label>
@ -32,7 +49,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="date" max="2999-12-31" value="<?php echo date("Y-m-d"); ?>" required>
<input type="date" class="form-control" name="date" max="2999-12-31" value="<?php echo date("Y-m-d"); ?>">
</div>
</div>
@ -42,7 +59,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
</div>
<select class="form-control select2" name="category" required>
<select class="form-control select2" name="category">
<option value="">- Category -</option>
<?php
@ -76,7 +93,12 @@
</div>
<div class="tab-pane fade" id="pills-add-to-invoice">
<?php if ($addToExistingInvoice): ?>
<div class="tab-pane fade show active" id="pills-add-to-invoice">
<?php else: ?>
<div class="tab-pane fade" id="pills-add-to-invoice">
<?php endif; ?>
<div class="form-group">
<label>Invoice</label>
@ -84,7 +106,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
</div>
<select class="form-control select2" name="invoice_id">
<select class="form-control" name="invoice_id">
<option value="0">- Invoice -</option>
<?php
@ -100,7 +122,7 @@
$invoice_amount = floatval($row['invoice_amount']);
?>
<option value="<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number $invoice_scope"; ?></option>
<option value="<?php echo $invoice_id; ?>" <?php if ($invoice_id == $_GET['invoice_id']) echo "selected"; ?>><?php echo "$invoice_prefix$invoice_number $invoice_scope"; ?></option>
<?php
}