From 1f02a1d2872d933971ee01cfb452ba60bba34dbf Mon Sep 17 00:00:00 2001 From: root Date: Fri, 17 May 2019 22:43:51 -0400 Subject: [PATCH] Quotes fully work now, including PDF, Email, Approval, Cancel, Edit, Copy, Copy to Invoice, also added quote_footer config to settings --- add_quote_copy_modal.php | 32 ++ add_quote_to_invoice_modal.php | 43 +++ client_quotes.php | 8 +- config.php | 1 + edit_quote_modal.php | 56 ++++ functions.php | 19 ++ post.php | 554 ++++++++++++++++++++++++++++++++- quote.php | 47 +-- quotes.php | 17 +- settings-invoice.php | 5 + 10 files changed, 755 insertions(+), 27 deletions(-) create mode 100644 add_quote_copy_modal.php create mode 100644 add_quote_to_invoice_modal.php create mode 100644 edit_quote_modal.php create mode 100644 functions.php diff --git a/add_quote_copy_modal.php b/add_quote_copy_modal.php new file mode 100644 index 00000000..e951017d --- /dev/null +++ b/add_quote_copy_modal.php @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/add_quote_to_invoice_modal.php b/add_quote_to_invoice_modal.php new file mode 100644 index 00000000..c150c628 --- /dev/null +++ b/add_quote_to_invoice_modal.php @@ -0,0 +1,43 @@ + \ No newline at end of file diff --git a/client_quotes.php b/client_quotes.php index cd3c8aa2..3cf9054b 100644 --- a/client_quotes.php +++ b/client_quotes.php @@ -1,6 +1,6 @@ @@ -17,6 +17,7 @@ Number Amount Date + Category Status Actions @@ -30,6 +31,8 @@ $quote_status = $row['quote_status']; $quote_date = $row['quote_date']; $quote_amount = $row['quote_amount']; + $category_id = $row['category_id']; + $category_name = $row['category_name']; if($quote_status == "Sent"){ $quote_badge_color = "warning"; @@ -37,6 +40,8 @@ $quote_badge_color = "primary"; }elseif($quote_status == "Approved"){ $quote_badge_color = "success"; + }elseif($quote_status == "Cancelled"){ + $quote_badge_color = "danger"; }else{ $quote_badge_color = "secondary"; } @@ -47,6 +52,7 @@ QUO- $ + diff --git a/config.php b/config.php index a4b06d22..c71234a4 100644 --- a/config.php +++ b/config.php @@ -31,6 +31,7 @@ $config_next_invoice_number = $row['config_next_invoice_number']; $config_invoice_logo = $row['config_invoice_logo']; $config_invoice_footer = $row['config_invoice_footer']; + $config_quote_footer = $row['config_quote_footer']; $config_smtp_host = $row['config_smtp_host']; $config_smtp_username = $row['config_smtp_username']; $config_smtp_password = $row['config_smtp_password']; diff --git a/edit_quote_modal.php b/edit_quote_modal.php new file mode 100644 index 00000000..914a9ca2 --- /dev/null +++ b/edit_quote_modal.php @@ -0,0 +1,56 @@ + \ No newline at end of file diff --git a/functions.php b/functions.php new file mode 100644 index 00000000..2f689b32 --- /dev/null +++ b/functions.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/post.php b/post.php index 46340703..0dfe5518 100644 --- a/post.php +++ b/post.php @@ -2,7 +2,7 @@ include("config.php"); include("check_login.php"); -//include("functions.php"); +include("functions.php"); require("vendor/PHPMailer-6.0.7/src/PHPMailer.php"); require("vendor/PHPMailer-6.0.7/src/SMTP.php"); @@ -63,8 +63,9 @@ if(isset($_POST['edit_invoice_settings'])){ $config_mail_from_email = strip_tags(mysqli_real_escape_string($mysqli,$_POST['config_mail_from_email'])); $config_mail_from_name = strip_tags(mysqli_real_escape_string($mysqli,$_POST['config_mail_from_name'])); $config_invoice_footer = strip_tags(mysqli_real_escape_string($mysqli,$_POST['config_invoice_footer'])); + $config_quote_footer = strip_tags(mysqli_real_escape_string($mysqli,$_POST['config_quote_footer'])); - mysqli_query($mysqli,"UPDATE settings SET config_next_invoice_number = '$config_next_invoice_number', config_mail_from_email = '$config_mail_from_email', config_mail_from_name = '$config_mail_from_name', config_invoice_footer = '$config_invoice_footer'"); + mysqli_query($mysqli,"UPDATE settings SET config_next_invoice_number = '$config_next_invoice_number', config_mail_from_email = '$config_mail_from_email', config_mail_from_name = '$config_mail_from_name', config_invoice_footer = '$config_invoice_footer', config_quote_footer = '$config_quote_footer'"); header("Location: " . $_SERVER["HTTP_REFERER"]); @@ -187,8 +188,9 @@ if(isset($_POST['edit_user'])){ $path = strip_tags(mysqli_real_escape_string($mysqli,$_POST['current_avatar_path'])); if($_FILES['file']['tmp_name']!='') { - //remove old receipt + //delete old avatar file unlink($path); + //Update with new path $path = "uploads/user_avatars/"; $path = $path . basename( $_FILES['file']['name']); $file_name = basename($path); @@ -829,7 +831,11 @@ if(isset($_POST['add_quote'])){ $row = mysqli_fetch_array($sql); $quote_number = $row['quote_number'] + 1; - mysqli_query($mysqli,"INSERT INTO quotes SET quote_number = $quote_number, quote_date = '$date', category_id = $category, quote_status = 'Draft', client_id = $client"); + //Generate a unique URL key for clients to access + $quote_url_key = keygen(); + + + mysqli_query($mysqli,"INSERT INTO quotes SET quote_number = $quote_number, quote_date = '$date', category_id = $category, quote_status = 'Draft', quote_url_key = '$quote_url_key', quote_created_at = NOW(), client_id = $client"); $quote_id = mysqli_insert_id($mysqli); @@ -841,6 +847,107 @@ if(isset($_POST['add_quote'])){ } +if(isset($_POST['edit_quote'])){ + + $quote_id = intval($_POST['quote_id']); + $date = strip_tags(mysqli_real_escape_string($mysqli,$_POST['date'])); + $category = intval($_POST['category']); + + mysqli_query($mysqli,"UPDATE quotes SET quote_date = '$date', category_id = $category, quote_updated_at = NOW() WHERE quote_id = $quote_id"); + + $_SESSION['alert_message'] = "Quote modified"; + + header("Location: " . $_SERVER["HTTP_REFERER"]); + +} + +if(isset($_POST['add_quote_copy'])){ + + $quote_id = intval($_POST['quote_id']); + $date = strip_tags(mysqli_real_escape_string($mysqli,$_POST['date'])); + + //Get the last Invoice Number and add 1 for the new invoice number + $sql = mysqli_query($mysqli,"SELECT quote_number FROM quotes ORDER BY quote_number DESC LIMIT 1"); + $row = mysqli_fetch_array($sql); + $quote_number = $row['quote_number'] + 1; + + $sql = mysqli_query($mysqli,"SELECT * FROM quotes WHERE quote_id = $quote_id"); + $row = mysqli_fetch_array($sql); + $quote_amount = $row['quote_amount']; + $quote_note = $row['quote_note']; + $client_id = $row['client_id']; + $category_id = $row['category_id']; + + mysqli_query($mysqli,"INSERT INTO quotes SET quote_number = $quote_number, quote_date = '$date', category_id = $category_id, quote_status = 'Draft', quote_amount = '$quote_amount', quote_note = '$quote_note', quote_created_at = NOW(), client_id = $client_id"); + + $new_quote_id = mysqli_insert_id($mysqli); + + mysqli_query($mysqli,"INSERT INTO invoice_history SET invoice_history_date = CURDATE(), invoice_history_status = 'Draft', invoice_history_description = 'Quote copied!', quote_id = $new_quote_id"); + + $sql_items = mysqli_query($mysqli,"SELECT * FROM invoice_items WHERE quote_id = $quote_id"); + while($row = mysqli_fetch_array($sql_items)){ + $item_id = $row['item_id']; + $item_name = $row['item_name']; + $item_description = $row['item_description']; + $item_quantity = $row['item_quantity']; + $item_price = $row['item_price']; + $item_subtotal = $row['item_subtotal']; + $item_tax = $row['item_tax']; + $item_total = $row['item_total']; + + mysqli_query($mysqli,"INSERT INTO invoice_items SET item_name = '$item_name', item_description = '$item_description', item_quantity = $item_quantity, item_price = '$item_price', item_subtotal = '$item_subtotal', item_tax = '$item_tax', item_total = '$item_total', quote_id = $new_quote_id"); + } + + $_SESSION['alert_message'] = "Quote copied"; + + header("Location: quote.php?quote_id=$new_quote_id"); + +} + +if(isset($_POST['add_quote_to_invoice'])){ + + $quote_id = intval($_POST['quote_id']); + $date = strip_tags(mysqli_real_escape_string($mysqli,$_POST['date'])); + $due = strip_tags(mysqli_real_escape_string($mysqli,$_POST['due'])); + + //Get the last Invoice Number and add 1 for the new invoice number + $sql = mysqli_query($mysqli,"SELECT invoice_number FROM invoices ORDER BY invoice_number DESC LIMIT 1"); + $row = mysqli_fetch_array($sql); + $invoice_number = $row['invoice_number'] + 1; + + $sql = mysqli_query($mysqli,"SELECT * FROM quotes WHERE quote_id = $quote_id"); + $row = mysqli_fetch_array($sql); + $quote_amount = $row['quote_amount']; + $quote_note = $row['quote_note']; + $client_id = $row['client_id']; + $category_id = $row['category_id']; + + mysqli_query($mysqli,"INSERT INTO invoices SET invoice_number = $invoice_number, invoice_date = '$date', invoice_due = '$due', category_id = $category_id, invoice_status = 'Draft', invoice_amount = '$quote_amount', invoice_note = '$quote_note', invoice_created_at = NOW(), client_id = $client_id"); + + $new_invoice_id = mysqli_insert_id($mysqli); + + mysqli_query($mysqli,"INSERT INTO invoice_history SET invoice_history_date = CURDATE(), invoice_history_status = 'Draft', invoice_history_description = 'Quote copied to Invoice!', invoice_id = $new_invoice_id"); + + $sql_items = mysqli_query($mysqli,"SELECT * FROM invoice_items WHERE quote_id = $quote_id"); + while($row = mysqli_fetch_array($sql_items)){ + $item_id = $row['item_id']; + $item_name = $row['item_name']; + $item_description = $row['item_description']; + $item_quantity = $row['item_quantity']; + $item_price = $row['item_price']; + $item_subtotal = $row['item_subtotal']; + $item_tax = $row['item_tax']; + $item_total = $row['item_total']; + + mysqli_query($mysqli,"INSERT INTO invoice_items SET item_name = '$item_name', item_description = '$item_description', item_quantity = $item_quantity, item_price = '$item_price', item_subtotal = '$item_subtotal', item_tax = '$item_tax', item_total = '$item_total', invoice_id = $new_invoice_id"); + } + + $_SESSION['alert_message'] = "Quoted copied to Invoice"; + + header("Location: invoice.php?invoice_id=$new_invoice_id"); + +} + if(isset($_POST['add_quote_item'])){ $quote_id = intval($_POST['quote_id']); @@ -896,6 +1003,445 @@ if(isset($_GET['delete_quote_item'])){ } +if(isset($_POST['edit_quote_note'])){ + + $quote_id = intval($_POST['quote_id']); + $quote_note = strip_tags(mysqli_real_escape_string($mysqli,$_POST['quote_note'])); + + mysqli_query($mysqli,"UPDATE quotes SET quote_note = '$quote_note' WHERE quote_id = $quote_id"); + + $_SESSION['alert_message'] = "Notes added"; + + header("Location: " . $_SERVER["HTTP_REFERER"]); + +} + +if(isset($_GET['approve_quote'])){ + + $quote_id = intval($_GET['approve_quote']); + + mysqli_query($mysqli,"UPDATE quotes SET quote_status = 'Approved' WHERE quote_id = $quote_id"); + + mysqli_query($mysqli,"INSERT INTO invoice_history SET invoice_history_date = CURDATE(), invoice_history_status = 'Approved', invoice_history_description = 'Quote approved!', quote_id = $quote_id"); + + $_SESSION['alert_message'] = "Quote approved"; + + header("Location: " . $_SERVER["HTTP_REFERER"]); + +} + +if(isset($_GET['cancel_quote'])){ + + $quote_id = intval($_GET['cancel_quote']); + + mysqli_query($mysqli,"UPDATE quotes SET quote_status = 'Cancelled' WHERE quote_id = $quote_id"); + + mysqli_query($mysqli,"INSERT INTO invoice_history SET invoice_history_date = CURDATE(), invoice_history_status = 'Cancelled', invoice_history_description = 'Quote cancelled!', quote_id = $quote_id"); + + $_SESSION['alert_message'] = "Quote cancelled"; + + header("Location: " . $_SERVER["HTTP_REFERER"]); + +} + +if(isset($_GET['pdf_quote'])){ + + $quote_id = intval($_GET['pdf_quote']); + + $sql = mysqli_query($mysqli,"SELECT * FROM quotes, clients + WHERE quotes.client_id = clients.client_id + AND quotes.quote_id = $quote_id" + ); + + $row = mysqli_fetch_array($sql); + $quote_id = $row['quote_id']; + $quote_number = $row['quote_number']; + $quote_status = $row['quote_status']; + $quote_date = $row['quote_date']; + $quote_amount = $row['quote_amount']; + $quote_note = $row['quote_note']; + $quote_url_key = $row['quote_url_key']; + $client_id = $row['client_id']; + $client_name = $row['client_name']; + $client_address = $row['client_address']; + $client_city = $row['client_city']; + $client_state = $row['client_state']; + $client_zip = $row['client_zip']; + $client_email = $row['client_email']; + $client_phone = $row['client_phone']; + if(strlen($client_phone)>2){ + $client_phone = substr($row['client_phone'],0,3)."-".substr($row['client_phone'],3,3)."-".substr($row['client_phone'],6,4); + } + $client_website = $row['client_website']; + + $sql_items = mysqli_query($mysqli,"SELECT * FROM invoice_items WHERE quote_id = $quote_id ORDER BY item_id ASC"); + + while($row = mysqli_fetch_array($sql_items)){ + $item_id = $row['item_id']; + $item_name = $row['item_name']; + $item_description = $row['item_description']; + $item_quantity = $row['item_quantity']; + $item_price = $row['item_price']; + $item_subtotal = $row['item_price']; + $item_tax = $row['item_tax']; + $item_total = $row['item_total']; + $total_tax = $item_tax + $total_tax; + $sub_total = $item_price * $item_quantity + $sub_total; + + + $items .= " + + $item_name + $item_description + $$item_price + $item_quantity + $$item_tax + $$item_total + + "; + + } + + $html = ' + + + + + + +
Date: '.$quote_date.'
+ + + + +
TO:

