Rework Payment Provider AI Provider Tables and logic add cascading deletes

This commit is contained in:
johnnyq 2025-07-08 14:07:10 -04:00
parent a6f83493f8
commit 93f4ea51fd
3 changed files with 136 additions and 92 deletions

View File

@ -3675,10 +3675,10 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.0'");
}
if (CURRENT_DATABASE_VERSION == '2.2.0') {
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_quote_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_asset_id`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.1'");
}
if (CURRENT_DATABASE_VERSION == '2.2.0') {
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_quote_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_asset_id`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.1'");
}
if (CURRENT_DATABASE_VERSION == '2.2.1') {
mysqli_query($mysqli, "CREATE TABLE `ai_providers` (
@ -3691,16 +3691,21 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
PRIMARY KEY (`ai_provider_id`)
)");
mysqli_query($mysqli, "CREATE TABLE `ai_models` (
`ai_model_id` INT(11) NOT NULL AUTO_INCREMENT,
`ai_model_name` VARCHAR(200) NOT NULL,
`ai_model_prompt` TEXT DEFAULT NULL,
`ai_model_use_case` VARCHAR(200) DEFAULT NULL,
`ai_model_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ai_model_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`ai_model_ai_provider_id` INT(11) NOT NULL,
PRIMARY KEY (`ai_model_id`)
)");
mysqli_query($mysqli, "
CREATE TABLE `ai_models` (
`ai_model_id` INT(11) NOT NULL AUTO_INCREMENT,
`ai_model_name` VARCHAR(200) NOT NULL,
`ai_model_prompt` TEXT DEFAULT NULL,
`ai_model_use_case` VARCHAR(200) DEFAULT NULL,
`ai_model_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ai_model_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`ai_model_ai_provider_id` INT(11) NOT NULL,
PRIMARY KEY (`ai_model_id`),
FOREIGN KEY (`ai_model_ai_provider_id`)
REFERENCES `ai_providers`(`ai_provider_id`)
ON DELETE CASCADE
)
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.2'");
}
@ -3710,7 +3715,6 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
`payment_method_id` INT(11) NOT NULL AUTO_INCREMENT,
`payment_method_name` VARCHAR(200) NOT NULL,
`payment_method_description` VARCHAR(250) DEFAULT NULL,
`payment_method_provider_id` INT(11) DEFAULT 0,
`payment_method_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`payment_method_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`payment_method_id`)
@ -3736,16 +3740,31 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "CREATE TABLE `client_saved_payment_methods` (
`saved_payment_id` INT(11) NOT NULL AUTO_INCREMENT,
`saved_payment_provider_client` VARCHAR(200) NOT NULL,
`saved_payment_provider_method` VARCHAR(200) NOT NULL,
`saved_payment_details` VARCHAR(200) DEFAULT NULL,
`saved_payment_description` VARCHAR(200) DEFAULT NULL,
`saved_payment_client_id` INT(11) NOT NULL,
`saved_payment_provider_id` INT(11) NOT NULL,
`saved_payment_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`saved_payment_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`saved_payment_id`)
PRIMARY KEY (`saved_payment_id`),
FOREIGN KEY (`saved_payment_client_id`) REFERENCES clients(`client_id`) ON DELETE CASCADE,
FOREIGN KEY (`saved_payment_provider_id`) REFERENCES payment_providers(`payment_provider_id`) ON DELETE CASCADE
)");
mysqli_query($mysqli, "CREATE TABLE `client_payment_provider` (
`client_id` INT(11) NOT NULL,
`payment_provider_id` INT(11) NOT NULL,
`payment_provider_client` VARCHAR(200) NOT NULL,
`client_payment_provider_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`client_id`, `payment_provider_id`),
FOREIGN KEY (`client_id`) REFERENCES clients(`client_id`) ON DELETE CASCADE,
FOREIGN KEY (`payment_provider_id`) REFERENCES payment_providers(`payment_provider_id`) ON DELETE CASCADE
)");
mysqli_query($mysqli, "ALTER TABLE `recurring_payments` ADD `recurring_payment_saved_payment_id` INT(11) DEFAULT NULL AFTER `recurring_payment_recurring_invoice_id`");
mysqli_query($mysqli, "ALTER TABLE `recurring_payments` ADD CONSTRAINT `fk_recurring_saved_payment` FOREIGN KEY (`recurring_payment_saved_payment_id`) REFERENCES `client_saved_payment_methods`(`saved_payment_id`) ON DELETE CASCADE");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.3'");
}

74
db.sql
View File

@ -53,7 +53,9 @@ CREATE TABLE `ai_models` (
`ai_model_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`ai_model_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`ai_model_ai_provider_id` int(11) NOT NULL,
PRIMARY KEY (`ai_model_id`)
PRIMARY KEY (`ai_model_id`),
KEY `ai_model_ai_provider_id` (`ai_model_ai_provider_id`),
CONSTRAINT `ai_models_ibfk_1` FOREIGN KEY (`ai_model_ai_provider_id`) REFERENCES `ai_providers` (`ai_provider_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
@ -486,26 +488,6 @@ CREATE TABLE `certificates` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `cient_saved_payment_methods`
--
DROP TABLE IF EXISTS `cient_saved_payment_methods`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `cient_saved_payment_methods` (
`saved_payment_id` int(11) NOT NULL AUTO_INCREMENT,
`saved_payment_provider_client` varchar(200) NOT NULL,
`saved_payment_provider_method` varchar(200) NOT NULL,
`saved_payment_details` varchar(200) DEFAULT NULL,
`saved_payment_client_id` int(11) NOT NULL,
`saved_payment_provider_id` int(11) NOT NULL,
`saved_payment_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`saved_payment_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
PRIMARY KEY (`saved_payment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `client_notes`
--
@ -528,6 +510,48 @@ CREATE TABLE `client_notes` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `client_payment_provider`
--
DROP TABLE IF EXISTS `client_payment_provider`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `client_payment_provider` (
`client_id` int(11) NOT NULL,
`payment_provider_id` int(11) NOT NULL,
`payment_provider_client` varchar(200) NOT NULL,
`client_payment_provider_created_at` datetime NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`client_id`,`payment_provider_id`),
KEY `payment_provider_id` (`payment_provider_id`),
CONSTRAINT `client_payment_provider_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `clients` (`client_id`) ON DELETE CASCADE,
CONSTRAINT `client_payment_provider_ibfk_2` FOREIGN KEY (`payment_provider_id`) REFERENCES `payment_providers` (`payment_provider_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `client_saved_payment_methods`
--
DROP TABLE IF EXISTS `client_saved_payment_methods`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `client_saved_payment_methods` (
`saved_payment_id` int(11) NOT NULL AUTO_INCREMENT,
`saved_payment_provider_method` varchar(200) NOT NULL,
`saved_payment_description` varchar(200) DEFAULT NULL,
`saved_payment_client_id` int(11) NOT NULL,
`saved_payment_provider_id` int(11) NOT NULL,
`saved_payment_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`saved_payment_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
PRIMARY KEY (`saved_payment_id`),
KEY `saved_payment_client_id` (`saved_payment_client_id`),
KEY `saved_payment_provider_id` (`saved_payment_provider_id`),
CONSTRAINT `client_saved_payment_methods_ibfk_1` FOREIGN KEY (`saved_payment_client_id`) REFERENCES `clients` (`client_id`) ON DELETE CASCADE,
CONSTRAINT `client_saved_payment_methods_ibfk_2` FOREIGN KEY (`saved_payment_provider_id`) REFERENCES `payment_providers` (`payment_provider_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `client_stripe`
--
@ -1331,7 +1355,6 @@ CREATE TABLE `payment_methods` (
`payment_method_id` int(11) NOT NULL AUTO_INCREMENT,
`payment_method_name` varchar(200) NOT NULL,
`payment_method_description` varchar(250) DEFAULT NULL,
`payment_method_provider_id` int(11) DEFAULT 0,
`payment_method_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`payment_method_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
PRIMARY KEY (`payment_method_id`)
@ -1661,7 +1684,10 @@ CREATE TABLE `recurring_payments` (
`recurring_payment_account_id` int(11) NOT NULL,
`recurring_payment_recurring_expense_id` int(11) NOT NULL DEFAULT 0,
`recurring_payment_recurring_invoice_id` int(11) NOT NULL,
PRIMARY KEY (`recurring_payment_id`)
`recurring_payment_saved_payment_id` int(11) DEFAULT NULL,
PRIMARY KEY (`recurring_payment_id`),
KEY `fk_recurring_saved_payment` (`recurring_payment_saved_payment_id`),
CONSTRAINT `fk_recurring_saved_payment` FOREIGN KEY (`recurring_payment_saved_payment_id`) REFERENCES `client_saved_payment_methods` (`saved_payment_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
@ -2692,4 +2718,4 @@ CREATE TABLE `vendors` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-07-07 16:36:58
-- Dump completed on 2025-07-08 14:06:43

View File

@ -5,66 +5,65 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
if (isset($_GET['delete_saved_payment'])) {
validateCSRFToken($_GET['csrf_token']);
if (!$config_stripe_enable) {
$_SESSION['alert_message'] = "Stripe not enabled";
header("Location: " . $_SERVER["HTTP_REFERER"]);
exit();
}
$saved_payment_id = intval($_GET['delete_saved_payment']);
$client_id = intval($_GET['client_id']);
$payment_method = sanitizeInput($_GET['pm']);
$sql = mysqli_query($mysqli, "
SELECT
client_saved_payment_methods.saved_payment_id,
client_saved_payment_methods.saved_payment_client_id,
client_saved_payment_methods.saved_payment_provider_id,
client_saved_payment_methods.saved_payment_provider_method,
client_saved_payment_methods.saved_payment_description,
client_payment_provider.payment_provider_client,
payment_providers.payment_provider_name,
payment_providers.payment_provider_private_key
FROM client_saved_payment_methods
LEFT JOIN client_payment_provider
ON client_payment_provider.client_id = client_saved_payment_methods.saved_payment_client_id
AND client_payment_provider.payment_provider_id = client_saved_payment_methods.saved_payment_provider_id
LEFT JOIN payment_providers
ON payment_providers.payment_provider_id = client_saved_payment_methods.saved_payment_provider_id
WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id"
);
try {
// Initialize stripe
require_once 'plugins/stripe-php/init.php';
$stripe = new \Stripe\StripeClient($config_stripe_secret);
$row = mysqli_fetch_array($sql);
$client_id = intval($row['saved_payment_client_id']);
$provider_id = intval($row['saved_payment_provider_id']);
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']);
$saved_payment_description = nullable_htmlentities($row['saved_payment_description']);
$provider_client = nullable_htmlentities($row['payment_provider_client']);
$payment_method = $row['saved_payment_provider_method'];
// Detach PM
$stripe->paymentMethods->detach($payment_method, []);
$private_key = $row['payment_provider_private_key'];
// Seperate logic for each Payment Provider
if ($payment_provider_name == 'Stripe') {
try {
// Initialize stripe
require_once 'plugins/stripe-php/init.php';
$stripe = new \Stripe\StripeClient($private_key);
// Detach PM
$stripe->paymentMethods->detach($payment_method, []);
} catch (Exception $e) {
$error = $e->getMessage();
error_log("Stripe payment error - encountered exception when removing payment method info for $payment_method: $error");
logApp("Stripe", "error", "Exception removing payment method for $payment_method: $error");
}
} catch (Exception $e) {
$error = $e->getMessage();
error_log("Stripe payment error - encountered exception when removing payment method info for $payment_method: $error");
logApp("Stripe", "error", "Exception removing payment method for $payment_method: $error");
}
// Remove payment method from ITFlow
mysqli_query($mysqli, "UPDATE client_stripe SET stripe_pm = NULL WHERE client_id = $client_id LIMIT 1");
mysqli_query($mysqli, "DELETE FROM client_saved_payment_methods WHERE saved_payment_id = $saved_payment_id");
// Remove Auto Pay on recurring invoices that are stripe
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
while ($row = mysqli_fetch_array($sql_recurring_invoices)) {
$recurring_invoice_id = intval($row['recurring_invoice_id']);
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
}
// Remove All Associted Auto Payment Methods on recurring invoices
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_saved_payment_id = $saved_payment_id");
// Logging & Redirect
logAction("Stripe", "Update", "$session_name deleted saved Stripe payment method (PM: $payment_method)", $client_id);
$_SESSION['alert_message'] = "Payment method removed";
logAction("Payment Provider", "Update", "$session_name deleted saved payment method $saved_payment_description (PM: $payment_method)", $client_id);
$_SESSION['alert_message'] = "Payment method <strong>$saved_payment_description</strong> removed";
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
if (isset($_GET['stripe_reset_customer'])) {
validateCSRFToken($_GET['csrf_token']);
$client_id = intval($_GET['client_id']);
// Delete the customer id and payment method id stored in ITFlow, allowing the client to set these up again
mysqli_query($mysqli, "DELETE FROM client_stripe WHERE client_id = $client_id");
// Remove Auto Pay on recurring invoices that are stripe
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
while ($row = mysqli_fetch_array($sql_recurring_invoices)) {
$recurring_invoice_id = intval($row['recurring_invoice_id']);
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
}
// Logging
logAction("Stripe", "Delete", "$session_name reset Stripe settings for client", $client_id);
$_SESSION['alert_message'] = "Reset client Stripe settings";
header("Location: " . $_SERVER["HTTP_REFERER"]);
}