Merge branch 'master' into stage
Some checks failed
SQL Syntax Check for db.sql / Check db.sql SQL Syntax (pull_request) Failing after 18s
PHPLint / build (pull_request) Successful in 26s
Welcome New Contributor / run (pull_request_target) Successful in 22s

# Conflicts:
#	guest/guest_post.php
This commit is contained in:
2025-10-21 13:07:25 -04:00
2998 changed files with 196488 additions and 27619 deletions

9
guest/custom/readme.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
/*
- Custom Pages -
If you wish to add custom pages to ITFlow, add them to this directory"
*/

View File

@@ -20,7 +20,6 @@ require_once "../plugins/totp/totp.php";
if (isset($_GET['stripe_create_pi'])) {
// Response header
header('Content-Type: application/json');
// Params from POST (guest_pay_invoice_stripe.js)
@@ -36,16 +35,13 @@ if (isset($_GET['stripe_create_pi'])) {
LEFT JOIN clients ON invoice_client_id = client_id
WHERE invoice_id = $invoice_id
AND invoice_url_key = '$url_key'
AND invoice_status != 'Draft'
AND invoice_status != 'Paid'
AND invoice_status != 'Cancelled'
AND invoice_status NOT IN ('Draft','Paid','Cancelled')
LIMIT 1"
);
if (!$invoice_sql || mysqli_num_rows($invoice_sql) !== 1) {
exit("Invalid Invoice ID/SQL query");
}
// Invoice exists - get details for payment
$row = mysqli_fetch_array($invoice_sql);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']);
@@ -54,15 +50,10 @@ if (isset($_GET['stripe_create_pi'])) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$config_sql = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1");
$config_row = mysqli_fetch_array($config_sql);
$config_stripe_percentage_fee = floatval($config_row['config_stripe_percentage_fee']);
$config_stripe_flat_fee = floatval($config_row['config_stripe_flat_fee']);
// 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);
$amount_paid = floatval($row['amount_paid']);
$row_amt = mysqli_fetch_array($sql_amount_paid);
$amount_paid = floatval($row_amt['amount_paid']);
$balance_to_pay = $invoice_amount - $amount_paid;
$balance_to_pay = round($balance_to_pay, 2);
@@ -71,24 +62,22 @@ if (isset($_GET['stripe_create_pi'])) {
exit("No balance outstanding");
}
// Setup Stripe
require_once '../plugins/stripe-php/init.php';
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_secret, config_stripe_account FROM settings WHERE company_id = 1"));
if ($row['config_stripe_enable'] == 0 || $row['config_stripe_account'] == 0) {
// Setup Stripe from payment_providers
$stripe_provider = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_name = 'Stripe' LIMIT 1"));
if (!$stripe_provider) {
exit("Stripe not enabled / configured");
}
$stripe_secret_key = $stripe_provider['payment_provider_private_key'];
require_once '../plugins/stripe-php/init.php';
$config_stripe_secret = $row['config_stripe_secret'];
$pi_description = "ITFlow: $client_name payment of $invoice_currency_code $balance_to_pay for $invoice_prefix$invoice_number";
// Create a PaymentIntent with amount, currency and client details
try {
\Stripe\Stripe::setApiKey($config_stripe_secret);
\Stripe\Stripe::setApiKey($stripe_secret_key);
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => intval($balance_to_pay * 100), // Times by 100 as Stripe expects values in cents
'amount' => intval($balance_to_pay * 100), // Stripe expects cents
'currency' => $invoice_currency_code,
'description' => $pi_description,
'metadata' => [
@@ -106,15 +95,10 @@ if (isset($_GET['stripe_create_pi'])) {
echo json_encode($output);
} catch (Error $e) {
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
}
if (isset($_GET['get_totp_token'])) {
$otp = TokenAuth6238::getTokenCode(strtoupper($_GET['totp_secret']));
echo json_encode($otp);
exit;
}

View File

@@ -1,103 +1,85 @@
<?php
require_once 'includes/guest_header.php';
require_once 'includes/inc_all_guest.php';
// Define wording
DEFINE("WORDING_PAYMENT_FAILED", "<br><h2>There was an error verifying your payment. Please contact us for more information before attempting payment again.</h2>");
// Setup Stripe
$stripe_vars = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret, config_stripe_account, config_stripe_expense_vendor, config_stripe_expense_category, config_stripe_percentage_fee, config_stripe_flat_fee FROM settings WHERE company_id = 1"));
$config_stripe_enable = intval($stripe_vars['config_stripe_enable']);
$config_stripe_publishable = nullable_htmlentities($stripe_vars['config_stripe_publishable']);
$config_stripe_secret = nullable_htmlentities($stripe_vars['config_stripe_secret']);
$config_stripe_account = intval($stripe_vars['config_stripe_account']);
$config_stripe_expense_vendor = intval($stripe_vars['config_stripe_expense_vendor']);
$config_stripe_expense_category = intval($stripe_vars['config_stripe_expense_category']);
$config_stripe_percentage_fee = floatval($stripe_vars['config_stripe_percentage_fee']);
$config_stripe_flat_fee = floatval($stripe_vars['config_stripe_flat_fee']);
// --- Get Stripe config from payment_providers table ---
$stripe_provider = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM payment_providers"));
$stripe_publishable = nullable_htmlentities($stripe_provider['payment_provider_public_key']);
$stripe_secret = nullable_htmlentities($stripe_provider['payment_provider_private_key']);
$stripe_account = intval($stripe_provider['payment_provider_account']);
$stripe_expense_vendor = intval($stripe_provider['payment_provider_expense_vendor']);
$stripe_expense_category = intval($stripe_provider['payment_provider_expense_category']);
$stripe_percentage_fee = floatval($stripe_provider['payment_provider_expense_percentage_fee']);
$stripe_flat_fee = floatval($stripe_provider['payment_provider_expense_flat_fee']);
// Check Stripe is configured
if ($config_stripe_enable == 0 || $config_stripe_account == 0 || empty($config_stripe_publishable) || empty($config_stripe_secret)) {
echo "<br><h2>Stripe payments not enabled/configured</h2>";
require_once 'includes/guest_footer.php';
error_log("Stripe payment error - disabled. Check payments are enabled, Expense account is set, Stripe publishable and secret keys are configured.");
exit();
}
// Show payment form
// Users are directed to this page with the invoice_id and url_key params to make a payment
if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent'])) {
$invoice_url_key = sanitizeInput($_GET['url_key']);
$invoice_id = intval($_GET['invoice_id']);
$invoice_id = intval($_GET['invoice_id']);
// Query invoice details
$sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
WHERE invoice_id = $invoice_id
AND invoice_url_key = '$invoice_url_key'
AND invoice_status != 'Draft'
AND invoice_status != 'Paid'
AND invoice_status != 'Cancelled'
LIMIT 1"
LEFT JOIN clients ON invoice_client_id = client_id
WHERE invoice_id = $invoice_id
AND invoice_url_key = '$invoice_url_key'
AND invoice_status NOT IN ('Draft', 'Paid', 'Cancelled')
LIMIT 1"
);
// Ensure we have a valid invoice
// Ensure valid invoice
if (!$sql || mysqli_num_rows($sql) !== 1) {
echo "<br><h2>Oops, something went wrong! Please ensure you have the correct URL and have not already paid this invoice.</h2>";
require_once 'includes/guest_footer.php';
error_log("Stripe payment error - Invoice with ID $invoice_id is unknown/not eligible to be paid.");
error_log("Stripe payment error - Invoice with ID $invoice_id not found or not eligible.");
exit();
}
// Process invoice, client and company details/settings
$row = mysqli_fetch_array($sql);
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']);
$invoice_status = nullable_htmlentities($row['invoice_status']);
$invoice_date = nullable_htmlentities($row['invoice_date']);
$invoice_due = nullable_htmlentities($row['invoice_due']);
$invoice_discount = floatval($row['invoice_discount_amount']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']);
$invoice_status = nullable_htmlentities($row['invoice_status']);
$invoice_date = nullable_htmlentities($row['invoice_date']);
$invoice_due = nullable_htmlentities($row['invoice_due']);
$invoice_discount = floatval($row['invoice_discount_amount']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_currency_code = nullable_htmlentities($row['invoice_currency_code']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$sql = mysqli_query($mysqli, "SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
$row = mysqli_fetch_array($sql);
$company_locale = nullable_htmlentities($row['company_locale']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
// Add up all the payments for the invoice and get the total amount paid to the invoice
// Company info for currency formatting, etc
$sql_company = mysqli_query($mysqli, "SELECT * FROM companies WHERE company_id = 1");
$company_row = mysqli_fetch_array($sql_company);
$company_locale = nullable_htmlentities($company_row['company_locale']);
$config_base_url = nullable_htmlentities($company_row['company_base_url'] ?? ''); // You might want to pull from settings if needed
// Add up all payments made 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);
$amount_paid = floatval($row['amount_paid']);
$balance_to_pay = $invoice_amount - $amount_paid;
//Round balance to pay to 2 decimal places
$balance_to_pay = round($balance_to_pay, 2);
$amount_paid = floatval(mysqli_fetch_array($sql_amount_paid)['amount_paid']);
$balance_to_pay = round($invoice_amount - $amount_paid, 2);
// Get invoice items
$sql_invoice_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_id ASC");
// Set Currency Formatting
// Currency formatting
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
?>
<!-- Include Stripe JS (must be Stripe-hosted, not local) -->
<!-- Stripe & jQuery -->
<script src="https://js.stripe.com/v3/"></script>
<!-- jQuery -->
<script src="plugins/jquery/jquery.min.js"></script>
<script src="../plugins/jquery/jquery.min.js"></script>
<div class="row pt-5">
<!-- Show invoice details -->
<div class="col-sm">
<div class="card">
<div class="card-header">
<h3 class="card-title">Payment for Invoice: <strong><?php echo "$invoice_prefix$invoice_number"; ?></strong></h3>
@@ -113,47 +95,39 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
</thead>
<tbody>
<?php
$item_total = 0;
while ($row = mysqli_fetch_array($sql_invoice_items)) {
$item_name = nullable_htmlentities($row['item_name']);
$item_quantity = floatval($row['item_quantity']);
$item_total = floatval($row['item_total']);
?>
?>
<tr>
<td><?php echo $item_name; ?></td>
<td class="text-center"><?php echo $item_quantity; ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_total, $invoice_currency_code); ?></td>
</tr>
<?php } ?>
<?php if ($invoice_discount > 0) { ?>
<?php if ($invoice_discount > 0) { ?>
<tr class="text-right">
<td colspan="2">Discount</td>
<td>
<?php echo numfmt_format_currency($currency_format, $invoice_discount, $invoice_currency_code); ?>
</td>
</tr>
<?php } ?>
<?php if (intval($amount_paid) > 0) { ?>
<?php } ?>
<?php if (intval($amount_paid) > 0) { ?>
<tr class="text-right">
<td colspan="2">Paid</td>
<td>
<?php echo numfmt_format_currency($currency_format, $amount_paid, $invoice_currency_code); ?>
</td>
</tr>
<?php } ?>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- End invoice details-->
<!-- Show Stripe payment form -->
<div class="col-sm offset-sm-1">
<div class="card">
<div class="card-header">
@@ -161,12 +135,10 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
</div>
<div class="card-body">
<form id="payment-form">
<input type="hidden" id="stripe_publishable_key" value="<?php echo $config_stripe_publishable ?>">
<input type="hidden" id="stripe_publishable_key" value="<?php echo $stripe_publishable ?>">
<input type="hidden" id="invoice_id" value="<?php echo $invoice_id ?>">
<input type="hidden" id="url_key" value="<?php echo $invoice_url_key ?>">
<div id="payment-element">
<!--Stripe.js injects the Payment Element-->
</div>
<div id="payment-element"></div>
<br>
<button type="submit" id="submit" class="btn btn-primary btn-lg btn-block text-bold" hidden="hidden">
<div class="spinner hidden" id="spinner"></div>
@@ -177,29 +149,21 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
</div>
</div>
</div>
<!-- End Stripe payment form -->
</div>
<!-- Include local JS that powers stripe -->
<script src="../js/guest_pay_invoice_stripe.js"></script>
<?php
// Process payment & redirect user back to invoice
// (Stripe will redirect back to this page upon payment success with the payment_intent and payment_intent_client_secret params set
// Payment result processing
} elseif (isset($_GET['payment_intent'], $_GET['payment_intent_client_secret'])) {
// Params from GET
$pi_id = sanitizeInput($_GET['payment_intent']);
$pi_cs = $_GET['payment_intent_client_secret'];
// Initialize stripe
require_once '../plugins/stripe-php/init.php';
\Stripe\Stripe::setApiKey($stripe_secret);
\Stripe\Stripe::setApiKey($config_stripe_secret);
// Check details of the PI
$pi_obj = \Stripe\PaymentIntent::retrieve($pi_id);
if ($pi_obj->client_secret !== $pi_cs) {
@@ -208,13 +172,11 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
} elseif ($pi_obj->status !== "succeeded") {
exit(WORDING_PAYMENT_FAILED);
} elseif ($pi_obj->amount !== $pi_obj->amount_received) {
// The invoice wasn't paid in full
// this should be flagged for manual review as would indicate something weird happening
error_log("Stripe payment error - payment amount does not match amount paid for $pi_id");
exit(WORDING_PAYMENT_FAILED);
}
// Get details from PI
// PI details
$pi_date = date('Y-m-d', $pi_obj->created);
$pi_invoice_id = intval($pi_obj->metadata->itflow_invoice_id);
$pi_client_id = intval($pi_obj->metadata->itflow_client_id);
@@ -226,20 +188,17 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
$invoice_sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1
WHERE invoice_id = $pi_invoice_id
AND invoice_status != 'Draft'
AND invoice_status != 'Paid'
AND invoice_status != 'Cancelled'
LIMIT 1"
LEFT JOIN clients ON invoice_client_id = client_id
LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1
WHERE invoice_id = $pi_invoice_id
AND invoice_status NOT IN ('Draft', 'Paid', 'Cancelled')
LIMIT 1"
);
if (!$invoice_sql || mysqli_num_rows($invoice_sql) !== 1) {
error_log("Stripe payment error - Invoice with ID $invoice_id is unknown/not eligible to be paid. PI $pi_id");
error_log("Stripe payment error - Invoice with ID $pi_invoice_id is unknown/not eligible. PI $pi_id");
exit(WORDING_PAYMENT_FAILED);
}
// Invoice exists - get details
$row = mysqli_fetch_array($invoice_sql);
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = sanitizeInput($row['invoice_prefix']);
@@ -251,79 +210,56 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
$client_name = sanitizeInput($row['client_name']);
$contact_name = sanitizeInput($row['contact_name']);
$contact_email = sanitizeInput($row['contact_email']);
$sql_company = mysqli_query($mysqli, "SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql_company);
$company_name = sanitizeInput($row['company_name']);
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone']));
$company_locale = sanitizeInput($row['company_locale']);
// Set Currency Formatting
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
// Add up all the payments for the invoice and get the total amount paid to the invoice already (if any)
$sql_amount_paid_previously = 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_previously);
$amount_paid_previously = $row['amount_paid'];
$amount_paid_previously = floatval(mysqli_fetch_array($sql_amount_paid_previously)['amount_paid']);
$balance_to_pay = $invoice_amount - $amount_paid_previously;
// Check to see if Expense Fields are configured to create Stripe payment expense
if ($config_stripe_expense_vendor > 0 && $config_stripe_expense_category > 0) {
// Calculate gateway expense fee
$gateway_fee = round($balance_to_pay * $config_stripe_percentage_fee + $config_stripe_flat_fee, 2);
// Add Expense
mysqli_query($mysqli,"INSERT INTO expenses SET expense_date = '$pi_date', expense_amount = $gateway_fee, expense_currency_code = '$invoice_currency_code', expense_account_id = $config_stripe_account, expense_vendor_id = $config_stripe_expense_vendor, expense_client_id = $client_id, expense_category_id = $config_stripe_expense_category, expense_description = 'Stripe Transaction for Invoice $invoice_prefix$invoice_number In the Amount of $balance_to_pay', expense_reference = 'Stripe - $pi_id'");
// Stripe expense
if ($stripe_expense_vendor > 0 && $stripe_expense_category > 0) {
$gateway_fee = round($balance_to_pay * $stripe_percentage_fee + $stripe_flat_fee, 2);
mysqli_query($mysqli, "INSERT INTO expenses SET expense_date = '$pi_date', expense_amount = $gateway_fee, expense_currency_code = '$invoice_currency_code', expense_account_id = $stripe_account, expense_vendor_id = $stripe_expense_vendor, expense_client_id = $client_id, expense_category_id = $stripe_expense_category, expense_description = 'Stripe Transaction for Invoice $invoice_prefix$invoice_number In the Amount of $balance_to_pay', expense_reference = 'Stripe - $pi_id'");
}
// Round balance to pay to 2 decimal places
$balance_to_pay = round($balance_to_pay, 2);
// Sanity check that the amount paid is exactly the invoice outstanding balance
if (intval($balance_to_pay) !== intval($pi_amount_paid)) {
error_log("Stripe payment error - Invoice balance does not match amount paid for $pi_id");
exit(WORDING_PAYMENT_FAILED);
}
// Apply payment
// Update Invoice Status
mysqli_query($mysqli, "UPDATE invoices SET invoice_status = 'Paid' WHERE invoice_id = $invoice_id");
// Add Payment to History
mysqli_query($mysqli, "INSERT INTO payments SET payment_date = '$pi_date', payment_amount = $pi_amount_paid, payment_currency_code = '$pi_currency', payment_account_id = $config_stripe_account, payment_method = 'Stripe', payment_reference = 'Stripe - $pi_id', payment_invoice_id = $invoice_id");
mysqli_query($mysqli, "INSERT INTO payments SET payment_date = '$pi_date', payment_amount = $pi_amount_paid, payment_currency_code = '$pi_currency', payment_account_id = $stripe_account, payment_method = 'Stripe', payment_reference = 'Stripe - $pi_id', payment_invoice_id = $invoice_id");
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Paid', history_description = 'Online Payment added (client) - $ip - $os - $browser', history_invoice_id = $invoice_id");
// Notify
appNotify("Invoice Paid", "Invoice $invoice_prefix$invoice_number has been paid by $client_name - $ip - $os - $browser", "invoice.php?invoice_id=$invoice_id", $pi_client_id);
appNotify("Invoice Paid", "Invoice $invoice_prefix$invoice_number has been paid by $client_name - $ip - $os - $browser", "/agent/invoice.php?invoice_id=$invoice_id", $pi_client_id);
customAction('invoice_pay', $invoice_id);
// Logging
$extended_log_desc = '';
if (!$pi_livemode) {
$extended_log_desc = '(DEV MODE)';
}
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Payment', log_action = 'Create', log_description = 'Stripe payment of $pi_currency $pi_amount_paid against invoice $invoice_prefix$invoice_number - $pi_id $extended_log_desc', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $pi_client_id");
// Send email receipt
// Email Receipt
$sql_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1");
$row = mysqli_fetch_array($sql_settings);
$settings = mysqli_fetch_array($sql_settings);
$config_smtp_host = $row['config_smtp_host'];
$config_smtp_port = intval($row['config_smtp_port']);
$config_smtp_encryption = $row['config_smtp_encryption'];
$config_smtp_username = $row['config_smtp_username'];
$config_smtp_password = $row['config_smtp_password'];
$config_invoice_from_name = sanitizeInput($row['config_invoice_from_name']);
$config_invoice_from_email = sanitizeInput($row['config_invoice_from_email']);
$config_invoice_paid_notification_email = sanitizeInput($row['config_invoice_paid_notification_email']);
$config_base_url = sanitizeInput($config_base_url);
$config_smtp_host = $settings['config_smtp_host'];
$config_invoice_from_name = sanitizeInput($settings['config_invoice_from_name']);
$config_invoice_from_email = sanitizeInput($settings['config_invoice_from_email']);
$config_invoice_paid_notification_email = sanitizeInput($settings['config_invoice_paid_notification_email']);
if (!empty($config_smtp_host)) {
$subject = "Payment Received - Invoice $invoice_prefix$invoice_number";
@@ -339,36 +275,29 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
'body' => $body,
]
];
// Email the internal notification address too
// Internal notification
if (!empty($config_invoice_paid_notification_email)) {
$subject = "Payment Received - $client_name - Invoice $invoice_prefix$invoice_number";
$body = "Hello, <br><br>This is a notification that an invoice has been paid in ITFlow. Below is a copy of the receipt sent to the client:-<br><br>--------<br><br>Hello $contact_name,<br><br>We have received online payment for the amount of " . $pi_currency . $pi_amount_paid . " for invoice <a href=\'https://$config_base_url/guest/guest_view_invoice.php?invoice_id=$invoice_id&url_key=$invoice_url_key\'>$invoice_prefix$invoice_number</a>. Please keep this email as a receipt for your records.<br><br>Amount: " . numfmt_format_currency($currency_format, $pi_amount_paid, $invoice_currency_code) . "<br><br>Thank you for your business!<br><br><br>~<br>$company_name - Billing<br>$config_invoice_from_email<br>$company_phone";
$subject_internal = "Payment Received - $client_name - Invoice $invoice_prefix$invoice_number";
$body_internal = "This is a notification that an invoice has been paid in ITFlow. Below is a copy of the receipt sent to the client:-<br><br>--------<br><br>$body";
$data[] = [
'from' => $config_invoice_from_email,
'from_name' => $config_invoice_from_name,
'recipient' => $config_invoice_paid_notification_email,
'recipient_name' => $contact_name,
'subject' => $subject,
'body' => $body,
'subject' => $subject_internal,
'body' => $body_internal,
];
}
$mail = addToMailQueue($data);
// Email logging
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Sent', history_description = 'Emailed Receipt!', history_invoice_id = $invoice_id");
}
// Redirect user to invoice
header('Location: //' . $config_base_url . '/guest/guest_view_invoice.php?invoice_id=' . $pi_invoice_id . '&url_key=' . $invoice_url_key);
header('Location: //' . $config_base_url . '/guest/guest_view_invoice.php?invoice_id=' . $invoice_id . '&url_key=' . $invoice_url_key);
} else {
exit(WORDING_PAYMENT_FAILED);
}
require_once 'includes/guest_footer.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';

View File

@@ -2,13 +2,14 @@
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/get_settings.php";
require_once "../includes/load_global_settings.php";
session_start();
require_once "../includes/inc_set_timezone.php"; // Must be included after session_start to work
if (isset($_GET['accept_quote'], $_GET['url_key'])) {
$quote_id = intval($_GET['accept_quote']);
$url_key = sanitizeInput($_GET['url_key']);
@@ -26,7 +27,7 @@ if (isset($_GET['accept_quote'], $_GET['url_key'])) {
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Accepted', history_description = 'Client accepted Quote!', history_quote_id = $quote_id");
// Notification
appNotify("Quote Accepted", "Quote $quote_prefix$quote_number has been accepted by $client_name", "quote.php?quote_id=$quote_id", $client_id);
appNotify("Quote Accepted", "Quote $quote_prefix$quote_number has been accepted by $client_name", "/agent/quote.php?quote_id=$quote_id", $client_id);
customAction('quote_accept', $quote_id);
// Internal email notification
@@ -62,14 +63,18 @@ if (isset($_GET['accept_quote'], $_GET['url_key'])) {
$mail = addToMailQueue($data);
}
$_SESSION['alert_message'] = "Quote Accepted";
header("Location: " . $_SERVER["HTTP_REFERER"]);
flash_alert("Quote Accepted");
redirect();
} else {
echo "Invalid!!";
}
}
if (isset($_GET['decline_quote'], $_GET['url_key'])) {
$quote_id = intval($_GET['decline_quote']);
$url_key = sanitizeInput($_GET['url_key']);
@@ -87,7 +92,7 @@ if (isset($_GET['decline_quote'], $_GET['url_key'])) {
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Declined', history_description = 'Client declined Quote!', history_quote_id = $quote_id");
// Notification
appNotify("Quote Declined", "Quote $quote_prefix$quote_number has been declined by $client_name", "quote.php?quote_id=$quote_id", $client_id);
appNotify("Quote Declined", "Quote $quote_prefix$quote_number has been declined by $client_name", "/agent/quote.php?quote_id=$quote_id", $client_id);
customAction('quote_decline', $quote_id);
// Internal email notification
@@ -122,16 +127,18 @@ if (isset($_GET['decline_quote'], $_GET['url_key'])) {
$mail = addToMailQueue($data);
}
flash_alert("Quote Declined", 'danger');
$_SESSION['alert_type'] = "danger";
$_SESSION['alert_message'] = "Quote Declined";
header("Location: " . $_SERVER["HTTP_REFERER"]);
redirect();
} else {
echo "Invalid!!";
}
}
if (isset($_GET['reopen_ticket'], $_GET['url_key'])) {
$ticket_id = intval($_GET['ticket_id']);
$url_key = sanitizeInput($_GET['url_key']);
@@ -141,18 +148,24 @@ if (isset($_GET['reopen_ticket'], $_GET['url_key'])) {
if (mysqli_num_rows($sql) == 1) {
// Update the ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id AND ticket_url_key = '$url_key'");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket reopened by client (guest URL).', ticket_reply_type = 'Internal', ticket_reply_by = 0, ticket_reply_ticket_id = $ticket_id");
// Logging
customAction('ticket_update', $ticket_id);
$_SESSION['alert_message'] = "Ticket reopened";
header("Location: " . $_SERVER["HTTP_REFERER"]);
flash_alert("Ticket reopened");
redirect();
} else {
echo "Invalid!!";
}
}
if (isset($_GET['close_ticket'], $_GET['url_key'])) {
$ticket_id = intval($_GET['ticket_id']);
$url_key = sanitizeInput($_GET['url_key']);
@@ -160,20 +173,26 @@ if (isset($_GET['close_ticket'], $_GET['url_key'])) {
$sql = mysqli_query($mysqli, "SELECT ticket_id FROM tickets WHERE ticket_id = $ticket_id AND ticket_url_key = '$url_key' AND ticket_resolved_at IS NOT NULL AND ticket_closed_at IS NULL");
if (mysqli_num_rows($sql) == 1) {
// Update the ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_url_key = '$url_key'");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket closed by client (guest URL).', ticket_reply_type = 'Internal', ticket_reply_by = 0, ticket_reply_ticket_id = $ticket_id");
// Logging
customAction('ticket_close', $ticket_id);
$_SESSION['alert_message'] = "Ticket closed";
header("Location: " . $_SERVER["HTTP_REFERER"]);
flash_alert("Ticket closed");
redirect();
} else {
echo "Invalid!!";
}
}
if (isset($_GET['add_ticket_feedback'], $_GET['url_key'])) {
$ticket_id = intval($_GET['ticket_id']);
$url_key = sanitizeInput($_GET['url_key']);
$feedback = sanitizeInput($_GET['feedback']);
@@ -191,7 +210,7 @@ if (isset($_GET['add_ticket_feedback'], $_GET['url_key'])) {
$ticket_prefix = sanitizeInput($ticket_details['ticket_prefix']);
$ticket_number = intval($ticket_details['ticket_number']);
appNotify("Feedback", "Guest rated ticket number $ticket_prefix$ticket_number (ID: $ticket_id) as bad", "ticket.php?ticket_id=$ticket_id");
appNotify("Feedback", "Guest rated ticket number $ticket_prefix$ticket_number (ID: $ticket_id) as bad", "/agent/ticket.php?ticket_id=$ticket_id");
} else {
$ticket_details = mysqli_fetch_array(mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number FROM tickets WHERE ticket_id = $ticket_id LIMIT 1"));
$ticket_prefix = sanitizeInput($ticket_details['ticket_prefix']);
@@ -200,12 +219,16 @@ if (isset($_GET['add_ticket_feedback'], $_GET['url_key'])) {
appNotify("Feedback", "Guest rated ticket number $ticket_prefix$ticket_number (ID: $ticket_id) as good. Fuck ya bud!", "ticket.php?ticket_id=$ticket_id");
}
$_SESSION['alert_message'] = "Feedback recorded - thank you";
header("Location: " . $_SERVER["HTTP_REFERER"]);
flash_alert("Feedback recorded - thank you");
redirect();
customAction('ticket_feedback', $ticket_id);
} else {
echo "Invalid!!";
}
}
if (isset($_GET['export_quote_pdf'])) {
@@ -283,21 +306,18 @@ if (isset($_GET['export_quote_pdf'])) {
// Start TCPDF
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetMargins(15, 15, 15);
$pdf->SetMargins(10, 10, 10);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 10);
// Logo + Right Columns
$html = '<table width="100%" cellspacing="0" cellpadding="5">
$html = '<table width="100%" cellspacing="0" cellpadding="3">
<tr>
<td width="40%">';
if (!empty($company_logo)) {
$logo_path = "../uploads/settings/$company_logo";
if (file_exists($logo_path)) {
$pdf->Image($logo_path, $pdf->GetX(), $pdf->GetY(), 40);
}
if (!empty($company_logo) && file_exists("../uploads/settings/$company_logo")) {
$html .= '<img src="/uploads/settings/' . $company_logo . '" width="120">';
}
$html .= '</td>
<td width="60%" align="right">
@@ -311,7 +331,7 @@ if (isset($_GET['export_quote_pdf'])) {
}
$html .= '</td>
</tr>
</table><br><br>';
</table><br>';
// Billing titles
$html .= '<table width="100%" cellspacing="0" cellpadding="2">
@@ -326,7 +346,7 @@ if (isset($_GET['export_quote_pdf'])) {
</table><br>';
// Date table
$html .= '<table border="0" cellpadding="3" cellspacing="0" width="100%">
$html .= '<table border="0" cellpadding="2" cellspacing="0" width="100%">
<tr>
<td width="60%"></td>
<td width="20%" style="font-size:10pt;"><strong>Date:</strong></td>
@@ -351,6 +371,9 @@ if (isset($_GET['export_quote_pdf'])) {
</tr>';
// Load items
$sub_total = 0;
$total_tax = 0;
$sql_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_quote_id = $quote_id ORDER BY item_order ASC");
while ($item = mysqli_fetch_array($sql_items)) {
$name = $item['item_name'];
@@ -365,9 +388,8 @@ if (isset($_GET['export_quote_pdf'])) {
$html .= '
<tr>
<td>
<strong>' . $name . '</strong><br>
<span style="font-style:italic; font-size:9pt;">' . nl2br($desc) . '</span>
<td><strong>' . $name . '</strong>
<br><span style="font-style:italic; font-size:9pt;">' . nl2br($desc) . '</span>
</td>
<td align="center">' . number_format($qty, 2) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $price, $quote_currency_code) . '</td>
@@ -381,8 +403,8 @@ if (isset($_GET['export_quote_pdf'])) {
// Totals
$html .= '<table width="100%" cellspacing="0" cellpadding="4">
<tr>
<td width="70%" rowspan="6" valign="top"><i>' . nl2br($quote_note) . '</i></td>
<td width="30%">
<td width="60%"><i style="font-size:9pt;">' . nl2br($quote_note) . '</i></td>
<td width="40%">
<table width="100%" cellpadding="3" cellspacing="0">
<tr><td>Subtotal:</td><td align="right">' . numfmt_format_currency($currency_format, $sub_total, $quote_currency_code) . '</td></tr>';
if ($quote_discount > 0) {
@@ -407,6 +429,7 @@ if (isset($_GET['export_quote_pdf'])) {
$pdf->Output("$filename.pdf", 'I');
}
exit;
}
if (isset($_GET['export_invoice_pdf'])) {
@@ -509,21 +532,18 @@ if (isset($_GET['export_invoice_pdf'])) {
// Start TCPDF
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetMargins(15, 15, 15);
$pdf->SetMargins(10, 10, 10);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 10);
// Logo + Right Columns
$html = '<table width="100%" cellspacing="0" cellpadding="5">
$html = '<table width="100%" cellspacing="0" cellpadding="3">
<tr>
<td width="40%">';
if (!empty($company_logo)) {
$logo_path = "../uploads/settings/$company_logo";
if (file_exists($logo_path)) {
$pdf->Image($logo_path, $pdf->GetX(), $pdf->GetY(), 40);
}
if (!empty($company_logo) && file_exists("../uploads/settings/$company_logo")) {
$html .= '<img src="/uploads/settings/' . $company_logo . '" width="120">';
}
$html .= '</td>
<td width="60%" align="right">
@@ -534,7 +554,7 @@ if (isset($_GET['export_invoice_pdf'])) {
}
$html .= '</td>
</tr>
</table><br><br>';
</table><br>';
// Billing titles
$html .= '<table width="100%" cellspacing="0" cellpadding="2">
@@ -549,7 +569,7 @@ if (isset($_GET['export_invoice_pdf'])) {
</table><br>';
// Date table
$html .= '<table border="0" cellpadding="3" cellspacing="0" width="100%">
$html .= '<table border="0" cellpadding="2" cellspacing="0" width="100%">
<tr>
<td width="60%"></td>
<td width="20%" style="font-size:10pt;"><strong>Date:</strong></td>
@@ -574,6 +594,9 @@ if (isset($_GET['export_invoice_pdf'])) {
</tr>';
// Load items
$sub_total = 0;
$total_tax = 0;
$sql_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_order ASC");
while ($item = mysqli_fetch_array($sql_items)) {
$name = $item['item_name'];
@@ -588,9 +611,8 @@ if (isset($_GET['export_invoice_pdf'])) {
$html .= '
<tr>
<td>
<strong>' . $name . '</strong><br>
<span style="font-style:italic; font-size:9pt;">' . nl2br($desc) . '</span>
<td><strong>' . $name . '</strong>
<br><span style="font-style:italic; font-size:9pt;">' . nl2br($desc) . '</span>
</td>
<td align="center">' . number_format($qty, 2) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $price, $invoice_currency_code) . '</td>
@@ -604,8 +626,8 @@ if (isset($_GET['export_invoice_pdf'])) {
// Totals
$html .= '<table width="100%" cellspacing="0" cellpadding="4">
<tr>
<td width="70%" rowspan="6" valign="top"><i>' . nl2br($invoice_note) . '</i></td>
<td width="30%">
<td width="60%"><i style="font-size:9pt;">' . nl2br($invoice_note) . '</i></td>
<td width="40%">
<table width="100%" cellpadding="3" cellspacing="0">
<tr><td>Subtotal:</td><td align="right">' . numfmt_format_currency($currency_format, $sub_total, $invoice_currency_code) . '</td></tr>';
if ($invoice_discount > 0) {
@@ -640,6 +662,7 @@ if (isset($_GET['export_invoice_pdf'])) {
}
if (isset($_POST['guest_quote_upload_file'])) {
$quote_id = intval($_POST['quote_id']);
$url_key = sanitizeInput($_POST['url_key']);
@@ -708,25 +731,27 @@ if (isset($_POST['guest_quote_upload_file'])) {
mysqli_query($mysqli, "INSERT INTO quote_files SET quote_id = $quote_id, file_id = $file_id");
// Logging & feedback
$_SESSION['alert_message'] = 'File uploaded!';
appNotify("Quote File", "$file_name was uploaded to quote $quote_prefix$quote_number", "quote.php?quote_id=$quote_id", $client_id);
flash_alert('File uploaded!');
appNotify("Quote File", "$file_name was uploaded to quote $quote_prefix$quote_number", "/agent/quote.php?quote_id=$quote_id", $client_id);
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Upload', history_description = 'Client uploaded file $file_name', history_quote_id = $quote_id");
logAction("File", "Upload", "Guest uploaded file $file_name to quote $quote_prefix$quote_number", $client_id);
} else {
$_SESSION['alert_type'] = 'error';
$_SESSION['alert_message'] = 'Something went wrong uploading the file - please let the support team know.';
flash_alert('Something went wrong uploading the file - please let the support team know.', 'error');
logApp("Guest", "error", "Error uploading file to invoice");
}
}
}
header("Location: " . $_SERVER["HTTP_REFERER"]);
redirect();
} else {
echo "Invalid!!";
}
}
?>
}

View File

@@ -1,10 +1,10 @@
<?php
require_once "includes/guest_header.php";
require_once "includes/inc_all_guest.php";
if (!isset($_GET['invoice_id'], $_GET['url_key'])) {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -25,7 +25,7 @@ $sql = mysqli_query(
if (mysqli_num_rows($sql) !== 1) {
// Invalid invoice/key
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -60,9 +60,6 @@ $contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile']
$client_website = nullable_htmlentities($row['client_website']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$client_net_terms = intval($row['client_net_terms']);
if ($client_net_terms == 0) {
$client_net_terms = intval($row['config_default_net_terms']);
}
$sql = mysqli_query($mysqli, "SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
$row = mysqli_fetch_array($sql);
@@ -88,10 +85,14 @@ if (!empty($company_logo)) {
$company_logo_base64 = base64_encode(file_get_contents("../uploads/settings/$company_logo"));
}
$company_locale = nullable_htmlentities($row['company_locale']);
$config_invoice_footer = nullable_htmlentities($row['config_invoice_footer']);
$config_stripe_enable = intval($row['config_stripe_enable']);
$config_stripe_percentage_fee = floatval($row['config_stripe_percentage_fee']);
$config_stripe_flat_fee = floatval($row['config_stripe_flat_fee']);
$config_invoice_footer = nullable_htmlentities($row['config_invoice_footer']);
// Get Payment Provide Details
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_active = 1 LIMIT 1");
$row = mysqli_fetch_array($sql);
$payment_provider_id = intval($row['payment_provider_id']);
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']);
$payment_provider_threshold = floatval($row['payment_provider_threshold']);
//Set Currency Format
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
@@ -111,7 +112,7 @@ mysqli_query($mysqli, "INSERT INTO history SET history_status = '$invoice_status
if ($invoice_status !== 'Paid') {
appNotify("Invoice Viewed", "Invoice $invoice_prefix$invoice_number has been viewed by $client_name_escaped - $ip - $os - $browser", "invoice.php?invoice_id=$invoice_id", $client_id);
appNotify("Invoice Viewed", "Invoice $invoice_prefix$invoice_number has been viewed by $client_name_escaped - $ip - $os - $browser", "/agent/invoice.php?invoice_id=$invoice_id", $client_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");
@@ -172,7 +173,15 @@ if ($balance > 0) {
<i class="fa fa-fw fa-download mr-2"></i>Download
</a>
<?php
if ($invoice_status !== "Paid" && $invoice_status !== "Cancelled" && $invoice_status !== "Draft" && $config_stripe_enable == 1) { ?>
if ($invoice_status !== "Paid" &&
$invoice_status !== "Cancelled" &&
$invoice_status !== "Draft" &&
$payment_provider_id &&
(
$payment_provider_threshold == 0 ||
$payment_provider_threshold > $invoice_amount
)
){ ?>
<a class="btn btn-success" href="guest_pay_invoice_stripe.php?invoice_id=<?php echo $invoice_id; ?>&url_key=<?php echo $url_key; ?>"><i class="fa fa-fw fa-credit-card mr-2"></i>Pay Now </a>
<?php } ?>
</div>
@@ -238,7 +247,7 @@ if ($balance > 0) {
<div class="col-md-12">
<div class="card">
<div class="table-responsive">
<table class="table table-borderless">
<table class="table table-hover mb-0">
<thead class="bg-light">
<tr>
<th>Item</th>
@@ -297,7 +306,7 @@ if ($balance > 0) {
<?php } ?>
</div>
<div class="col-sm-3 offset-sm-2">
<table class="table table-borderless">
<table class="table table-hover mb-0">
<tbody>
<tr>
<td>Subtotal:</td>
@@ -331,7 +340,7 @@ if ($balance > 0) {
<?php
}
?>
<tr class="border-top h5 text-bold">
<tr class="h5 text-bold">
<td>Balance:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $invoice_currency_code); ?></td>
</tr>
@@ -469,4 +478,4 @@ if ($outstanding_invoices_count > 0) { ?>
<?php } // End previous unpaid invoices
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';

View File

@@ -4,7 +4,7 @@ header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
require_once "includes/guest_header.php";
require_once "includes/inc_all_guest.php";
//Initialize the HTML Purifier to prevent XSS
@@ -39,7 +39,7 @@ $currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
<?php
if (!isset($_GET['id']) || !isset($_GET['key'])) {
echo "<div class='alert alert-danger'>Incorrect URL.</div>";
include "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -53,7 +53,7 @@ $row = mysqli_fetch_array($sql);
// Check we got a result
if (mysqli_num_rows($sql) !== 1 || !$row) {
echo "<div class='alert alert-danger' >No item to view. Check with the person that sent you this link to ensure it is correct and has not expired.</div>";
include "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -61,7 +61,7 @@ if (mysqli_num_rows($sql) !== 1 || !$row) {
// Check item share is active & hasn't been viewed too many times but allow 0 views as that is consider infinite views
if ($row['item_active'] !== "1" || ($row['item_view_limit'] > 0 && $row['item_views'] >= $row['item_view_limit'])) {
echo "<div class='alert alert-danger'>Item cannot be viewed at this time. Check with the person that sent you this link to ensure it is correct and has not expired.</div>";
include "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -83,7 +83,7 @@ $client_id = intval($row['item_client_id']);
$item_type_sql_escaped = sanitizeInput($row['item_type']);
$item_recipient_sql_escaped = sanitizeInput($row['item_recipient']);
appNotify("Share Viewed", "$item_type_sql_escaped has been viewed by $item_recipient_sql_escaped", "client_overview.php?client_id=$client_id", $client_id);
appNotify("Share Viewed", "$item_type_sql_escaped has been viewed by $item_recipient_sql_escaped", "/agent/client_overview.php?client_id=$client_id", $client_id);
?>
@@ -123,7 +123,7 @@ if ($item_type == "Document") {
if (mysqli_num_rows($doc_sql) !== 1 || !$doc_row) {
echo "<div class='alert alert-danger'>Error retrieving document to view.</div>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -150,7 +150,7 @@ if ($item_type == "Document") {
if (mysqli_num_rows($file_sql) !== 1 || !$file_row) {
echo "<div class='alert alert-danger'>Error retrieving file.</div>";
include "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -171,7 +171,7 @@ if ($item_type == "Document") {
$credential_row = mysqli_fetch_array($credential_sql);
if (mysqli_num_rows($credential_sql) !== 1 || !$credential_row) {
echo "<div class='alert alert-danger'>Error retrieving login.</div>";
include "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -274,6 +274,4 @@ if ($item_type == "Document") {
</div>
<?php
require_once "includes/guest_footer.php";
?>
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';

View File

@@ -1,11 +1,11 @@
<?php
require_once "includes/guest_header.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/guest/includes/inc_all_guest.php';
if (!isset($_GET['quote_id'], $_GET['url_key'])) {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -27,7 +27,7 @@ $sql = mysqli_query(
if (mysqli_num_rows($sql) !== 1) {
// Invalid quote/key
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -60,10 +60,6 @@ $contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_countr
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$client_website = nullable_htmlentities($row['client_website']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$client_net_terms = intval($row['client_net_terms']);
if ($client_net_terms == 0) {
$client_net_terms = intval($row['config_default_net_terms']);
}
$sql = mysqli_query($mysqli, "SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
$row = mysqli_fetch_array($sql);
@@ -112,7 +108,7 @@ mysqli_query($mysqli, "INSERT INTO history SET history_status = '$quote_status',
if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Viewed") {
appNotify("Quote Viewed", "Quote $quote_prefix$quote_number has been viewed by $client_name_escaped - $ip - $os - $browser", "quote.php?quote_id=$quote_id", $client_id);
appNotify("Quote Viewed", "Quote $quote_prefix$quote_number has been viewed by $client_name_escaped - $ip - $os - $browser", "/agent/quote.php?quote_id=$quote_id", $client_id);
}
?>
@@ -133,7 +129,7 @@ if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Vie
<div class="row mb-3">
<?php if (file_exists("../uploads/settings/$company_logo")) { ?>
<div class="col-sm-2">
<img class="img-fluid" src="<?php echo "../uploads/settings/$company_logo"; ?>" alt="Company logo">
<img class="img-fluid" src="<?php echo "/uploads/settings/$company_logo"; ?>" alt="Company logo">
</div>
<?php } ?>
<div class="col-sm-6 <?php if (!file_exists("../uploads/settings/$company_logo")) { echo "col-sm-8"; } ?>">
@@ -186,7 +182,7 @@ if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Vie
<div class="col-md-12">
<div class="card">
<div class="table-responsive">
<table class="table table-borderless">
<table class="table table-hover mb-0">
<thead class="bg-light">
<tr>
<th>Item</th>
@@ -249,7 +245,7 @@ if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Vie
</div>
<div class="col-sm-3 offset-sm-2">
<table class="table table-borderless">
<table class="table table-hover mb-0">
<tbody>
<tr>
<td>Subtotal:</td>
@@ -301,4 +297,4 @@ if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Vie
<?php
require_once "guest_quote_upload_file_modal.php";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';

View File

@@ -1,6 +1,6 @@
<?php
require_once "includes/guest_header.php";
require_once "includes/inc_all_guest.php";
//Initialize the HTML Purifier to prevent XSS
require "../plugins/htmlpurifier/HTMLPurifier.standalone.php";
@@ -12,12 +12,24 @@ $purifier = new HTMLPurifier($purifier_config);
if (!isset($_GET['ticket_id'], $_GET['url_key'])) {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
// Company info
$company_sql_row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT company_phone, company_website FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1"));
$company_sql_row = mysqli_fetch_array(mysqli_query($mysqli, "
SELECT
company_phone,
company_phone_country_code,
company_website
FROM
companies,
settings
WHERE
companies.company_id = settings.company_id
AND companies.company_id = 1"
));
$company_phone_country_code = nullable_htmlentities($company_sql_row['company_phone_country_code']);
$company_phone = nullable_htmlentities(formatPhoneNumber($company_sql_row['company_phone'], $company_phone_country_code));
$company_website = nullable_htmlentities($company_sql_row['company_website']);
@@ -35,7 +47,7 @@ $ticket_sql = mysqli_query($mysqli,
if (mysqli_num_rows($ticket_sql) !== 1) {
// Invalid invoice/key
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
@@ -198,7 +210,7 @@ if ($ticket_row) {
?>
<script src="../js/pretty_content.js"></script>
<script src="/js/pretty_content.js"></script>
<?php } else {
echo "Ticket ID not found!";
@@ -209,4 +221,4 @@ if ($ticket_row) {
</div>
<?php
require_once "includes/guest_footer.php";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';

View File

@@ -1,29 +0,0 @@
</div><!-- /.container-fluid -->
</div>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
</div>
<!-- ./wrapper -->
<!-- REQUIRED SCRIPTS -->
<?php require_once "../includes/inc_confirm_modal.php"; ?>
<!-- jQuery -->
<script src="../plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="../plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="../plugins/adminlte/js/adminlte.min.js"></script>
<!-- Custom js -->
<script src="../plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
<script src="../plugins/moment/moment.min.js"></script>
<script src='../plugins/daterangepicker/daterangepicker.js'></script>
<script src='../plugins/select2/js/select2.min.js'></script>
<script src='../plugins/inputmask/inputmask.min.js'></script>
<script src="../js/app.js"></script>
<script src="../js/pretty_content.js"></script>
<script src="../js/confirm_modal.js"></script>
</body>
</html>

View File

@@ -1,27 +1,3 @@
<?php
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/get_settings.php";
session_start();
// Set Timezone
require_once "../includes/inc_set_timezone.php";
$ip = sanitizeInput(getIP());
$user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);
$os = sanitizeInput(getOS($user_agent));
$browser = sanitizeInput(getWebBrowser($user_agent));
// Get Company Name
$sql = mysqli_query($mysqli, "SELECT company_name FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql);
$session_company_name = $row['company_name'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
@@ -36,47 +12,25 @@ $session_company_name = $row['company_name'];
Favicon
If Fav Icon exists else use the default one
-->
<?php if(file_exists('../uploads/favicon.ico')) { ?>
<link rel="icon" type="image/x-icon" href="../uploads/favicon.ico">
<?php if(file_exists($_SERVER['DOCUMENT_ROOT'] . '/uploads/favicon.ico')) { ?>
<link rel="icon" href="/uploads/favicon.ico">
<?php } ?>
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="../plugins/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="/plugins/fontawesome-free/css/all.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="../plugins/adminlte/css/adminlte.min.css">
<link rel="stylesheet" href="/plugins/adminlte/css/adminlte.min.css">
<!-- Custom Style Sheet -->
<link href="../plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css" rel="stylesheet" type="text/css">
<link href="../plugins/select2/css/select2.min.css" rel="stylesheet" type="text/css">
<link href="../plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css" rel="stylesheet" type="text/css">
<link href='../plugins/daterangepicker/daterangepicker.css' rel='stylesheet' />
<link rel="stylesheet" href="/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">
<link rel="stylesheet" href="/plugins/select2/css/select2.min.css">
<link rel="stylesheet" href="/plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css">
<link rel="stylesheet" href='/plugins/daterangepicker/daterangepicker.css'>
<!-- Scripts -->
<script src="/plugins/jquery/jquery.min.js"></script>
<script src="/plugins/toastr/toastr.min.js"></script>
</head>
<body class="layout-top-nav">
<div class="wrapper text-sm">
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Main content -->
<div class="content">
<div class="container">
<?php
//Alert Feedback
if (!empty($_SESSION['alert_message'])) {
if (!isset($_SESSION['alert_type'])) {
$_SESSION['alert_type'] = "info";
}
?>
<div class="alert alert-<?php echo $_SESSION['alert_type']; ?>" id="alert">
<?php echo nullable_htmlentities($_SESSION['alert_message']); ?>
<button class='close' data-dismiss='alert'>&times;</button>
</div>
<?php
unset($_SESSION['alert_type']);
unset($_SESSION['alert_message']);
}
?>
<div class="wrapper text-sm">

View File

@@ -0,0 +1,32 @@
<?php
// Configuration & core
require_once $_SERVER['DOCUMENT_ROOT'] . '/config.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/functions.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/load_global_settings.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/session_init.php';
// Set Timezone
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/inc_set_timezone.php';
$ip = sanitizeInput(getIP());
$user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);
$os = sanitizeInput(getOS($user_agent));
$browser = sanitizeInput(getWebBrowser($user_agent));
// Get Company Name
$sql = mysqli_query($mysqli, "SELECT company_name FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql);
$session_company_name = $row['company_name'];
// Page setup
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/page_title.php';
// Layout UI
require_once $_SERVER['DOCUMENT_ROOT'] . '/guest/includes/guest_header.php';
// Wrapper & alerts
require_once $_SERVER['DOCUMENT_ROOT'] . '/guest/includes/inc_wrapper.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/inc_alert_feedback.php';
//require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/filter_header.php';

View File

@@ -0,0 +1,6 @@
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Main content -->
<div class="content">
<div class="container">

View File

@@ -1,3 +1,3 @@
<?php
// Redirect to the portal
header("Location: ../client/");
header("Location: /client");