env and vendor added temporary
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
include('include/headscript.php');
|
||||
|
||||
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
// Verifica che iduserlogin sia definito
|
||||
if (!isset($iduserlogin)) {
|
||||
die("Errore: ID utente non definito.");
|
||||
}
|
||||
|
||||
// Recupera i dati della scuola in base all'utente loggato
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT id, name, website, email, phone, description, address_street, address_city, address_postal_code, address_province, address_country, logo, status
|
||||
FROM schools
|
||||
WHERE owner_id = ?
|
||||
");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$school = $stmt->fetch();
|
||||
if (!$school) {
|
||||
die("Errore: Nessuna scuola trovata per l'utente loggato.");
|
||||
}
|
||||
$school_id = $school['id'];
|
||||
|
||||
$product_id = $_GET['product_id'] ?? 0;
|
||||
|
||||
// Verifica che il prodotto appartenga alla scuola
|
||||
$stmt = $pdo->prepare("SELECT id FROM products WHERE id = ? AND school_id = ?");
|
||||
$stmt->execute([$product_id, $school_id]);
|
||||
if (!$stmt->fetch()) {
|
||||
die("Errore: Prodotto non trovato o non autorizzato.");
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("SELECT class_type_id FROM product_class_types WHERE product_id = ?");
|
||||
$stmt->execute([$product_id]);
|
||||
$class_types = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($class_types);
|
||||
@@ -0,0 +1,696 @@
|
||||
<?php
|
||||
include('include/headscript.php');
|
||||
|
||||
|
||||
|
||||
|
||||
// Connessione al database
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
|
||||
|
||||
// Verifica che iduserlogin sia definito
|
||||
if (!isset($iduserlogin)) {
|
||||
die("Errore: ID utente non definito.");
|
||||
}
|
||||
|
||||
// Recupera i dati della scuola in base all'utente loggato
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT id, name, website, email, phone, description, address_street, address_city, address_postal_code, address_province, address_country, logo, status
|
||||
FROM schools
|
||||
WHERE owner_id = ?
|
||||
");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$school = $stmt->fetch();
|
||||
if (!$school) {
|
||||
die("Errore: Nessuna scuola trovata per l'utente loggato.");
|
||||
}
|
||||
$school_id = $school['id'];
|
||||
$school_name = $school['name'];
|
||||
|
||||
// Recupera i prodotti della scuola con classi e variazioni associate
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT p.*,
|
||||
GROUP_CONCAT(DISTINCT c.name) AS class_names,
|
||||
GROUP_CONCAT(DISTINCT CONCAT(ct.level, ' (', ct.day_of_week, ')')) AS variation_names
|
||||
FROM products p
|
||||
LEFT JOIN product_class_types pct ON p.id = pct.product_id
|
||||
LEFT JOIN class_types ct ON pct.class_type_id = ct.id
|
||||
LEFT JOIN classes c ON ct.class_id = c.id
|
||||
WHERE p.school_id = ?
|
||||
GROUP BY p.id
|
||||
ORDER BY p.created_at DESC
|
||||
");
|
||||
$stmt->execute([$school_id]);
|
||||
$products = $stmt->fetchAll();
|
||||
|
||||
// Recupera tutte le classi e le loro variazioni per il modale di aggiunta/modifica prodotti
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT c.id AS class_id, c.name AS class_name, ct.id AS class_type_id, ct.level, ct.day_of_week
|
||||
FROM classes c
|
||||
LEFT JOIN class_types ct ON c.id = ct.class_id
|
||||
WHERE c.school_id = ?
|
||||
ORDER BY c.name, ct.level, ct.day_of_week
|
||||
");
|
||||
$stmt->execute([$school_id]);
|
||||
$class_data = $stmt->fetchAll();
|
||||
|
||||
// Organizza i dati in una struttura gerarchica: classi -> variazioni
|
||||
$all_classes = [];
|
||||
foreach ($class_data as $row) {
|
||||
$class_id = $row['class_id'];
|
||||
if (!isset($all_classes[$class_id])) {
|
||||
$all_classes[$class_id] = [
|
||||
'name' => $row['class_name'],
|
||||
'variations' => []
|
||||
];
|
||||
}
|
||||
if ($row['class_type_id']) {
|
||||
$all_classes[$class_id]['variations'][] = [
|
||||
'id' => $row['class_type_id'],
|
||||
'name' => ucfirst($row['level']) . ' (' . ucfirst($row['day_of_week']) . ')'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Gestione delle azioni (aggiunta, modifica, eliminazione)
|
||||
$success_message = '';
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
// Aggiungi un prodotto
|
||||
if ($action === 'add_product') {
|
||||
$name = $_POST['name'] ?? '';
|
||||
$type = $_POST['type'] ?? '';
|
||||
$price = $_POST['price'] ?? 0;
|
||||
$duration_days = $_POST['duration_days'] ?: null;
|
||||
$max_entries = $_POST['max_entries'] ?: null;
|
||||
$weekly_limit = $_POST['weekly_limit'] ?: null;
|
||||
$max_recoveries = $_POST['max_recoveries'] ?: null;
|
||||
$recovery_validity_days = $_POST['recovery_validity_days'] ?: null;
|
||||
$allow_freeze = $_POST['allow_freeze'] ?? 0;
|
||||
$freeze_max_days = $_POST['freeze_max_days'] ?: null;
|
||||
$max_inventory = $_POST['max_inventory'] ?: null;
|
||||
$class_types = $_POST['class_types'] ?? [];
|
||||
|
||||
if (empty($name) || empty($type) || $price <= 0) {
|
||||
$error = "Nome, tipo e prezzo sono obbligatori.";
|
||||
} else {
|
||||
$current_inventory = $max_inventory; // All'inizio, l'inventario corrente è uguale al massimo
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO products (school_id, name, type, price, duration_days, max_entries, weekly_limit, max_recoveries, recovery_validity_days, allow_freeze, freeze_max_days, max_inventory, current_inventory)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
$stmt->execute([
|
||||
$school_id,
|
||||
$name,
|
||||
$type,
|
||||
$price,
|
||||
$duration_days,
|
||||
$max_entries,
|
||||
$weekly_limit,
|
||||
$max_recoveries,
|
||||
$recovery_validity_days,
|
||||
$allow_freeze,
|
||||
$freeze_max_days,
|
||||
$max_inventory,
|
||||
$current_inventory
|
||||
]);
|
||||
|
||||
$product_id = $pdo->lastInsertId();
|
||||
|
||||
// Associa le classi selezionate
|
||||
if (!empty($class_types)) {
|
||||
$stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, class_type_id, entry_cost) VALUES (?, ?, 1)");
|
||||
foreach ($class_types as $class_type_id) {
|
||||
$stmt->execute([$product_id, $class_type_id]);
|
||||
}
|
||||
}
|
||||
|
||||
$success_message = "Prodotto aggiunto con successo!";
|
||||
header("Location: products.php");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Modifica un prodotto
|
||||
if ($action === 'edit_product') {
|
||||
$id = $_POST['id'] ?? 0;
|
||||
$name = $_POST['name'] ?? '';
|
||||
$type = $_POST['type'] ?? '';
|
||||
$price = $_POST['price'] ?? 0;
|
||||
$duration_days = $_POST['duration_days'] ?: null;
|
||||
$max_entries = $_POST['max_entries'] ?: null;
|
||||
$weekly_limit = $_POST['weekly_limit'] ?: null;
|
||||
$max_recoveries = $_POST['max_recoveries'] ?: null;
|
||||
$recovery_validity_days = $_POST['recovery_validity_days'] ?: null;
|
||||
$allow_freeze = $_POST['allow_freeze'] ?? 0;
|
||||
$freeze_max_days = $_POST['freeze_max_days'] ?: null;
|
||||
$max_inventory = $_POST['max_inventory'] ?: null;
|
||||
$current_inventory = $_POST['current_inventory'] ?: null;
|
||||
$status = $_POST['status'] ?? 'active';
|
||||
$class_types = $_POST['class_types'] ?? [];
|
||||
|
||||
if ($id <= 0 || empty($name) || empty($type) || $price <= 0) {
|
||||
$error = "ID, nome, tipo e prezzo sono obbligatori.";
|
||||
} else {
|
||||
$stmt = $pdo->prepare("
|
||||
UPDATE products
|
||||
SET name = ?, type = ?, price = ?, duration_days = ?, max_entries = ?, weekly_limit = ?, max_recoveries = ?, recovery_validity_days = ?, allow_freeze = ?, freeze_max_days = ?, max_inventory = ?, current_inventory = ?, status = ?
|
||||
WHERE id = ? AND school_id = ?
|
||||
");
|
||||
$stmt->execute([
|
||||
$name,
|
||||
$type,
|
||||
$price,
|
||||
$duration_days,
|
||||
$max_entries,
|
||||
$weekly_limit,
|
||||
$max_recoveries,
|
||||
$recovery_validity_days,
|
||||
$allow_freeze,
|
||||
$freeze_max_days,
|
||||
$max_inventory,
|
||||
$current_inventory,
|
||||
$status,
|
||||
$id,
|
||||
$school_id
|
||||
]);
|
||||
|
||||
// Aggiorna le classi associate
|
||||
$stmt = $pdo->prepare("DELETE FROM product_class_types WHERE product_id = ?");
|
||||
$stmt->execute([$id]);
|
||||
|
||||
if (!empty($class_types)) {
|
||||
$stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, class_type_id, entry_cost) VALUES (?, ?, 1)");
|
||||
foreach ($class_types as $class_type_id) {
|
||||
$stmt->execute([$id, $class_type_id]);
|
||||
}
|
||||
}
|
||||
|
||||
$success_message = "Prodotto modificato con successo!";
|
||||
header("Location: products.php");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Elimina un prodotto
|
||||
if ($action === 'delete_product') {
|
||||
$id = $_POST['id'] ?? 0;
|
||||
|
||||
if ($id <= 0) {
|
||||
$error = "ID non valido.";
|
||||
} else {
|
||||
$stmt = $pdo->prepare("DELETE FROM products WHERE id = ? AND school_id = ?");
|
||||
$stmt->execute([$id, $school_id]);
|
||||
$success_message = "Prodotto eliminato con successo!";
|
||||
header("Location: products.php");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!--favicon-->
|
||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<?php include('siteinfo.php'); ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--wrapper-->
|
||||
<div class="wrapper">
|
||||
<!--sidebar wrapper -->
|
||||
<?php include('include/navbar.php'); ?>
|
||||
<!--end sidebar wrapper -->
|
||||
<!--start header -->
|
||||
<?php include('include/topbar.php'); ?>
|
||||
<!--end header -->
|
||||
<!--start page wrapper -->
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
<!-- Messaggi di successo o errore -->
|
||||
<?php if ($success_message): ?>
|
||||
<div class="alert alert-success" role="alert">
|
||||
<?php echo htmlspecialchars($success_message); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card radius-10">
|
||||
<div class="card-header">
|
||||
<div class="d-flex align-items-center">
|
||||
<div>
|
||||
<h6 class="mb-0">Prodotti</h6>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#addProductModal">
|
||||
<i class="bx bx-plus"></i> Aggiungi Prodotto
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table id="productsTable" class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th>Tipo</th>
|
||||
<th>Prezzo</th>
|
||||
<th>Durata (giorni)</th>
|
||||
<th>Ingressi</th>
|
||||
<th>Inventario</th>
|
||||
<th>Classi Associate</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($products)): ?>
|
||||
<tr>
|
||||
<td colspan="8" class="text-center">Nessun prodotto trovato.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($products as $product): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($product['name']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$type_labels = [
|
||||
'carnet' => 'Carnet',
|
||||
'subscription' => 'Abbonamento',
|
||||
'drop_in' => 'Lezione Singola'
|
||||
];
|
||||
echo $type_labels[$product['type']] ?? $product['type'];
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo number_format($product['price'], 2); ?> €</td>
|
||||
<td><?php echo $product['duration_days'] ?? 'N/A'; ?></td>
|
||||
<td><?php echo $product['max_entries'] ?? 'Illimitati'; ?></td>
|
||||
<td>
|
||||
<?php
|
||||
if ($product['max_inventory'] !== null) {
|
||||
echo htmlspecialchars($product['current_inventory']) . ' / ' . htmlspecialchars($product['max_inventory']);
|
||||
} else {
|
||||
echo 'Illimitato';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$class_names = $product['class_names'] ?? '';
|
||||
$variation_names = $product['variation_names'] ?? '';
|
||||
if ($class_names || $variation_names) {
|
||||
echo htmlspecialchars($class_names);
|
||||
if ($variation_names) {
|
||||
echo '<br><small>' . htmlspecialchars($variation_names) . '</small>';
|
||||
}
|
||||
} else {
|
||||
echo 'Nessuna classe associata';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-warning" data-bs-toggle="modal" data-bs-target="#editProductModal"
|
||||
onclick='fillEditProductModal(<?php echo json_encode([
|
||||
"id" => $product['id'],
|
||||
"name" => htmlspecialchars($product['name'], ENT_QUOTES),
|
||||
"type" => $product['type'],
|
||||
"price" => $product['price'],
|
||||
"duration_days" => $product['duration_days'],
|
||||
"max_entries" => $product['max_entries'],
|
||||
"weekly_limit" => $product['weekly_limit'],
|
||||
"max_recoveries" => $product['max_recoveries'],
|
||||
"recovery_validity_days" => $product['recovery_validity_days'],
|
||||
"allow_freeze" => $product['allow_freeze'],
|
||||
"freeze_max_days" => $product['freeze_max_days'],
|
||||
"max_inventory" => $product['max_inventory'],
|
||||
"current_inventory" => $product['current_inventory'],
|
||||
"status" => $product['status']
|
||||
]); ?>)'
|
||||
data-bs-toggle="tooltip" data-bs-placement="top" title="Modifica">
|
||||
<i class="bx bx-edit"></i>
|
||||
</button>
|
||||
<form action="" method="POST" style="display:inline;" onsubmit="return confirm('Sei sicuro di voler eliminare questo prodotto?');">
|
||||
<input type="hidden" name="action" value="delete_product">
|
||||
<input type="hidden" name="id" value="<?php echo $product['id']; ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="Elimina">
|
||||
<i class="bx bx-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modale per aggiungere un prodotto -->
|
||||
<div class="modal fade" id="addProductModal" tabindex="-1" aria-labelledby="addProductModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addProductModalLabel">Aggiungi Prodotto</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="" method="POST">
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="action" value="add_product">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_name" class="form-label">Nome</label>
|
||||
<input type="text" class="form-control" id="add_product_name" name="name" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_type" class="form-label">Tipo</label>
|
||||
<select class="form-control" id="add_product_type" name="type" required>
|
||||
<option value="carnet">Carnet</option>
|
||||
<option value="subscription">Abbonamento</option>
|
||||
<option value="drop_in">Lezione Singola</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_price" class="form-label">Prezzo (€)</label>
|
||||
<input type="number" step="0.01" class="form-control" id="add_product_price" name="price" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_duration_days" class="form-label">Durata (giorni)</label>
|
||||
<input type="number" class="form-control" id="add_product_duration_days" name="duration_days">
|
||||
<small class="form-text text-muted">Lascia vuoto per lezioni singole.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_max_entries" class="form-label">Numero Massimo di Ingressi</label>
|
||||
<input type="number" class="form-control" id="add_product_max_entries" name="max_entries">
|
||||
<small class="form-text text-muted">Lascia vuoto per abbonamenti illimitati.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_weekly_limit" class="form-label">Limite Settimanale</label>
|
||||
<input type="number" class="form-control" id="add_product_weekly_limit" name="weekly_limit">
|
||||
<small class="form-text text-muted">Lascia vuoto se non applicabile.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_max_recoveries" class="form-label">Numero Massimo di Recuperi</label>
|
||||
<input type="number" class="form-control" id="add_product_max_recoveries" name="max_recoveries">
|
||||
<small class="form-text text-muted">Lascia vuoto se non applicabile.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_recovery_validity_days" class="form-label">Validità Recuperi (giorni)</label>
|
||||
<input type="number" class="form-control" id="add_product_recovery_validity_days" name="recovery_validity_days">
|
||||
<small class="form-text text-muted">Lascia vuoto se non applicabile.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_max_inventory" class="form-label">Inventario Massimo</label>
|
||||
<input type="number" class="form-control" id="add_product_max_inventory" name="max_inventory">
|
||||
<small class="form-text text-muted">Lascia vuoto per illimitato.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_allow_freeze" class="form-label">Permetti Congelamento</label>
|
||||
<select class="form-control" id="add_product_allow_freeze" name="allow_freeze">
|
||||
<option value="0">No</option>
|
||||
<option value="1">Sì</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="add_product_freeze_max_days" class="form-label">Giorni Massimi di Congelamento</label>
|
||||
<input type="number" class="form-control" id="add_product_freeze_max_days" name="freeze_max_days">
|
||||
<small class="form-text text-muted">Lascia vuoto se non applicabile.</small>
|
||||
</div>
|
||||
<div class="col-md-12 mb-3">
|
||||
<label class="form-label">Classi e Variazioni Associate</label>
|
||||
<?php foreach ($all_classes as $class_id => $class): ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input class-checkbox" type="checkbox" id="add_class_<?php echo $class_id; ?>" data-class-id="<?php echo $class_id; ?>">
|
||||
<label class="form-check-label" for="add_class_<?php echo $class_id; ?>">
|
||||
<?php echo htmlspecialchars($class['name']); ?>
|
||||
</label>
|
||||
<?php if (!empty($class['variations'])): ?>
|
||||
<div class="ms-4">
|
||||
<?php foreach ($class['variations'] as $variation): ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input variation-checkbox" type="checkbox" name="class_types[]" value="<?php echo $variation['id']; ?>" id="add_variation_<?php echo $variation['id']; ?>" data-class-id="<?php echo $class_id; ?>">
|
||||
<label class="form-check-label" for="add_variation_<?php echo $variation['id']; ?>">
|
||||
<?php echo htmlspecialchars($variation['name']); ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Chiudi</button>
|
||||
<button type="submit" class="btn btn-primary">Aggiungi</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modale per modificare un prodotto -->
|
||||
<div class="modal fade" id="editProductModal" tabindex="-1" aria-labelledby="editProductModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="editProductModalLabel">Modifica Prodotto</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="" method="POST">
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="action" value="edit_product">
|
||||
<input type="hidden" name="id" id="edit_product_id">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_name" class="form-label">Nome</label>
|
||||
<input type="text" class="form-control" id="edit_product_name" name="name" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_type" class="form-label">Tipo</label>
|
||||
<select class="form-control" id="edit_product_type" name="type" required>
|
||||
<option value="carnet">Carnet</option>
|
||||
<option value="subscription">Abbonamento</option>
|
||||
<option value="drop_in">Lezione Singola</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_price" class="form-label">Prezzo (€)</label>
|
||||
<input type="number" step="0.01" class="form-control" id="edit_product_price" name="price" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_duration_days" class="form-label">Durata (giorni)</label>
|
||||
<input type="number" class="form-control" id="edit_product_duration_days" name="duration_days">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_max_entries" class="form-label">Numero Massimo di Ingressi</label>
|
||||
<input type="number" class="form-control" id="edit_product_max_entries" name="max_entries">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_weekly_limit" class="form-label">Limite Settimanale</label>
|
||||
<input type="number" class="form-control" id="edit_product_weekly_limit" name="weekly_limit">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_max_recoveries" class="form-label">Numero Massimo di Recuperi</label>
|
||||
<input type="number" class="form-control" id="edit_product_max_recoveries" name="max_recoveries">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_recovery_validity_days" class="form-label">Validità Recuperi (giorni)</label>
|
||||
<input type="number" class="form-control" id="edit_product_recovery_validity_days" name="recovery_validity_days">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_max_inventory" class="form-label">Inventario Massimo</label>
|
||||
<input type="number" class="form-control" id="edit_product_max_inventory" name="max_inventory">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_current_inventory" class="form-label">Inventario Corrente</label>
|
||||
<input type="number" class="form-control" id="edit_product_current_inventory" name="current_inventory">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_allow_freeze" class="form-label">Permetti Congelamento</label>
|
||||
<select class="form-control" id="edit_product_allow_freeze" name="allow_freeze">
|
||||
<option value="0">No</option>
|
||||
<option value="1">Sì</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_freeze_max_days" class="form-label">Giorni Massimi di Congelamento</label>
|
||||
<input type="number" class="form-control" id="edit_product_freeze_max_days" name="freeze_max_days">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_product_status" class="form-label">Stato</label>
|
||||
<select class="form-control" id="edit_product_status" name="status">
|
||||
<option value="active">Attivo</option>
|
||||
<option value="inactive">Inattivo</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12 mb-3">
|
||||
<label class="form-label">Classi e Variazioni Associate</label>
|
||||
<?php foreach ($all_classes as $class_id => $class): ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input class-checkbox" type="checkbox" id="edit_class_<?php echo $class_id; ?>" data-class-id="<?php echo $class_id; ?>">
|
||||
<label class="form-check-label" for="edit_class_<?php echo $class_id; ?>">
|
||||
<?php echo htmlspecialchars($class['name']); ?>
|
||||
</label>
|
||||
<?php if (!empty($class['variations'])): ?>
|
||||
<div class="ms-4">
|
||||
<?php foreach ($class['variations'] as $variation): ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input variation-checkbox" type="checkbox" name="class_types[]" value="<?php echo $variation['id']; ?>" id="edit_variation_<?php echo $variation['id']; ?>" data-class-id="<?php echo $class_id; ?>">
|
||||
<label class="form-check-label" for="edit_variation_<?php echo $variation['id']; ?>">
|
||||
<?php echo htmlspecialchars($variation['name']); ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Chiudi</button>
|
||||
<button type="submit" class="btn btn-primary">Salva</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end page wrapper -->
|
||||
<!--start overlay-->
|
||||
<div class="overlay toggle-icon"></div>
|
||||
<!--end overlay-->
|
||||
<!--Start Back To Top Button-->
|
||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
||||
<!--End Back To Top Button-->
|
||||
<?php include('include/footer.php'); ?>
|
||||
</div>
|
||||
<!--end wrapper-->
|
||||
|
||||
<!-- search modal -->
|
||||
<?php //include('include/searchmodal.php');
|
||||
?>
|
||||
<!-- end search modal -->
|
||||
|
||||
<!--start switcher-->
|
||||
<?php //include('include/themeswitcher.php');
|
||||
?>
|
||||
<!--end switcher-->
|
||||
<?php include('jsinclude.php'); ?>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#productsTable').DataTable({
|
||||
"language": {
|
||||
"url": "//cdn.datatables.net/plug-ins/1.10.25/i18n/Italian.json"
|
||||
}
|
||||
});
|
||||
|
||||
// Inizializza i tooltip
|
||||
$('[data-bs-toggle="tooltip"]').tooltip();
|
||||
|
||||
// Gestione selezione/deselezione delle classi e variazioni
|
||||
$('.class-checkbox').on('change', function() {
|
||||
const classId = $(this).data('class-id');
|
||||
const isChecked = $(this).is(':checked');
|
||||
// Seleziona/deseleziona tutte le variazioni della classe
|
||||
$(`.variation-checkbox[data-class-id="${classId}"]`).prop('checked', isChecked);
|
||||
});
|
||||
|
||||
$('.variation-checkbox').on('change', function() {
|
||||
const classId = $(this).data('class-id');
|
||||
const classCheckbox = $(`#add_class_${classId}, #edit_class_${classId}`);
|
||||
const variations = $(`.variation-checkbox[data-class-id="${classId}"]`);
|
||||
const allChecked = variations.length === variations.filter(':checked').length;
|
||||
const someChecked = variations.filter(':checked').length > 0;
|
||||
|
||||
// Aggiorna lo stato della checkbox della classe
|
||||
if (allChecked) {
|
||||
classCheckbox.prop('checked', true).prop('indeterminate', false);
|
||||
} else if (someChecked) {
|
||||
classCheckbox.prop('checked', false).prop('indeterminate', true);
|
||||
} else {
|
||||
classCheckbox.prop('checked', false).prop('indeterminate', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function fillEditProductModal(data) {
|
||||
document.getElementById('edit_product_id').value = data.id;
|
||||
document.getElementById('edit_product_name').value = data.name;
|
||||
document.getElementById('edit_product_type').value = data.type;
|
||||
document.getElementById('edit_product_price').value = data.price;
|
||||
document.getElementById('edit_product_duration_days').value = data.duration_days || '';
|
||||
document.getElementById('edit_product_max_entries').value = data.max_entries || '';
|
||||
document.getElementById('edit_product_weekly_limit').value = data.weekly_limit || '';
|
||||
document.getElementById('edit_product_max_recoveries').value = data.max_recoveries || '';
|
||||
document.getElementById('edit_product_recovery_validity_days').value = data.recovery_validity_days || '';
|
||||
document.getElementById('edit_product_allow_freeze').value = data.allow_freeze;
|
||||
document.getElementById('edit_product_freeze_max_days').value = data.freeze_max_days || '';
|
||||
document.getElementById('edit_product_max_inventory').value = data.max_inventory || '';
|
||||
document.getElementById('edit_product_current_inventory').value = data.current_inventory || '';
|
||||
document.getElementById('edit_product_status').value = data.status;
|
||||
|
||||
// Recupera le classi associate al prodotto
|
||||
fetch('get_product_classes.php?product_id=' + data.id)
|
||||
.then(response => response.json())
|
||||
.then(class_types => {
|
||||
// Resetta tutte le checkbox
|
||||
document.querySelectorAll('.variation-checkbox').forEach(checkbox => {
|
||||
checkbox.checked = false;
|
||||
});
|
||||
document.querySelectorAll('.class-checkbox').forEach(checkbox => {
|
||||
checkbox.checked = false;
|
||||
checkbox.indeterminate = false;
|
||||
});
|
||||
|
||||
// Seleziona le variazioni associate
|
||||
document.querySelectorAll('.variation-checkbox').forEach(checkbox => {
|
||||
if (class_types.includes(parseInt(checkbox.value))) {
|
||||
checkbox.checked = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Aggiorna lo stato delle checkbox delle classi
|
||||
document.querySelectorAll('.class-checkbox').forEach(classCheckbox => {
|
||||
const classId = classCheckbox.getAttribute('data-class-id');
|
||||
const variations = document.querySelectorAll(`.variation-checkbox[data-class-id="${classId}"]`);
|
||||
const checkedVariations = document.querySelectorAll(`.variation-checkbox[data-class-id="${classId}"]:checked`);
|
||||
if (variations.length === checkedVariations.length && variations.length > 0) {
|
||||
classCheckbox.checked = true;
|
||||
classCheckbox.indeterminate = false;
|
||||
} else if (checkedVariations.length > 0) {
|
||||
classCheckbox.checked = false;
|
||||
classCheckbox.indeterminate = true;
|
||||
} else {
|
||||
classCheckbox.checked = false;
|
||||
classCheckbox.indeterminate = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user