diff --git a/db/migrations/20260216_add_credit_limit.sql b/db/migrations/20260216_add_credit_limit.sql index 541ed76..5e1732f 100644 --- a/db/migrations/20260216_add_credit_limit.sql +++ b/db/migrations/20260216_add_credit_limit.sql @@ -1 +1,3 @@ -ALTER TABLE customers ADD COLUMN credit_limit DECIMAL(15,3) DEFAULT 0.000 AFTER balance; +-- Ensure legacy customer installs have the monetary columns before later migrations modify them. +ALTER TABLE customers ADD COLUMN IF NOT EXISTS balance DECIMAL(15,3) DEFAULT 0.000; +ALTER TABLE customers ADD COLUMN IF NOT EXISTS credit_limit DECIMAL(15,3) DEFAULT 0.000; diff --git a/db/migrations/20260502_full_schema_sync.php b/db/migrations/20260502_full_schema_sync.php index e29e67e..1206a7b 100644 --- a/db/migrations/20260502_full_schema_sync.php +++ b/db/migrations/20260502_full_schema_sync.php @@ -76,9 +76,13 @@ if (!function_exists('full_schema_sync_20260502_run')) { ], 'customers' => [ 'outlet_id' => 'INT(11) DEFAULT NULL', + 'balance' => 'DECIMAL(15,3) DEFAULT 0.000', + 'credit_limit' => 'DECIMAL(15,3) DEFAULT 0.000', ], 'suppliers' => [ 'outlet_id' => 'INT(11) DEFAULT 1', + 'balance' => 'DECIMAL(15,3) DEFAULT NULL', + 'credit_limit' => 'DECIMAL(15,3) DEFAULT NULL', ], 'stock_categories' => [ 'outlet_id' => 'INT(11) DEFAULT 1', diff --git a/db/migrations/20260503_ensure_entity_balance_columns.php b/db/migrations/20260503_ensure_entity_balance_columns.php new file mode 100644 index 0000000..d906c8a --- /dev/null +++ b/db/migrations/20260503_ensure_entity_balance_columns.php @@ -0,0 +1,65 @@ + [ + 'balance' => 'DECIMAL(15,3) DEFAULT 0.000', + 'credit_limit' => 'DECIMAL(15,3) DEFAULT 0.000', + ], + 'suppliers' => [ + 'balance' => 'DECIMAL(15,3) DEFAULT NULL', + 'credit_limit' => 'DECIMAL(15,3) DEFAULT NULL', + ], + ]; + + foreach ($definitions as $table => $columns) { + if (!ensure_entity_balance_columns_20260503_table_exists($pdo, $table)) { + continue; + } + + foreach ($columns as $column => $definition) { + if (ensure_entity_balance_columns_20260503_column_exists($pdo, $table, $column)) { + continue; + } + + $statement = sprintf( + 'ALTER TABLE `%s` ADD COLUMN `%s` %s', + str_replace('`', '', $table), + str_replace('`', '', $column), + $definition + ); + + $pdo->exec($statement); + } + } + } + + function ensure_entity_balance_columns_20260503_table_exists(PDO $pdo, string $table): bool + { + $stmt = $pdo->prepare( + 'SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? LIMIT 1' + ); + $stmt->execute([$table]); + + return (bool) $stmt->fetchColumn(); + } + + function ensure_entity_balance_columns_20260503_column_exists(PDO $pdo, string $table, string $column): bool + { + $stmt = $pdo->prepare( + 'SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1' + ); + $stmt->execute([$table, $column]); + + return (bool) $stmt->fetchColumn(); + } +} + +ensure_entity_balance_columns_20260503_run(); diff --git a/debug.log b/debug.log index f0c1e6a..06a519f 100644 --- a/debug.log +++ b/debug.log @@ -135,3 +135,4 @@ 2026-05-02 17:32:11 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} 2026-05-02 17:32:54 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} 2026-05-02 18:41:44 - Items case hit +2026-05-03 01:36:24 - Items case hit diff --git a/index.php b/index.php index 3a1e161..a6e3cf7 100644 --- a/index.php +++ b/index.php @@ -4257,6 +4257,7 @@ switch ($page) { $data['expense_categories'] = db()->query("SELECT * FROM expense_categories ORDER BY name_en ASC")->fetchAll(); break; case 'expenses': + $data['expense_categories'] = db()->query("SELECT * FROM expense_categories ORDER BY name_en ASC")->fetchAll(); $where = ["1=1"]; $params = []; if (!empty($_GET['category_id'])) { @@ -8612,14 +8613,25 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System'; +