- Added error_log debugging to process-csv.php - Fixed test-csv.php syntax (removed use statements in code) - Created test-process2.php for step-by-step class loading test - All service classes load successfully in tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
265 lines
9.3 KiB
PHP
265 lines
9.3 KiB
PHP
<?php
|
|
/**
|
|
* Process CSV Upload
|
|
* Handles CSV transformation with detailed progress tracking and error reporting
|
|
*/
|
|
|
|
session_start();
|
|
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 1);
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
try {
|
|
// Load dependencies
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
require_once __DIR__ . '/AuthMiddleware.php';
|
|
require_once __DIR__ . '/CSVTransformer.php';
|
|
require_once __DIR__ . '/OMGService.php';
|
|
require_once __DIR__ . '/EmailService.php';
|
|
|
|
// Authenticate
|
|
$auth = new AuthMiddleware();
|
|
$user = $auth->requireAuth();
|
|
|
|
// 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 & 5: For testing, skip OMG API and use "TESTING" as business unit
|
|
// TODO: Uncomment when OMG API key is provided
|
|
$businessUnit = 'TESTING';
|
|
$progress[] = ['stage' => 'omg_api', 'status' => 'success', 'message' => 'Using TESTING business unit (OMG API skipped)'];
|
|
$progress[] = ['stage' => 'business_unit', 'status' => 'success', 'message' => 'Business unit: TESTING'];
|
|
|
|
/*
|
|
// STAGE 4: Call OMG API (Disabled for testing)
|
|
$progress[] = ['stage' => 'omg_api', 'status' => 'processing', 'message' => 'Looking up campaign in OMG...'];
|
|
|
|
$projectResult = $omgService->getProject($campaignNumber);
|
|
|
|
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' => $omgService->config['base_url'] . '/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);
|
|
|
|
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);
|
|
|
|
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
|
|
$csvReader = \League\Csv\Reader::createFromString($firstCSV['content']);
|
|
$csvReader->setHeaderOffset(0);
|
|
$previewData = iterator_to_array($csvReader->getRecords());
|
|
$previewRows = array_slice($previewData, 0, 20); // Show first 20 rows
|
|
|
|
// 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()
|
|
]);
|
|
}
|