From 928af1d90ddf8777cec185ebe601e1bb6ae33d73 Mon Sep 17 00:00:00 2001 From: johnnyq Date: Fri, 11 Mar 2022 20:24:03 -0500 Subject: [PATCH] Added Ticket to Invoice functionality Thanks @aftechro --- ...c0a322b208e83d22d3aef33ecb184bc71d31,1.ser | Bin 0 -> 93746 bytes post.php | 92 +++++++++++ ticket.php | 4 +- ticket_invoice_add_modal.php | 147 ++++++++++++++++++ 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/4.14.0,f474c0a322b208e83d22d3aef33ecb184bc71d31,1.ser create mode 100644 ticket_invoice_add_modal.php diff --git a/plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/4.14.0,f474c0a322b208e83d22d3aef33ecb184bc71d31,1.ser b/plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/4.14.0,f474c0a322b208e83d22d3aef33ecb184bc71d31,1.ser new file mode 100644 index 0000000000000000000000000000000000000000..1dd448221e04ce8926e42cbe9fb26a8bc3f20176 GIT binary patch literal 93746 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 BRI>m8 literal 0 HcmV?d00001 diff --git a/post.php b/post.php index d3ef6358..b7783370 100644 --- a/post.php +++ b/post.php @@ -5760,6 +5760,98 @@ if(isset($_GET['close_ticket'])){ } +if(isset($_POST['add_invoice_from_ticket'])){ + + $ticket_id = intval($_GET['ticket_id']); + $date = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['date']))); + $category = intval($_POST['category']); + $scope = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['scope']))); + + $sql = mysqli_query($mysqli, "SELECT * FROM tickets + LEFT JOIN clients ON ticket_client_id = client_id + LEFT JOIN contacts ON ticket_contact_id = contact_id + LEFT JOIN assets ON ticket_asset_id = asset_id + LEFT JOIN locations ON ticket_location_id = location_id + WHERE ticket_id = $ticket_id + AND tickets.company_id = $session_company_id" + ); + + $row = mysqli_fetch_array($sql); + $client_id = $row['client_id']; + $client_net_terms = $row['client_net_terms']; + if($client_net_terms == 0){ + $client_net_terms = $config_default_net_terms; + } + + $ticket_prefix = $row['ticket_prefix']; + $ticket_number = $row['ticket_number']; + $ticket_category = $row['ticket_category']; + $ticket_subject = $row['ticket_subject']; + $ticket_created_at = $row['ticket_created_at']; + $ticket_updated_at = $row['ticket_updated_at']; + $ticket_closed_at = $row['ticket_closed_at']; + + $contact_id = $row['contact_id']; + $contact_name = $row['contact_name']; + $contact_email = $row['contact_email']; + + $asset_id = $row['asset_id']; + + $location_name = $row['location_name']; + + + //Get the last Invoice Number and add 1 for the new invoice number + $invoice_number = $config_invoice_next_number; + $new_config_invoice_next_number = $config_invoice_next_number + 1; + mysqli_query($mysqli,"UPDATE settings SET config_invoice_next_number = $new_config_invoice_next_number WHERE company_id = $session_company_id"); + + //Generate a unique URL key for clients to access + $url_key = keygen(); + + mysqli_query($mysqli,"INSERT INTO invoices SET invoice_prefix = '$config_invoice_prefix', invoice_number = $invoice_number, invoice_scope = '$scope', invoice_date = '$date', invoice_due = DATE_ADD('$date', INTERVAL $client_net_terms day), invoice_currency_code = '$session_company_currency', invoice_category_id = $category, invoice_status = 'Draft', invoice_url_key = '$url_key', invoice_created_at = NOW(), invoice_client_id = $client_id, company_id = $session_company_id"); + $invoice_id = mysqli_insert_id($mysqli); + + //Add Item + $item_name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['item_name']))); + $item_description = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['item_description']))); + $qty = floatval($_POST['qty']); + $price = floatval($_POST['price']); + $tax_id = intval($_POST['tax_id']); + + $subtotal = $price * $qty; + + if($tax_id > 0){ + $sql = mysqli_query($mysqli,"SELECT * FROM taxes WHERE tax_id = $tax_id"); + $row = mysqli_fetch_array($sql); + $tax_percent = $row['tax_percent']; + $tax_amount = $subtotal * $tax_percent / 100; + }else{ + $tax_amount = 0; + } + + $total = $subtotal + $tax_amount; + + mysqli_query($mysqli,"INSERT INTO invoice_items SET item_name = '$item_name', item_description = '$item_description', item_quantity = $qty, item_price = '$price', item_subtotal = '$subtotal', item_tax = '$tax_amount', item_total = '$total', item_created_at = NOW(), item_tax_id = $tax_id, item_invoice_id = $invoice_id, company_id = $session_company_id"); + + //Update Invoice Balances + + $sql = mysqli_query($mysqli,"SELECT * FROM invoices WHERE invoice_id = $invoice_id AND company_id = $session_company_id"); + $row = mysqli_fetch_array($sql); + + $new_invoice_amount = $row['invoice_amount'] + $total; + + mysqli_query($mysqli,"UPDATE invoices SET invoice_amount = '$new_invoice_amount', invoice_updated_at = NOW() WHERE invoice_id = $invoice_id AND company_id = $session_company_id"); + + mysqli_query($mysqli,"INSERT INTO history SET history_status = 'Draft', history_description = 'Invoice created from Ticket $ticket_prefix$ticket_number', history_created_at = NOW(), history_invoice_id = $invoice_id, company_id = $session_company_id"); + + //Logging + mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Invoice', log_action = 'Created', log_description = '$config_invoice_prefix$invoice_number created from Ticket $ticket_prefix$ticket_number', log_created_at = NOW(), company_id = $session_company_id, log_user_id = $session_user_id"); + + $_SESSION['alert_message'] = "Invoice created from ticket"; + + header("Location: invoice.php?invoice_id=$invoice_id"); +} + if(isset($_GET['export_client_tickets_csv'])){ $client_id = intval($_GET['export_client_tickets_csv']); diff --git a/ticket.php b/ticket.php index 9deb0537..ab2fc301 100644 --- a/ticket.php +++ b/ticket.php @@ -38,6 +38,7 @@ if(isset($_GET['ticket_id'])){ $ticket_priority = $row['ticket_priority']; $ticket_status = $row['ticket_status']; $ticket_created_at = $row['ticket_created_at']; + $ticket_date = date('Y-m-d',strtotime($ticket_created_at)); $ticket_updated_at = $row['ticket_updated_at']; $ticket_closed_at = $row['ticket_closed_at']; $ticket_created_by = $row['ticket_created_by']; @@ -561,7 +562,7 @@ if(isset($_GET['ticket_id'])){ @@ -577,6 +578,7 @@ if(isset($_GET['ticket_id'])){ + + \ No newline at end of file