query("SELECT id, code FROM projects WHERE tenant_id = 1"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $projects[$row['code']] = $row['id']; $employees = []; $stmt = db()->query("SELECT id, email FROM employees WHERE tenant_id = 1"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $employees[$row['email']] = $row['id']; $labourTypes = []; $stmt = db()->query("SELECT id, name FROM labour_types"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $labourTypes[strtolower($row['name'])] = $row['id']; $evidenceTypes = []; $stmt = db()->query("SELECT id, name FROM evidence_types"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $evidenceTypes[strtolower($row['name'])] = $row['id']; $rowCount = 0; $importCount = 0; $skippedCount = 0; db()->beginTransaction(); try { $stmt = db()->prepare("INSERT INTO labour_entries (tenant_id, project_id, employee_id, entry_date, hours, labour_type_id, evidence_type_id, 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]]) : ''; } $rowErrors = []; $projectId = $projects[$data['project_code']] ?? null; $employeeId = $employees[$data['employee_email']] ?? null; $labourTypeId = $labourTypes[strtolower($data['labour_type'])] ?? null; $evidenceTypeId = $evidenceTypes[strtolower($data['evidence_type'])] ?? 5; // Default to 'None' if (!$projectId) $rowErrors[] = "Invalid Project Code: " . $data['project_code']; if (!$employeeId) $rowErrors[] = "Invalid Employee Email: " . $data['employee_email']; if (!$labourTypeId) $rowErrors[] = "Invalid Labour Type: " . $data['labour_type']; if (empty($data['date']) || !strtotime($data['date'])) $rowErrors[] = "Invalid Date: " . $data['date']; if (!is_numeric($data['hours'])) $rowErrors[] = "Invalid Hours: " . $data['hours']; if (!empty($rowErrors)) { $skippedCount++; $results[] = "Row $rowCount: Skipped (" . implode(', ', $rowErrors) . ")"; continue; } $stmt->execute([ 1, $projectId, $employeeId, date('Y-m-d', strtotime($data['date'])), $data['hours'], $labourTypeId, $evidenceTypeId, $data['notes'] ]); $importCount++; } db()->commit(); $message = "Import completed successfully. $importCount activities imported, $skippedCount skipped."; } catch (Exception $e) { db()->rollBack(); $error = 'Database error: ' . $e->getMessage(); } } fclose($handle); } } include 'includes/header.php'; ?>

Import Labour Activities

Download Template
Max file size: 5MB. Only .csv files are allowed.
Import Instructions
  1. Download the CSV template using the button above.
  2. Ensure Project Code and Employee Email match existing records.
  3. Date should be in YYYY-MM-DD format.
  4. Labour Type must match one of:
    • Experimental Development
    • Technical Support
    • Technical Planning
  5. Upload and review the logs for any skipped rows.
Import Logs