175 lines
7.2 KiB
SQL
175 lines
7.2 KiB
SQL
-- Migration Script: Billing System with Invoice Table
|
|
-- This script upgrades existing billing installations to the new invoice-based system
|
|
-- Run this ONCE on existing installations (not needed for fresh installs)
|
|
-- Compatible with MySQL 5.7+ and MariaDB 10.2+
|
|
|
|
-- Step 1: Add new columns to billing_orders (only if they don't exist)
|
|
SET @dbname = DATABASE();
|
|
SET @tablename = 'ogp_billing_orders';
|
|
|
|
-- Add order_date column
|
|
SET @col_exists = 0;
|
|
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'order_date';
|
|
SET @sql = IF(@col_exists = 0,
|
|
'ALTER TABLE `ogp_billing_orders` ADD COLUMN `order_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `status`',
|
|
'SELECT "Column order_date already exists" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- Add payment_txid column
|
|
SET @col_exists = 0;
|
|
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'payment_txid';
|
|
SET @sql = IF(@col_exists = 0,
|
|
'ALTER TABLE `ogp_billing_orders` ADD COLUMN `payment_txid` VARCHAR(255) NULL AFTER `end_date`',
|
|
'SELECT "Column payment_txid already exists" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- Add paid_ts column
|
|
SET @col_exists = 0;
|
|
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'paid_ts';
|
|
SET @sql = IF(@col_exists = 0,
|
|
'ALTER TABLE `ogp_billing_orders` ADD COLUMN `paid_ts` DATETIME NULL AFTER `payment_txid`',
|
|
'SELECT "Column paid_ts already exists" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- Step 2: Modify existing columns to use proper data types
|
|
ALTER TABLE `ogp_billing_orders`
|
|
MODIFY COLUMN `status` VARCHAR(16) NOT NULL DEFAULT 'in-cart',
|
|
MODIFY COLUMN `remote_control_password` VARCHAR(255) NULL,
|
|
MODIFY COLUMN `ftp_password` VARCHAR(255) NULL;
|
|
|
|
-- Convert end_date from VARCHAR to DATETIME (handle existing data)
|
|
-- First, update any '0' values to NULL
|
|
UPDATE `ogp_billing_orders` SET `end_date` = NULL WHERE `end_date` = '0' OR `end_date` = '';
|
|
|
|
-- Check current end_date type and convert if needed
|
|
SET @col_type = '';
|
|
SELECT DATA_TYPE INTO @col_type FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'end_date';
|
|
|
|
SET @sql = IF(@col_type = 'varchar',
|
|
'ALTER TABLE `ogp_billing_orders` MODIFY COLUMN `end_date` DATETIME NULL',
|
|
'SELECT "Column end_date already DATETIME" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- Step 3: Remove obsolete columns from billing_orders
|
|
SET @col_exists = 0;
|
|
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'cart_id';
|
|
SET @sql = IF(@col_exists > 0,
|
|
'ALTER TABLE `ogp_billing_orders` DROP COLUMN `cart_id`',
|
|
'SELECT "Column cart_id already removed" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
SET @col_exists = 0;
|
|
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'extended';
|
|
SET @sql = IF(@col_exists > 0,
|
|
'ALTER TABLE `ogp_billing_orders` DROP COLUMN `extended`',
|
|
'SELECT "Column extended already removed" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- Step 4: Add indexes to billing_orders for better performance
|
|
SET @index_exists = 0;
|
|
SELECT COUNT(*) INTO @index_exists FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND INDEX_NAME = 'idx_user_id';
|
|
SET @sql = IF(@index_exists = 0,
|
|
'ALTER TABLE `ogp_billing_orders` ADD INDEX `idx_user_id` (`user_id`)',
|
|
'SELECT "Index idx_user_id already exists" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
SET @index_exists = 0;
|
|
SELECT COUNT(*) INTO @index_exists FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND INDEX_NAME = 'idx_status';
|
|
SET @sql = IF(@index_exists = 0,
|
|
'ALTER TABLE `ogp_billing_orders` ADD INDEX `idx_status` (`status`)',
|
|
'SELECT "Index idx_status already exists" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
SET @index_exists = 0;
|
|
SELECT COUNT(*) INTO @index_exists FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND INDEX_NAME = 'idx_home_id';
|
|
SET @sql = IF(@index_exists = 0,
|
|
'ALTER TABLE `ogp_billing_orders` ADD INDEX `idx_home_id` (`home_id`)',
|
|
'SELECT "Index idx_home_id already exists" AS message');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
|
|
-- Step 5: Create the new billing_invoices table
|
|
CREATE TABLE IF NOT EXISTS `ogp_billing_invoices` (
|
|
`invoice_id` INT(11) NOT NULL AUTO_INCREMENT,
|
|
`order_id` INT(11) NOT NULL,
|
|
`user_id` INT(11) NOT NULL,
|
|
`customer_name` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`customer_email` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`amount` FLOAT(15,2) NOT NULL DEFAULT 0,
|
|
`currency` VARCHAR(3) NOT NULL DEFAULT 'USD',
|
|
`status` VARCHAR(16) NOT NULL DEFAULT 'unpaid',
|
|
`invoice_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`due_date` DATETIME NULL,
|
|
`paid_date` DATETIME NULL,
|
|
`payment_txid` VARCHAR(255) NULL,
|
|
`payment_method` VARCHAR(50) NULL,
|
|
`description` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`invoice_duration` VARCHAR(16) NOT NULL DEFAULT 'month',
|
|
`qty` INT(11) NOT NULL DEFAULT 1,
|
|
PRIMARY KEY (`invoice_id`),
|
|
KEY `order_id` (`order_id`),
|
|
KEY `user_id` (`user_id`),
|
|
KEY `status` (`status`),
|
|
KEY `due_date` (`due_date`)
|
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
|
|
|
-- Step 6: Migrate existing paid orders to create initial invoices
|
|
-- This creates a historical invoice for each paid/installed order
|
|
INSERT INTO `ogp_billing_invoices`
|
|
(`order_id`, `user_id`, `customer_name`, `customer_email`, `amount`, `currency`, `status`, `invoice_date`, `paid_date`, `payment_txid`, `description`, `invoice_duration`, `qty`)
|
|
SELECT
|
|
o.order_id,
|
|
o.user_id,
|
|
CONCAT(COALESCE(u.users_fname, ''), ' ', COALESCE(u.users_lname, '')) AS customer_name,
|
|
u.users_email AS customer_email,
|
|
o.price AS amount,
|
|
'USD' AS currency,
|
|
'paid' AS status,
|
|
COALESCE(o.order_date, NOW()) AS invoice_date,
|
|
COALESCE(o.paid_ts, o.order_date, NOW()) AS paid_date,
|
|
o.payment_txid,
|
|
CONCAT('Initial invoice for ', o.home_name) AS description,
|
|
o.invoice_duration,
|
|
o.qty
|
|
FROM `ogp_billing_orders` o
|
|
LEFT JOIN `ogp_users` u ON o.user_id = u.user_id
|
|
WHERE o.status IN ('paid', 'installed')
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM `ogp_billing_invoices` i
|
|
WHERE i.order_id = o.order_id AND i.status = 'paid'
|
|
);
|
|
|
|
-- Step 7: Drop the obsolete billing_carts table (replaced by invoice system)
|
|
DROP TABLE IF EXISTS `ogp_billing_carts`;
|
|
|
|
-- Step 8: Update billing_services charset for consistency
|
|
ALTER TABLE `ogp_billing_services` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
|
|
|
SELECT 'Migration completed successfully! Invoice-based billing system is now active.' AS Status;
|