159 lines
6.5 KiB
PHP
159 lines
6.5 KiB
PHP
<?php
|
|
require_once 'db/config.php';
|
|
$pageTitle = 'Import Clients';
|
|
|
|
$message = '';
|
|
$error = '';
|
|
$results = [];
|
|
|
|
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 columns: name, email, phone, address, city, province_state, postal_code, country
|
|
$expected = ['name', 'email', 'phone', 'address', 'city', 'province_state', 'postal_code', 'country'];
|
|
|
|
if (!$header || count(array_intersect($expected, $header)) < 1) {
|
|
$error = 'Invalid CSV format. Please use the provided template.';
|
|
} else {
|
|
$columnMap = array_flip($header);
|
|
$rowCount = 0;
|
|
$importCount = 0;
|
|
$skippedCount = 0;
|
|
|
|
db()->beginTransaction();
|
|
try {
|
|
$stmt = db()->prepare("INSERT INTO clients (tenant_id, name, email, phone, address, city, province_state, postal_code, country) 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]]) : '';
|
|
}
|
|
|
|
if (empty($data['name'])) {
|
|
$skippedCount++;
|
|
$results[] = "Row $rowCount: Skipped (Missing Name)";
|
|
continue;
|
|
}
|
|
|
|
// Simple validation: email
|
|
if (!empty($data['email']) && !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
|
|
$results[] = "Row $rowCount: Warning (Invalid Email: " . htmlspecialchars($data['email']) . ")";
|
|
}
|
|
|
|
$stmt->execute([
|
|
1, // Hardcoded tenant_id for now as per app convention
|
|
$data['name'],
|
|
$data['email'],
|
|
$data['phone'],
|
|
$data['address'],
|
|
$data['city'],
|
|
$data['province_state'],
|
|
$data['postal_code'],
|
|
$data['country']
|
|
]);
|
|
$importCount++;
|
|
}
|
|
db()->commit();
|
|
$message = "Import completed successfully. $importCount clients imported, $skippedCount skipped.";
|
|
} catch (Exception $e) {
|
|
db()->rollBack();
|
|
$error = 'Database error: ' . $e->getMessage();
|
|
}
|
|
}
|
|
fclose($handle);
|
|
}
|
|
}
|
|
|
|
include 'includes/header.php';
|
|
?>
|
|
|
|
<div class="container mt-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2><i class="bi bi-file-earmark-arrow-up me-2"></i>Import Clients</h2>
|
|
<a href="samples/clients_template.csv" class="btn btn-outline-primary btn-sm">
|
|
<i class="bi bi-download me-1"></i>Download Template
|
|
</a>
|
|
</div>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
|
<?= $message ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($error): ?>
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
<?= $error ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body p-4">
|
|
<form action="import_clients.php" method="POST" enctype="multipart/form-data">
|
|
<div class="mb-4">
|
|
<label for="csv_file" class="form-label fw-bold">Select CSV File</label>
|
|
<input type="file" class="form-control" id="csv_file" name="csv_file" accept=".csv" required>
|
|
<div class="form-text mt-2">
|
|
Max file size: 2MB. Only .csv files are allowed.
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary w-100 py-2">
|
|
<i class="bi bi-upload me-2"></i>Upload and Import
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card shadow-sm border-0 h-100">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="mb-0">Import Instructions</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<ol class="small text-muted">
|
|
<li>Download the CSV template using the button above.</li>
|
|
<li>Fill in your client data, ensuring the <strong>name</strong> field is not empty.</li>
|
|
<li>Save the file as a CSV (Comma Separated Values).</li>
|
|
<li>Upload the file using the form on the left.</li>
|
|
<li>Review any warnings or errors that appear after processing.</li>
|
|
</ol>
|
|
<div class="alert alert-info py-2 small mb-0">
|
|
<i class="bi bi-info-circle me-1"></i> Existing clients with the same name will be added as new entries.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!empty($results)): ?>
|
|
<div class="card shadow-sm border-0 mt-4">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="mb-0">Import Logs</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="list-group list-group-flush small">
|
|
<?php foreach ($results as $res): ?>
|
|
<div class="list-group-item px-0 border-0 py-1">
|
|
<i class="bi bi-dot me-1"></i><?= $res ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<?php include 'includes/footer.php'; ?>
|