excel import

This commit is contained in:
Flatlogic Bot 2026-03-05 13:19:30 +00:00
parent e15aadbaf9
commit d04323d02a
5 changed files with 1480 additions and 85 deletions

1170
includes/SimpleXLSX.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
require_once __DIR__ . '/../db/config.php'; require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../helpers.php'; require_once __DIR__ . '/../helpers.php';
$db = db(); $db = db();
function parse_import_file($file_input) {
if (!isset($file_input['error']) || $file_input['error'] !== UPLOAD_ERR_OK) {
return false;
}
$ext = strtolower(pathinfo($file_input['name'], PATHINFO_EXTENSION));
$rows = [];
if ($ext === 'csv') {
$handle = fopen($file_input['tmp_name'], 'r');
// Skip header
fgetcsv($handle);
while (($row = fgetcsv($handle)) !== false) {
if (array_filter($row)) {
$rows[] = $row;
}
}
fclose($handle);
} elseif ($ext === 'xlsx' || $ext === 'xls') {
require_once __DIR__ . '/SimpleXLSX.php';
if ($xlsx = Shuchkin\SimpleXLSX::parse($file_input['tmp_name'])) {
$rows = $xlsx->rows();
array_shift($rows); // Skip header
}
}
return $rows;
}
function upload_file($file_array, $index, $target_dir = "assets/uploads/") { function upload_file($file_array, $index, $target_dir = "assets/uploads/") {
if (!isset($file_array["name"][$index]) || $file_array["error"][$index] !== UPLOAD_ERR_OK) { if (!isset($file_array["name"][$index]) || $file_array["error"][$index] !== UPLOAD_ERR_OK) {
return null; return null;
@ -736,47 +764,44 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$redirect = true; $redirect = true;
} }
} elseif ($_POST['action'] === 'import_drugs_groups') { } elseif ($_POST['action'] === 'import_drugs_groups') {
if (isset($_FILES['csv_file']) && $_FILES['csv_file']['error'] === UPLOAD_ERR_OK) { if (isset($_FILES['csv_file'])) {
$file = fopen($_FILES['csv_file']['tmp_name'], 'r'); $rows = parse_import_file($_FILES['csv_file']);
// Skip header
fgetcsv($file);
if ($rows) {
$stmt = $db->prepare("INSERT INTO drugs_groups (name_en, name_ar) VALUES (?, ?)"); $stmt = $db->prepare("INSERT INTO drugs_groups (name_en, name_ar) VALUES (?, ?)");
$checkStmt = $db->prepare("SELECT id FROM drugs_groups WHERE name_en = ?"); $checkStmt = $db->prepare("SELECT id FROM drugs_groups WHERE name_en = ?");
while (($row = fgetcsv($file)) !== false) { foreach ($rows as $row) {
$name_en = $row[0] ?? ''; $name_en = $row[0] ?? '';
$name_ar = $row[1] ?? ''; $name_ar = $row[1] ?? '';
if ($name_en) { if ($name_en) {
// Check duplicate
$checkStmt->execute([$name_en]); $checkStmt->execute([$name_en]);
if (!$checkStmt->fetch()) { if (!$checkStmt->fetch()) {
$stmt->execute([$name_en, $name_ar]); $stmt->execute([$name_en, $name_ar]);
} }
} }
} }
fclose($file);
$_SESSION['flash_message'] = __('import_successfully'); $_SESSION['flash_message'] = __('import_successfully');
$redirect = true; $redirect = true;
} }
}
} elseif ($_POST['action'] === 'import_drugs') { } elseif ($_POST['action'] === 'import_drugs') {
if (isset($_FILES['csv_file']) && $_FILES['csv_file']['error'] === UPLOAD_ERR_OK) { if (isset($_FILES['csv_file'])) {
$file = fopen($_FILES['csv_file']['tmp_name'], 'r'); $rows = parse_import_file($_FILES['csv_file']);
// Skip header
fgetcsv($file);
if ($rows) {
$stmt = $db->prepare("INSERT INTO drugs (name_en, name_ar, group_id, price, expiry_date, supplier_id) VALUES (?, ?, ?, ?, ?, ?)"); $stmt = $db->prepare("INSERT INTO drugs (name_en, name_ar, group_id, price, expiry_date, supplier_id) VALUES (?, ?, ?, ?, ?, ?)");
$groupMap = []; $groupMap = [];
$supplierMap = []; $supplierMap = [];
while (($row = fgetcsv($file)) !== false) { foreach ($rows as $row) {
$name_en = $row[0] ?? ''; $name_en = $row[0] ?? '';
$name_ar = $row[1] ?? ''; $name_ar = $row[1] ?? '';
$group_name = $row[2] ?? ''; $group_name = $row[2] ?? '';
$price = $row[3] ?? 0; $price = $row[3] ?? 0;
$expiry = $row[4] ?? null; // YYYY-MM-DD $expiry = $row[4] ?? null;
$supplier_name = $row[5] ?? ''; $supplier_name = $row[5] ?? '';
if ($name_en) { if ($name_en) {
@ -791,7 +816,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($gRes) { if ($gRes) {
$group_id = $gRes['id']; $group_id = $gRes['id'];
} else { } else {
// Create group
$cgStmt = $db->prepare("INSERT INTO drugs_groups (name_en, name_ar) VALUES (?, ?)"); $cgStmt = $db->prepare("INSERT INTO drugs_groups (name_en, name_ar) VALUES (?, ?)");
$cgStmt->execute([$group_name, $group_name]); $cgStmt->execute([$group_name, $group_name]);
$group_id = $db->lastInsertId(); $group_id = $db->lastInsertId();
@ -811,7 +835,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($sRes) { if ($sRes) {
$supplier_id = $sRes['id']; $supplier_id = $sRes['id'];
} else { } else {
// Create supplier
$csStmt = $db->prepare("INSERT INTO suppliers (name_en, name_ar) VALUES (?, ?)"); $csStmt = $db->prepare("INSERT INTO suppliers (name_en, name_ar) VALUES (?, ?)");
$csStmt->execute([$supplier_name, $supplier_name]); $csStmt->execute([$supplier_name, $supplier_name]);
$supplier_id = $db->lastInsertId(); $supplier_id = $db->lastInsertId();
@ -820,17 +843,57 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} }
} }
// Validate date
if ($expiry && !strtotime($expiry)) $expiry = null; if ($expiry && !strtotime($expiry)) $expiry = null;
$stmt->execute([$name_en, $name_ar, $group_id, $price, $expiry, $supplier_id]); $stmt->execute([$name_en, $name_ar, $group_id, $price, $expiry, $supplier_id]);
} }
} }
fclose($file);
$_SESSION['flash_message'] = __('import_successfully'); $_SESSION['flash_message'] = __('import_successfully');
$redirect = true; $redirect = true;
} }
} }
} elseif ($_POST['action'] === 'import_tests') {
if (isset($_FILES['csv_file'])) {
$rows = parse_import_file($_FILES['csv_file']);
if ($rows) {
$stmt = $db->prepare("INSERT INTO laboratory_tests (name_en, name_ar, group_id, price, normal_range) VALUES (?, ?, ?, ?, ?)");
$groupMap = [];
foreach ($rows as $row) {
$name_en = $row[0] ?? '';
$name_ar = $row[1] ?? '';
$group_name = $row[2] ?? '';
$price = $row[3] ?? 0;
$range = $row[4] ?? '';
if ($name_en) {
$group_id = null;
if ($group_name) {
if (isset($groupMap[$group_name])) {
$group_id = $groupMap[$group_name];
} else {
$gStmt = $db->prepare("SELECT id FROM test_groups WHERE name_en = ? OR name_ar = ?");
$gStmt->execute([$group_name, $group_name]);
$gRes = $gStmt->fetch();
if ($gRes) {
$group_id = $gRes['id'];
} else {
$cgStmt = $db->prepare("INSERT INTO test_groups (name_en, name_ar) VALUES (?, ?)");
$cgStmt->execute([$group_name, $group_name]);
$group_id = $db->lastInsertId();
}
$groupMap[$group_name] = $group_id;
}
}
$stmt->execute([$name_en, $name_ar, $group_id, $price, $range]);
}
}
$_SESSION['flash_message'] = __('import_successfully');
$redirect = true;
}
}
}
} }
if ($redirect) { if ($redirect) {

View File

@ -38,7 +38,7 @@ $all_suppliers = $sStmt->fetchAll();
<h3 class="fw-bold text-secondary"><?php echo __('drugs'); ?></h3> <h3 class="fw-bold text-secondary"><?php echo __('drugs'); ?></h3>
<div> <div>
<button class="btn btn-outline-primary shadow-sm me-2" data-bs-toggle="modal" data-bs-target="#importDrugsModal"> <button class="btn btn-outline-primary shadow-sm me-2" data-bs-toggle="modal" data-bs-target="#importDrugsModal">
<i class="bi bi-upload me-1"></i> <?php echo __('import_csv'); ?> <i class="bi bi-upload me-1"></i> <?php echo __('import'); ?>
</button> </button>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addDrugModal" onclick="resetDrugModal()"> <button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addDrugModal" onclick="resetDrugModal()">
<i class="bi bi-plus-circle me-1"></i> <?php echo __('add_drug'); ?> <i class="bi bi-plus-circle me-1"></i> <?php echo __('add_drug'); ?>
@ -239,8 +239,8 @@ $all_suppliers = $sStmt->fetchAll();
<input type="hidden" name="action" value="import_drugs"> <input type="hidden" name="action" value="import_drugs">
<div class="modal-body p-4"> <div class="modal-body p-4">
<div class="mb-3"> <div class="mb-3">
<label class="form-label"><?php echo __('upload_csv_file'); ?> <span class="text-danger">*</span></label> <label class="form-label"><?php echo __('upload_file'); ?> (CSV, Excel) <span class="text-danger">*</span></label>
<input type="file" class="form-control" name="csv_file" accept=".csv" required> <input type="file" class="form-control" name="csv_file" accept=".csv, .xlsx, .xls" required>
</div> </div>
<div class="alert alert-info small mb-0"> <div class="alert alert-info small mb-0">
<i class="bi bi-info-circle me-1"></i> <?php echo __('csv_format_drugs'); ?> <i class="bi bi-info-circle me-1"></i> <?php echo __('csv_format_drugs'); ?>

View File

@ -23,13 +23,22 @@ $query .= " ORDER BY t.id DESC";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->execute($params); $stmt->execute($params);
$tests = $stmt->fetchAll(); $tests = $stmt->fetchAll();
// Fetch all groups for filter dropdown
$gStmt = $db->query("SELECT * FROM test_groups ORDER BY name_$lang");
$all_test_groups = $gStmt->fetchAll();
?> ?>
<div class="d-flex justify-content-between align-items-center mb-4"> <div class="d-flex justify-content-between align-items-center mb-4">
<h3 class="fw-bold text-secondary"><?php echo __('tests'); ?></h3> <h3 class="fw-bold text-secondary"><?php echo __('tests'); ?></h3>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addTestModal"> <div>
<button class="btn btn-outline-primary shadow-sm me-2" data-bs-toggle="modal" data-bs-target="#importTestsModal">
<i class="bi bi-upload me-1"></i> <?php echo __('import'); ?>
</button>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addTestModal" onclick="resetTestModal()">
<i class="bi bi-plus-circle me-1"></i> <?php echo __('add_test'); ?> <i class="bi bi-plus-circle me-1"></i> <?php echo __('add_test'); ?>
</button> </button>
</div>
</div> </div>
<!-- Search Bar --> <!-- Search Bar -->
@ -47,7 +56,7 @@ $tests = $stmt->fetchAll();
<option value=""><?php echo __('test_group'); ?> (<?php echo __('all'); ?>)</option> <option value=""><?php echo __('test_group'); ?> (<?php echo __('all'); ?>)</option>
<?php foreach ($all_test_groups as $group): ?> <?php foreach ($all_test_groups as $group): ?>
<option value="<?php echo $group['id']; ?>" <?php echo $search_group == $group['id'] ? 'selected' : ''; ?>> <option value="<?php echo $group['id']; ?>" <?php echo $search_group == $group['id'] ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($group['name']); ?> <?php echo htmlspecialchars($group['name_' . $lang]); ?>
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
@ -129,3 +138,149 @@ $tests = $stmt->fetchAll();
</div> </div>
</div> </div>
</div> </div>
<!-- Import Tests Modal -->
<div class="modal fade" id="importTestsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title"><?php echo __('import_tests'); ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="POST" action="" enctype="multipart/form-data">
<input type="hidden" name="action" value="import_tests">
<div class="modal-body p-4">
<div class="mb-3">
<label class="form-label"><?php echo __('upload_file'); ?> (CSV, Excel) <span class="text-danger">*</span></label>
<input type="file" class="form-control" name="csv_file" accept=".csv, .xlsx, .xls" required>
</div>
<div class="alert alert-info small mb-0">
<i class="bi bi-info-circle me-1"></i> <?php echo __('format'); ?>: Name (En), Name (Ar), Group, Price, Normal Range
</div>
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('close'); ?></button>
<button type="submit" class="btn btn-primary"><?php echo __('import'); ?></button>
</div>
</form>
</div>
</div>
</div>
<!-- Add/Edit Test Modal -->
<div class="modal fade" id="addTestModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title" id="testModalTitle"><?php echo __('add_test'); ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="POST" action="">
<input type="hidden" name="action" id="testAction" value="add_test">
<input type="hidden" name="id" id="testId">
<div class="modal-body p-4">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label"><?php echo __('name_en'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="name_en" id="testNameEn" required>
</div>
<div class="col-md-6">
<label class="form-label"><?php echo __('name_ar'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="name_ar" id="testNameAr" required>
</div>
<div class="col-md-6">
<label class="form-label"><?php echo __('test_group'); ?></label>
<select class="form-select" name="group_id" id="testGroupId">
<option value=""><?php echo __('select_group'); ?></option>
<?php foreach ($all_test_groups as $group): ?>
<option value="<?php echo $group['id']; ?>">
<?php echo htmlspecialchars($group['name_' . $lang]); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-6">
<label class="form-label"><?php echo __('price'); ?></label>
<div class="input-group">
<span class="input-group-text">$</span>
<input type="number" step="0.01" class="form-control" name="price" id="testPrice">
</div>
</div>
<div class="col-12">
<label class="form-label"><?php echo __('normal_range'); ?></label>
<textarea class="form-control" name="normal_range" id="testRange" rows="2"></textarea>
</div>
</div>
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('close'); ?></button>
<button type="submit" class="btn btn-primary"><?php echo __('save'); ?></button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Test Modal -->
<div class="modal fade" id="deleteTestModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title"><?php echo __('delete_test'); ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="POST" action="">
<input type="hidden" name="action" value="delete_test">
<input type="hidden" name="id" id="deleteTestId">
<div class="modal-body p-4 text-center">
<div class="mb-3 text-danger">
<i class="bi bi-exclamation-triangle display-1"></i>
</div>
<p class="mb-0 fs-5"><?php echo __('are_you_sure_delete'); ?></p>
<p class="text-muted small"><?php echo __('action_cannot_be_undone'); ?></p>
</div>
<div class="modal-footer bg-light justify-content-center">
<button type="button" class="btn btn-secondary px-4" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
<button type="submit" class="btn btn-danger px-4"><?php echo __('delete'); ?></button>
</div>
</form>
</div>
</div>
</div>
<script>
function resetTestModal() {
document.getElementById('testModalTitle').textContent = '<?php echo __('add_test'); ?>';
document.getElementById('testAction').value = 'add_test';
document.getElementById('testId').value = '';
document.getElementById('testNameEn').value = '';
document.getElementById('testNameAr').value = '';
document.getElementById('testGroupId').value = '';
document.getElementById('testPrice').value = '';
document.getElementById('testRange').value = '';
}
function showEditTestModal(test) {
document.getElementById('testModalTitle').textContent = '<?php echo __('edit_test'); ?>';
document.getElementById('testAction').value = 'edit_test';
document.getElementById('testId').value = test.id;
document.getElementById('testNameEn').value = test.name_en;
document.getElementById('testNameAr').value = test.name_ar;
document.getElementById('testGroupId').value = test.group_id || '';
document.getElementById('testPrice').value = test.price;
document.getElementById('testRange').value = test.normal_range;
var modal = new bootstrap.Modal(document.getElementById('addTestModal'));
modal.show();
}
function showDeleteTestModal(id) {
document.getElementById('deleteTestId').value = id;
var modal = new bootstrap.Modal(document.getElementById('deleteTestModal'));
modal.show();
}
</script>

View File

@ -1,5 +1,12 @@
<?php <?php
$section = 'suppliers'; $section = 'suppliers';
require_once __DIR__ . '/db/config.php';
require_once __DIR__ . '/helpers.php';
$db = db();
$lang = $_SESSION['lang'] ?? 'en';
require_once __DIR__ . '/includes/actions.php';
require_once __DIR__ . '/includes/layout/header.php'; require_once __DIR__ . '/includes/layout/header.php';
require_once __DIR__ . '/includes/pages/suppliers.php'; require_once __DIR__ . '/includes/pages/suppliers.php';
require_once __DIR__ . '/includes/layout/footer.php'; require_once __DIR__ . '/includes/layout/footer.php';