Update: 2026-05-04 14:40:41
This commit is contained in:
@@ -153,22 +153,24 @@ CREATE TABLE invoices (
|
||||
invoice_type ENUM('cash','credit') DEFAULT 'cash',
|
||||
ubl_type_code CHAR(3) DEFAULT '388',
|
||||
payment_method_code CHAR(3) DEFAULT '013',
|
||||
supplier_tin VARCHAR(20) NULL,
|
||||
supplier_name VARCHAR(255) NULL,
|
||||
supplier_tin TEXT NULL,
|
||||
supplier_name TEXT NULL,
|
||||
supplier_address TEXT NULL,
|
||||
buyer_tin VARCHAR(20) NULL,
|
||||
buyer_national_id VARCHAR(20) NULL,
|
||||
buyer_name VARCHAR(255) NULL,
|
||||
buyer_tin TEXT NULL,
|
||||
buyer_national_id TEXT NULL,
|
||||
buyer_name TEXT NULL,
|
||||
subtotal DECIMAL(15,3) DEFAULT 0,
|
||||
discount_total DECIMAL(15,3) DEFAULT 0,
|
||||
tax_amount DECIMAL(15,3) DEFAULT 0,
|
||||
grand_total DECIMAL(15,3) DEFAULT 0,
|
||||
currency_code CHAR(3) DEFAULT 'JOD',
|
||||
status ENUM('uploaded','extracting','extracted','validated','validation_failed','submitting','approved','rejected') DEFAULT 'uploaded',
|
||||
status ENUM('extracted', 'approved', 'rejected') DEFAULT 'extracted',
|
||||
jofotara_uuid VARCHAR(255) NULL,
|
||||
qr_code TEXT NULL,
|
||||
invoice_number VARCHAR(50) NULL,
|
||||
original_file_path TEXT NULL,
|
||||
invoice_category VARCHAR(20) DEFAULT 'simplified',
|
||||
validation_errors JSON NULL,
|
||||
qr_code TEXT NULL,
|
||||
ai_confidence_score DECIMAL(4,3) NULL,
|
||||
ai_prompt_tokens INT DEFAULT 0,
|
||||
ai_completion_tokens INT DEFAULT 0,
|
||||
@@ -309,3 +311,110 @@ echo "--- Migration Complete ---\n";
|
||||
|
||||
```
|
||||
|
||||
## File: `seed_super_admin.php`
|
||||
|
||||
```php
|
||||
<?php
|
||||
/**
|
||||
* Seed Super Admin Script
|
||||
* Run this from CLI: php scripts/seed_super_admin.php
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../app/bootstrap/init.php';
|
||||
|
||||
use App\Core\Database;
|
||||
use App\Core\Encryption;
|
||||
|
||||
$db = Database::getInstance();
|
||||
|
||||
echo "--- Starting Super Admin Seeding ---\n";
|
||||
|
||||
try {
|
||||
$db->beginTransaction();
|
||||
|
||||
// 1. We must create a "System Tenant" for the Super Admin to satisfy the Foreign Key constraint
|
||||
$systemTenantId = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
// Check if system tenant exists
|
||||
$stmt = $db->prepare("SELECT id FROM tenants WHERE id = ?");
|
||||
$stmt->execute([$systemTenantId]);
|
||||
if (!$stmt->fetch()) {
|
||||
$stmt = $db->prepare("INSERT INTO tenants (id, name, email, status, created_at) VALUES (?, 'System Administration', 'system@musadaq.com', 'active', NOW())");
|
||||
$stmt->execute([$systemTenantId]);
|
||||
echo "[OK] System Tenant created.\n";
|
||||
}
|
||||
|
||||
// 2. Setup Super Admin details
|
||||
$adminEmail = 'admin@musadaq.app';
|
||||
$adminName = 'Hamza';
|
||||
$adminPassword = 'password123'; // Default password
|
||||
|
||||
// Check if user already exists
|
||||
$emailHash = hash('sha256', strtolower($adminEmail));
|
||||
$stmt = $db->prepare("SELECT id FROM users WHERE email_hash = ?");
|
||||
$stmt->execute([$emailHash]);
|
||||
|
||||
if ($stmt->fetch()) {
|
||||
echo "[INFO] Super Admin already exists with this email.\n";
|
||||
} else {
|
||||
$adminId = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
|
||||
);
|
||||
|
||||
$encryptedName = Encryption::encrypt($adminName);
|
||||
$encryptedEmail = Encryption::encrypt($adminEmail);
|
||||
$passwordHash = password_hash($adminPassword, PASSWORD_DEFAULT);
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO users (id, tenant_id, name, email, email_hash, password_hash, role, is_active, created_at) VALUES (?, ?, ?, ?, ?, ?, 'super_admin', 1, NOW())");
|
||||
$stmt->execute([
|
||||
$adminId,
|
||||
$systemTenantId,
|
||||
$encryptedName,
|
||||
$encryptedEmail,
|
||||
$emailHash,
|
||||
$passwordHash
|
||||
]);
|
||||
|
||||
echo "[OK] Super Admin created successfully!\n";
|
||||
echo "----------------------------------------\n";
|
||||
echo "Email: $adminEmail\n";
|
||||
echo "Password: $adminPassword\n";
|
||||
echo "Role: super_admin\n";
|
||||
echo "----------------------------------------\n";
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
echo "--- Seeding Complete ---\n";
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$db->rollBack();
|
||||
echo "[ERROR] Seeding failed: " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## File: `debug_data.php`
|
||||
|
||||
```php
|
||||
<?php
|
||||
require_once __DIR__ . '/../app/bootstrap/init.php';
|
||||
use App\Core\Database;
|
||||
|
||||
$db = Database::getInstance();
|
||||
|
||||
echo "--- TENANTS ---\n";
|
||||
$stmt = $db->query("SELECT * FROM tenants");
|
||||
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
echo "\n--- USERS ---\n";
|
||||
$stmt = $db->query("SELECT u.id, u.name, u.role, u.tenant_id, t.name as tenant_name FROM users u LEFT JOIN tenants t ON u.tenant_id = t.id");
|
||||
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
echo "\n--- COMPANIES ---\n";
|
||||
$stmt = $db->query("SELECT * FROM companies");
|
||||
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -109,7 +109,6 @@ CREATE TABLE invoices (
|
||||
status ENUM('extracted', 'approved', 'rejected') DEFAULT 'extracted',
|
||||
jofotara_uuid VARCHAR(255) NULL,
|
||||
qr_code TEXT NULL,
|
||||
invoice_number VARCHAR(50) NULL,
|
||||
original_file_path TEXT NULL,
|
||||
invoice_category VARCHAR(20) DEFAULT 'simplified',
|
||||
validation_errors JSON NULL,
|
||||
@@ -119,12 +118,37 @@ CREATE TABLE invoices (
|
||||
ai_total_cost DECIMAL(10,6) DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_tenant (tenant_id),
|
||||
INDEX idx_company (company_id),
|
||||
INDEX idx_status (status),
|
||||
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
|
||||
);
|
||||
deleted_at DATETIME NULL,
|
||||
INDEX idx_tenant (tenant_id),
|
||||
INDEX idx_company (company_id),
|
||||
INDEX idx_status (status),
|
||||
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (uploaded_by) REFERENCES users(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- JoFotara Submissions (Audit Trail)
|
||||
CREATE TABLE jofotara_submissions (
|
||||
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
||||
invoice_id CHAR(36) NOT NULL,
|
||||
company_id CHAR(36) NOT NULL,
|
||||
tenant_id CHAR(36) NOT NULL,
|
||||
xml_payload LONGTEXT NULL,
|
||||
xml_hash VARCHAR(64) NULL,
|
||||
jofotara_uuid VARCHAR(255) NULL,
|
||||
qr_code_raw TEXT NULL,
|
||||
response_code VARCHAR(20) NULL,
|
||||
response_body JSON NULL,
|
||||
status ENUM('pending','submitted','accepted','rejected','error') DEFAULT 'pending',
|
||||
error_message TEXT NULL,
|
||||
retry_count TINYINT DEFAULT 0,
|
||||
submitted_at DATETIME NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (invoice_id) REFERENCES invoices(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Invoice Lines
|
||||
CREATE TABLE invoice_lines (
|
||||
|
||||
Reference in New Issue
Block a user