getActiveSheet(); $rows = $worksheet->toArray(); if (count($rows) < 2) { json_error('الملف فارغ أو لا يحتوي على بيانات', 422); } $header = array_shift($rows); $mapping = mapColumns($header); $db = Database::getInstance(); $db->beginTransaction(); $importedCount = 0; $errors = []; foreach ($rows as $index => $row) { if (empty(array_filter($row))) continue; // Skip empty rows try { // Check quota for each invoice (preventive) QuotaMiddleware::checkInvoiceQuota($tenantId); $invoiceData = [ 'id' => Database::generateUuid(), 'tenant_id' => $tenantId, 'company_id' => $companyId, 'invoice_number' => $row[$mapping['number']] ?? 'EXT-' . time() . '-' . $index, 'invoice_date' => formatDate($row[$mapping['date']] ?? date('Y-m-d')), 'customer_name' => Encryption::encrypt($row[$mapping['customer']] ?? 'عميل عام'), 'grand_total' => (float)($row[$mapping['total']] ?? 0), 'tax_amount' => (float)($row[$mapping['tax']] ?? 0), 'status' => 'extracted', // Ready for review/approval 'created_at' => date('Y-m-d H:i:s') ]; $stmt = $db->prepare(" INSERT INTO invoices (id, tenant_id, company_id, invoice_number, invoice_date, customer_name, grand_total, tax_amount, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "); $stmt->execute(array_values($invoiceData)); $importedCount++; } catch (\Exception $e) { $errors[] = "السطر " . ($index + 2) . ": " . $e->getMessage(); } } $db->commit(); json_success([ 'imported_count' => $importedCount, 'errors' => $errors ], "تم استيراد $importedCount فاتورة بنجاح"); } catch (\Exception $e) { if (isset($db)) $db->rollBack(); json_error('فشل معالجة ملف الاكسل: ' . $e->getMessage(), 500); } /** * Intelligent Column Mapping */ function mapColumns(array $header): array { $map = [ 'number' => 0, 'date' => 1, 'customer' => 2, 'total' => 3, 'tax' => 4 ]; foreach ($header as $i => $col) { $col = mb_strtolower(trim((string)$col)); if (str_contains($col, 'رقم') || str_contains($col, 'number')) $map['number'] = $i; if (str_contains($col, 'تاريخ') || str_contains($col, 'date')) $map['date'] = $i; if (str_contains($col, 'عميل') || str_contains($col, 'customer') || str_contains($col, 'اسم')) $map['customer'] = $i; if (str_contains($col, 'اجمالي') || str_contains($col, 'total') || str_contains($col, 'المجموع')) $map['total'] = $i; if (str_contains($col, 'ضريبة') || str_contains($col, 'tax')) $map['tax'] = $i; } return $map; } function formatDate($val): string { if (is_numeric($val)) { return date('Y-m-d', \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp($val)); } $ts = strtotime((string)$val); return $ts ? date('Y-m-d', $ts) : date('Y-m-d'); }