[], 'suppliers' => [], 'types' => [] ]; $s = $db->query("SELECT id, project_code FROM projects"); while($r = $s->fetch(PDO::FETCH_ASSOC)) $maps['projects'][strtolower($r['project_code'])] = $r['id']; $s = $db->query("SELECT id, name FROM suppliers"); while($r = $s->fetch(PDO::FETCH_ASSOC)) $maps['suppliers'][strtolower($r['name'])] = $r['id']; $s = $db->query("SELECT id, name FROM expense_types"); while($r = $s->fetch(PDO::FETCH_ASSOC)) $maps['types'][strtolower($r['name'])] = $r['id']; return $maps; } if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) { $file = $_FILES['csv_file']; if ($file['error'] !== UPLOAD_ERR_OK) { $error = 'File upload failed.'; } else { $handle = fopen($file['tmp_name'], 'r'); $header = fgetcsv($handle); $expected = ['project_code', 'supplier_name', 'expense_type', 'amount', 'date', 'notes']; if (!$header || count(array_intersect($expected, $header)) < 3) { $error = 'Invalid CSV format. Please ensure project_code, supplier_name, and expense_type are present.'; } else { $columnMap = array_flip($header); $maps = getLookupMaps(); $rowCount = 0; $importCount = 0; $skippedCount = 0; db()->beginTransaction(); try { $stmt = db()->prepare("INSERT INTO expenses (tenant_id, project_id, supplier_id, expense_type_id, amount, allocation_percent, entry_date, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); while (($row = fgetcsv($handle)) !== false) { $rowCount++; $data = []; foreach ($expected as $col) { $data[$col] = isset($columnMap[$col]) && isset($row[$columnMap[$col]]) ? trim($row[$columnMap[$col]]) : ''; } $projId = $maps['projects'][strtolower($data['project_code'])] ?? null; $suppId = $maps['suppliers'][strtolower($data['supplier_name'])] ?? null; $typeId = $maps['types'][strtolower($data['expense_type'])] ?? null; if (!$projId) { $results[] = "Row $rowCount: Skipped (Unknown Project Code: " . htmlspecialchars($data['project_code']) . ")"; $skippedCount++; continue; } if (!$suppId) { $results[] = "Row $rowCount: Skipped (Unknown Supplier: " . htmlspecialchars($data['supplier_name']) . ")"; $skippedCount++; continue; } if (!$typeId) { $results[] = "Row $rowCount: Skipped (Unknown Expense Type: " . htmlspecialchars($data['expense_type']) . ")"; $skippedCount++; continue; } $amount = floatval($data['amount']); $date = empty($data['date']) ? date('Y-m-d') : $data['date']; $stmt->execute([ 1, // tenant_id $projId, $suppId, $typeId, $amount, 100.00, // Default allocation_percent $date, $data['notes'] ]); $importCount++; } db()->commit(); $message = "Import completed. $importCount expenses imported, $skippedCount skipped."; } catch (Exception $e) { db()->rollBack(); $error = 'Database error: ' . $e->getMessage(); } } fclose($handle); } } include 'includes/header.php'; ?>