mirror of
https://github.com/itflow-org/itflow
synced 2026-02-28 10:54:52 +00:00
Fix dupe race condition with ticket, invoice, quote, project, recurring ticket numbering when being created in parallel Atomically update and get the next ticket number in one SQL query everywhere.
This commit is contained in:
184
client/post.php
184
client/post.php
@@ -34,10 +34,16 @@ if (isset($_POST['add_ticket'])) {
|
||||
$priority = sanitizeInput($_POST['priority']);
|
||||
}
|
||||
|
||||
// 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");
|
||||
// Atomically increment and get the new ticket number
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE settings
|
||||
SET
|
||||
config_ticket_next_number = LAST_INSERT_ID(config_ticket_next_number),
|
||||
config_ticket_next_number = config_ticket_next_number + 1
|
||||
WHERE company_id = 1
|
||||
");
|
||||
|
||||
$ticket_number = mysqli_insert_id($mysqli);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_source = 'Portal', ticket_category = $category, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 1, ticket_billable = $config_ticket_default_billable, ticket_created_by = $session_user_id, ticket_contact_id = $session_contact_id, ticket_asset_id = $asset, ticket_url_key = '$url_key', ticket_client_id = $session_client_id");
|
||||
$ticket_id = mysqli_insert_id($mysqli);
|
||||
@@ -180,7 +186,7 @@ if (isset($_POST['add_ticket_comment'])) {
|
||||
}
|
||||
|
||||
if (isset($_POST['add_ticket_feedback'])) {
|
||||
|
||||
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
$feedback = sanitizeInput($_POST['add_ticket_feedback']);
|
||||
|
||||
@@ -210,7 +216,7 @@ if (isset($_POST['add_ticket_feedback'])) {
|
||||
}
|
||||
|
||||
if (isset($_GET['resolve_ticket'])) {
|
||||
|
||||
|
||||
$ticket_id = intval($_GET['resolve_ticket']);
|
||||
|
||||
// Get ticket details for logging
|
||||
@@ -275,7 +281,7 @@ if (isset($_GET['reopen_ticket'])) {
|
||||
}
|
||||
|
||||
if (isset($_GET['close_ticket'])) {
|
||||
|
||||
|
||||
$ticket_id = intval($_GET['close_ticket']);
|
||||
|
||||
// Get ticket details for logging
|
||||
@@ -299,7 +305,7 @@ if (isset($_GET['close_ticket'])) {
|
||||
customAction('ticket_close', $ticket_id);
|
||||
|
||||
redirect("ticket.php?id=" . $ticket_id);
|
||||
|
||||
|
||||
} else {
|
||||
// The client does not have access to this ticket - send them home
|
||||
redirect("index.php");
|
||||
@@ -307,7 +313,7 @@ if (isset($_GET['close_ticket'])) {
|
||||
}
|
||||
|
||||
if (isset($_GET['logout'])) {
|
||||
|
||||
|
||||
setcookie("PHPSESSID", '', time() - 3600, "/");
|
||||
unset($_COOKIE['PHPSESSID']);
|
||||
|
||||
@@ -319,9 +325,9 @@ if (isset($_GET['logout'])) {
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_profile'])) {
|
||||
|
||||
|
||||
$new_password = $_POST['new_password'];
|
||||
|
||||
|
||||
if (!empty($new_password)) {
|
||||
$password_hash = password_hash($new_password, PASSWORD_DEFAULT);
|
||||
mysqli_query($mysqli, "UPDATE users SET user_password = '$password_hash' WHERE user_id = $session_user_id");
|
||||
@@ -329,7 +335,7 @@ if (isset($_POST['edit_profile'])) {
|
||||
// Logging
|
||||
logAction("Contact", "Edit", "Client contact $session_contact_name edited their profile/password in the client portal", $session_client_id, $session_contact_id);
|
||||
}
|
||||
|
||||
|
||||
redirect('index.php');
|
||||
|
||||
}
|
||||
@@ -362,12 +368,12 @@ if (isset($_POST['add_contact'])) {
|
||||
mysqli_query($mysqli, "INSERT INTO users SET user_name = '$contact_name', user_email = '$contact_email', user_password = '$password_hash', user_auth_method = '$contact_auth_method', user_type = 2");
|
||||
|
||||
$contact_user_id = mysqli_insert_id($mysqli);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Create contact record
|
||||
mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '$contact_name', contact_email = '$contact_email', contact_billing = $contact_billing, contact_technical = $contact_technical, contact_client_id = $session_client_id, contact_user_id = $contact_user_id");
|
||||
|
||||
|
||||
$contact_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Logging
|
||||
@@ -613,15 +619,15 @@ if (isset($_GET['add_payment_by_provider'])) {
|
||||
customAction('invoice_pay', $invoice_id);
|
||||
|
||||
flash_alert("The amount " . numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code) . " paid Invoice $invoice_prefix$invoice_number");
|
||||
|
||||
|
||||
redirect();
|
||||
|
||||
} else {
|
||||
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Payment failed', history_description = 'Stripe pay failed due to payment error', history_invoice_id = $invoice_id");
|
||||
|
||||
|
||||
logAction("Invoice", "Payment", "Failed online payment amount of invoice $invoice_prefix$invoice_number due to Stripe payment error", $client_id, $invoice_id);
|
||||
flash_alert("Payment failed", 'error');
|
||||
|
||||
|
||||
redirect();
|
||||
}
|
||||
|
||||
@@ -635,9 +641,9 @@ if (isset($_POST['create_stripe_customer'])) {
|
||||
|
||||
// Get Stripe provider
|
||||
$stripe_provider_result = mysqli_query($mysqli, "
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
@@ -657,10 +663,10 @@ if (isset($_POST['create_stripe_customer'])) {
|
||||
|
||||
// Check if client already has a Stripe customer
|
||||
$existing_customer = mysqli_fetch_array(mysqli_query($mysqli, "
|
||||
SELECT payment_provider_client
|
||||
FROM client_payment_provider
|
||||
WHERE client_id = $session_client_id
|
||||
AND payment_provider_id = $stripe_provider_id
|
||||
SELECT payment_provider_client
|
||||
FROM client_payment_provider
|
||||
WHERE client_id = $session_client_id
|
||||
AND payment_provider_id = $stripe_provider_id
|
||||
LIMIT 1
|
||||
"));
|
||||
|
||||
@@ -684,10 +690,10 @@ if (isset($_POST['create_stripe_customer'])) {
|
||||
|
||||
// Insert customer into client_payment_provider
|
||||
mysqli_query($mysqli, "
|
||||
INSERT INTO client_payment_provider
|
||||
SET client_id = $session_client_id,
|
||||
payment_provider_id = $stripe_provider_id,
|
||||
payment_provider_client = '$stripe_customer_id',
|
||||
INSERT INTO client_payment_provider
|
||||
SET client_id = $session_client_id,
|
||||
payment_provider_id = $stripe_provider_id,
|
||||
payment_provider_client = '$stripe_customer_id',
|
||||
client_payment_provider_created_at = NOW()
|
||||
");
|
||||
|
||||
@@ -697,9 +703,9 @@ if (isset($_POST['create_stripe_customer'])) {
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
|
||||
|
||||
error_log("Stripe error while creating customer for $session_client_name: $error");
|
||||
|
||||
|
||||
logApp("Stripe", "error", "Failed to create Stripe customer for $session_client_name: $error");
|
||||
|
||||
flash_alert("An error occurred while creating your Stripe customer. Please try again.", 'danger');
|
||||
@@ -723,9 +729,9 @@ if (isset($_GET['create_stripe_checkout'])) {
|
||||
|
||||
// Fetch Stripe provider info
|
||||
$stripe_provider_result = mysqli_query($mysqli, "
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
@@ -747,9 +753,9 @@ if (isset($_GET['create_stripe_checkout'])) {
|
||||
|
||||
// Get client currency
|
||||
$client_currency_result = mysqli_query($mysqli, "
|
||||
SELECT client_currency_code
|
||||
FROM clients
|
||||
WHERE client_id = $session_client_id
|
||||
SELECT client_currency_code
|
||||
FROM clients
|
||||
WHERE client_id = $session_client_id
|
||||
LIMIT 1
|
||||
");
|
||||
$client_currency_row = mysqli_fetch_assoc($client_currency_result);
|
||||
@@ -791,9 +797,9 @@ if (isset($_GET['stripe_save_card'])) {
|
||||
|
||||
// Get Stripe provider
|
||||
$stripe_provider_result = mysqli_query($mysqli, "
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
@@ -813,10 +819,10 @@ if (isset($_GET['stripe_save_card'])) {
|
||||
|
||||
// Get client's Stripe customer ID
|
||||
$client_provider_query = mysqli_query($mysqli, "
|
||||
SELECT payment_provider_client
|
||||
FROM client_payment_provider
|
||||
WHERE client_id = $session_client_id
|
||||
AND payment_provider_id = $stripe_provider_id
|
||||
SELECT payment_provider_client
|
||||
FROM client_payment_provider
|
||||
WHERE client_id = $session_client_id
|
||||
AND payment_provider_id = $stripe_provider_id
|
||||
LIMIT 1
|
||||
");
|
||||
$client_provider = mysqli_fetch_array($client_provider_query);
|
||||
@@ -854,8 +860,8 @@ if (isset($_GET['stripe_save_card'])) {
|
||||
|
||||
// Insert into client_saved_payment_methods
|
||||
mysqli_query($mysqli, "
|
||||
INSERT INTO client_saved_payment_methods
|
||||
SET
|
||||
INSERT INTO client_saved_payment_methods
|
||||
SET
|
||||
saved_payment_provider_method = '$payment_method_id',
|
||||
saved_payment_description = '$saved_payment_description',
|
||||
saved_payment_client_id = $session_client_id,
|
||||
@@ -874,8 +880,8 @@ if (isset($_GET['stripe_save_card'])) {
|
||||
|
||||
// Email Confirmation
|
||||
$sql_settings = mysqli_query($mysqli, "
|
||||
SELECT * FROM companies, settings
|
||||
WHERE companies.company_id = settings.company_id
|
||||
SELECT * FROM companies, settings
|
||||
WHERE companies.company_id = settings.company_id
|
||||
AND companies.company_id = 1
|
||||
");
|
||||
$row = mysqli_fetch_array($sql_settings);
|
||||
@@ -922,9 +928,9 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
|
||||
// Get Stripe provider info
|
||||
$stripe_provider_result = mysqli_query($mysqli, "
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
SELECT * FROM payment_providers
|
||||
WHERE payment_provider_name = 'Stripe'
|
||||
AND payment_provider_active = 1
|
||||
LIMIT 1
|
||||
");
|
||||
$stripe_provider = mysqli_fetch_array($stripe_provider_result);
|
||||
@@ -943,11 +949,11 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
}
|
||||
|
||||
$saved_payment_result = mysqli_query($mysqli, "
|
||||
SELECT saved_payment_id, saved_payment_description, saved_payment_provider_method
|
||||
FROM client_saved_payment_methods
|
||||
WHERE saved_payment_id = $saved_payment_id
|
||||
AND saved_payment_client_id = $session_client_id
|
||||
AND saved_payment_provider_id = $stripe_provider_id
|
||||
SELECT saved_payment_id, saved_payment_description, saved_payment_provider_method
|
||||
FROM client_saved_payment_methods
|
||||
WHERE saved_payment_id = $saved_payment_id
|
||||
AND saved_payment_client_id = $session_client_id
|
||||
AND saved_payment_provider_id = $stripe_provider_id
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
@@ -973,27 +979,27 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
|
||||
|
||||
error_log("Stripe error while removing payment method $payment_method_id: $error");
|
||||
|
||||
|
||||
logApp("Stripe", "error", "Exception removing payment method $payment_method_id: $error");
|
||||
|
||||
flash_alert("An error occurred while removing your payment method.", 'danger');
|
||||
|
||||
|
||||
redirect("saved_payment_methods.php");
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Remove saved payment method from local DB
|
||||
mysqli_query($mysqli, "
|
||||
DELETE FROM client_saved_payment_methods
|
||||
DELETE FROM client_saved_payment_methods
|
||||
WHERE saved_payment_id = $saved_payment_id
|
||||
");
|
||||
|
||||
// Remove any auto-pay records using this payment method
|
||||
$recurring_invoices = mysqli_query($mysqli, "
|
||||
SELECT recurring_invoice_id
|
||||
FROM recurring_invoices
|
||||
SELECT recurring_invoice_id
|
||||
FROM recurring_invoices
|
||||
WHERE recurring_invoice_client_id = $session_client_id
|
||||
");
|
||||
|
||||
@@ -1001,8 +1007,8 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
DELETE FROM recurring_payments
|
||||
WHERE recurring_payment_recurring_invoice_id = $recurring_invoice_id
|
||||
DELETE FROM recurring_payments
|
||||
WHERE recurring_payment_recurring_invoice_id = $recurring_invoice_id
|
||||
AND recurring_payment_saved_payment_id = $saved_payment_id
|
||||
");
|
||||
}
|
||||
@@ -1010,7 +1016,7 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
logAction("Stripe", "Update", "$session_contact_name deleted Stripe payment method $saved_payment_description (PM: $payment_method_id)", $session_client_id);
|
||||
|
||||
flash_alert("Payment method $saved_payment_description removed.");
|
||||
|
||||
|
||||
redirect("saved_payment_methods.php");
|
||||
}
|
||||
|
||||
@@ -1035,7 +1041,7 @@ if (isset($_POST['set_recurring_payment'])) {
|
||||
LEFT JOIN client_saved_payment_methods ON saved_payment_provider_id = payment_provider_id
|
||||
WHERE saved_payment_id = $saved_payment_id
|
||||
AND saved_payment_client_id = $session_client_id
|
||||
AND payment_provider_active = 1
|
||||
AND payment_provider_active = 1
|
||||
");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
@@ -1078,13 +1084,13 @@ if (isset($_POST['client_add_document'])) {
|
||||
$document_content_raw = sanitizeInput($document_name . " " . strip_tags($_POST['document_content']));
|
||||
|
||||
// Create document
|
||||
mysqli_query($mysqli, "INSERT INTO documents SET
|
||||
document_name = '$document_name',
|
||||
document_description = '$document_description',
|
||||
document_content = '',
|
||||
document_content_raw = '$document_content_raw',
|
||||
document_client_visible = 1,
|
||||
document_client_id = $session_client_id,
|
||||
mysqli_query($mysqli, "INSERT INTO documents SET
|
||||
document_name = '$document_name',
|
||||
document_description = '$document_description',
|
||||
document_content = '',
|
||||
document_content_raw = '$document_content_raw',
|
||||
document_client_visible = 1,
|
||||
document_client_id = $session_client_id,
|
||||
document_created_by = $session_contact_id");
|
||||
|
||||
$document_id = mysqli_insert_id($mysqli);
|
||||
@@ -1131,7 +1137,7 @@ if (isset($_POST['client_upload_document'])) {
|
||||
|
||||
// Check if file was uploaded
|
||||
if (isset($_FILES['document_file']) && $_FILES['document_file']['error'] == 0) {
|
||||
|
||||
|
||||
// Validate and get a safe file reference name
|
||||
if ($file_reference_name = checkFileUpload($_FILES['document_file'], $allowedExtensions)) {
|
||||
|
||||
@@ -1151,26 +1157,26 @@ if (isset($_POST['client_upload_document'])) {
|
||||
$document_content = "<p>Uploaded file: <strong>$file_name</strong></p><p>$document_description</p>";
|
||||
$document_content_raw = "$document_name $file_name $document_description";
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO documents SET
|
||||
document_name = '$document_name',
|
||||
document_description = '$document_description',
|
||||
document_content = '$document_content',
|
||||
document_content_raw = '$document_content_raw',
|
||||
document_client_visible = 1,
|
||||
document_client_id = $session_client_id,
|
||||
mysqli_query($mysqli, "INSERT INTO documents SET
|
||||
document_name = '$document_name',
|
||||
document_description = '$document_description',
|
||||
document_content = '$document_content',
|
||||
document_content_raw = '$document_content_raw',
|
||||
document_client_visible = 1,
|
||||
document_client_id = $session_client_id,
|
||||
document_created_by = $session_contact_id");
|
||||
|
||||
$document_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Create file entry
|
||||
mysqli_query($mysqli, "INSERT INTO files SET
|
||||
file_reference_name = '$file_reference_name',
|
||||
file_name = '$file_name',
|
||||
file_description = 'Attached to document: $document_name',
|
||||
file_ext = '$file_extension',
|
||||
file_mime_type = '$file_mime_type',
|
||||
file_size = $file_size,
|
||||
file_created_by = $session_contact_id,
|
||||
mysqli_query($mysqli, "INSERT INTO files SET
|
||||
file_reference_name = '$file_reference_name',
|
||||
file_name = '$file_name',
|
||||
file_description = 'Attached to document: $document_name',
|
||||
file_ext = '$file_extension',
|
||||
file_mime_type = '$file_mime_type',
|
||||
file_size = $file_size,
|
||||
file_created_by = $session_contact_id,
|
||||
file_client_id = $session_client_id");
|
||||
|
||||
$file_id = mysqli_insert_id($mysqli);
|
||||
|
||||
Reference in New Issue
Block a user