'.$client_name.'
'.$client_address.'
'.$client_city.' '.$client_state.' '.$client_zip.'

'.$client_email.'
'.$client_phone.'
 
+
+ + + + + + + + + + + + + '.$items.' + + + + + + + + + + + + + + +
ItemDescriptionUnit CostQuantityTaxLine Total

Notes

'.$quote_note.'
Subtotal:$ '.number_format($sub_total,2).'
Tax:$ '.number_format($total_tax,2).'
Total:$ '.number_format($quote_amount,2).'
+
'.$config_quote_footer.'
+ + + '; + + $mpdf = new \Mpdf\Mpdf([ + 'margin_left' => 20, + 'margin_right' => 15, + 'margin_top' => 48, + 'margin_bottom' => 25, + 'margin_header' => 10, + 'margin_footer' => 10 + ]); + $mpdf->SetProtection(array('print')); + $mpdf->SetTitle("$config_company_name - Quote"); + $mpdf->SetAuthor("$config_company_name"); + $mpdf->SetWatermarkText("Quote"); + $mpdf->showWatermarkText = true; + $mpdf->watermark_font = 'DejaVuSansCondensed'; + $mpdf->watermarkTextAlpha = 0.1; + $mpdf->SetDisplayMode('fullpage'); + $mpdf->WriteHTML($html); + $mpdf->Output(); + +} + +if(isset($_GET['email_quote'])){ + $quote_id = intval($_GET['email_quote']); + + $sql = mysqli_query($mysqli,"SELECT * FROM quotes, clients + WHERE quotes.client_id = clients.client_id + AND quotes.quote_id = $quote_id" + ); + + $row = mysqli_fetch_array($sql); + $quote_id = $row['quote_id']; + $quote_number = $row['quote_number']; + $quote_status = $row['quote_status']; + $quote_date = $row['quote_date']; + $quote_amount = $row['quote_amount']; + $quote_note = $row['quote_note']; + $quote_url_key = $row['quote_url_key']; + $client_id = $row['client_id']; + $client_name = $row['client_name']; + $client_address = $row['client_address']; + $client_city = $row['client_city']; + $client_state = $row['client_state']; + $client_zip = $row['client_zip']; + $client_email = $row['client_email']; + $client_phone = $row['client_phone']; + if(strlen($client_phone)>2){ + $client_phone = substr($row['client_phone'],0,3)."-".substr($row['client_phone'],3,3)."-".substr($row['client_phone'],6,4); + } + $client_website = $row['client_website']; + + $sql_items = mysqli_query($mysqli,"SELECT * FROM invoice_items WHERE quote_id = $quote_id ORDER BY item_id ASC"); + + while($row = mysqli_fetch_array($sql_items)){ + $item_id = $row['item_id']; + $item_name = $row['item_name']; + $item_description = $row['item_description']; + $item_quantity = $row['item_quantity']; + $item_price = $row['item_price']; + $item_subtotal = $row['item_price']; + $item_tax = $row['item_tax']; + $item_total = $row['item_total']; + $total_tax = $item_tax + $total_tax; + $sub_total = $item_price * $item_quantity + $sub_total; + + + $items .= " + + $item_name + $item_description + $$item_price + $item_quantity + $$item_tax + $$item_total + + "; + + } + + $html = ' + + + + + + +
Date: '.$quote_date.'
+ + + + +
TO:

