requireAuth(); // Initialize logger $logger = new ApplicationLogger(); // Debug: Log request error_log('process-csv.php: Started processing'); error_log('FILES: ' . json_encode(array_keys($_FILES))); // Check if file was uploaded if (!isset($_FILES['csvFile'])) { error_log('process-csv.php: No file in $_FILES'); echo json_encode([ 'success' => false, 'stage' => 'upload', 'error' => 'No file uploaded', 'details' => 'Please select a CSV file to upload', 'debug' => array_keys($_FILES) ]); exit; } $file = $_FILES['csvFile']; $transformer = new CSVTransformer(); $omgService = new OMGService(); $emailService = new EmailService(); $progress = []; // STAGE 1: Validate Upload $progress[] = ['stage' => 'upload', 'status' => 'processing', 'message' => 'Validating file upload...']; $validation = $transformer->validateUpload($file); if (!$validation['valid']) { echo json_encode([ 'success' => false, 'stage' => 'upload', 'error' => 'File validation failed', 'details' => implode('; ', $validation['errors']), 'action' => 'Please upload a valid CSV file (max 5MB)', 'progress' => $progress ]); exit; } $filename = $validation['filename']; $progress[] = ['stage' => 'upload', 'status' => 'success', 'message' => 'File uploaded: ' . $filename]; // STAGE 2: Parse CSV $progress[] = ['stage' => 'parse', 'status' => 'processing', 'message' => 'Parsing CSV file...']; $parseResult = $transformer->parseCSV($file['tmp_name']); if (!$parseResult['success']) { echo json_encode([ 'success' => false, 'stage' => 'parse', 'error' => $parseResult['error'], 'details' => $parseResult['details'] ?? '', 'action' => $parseResult['action'] ?? 'Check CSV format', 'progress' => $progress ]); exit; } $rowCount = $parseResult['rowCount']; $progress[] = ['stage' => 'parse', 'status' => 'success', 'message' => "Parsed $rowCount data rows"]; // STAGE 3: Extract Campaign Number $progress[] = ['stage' => 'campaign', 'status' => 'processing', 'message' => 'Extracting campaign number...']; $campaignResult = $transformer->extractCampaignNumber($filename); if (!$campaignResult['success']) { echo json_encode([ 'success' => false, 'stage' => 'campaign', 'error' => $campaignResult['error'], 'details' => $campaignResult['details'] ?? '', 'action' => $campaignResult['action'] ?? 'Fix filename format', 'progress' => $progress ]); exit; } $campaignNumber = $campaignResult['campaignNumber']; $message = 'Campaign number: ' . $campaignNumber; if (isset($campaignResult['warning'])) { $message .= ' (warning: ' . $campaignResult['warning'] . ')'; } $progress[] = ['stage' => 'campaign', 'status' => 'success', 'message' => $message]; // STAGE 4: Call OMG API (if enabled) $appConfig = require __DIR__ . '/config.php'; $omgEnabled = $appConfig['omg_api']['enabled'] ?? false; if (!$omgEnabled) { // OMG API disabled - use fallback $businessUnit = $appConfig['omg_api']['fallback_business_unit'] ?? 'TESTING'; $progress[] = ['stage' => 'omg_api', 'status' => 'success', 'message' => 'Using fallback business unit (OMG API disabled)']; $progress[] = ['stage' => 'business_unit', 'status' => 'success', 'message' => 'Business unit: ' . $businessUnit]; error_log('OMG API disabled in config - using fallback: ' . $businessUnit); } else { // OMG API enabled - make the call $progress[] = ['stage' => 'omg_api', 'status' => 'processing', 'message' => 'Looking up campaign in OMG...']; error_log('=== OMG API LOOKUP ==='); error_log('Campaign Number: ' . $campaignNumber); $projectResult = $omgService->getProject($campaignNumber); error_log('OMG API Result: ' . json_encode($projectResult)); if (!$projectResult['success']) { echo json_encode([ 'success' => false, 'stage' => 'omg_api', 'error' => $projectResult['error'], 'details' => $projectResult['details'] ?? '', 'action' => $projectResult['action'] ?? 'Check OMG API configuration', 'httpCode' => $projectResult['httpCode'] ?? 0, 'endpoint' => 'https://api2.omg.oliver.solutions/loreal/v1/getProject?project_number=' . $campaignNumber, 'progress' => $progress ]); exit; } $projectData = $projectResult['data']; $progress[] = ['stage' => 'omg_api', 'status' => 'success', 'message' => 'Retrieved campaign data from OMG']; // STAGE 5: Map Business Unit $progress[] = ['stage' => 'business_unit', 'status' => 'processing', 'message' => 'Mapping business unit...']; $businessArea = $omgService->getBusinessArea($projectData); error_log('Extracted Business Area: ' . ($businessArea ?? 'NULL')); if (empty($businessArea)) { echo json_encode([ 'success' => false, 'stage' => 'business_unit', 'error' => 'Business area not found in OMG response', 'details' => 'The OMG API response did not contain a business_area field', 'action' => 'Check if campaign data is complete in OMG system', 'omgResponse' => $projectData, 'progress' => $progress ]); exit; } $mappingResult = $omgService->mapBusinessUnit($businessArea); error_log('Business Unit Mapping Result: ' . json_encode($mappingResult)); if (!$mappingResult['success']) { // Non-fatal warning - continue with "ERROR" value $progress[] = [ 'stage' => 'business_unit', 'status' => 'warning', 'message' => 'Business unit "' . $businessArea . '" not recognized - using "ERROR"', 'warning' => $mappingResult['error'] ]; $businessUnit = 'ERROR'; } else { $businessUnit = $mappingResult['businessUnit']; $progress[] = [ 'stage' => 'business_unit', 'status' => 'success', 'message' => 'Business unit: ' . $businessUnit ]; } } // STAGE 6: Transform Data $progress[] = ['stage' => 'transform', 'status' => 'processing', 'message' => 'Transforming data for 16 markets...']; $transformResult = $transformer->transformData($parseResult['rows'], $campaignNumber, $businessUnit); if (!$transformResult['success']) { echo json_encode([ 'success' => false, 'stage' => 'transform', 'error' => 'Data transformation failed', 'details' => count($transformResult['errors']) . ' error(s) found', 'errors' => $transformResult['errors'], 'warnings' => $transformResult['warnings'], 'action' => 'Review errors and fix CSV data', 'progress' => $progress ]); exit; } $fileCount = $transformResult['fileCount']; $totalRows = $transformResult['totalOutputRows']; $progress[] = [ 'stage' => 'transform', 'status' => 'success', 'message' => "Created {$fileCount} CSV files with {$rowCount} rows each ({$totalRows} total rows)" ]; // Store in session for later upload $_SESSION['processed_csv'] = [ 'files' => $transformResult['csvFiles'], 'campaignNumber' => $campaignNumber, 'businessUnit' => $businessUnit, 'inputRowCount' => $rowCount, 'fileCount' => $fileCount ]; // Prepare preview data (show first CSV file as sample) $firstCSV = $transformResult['csvFiles'][0]; $previewRows = []; // Parse first CSV for preview (show all rows) $csvReader = \League\Csv\Reader::createFromString($firstCSV['content']); $csvReader->setHeaderOffset(0); $previewRows = iterator_to_array($csvReader->getRecords()); // Show all rows // Log successful transformation $logger->logGlobalToLocal($user, $campaignNumber, $businessUnit, $rowCount, $fileCount, 'success'); // Return success with preview data echo json_encode([ 'success' => true, 'stage' => 'complete', 'data' => [ 'inputRows' => $rowCount, 'fileCount' => $fileCount, 'totalRows' => $totalRows, 'campaignNumber' => $campaignNumber, 'businessUnit' => $businessUnit, 'files' => array_map(function($file) { return [ 'filename' => $file['filename'], 'isoCode' => $file['isoCode'], 'country' => $file['country'], 'rowCount' => $file['rowCount'] ]; }, $transformResult['csvFiles']), 'previewFile' => $firstCSV['filename'], 'preview' => $previewRows, 'warnings' => $transformResult['warnings'] ], 'progress' => $progress ]); } catch (Exception $e) { error_log('Process CSV exception: ' . $e->getMessage()); error_log('Stack trace: ' . $e->getTraceAsString()); echo json_encode([ 'success' => false, 'stage' => 'exception', 'error' => 'Unexpected error occurred', 'details' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); }