'.$client_name.'
'.$client_address.'
'.$client_city.' '.$client_state.' '.$client_zip.'

'.$client_email.'
'.$client_phone.'
 
+
+ + + + + + + + + + + + + '.$items.' + + + + + + + + + + + + + + +
ItemDescriptionUnit CostQuantityTaxLine Total

Notes

'.$quote_note.'
Subtotal:$ '.number_format($sub_total,2).'
Tax:$ '.number_format($total_tax,2).'
Total:$ '.number_format($quote_amount,2).'
+
'.$config_quote_footer.'
+ + + '; + + $mpdf = new \Mpdf\Mpdf([ + 'margin_left' => 20, + 'margin_right' => 15, + 'margin_top' => 48, + 'margin_bottom' => 25, + 'margin_header' => 10, + 'margin_footer' => 10 + ]); + $mpdf->SetProtection(array('print')); + $mpdf->SetTitle("$config_company_name - Quote"); + $mpdf->SetAuthor("$config_company_name"); + $mpdf->SetWatermarkText("Quote"); + $mpdf->showWatermarkText = true; + $mpdf->watermark_font = 'DejaVuSansCondensed'; + $mpdf->watermarkTextAlpha = 0.1; + $mpdf->SetDisplayMode('fullpage'); + $mpdf->WriteHTML($html); + $mpdf->Output("uploads/$quote_date-$config_company_name-Quote$quote_number.pdf", 'F'); + + $mail = new PHPMailer(true); + + try{ + + //Mail Server Settings + + //$mail->SMTPDebug = 2; // Enable verbose debug output + $mail->isSMTP(); // Set mailer to use SMTP + $mail->Host = $config_smtp_host; // Specify main and backup SMTP servers + $mail->SMTPAuth = true; // Enable SMTP authentication + $mail->Username = $config_smtp_username; // SMTP username + $mail->Password = $config_smtp_password; // SMTP password + $mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted + $mail->Port = $config_smtp_port; // TCP port to connect to + + //Recipients + $mail->setFrom($config_mail_from_email, $config_mail_from_name); + $mail->addAddress("$client_email", "$client_name"); // Add a recipient + + // Attachments + //$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments + //$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name + $mail->addAttachment("uploads/$quote_date-$config_company_name-Quote$quote_number.pdf"); // Optional name + + // Content + $mail->isHTML(true); // Set email format to HTML + + $mail->Subject = "Quote $quote_number - $quote_date"; + $mail->Body = "Hello $client_name,

Attached to this email is the Quote you requested. You can approve or disapprove this quote by clicking here.

If you have any questions please contact us at the number below.

~
$config_company_name
$config_company_phone"; + + $mail->send(); + echo 'Message has been sent'; + + mysqli_query($mysqli,"INSERT INTO invoice_history SET invoice_history_date = CURDATE(), invoice_history_status = 'Sent', invoice_history_description = 'Emailed Quote!', quote_id = $quote_id"); + + //Don't change the status to sent if the status is anything but draft + if($quote_status == 'Draft'){ + + mysqli_query($mysqli,"UPDATE quotes SET quote_status = 'Sent', client_id = $client_id WHERE quote_id = $quote_id"); + + } + + $_SESSION['alert_message'] = "Quote has been sent"; + + header("Location: " . $_SERVER["HTTP_REFERER"]); + + + } catch (Exception $e) { + echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; + } + unlink("uploads/$quote_date-$config_company_name-Quote$quote_number.pdf"); +} + if(isset($_POST['add_recurring'])){ $client = intval($_POST['client']); diff --git a/quote.php b/quote.php index fb1d12d8..604d34d6 100644 --- a/quote.php +++ b/quote.php @@ -18,7 +18,7 @@ if(isset($_GET['quote_id'])){ $quote_date = $row['quote_date']; $quote_amount = $row['quote_amount']; $quote_note = $row['quote_note']; - $quote_category_id = $row['category_id']; + $category_id = $row['category_id']; $client_id = $row['client_id']; $client_name = $row['client_name']; $client_address = $row['client_address']; @@ -32,15 +32,17 @@ if(isset($_GET['quote_id'])){ } $client_website = $row['client_website']; - $sql_quote_history = mysqli_query($mysqli,"SELECT * FROM quote_history WHERE quote_id = $quote_id ORDER BY quote_history_id ASC"); + $sql_invoice_history = mysqli_query($mysqli,"SELECT * FROM invoice_history WHERE quote_id = $quote_id ORDER BY invoice_history_id DESC"); //Set Badge color based off of quote status if($quote_status == "Sent"){ - $quote_badge_color = "warning"; + $quote_badge_color = "warning text-white"; }elseif($quote_status == "Viewed"){ $quote_badge_color = "primary"; }elseif($quote_status == "Approved"){ $quote_badge_color = "success"; + }elseif($quote_status == "Cancelled"){ + $quote_badge_color = "danger"; }else{ $quote_badge_color = "secondary"; } @@ -62,9 +64,11 @@ if(isset($_GET['quote_id'])){
-
+
Notes
-
-

+
+
+
+ + + +
-
+ +
@@ -257,16 +267,16 @@ if(isset($_GET['quote_id'])){ - - - + + + - + + diff --git a/quotes.php b/quotes.php index 24d94ed4..18186b76 100644 --- a/quotes.php +++ b/quotes.php @@ -2,8 +2,9 @@ @@ -21,6 +22,7 @@ + @@ -36,13 +38,17 @@ $quote_amount = $row['quote_amount']; $client_id = $row['client_id']; $client_name = $row['client_name']; + $category_id = $row['category_id']; + $category_name = $row['category_name']; if($quote_status == "Sent"){ - $quote_badge_color = "warning"; + $quote_badge_color = "warning text-white"; }elseif($quote_status == "Viewed"){ $quote_badge_color = "primary"; }elseif($quote_status == "Approved"){ $quote_badge_color = "success"; + }elseif($quote_status == "Cancelled"){ + $quote_badge_color = "danger"; }else{ $quote_badge_color = "secondary"; } @@ -54,6 +60,7 @@ +
Client Amount DateCategory Status Actions
$ @@ -65,8 +72,10 @@ diff --git a/settings-invoice.php b/settings-invoice.php index 61d38150..d2dfe2c5 100644 --- a/settings-invoice.php +++ b/settings-invoice.php @@ -43,6 +43,11 @@ + +
+ + +