Històric de compres: diferència entre les revisions

De Wiki personal d'en Guillem Serrat
Cap resum de modificació
 
(Hi ha 2 revisions intermèdies que no es mostren del mateix usuari)
Línia 16: Línia 16:


== Recuperació de l'històric ==
== Recuperació de l'històric ==
Mitjançant una consulta SQL, recuperem les dades de la taula compra i de la taula compres_detall. Fem servir JOINS per relacionar els detalls de les compres amb les compres i per relacionar IDs de productes amb els seus noms
Els resultats es troben ordenats segons la compra més recent a la més antiga<pre>
// Recuperació de l'històric de compres a partir de diferents taules de la BD
try {
    // Obtenim totes les compres amb els seus detalls i dades del producte
    // Fem JOIN per tenir-ho tot en una sola consulta i relacionar noms amb IDs, compres i detalls de compres
    $sql = "
        SELECT
            c.id AS compra_id,
            c.data_compra,
            c.total AS total_compra,
            cd.producte_id,
            cd.quantitat,
            cd.preu_unitari,
            cd.total_producte,
            p.nom AS nom_producte,
            p.categoria
        FROM compres c
        INNER JOIN compres_detall cd ON c.id = cd.compra_id
        INNER JOIN productes p ON cd.producte_id = p.id
        ORDER BY c.data_compra DESC, c.id DESC
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $resultats = $stmt->fetchAll();
} catch (PDOException $e) {
    die("Error BD: " . htmlspecialchars($e->getMessage()));
}
?>
</pre>


== Mostra de l'històric ==
== Mostra de l'històric ==
Línia 102: Línia 135:
     </button>
     </button>
</form>
</form>
</pre>Quan es prem, únicament esborra els registres de les taules compres i compres_detall<pre>
// Borrar tots els registres de la taula
if (isset($_POST['borrarCompres'])) { // En cas de prémer el botó d'esborrar l'historial
    try {
        $stmt = $pdo->prepare("DELETE FROM compres_detall");
        $stmt->execute();
        $stmt = $pdo->prepare("DELETE FROM compres");
        $stmt->execute();
    } catch (PDOException $e) {
        echo "<p>Error al eliminar els registres: " . htmlspecialchars($e->getMessage()) . "</p>";
    }
}
</pre>
== Codi complet ==
<pre>
<?php
require_once "../connexioBD/connexioRW.php";
// Borrar tots els registres de la taula
if (isset($_POST['borrarCompres'])) { // En cas de prémer el botó d'esborrar l'historial
    try {
        $stmt = $pdo->prepare("DELETE FROM compres_detall");
        $stmt->execute();
        $stmt = $pdo->prepare("DELETE FROM compres");
        $stmt->execute();
    } catch (PDOException $e) {
        echo "<p>Error al eliminar els registres: " . htmlspecialchars($e->getMessage()) . "</p>";
    }
}
// Recuperació de l'històric de compres a partir de diferents taules de la BD
try {
    // Obtenim totes les compres amb els seus detalls i dades del producte
    // Fem JOIN per tenir-ho tot en una sola consulta i relacionar noms amb IDs, compres i detalls de compres
    $sql = "
        SELECT
            c.id AS compra_id,
            c.data_compra,
            c.total AS total_compra,
            cd.producte_id,
            cd.quantitat,
            cd.preu_unitari,
            cd.total_producte,
            p.nom AS nom_producte,
            p.categoria
        FROM compres c
        INNER JOIN compres_detall cd ON c.id = cd.compra_id
        INNER JOIN productes p ON cd.producte_id = p.id
        ORDER BY c.data_compra DESC, c.id DESC
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $resultats = $stmt->fetchAll();
} catch (PDOException $e) {
    die("Error BD: " . htmlspecialchars($e->getMessage()));
}
?>
<!-- HTMl que mostra l'històric -->
<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <title>Històric de Compres</title>
    <link rel="stylesheet" href="../css/stylesHistorial.css"> <!-- Definim el full d'estils -->
    <style>
    </style>
</head>
<body>
<h1>Històric de Compres</h1>
<form method="POST" action="">
    <button name="borrarCompres" type="submit">
        <?php echo "Esborrar registre de compres" ?> <!-- Botó per esborrar històric de compres -->
    </button>
</form>
<?php
if (empty($resultats)) { // En cas de no haver-hi resultats a la consulta SQL
    echo "<center><p>No hi ha compres registrades.</p></center>";
    exit;
}
// Agrupem resultats per compra. Cada fila no és una compra, és un producte d'una compra
$compres = array(); // Definim un array per desar les compres i dins tots els productes
foreach ($resultats as $fila) { // Cada fila és un producte. Per cada producte
    $id = $fila['compra_id']; // Recuperem la ID de la compra a la que correspon
    if (!isset($compres[$id])) { // Si la compra no existeix a l'array, la creem
        $compres[$id] = array(
            'data' => $fila['data_compra'], // Desem la data de la compra
            'total' => $fila['total_compra'], // El total de la compra
            'productes' => array() // Una array on hi haurà tots els productes i els seus detalls
        );
    }
    $compres[$id]['productes'][] = $fila; // Afegim a la compra, dins de productes, els detalls (la fila) del producte 
}
// Mostrem cada compra amb les seves dades generals i el detall de productes
foreach ($compres as $id_compra => $dades): // Per cada compra (on hi és desat la data, el total, i els detalls de cada producte)
?>
    <h2>Compra #<?php echo (int)$id_compra; ?></h2> <!-- Títol per identificar la compra -->
    <center>
    <p>
        <strong>Data:</strong> <?php echo htmlspecialchars($dades['data']); ?><br> <!-- Mostrem la data -->
        <strong>Total compra:</strong> <?php echo number_format($dades['total'], 2); ?> € <!-- Mostrem el total -->
    </p>
    </center>
    <table> <!-- Creem una taula per mostrar els detalls dels productes. Una fila per cada producte -->
        <thead>
            <tr>
                <th>Producte</th>
                <th>Categoria</th>
                <th>Preu unitari</th>
                <th>Quantitat</th>
                <th>Total producte</th>
            </tr>
        </thead>
        <tbody>
        <?php foreach ($dades['productes'] as $p): ?> <!-- Per cada producte dins la compra -->
            <tr>
                <td><?php echo htmlspecialchars($p['nom_producte']); ?></td> <!-- Mostrem el nom del producte -->
                <td><?php echo htmlspecialchars($p['categoria']); ?></td> <!-- La categoria -->
                <td><?php echo number_format($p['preu_unitari'], 2); ?> €</td> <!-- El preu unitari -->
                <td><?php echo (int)$p['quantitat']; ?></td> <!-- La quantitat -->
                <td><?php echo number_format($p['total_producte'], 2); ?> €</td> <!-- El total (amb descompte inclòs) -->
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
<?php endforeach; ?>
</body>
</html>
</pre>
</pre>



Revisió de 19:29, 31 des 2025

Històric de compres

L'administrador o responsable del catàleg té la possibilitat de visualitzar un històric de compres que recull

  • La data de la compra
  • El total de la compra
  • Detalls dels productes comprats

A més a més, disposa de la possibilitat d'esborrar l'històric sempre que es desitji

Connexió a la BD

En aquest cas no requerim cap sessió, ja que únicament es mostren les dades de la BD

El que si necessitem és una connexió d'escriptura a la BD, ja que es defineix la funcionalitat de poder esborrar l'històric, no només mostrar-lo.

require_once "../connexioBD/connexioRW.php";

Recuperació de l'històric

Mitjançant una consulta SQL, recuperem les dades de la taula compra i de la taula compres_detall. Fem servir JOINS per relacionar els detalls de les compres amb les compres i per relacionar IDs de productes amb els seus noms

Els resultats es troben ordenats segons la compra més recent a la més antiga

// Recuperació de l'històric de compres a partir de diferents taules de la BD
try {
    // Obtenim totes les compres amb els seus detalls i dades del producte
    // Fem JOIN per tenir-ho tot en una sola consulta i relacionar noms amb IDs, compres i detalls de compres
    $sql = "
        SELECT
            c.id AS compra_id,
            c.data_compra,
            c.total AS total_compra,
            cd.producte_id,
            cd.quantitat,
            cd.preu_unitari,
            cd.total_producte,
            p.nom AS nom_producte,
            p.categoria
        FROM compres c
        INNER JOIN compres_detall cd ON c.id = cd.compra_id
        INNER JOIN productes p ON cd.producte_id = p.id 
        ORDER BY c.data_compra DESC, c.id DESC
    ";

    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $resultats = $stmt->fetchAll();

} catch (PDOException $e) {
    die("Error BD: " . htmlspecialchars($e->getMessage()));
}
?>

Mostra de l'històric

Agrupació de resultats per compra

Els resultats retornats per la consulta són els detalls de les compres i no les compres en sí. És possible que tinguem 9 resultats però realment son 3 compres, és per això que hem d'agrupar aquests 9 resultats en compres.

L'objectiu és tenir una array amb totes les compres que dins seu tingui com a vectors la data de compra, el total i una altra array que sigui els detalls de la compra. Es pot consultar l'Exemple de model de dades de l'array $compres per entendre millor l'estructura de dades de l'array.

Primer, definirem l'array $compres, que serà l'array que contindrà totes les compres i els seus detalls

// Agrupem resultats per compra. Cada fila no és una compra, és un producte d'una compra
$compres = array(); // Definim un array per desar les compres i dins tots els productes

Seguidament, per cada compra (cada registre) realitzarem el següent

  1. Recuperem la ID de compra del producte
  2. (Opcional) En cas que aquesta ID no existeixi dins de l'array $compres
    1. Afegim a l'array $compres un vector que té el valor de la ID de compra, el qual serà una altra array
    2. Dins de l'array de la ID de compra afegirem
      1. La data de compra
      2. El total de la compra
      3. Una altra array "productes" que servirà per emmagatzemar els detalls dels productes comprats
  3. Finalment, dins de l'array "productes" inserim les dades la compra (el registre, la fila retornada per SQL, que contempla els detalls del producte
foreach ($resultats as $fila) { // Cada fila és un producte. Per cada producte
    $id = $fila['compra_id']; // Recuperem la ID de la compra a la que correspon
    if (!isset($compres[$id])) { // Si la compra no existeix a l'array, la creem 
        $compres[$id] = array(
            'data' => $fila['data_compra'], // Desem la data de la compra
            'total' => $fila['total_compra'], // El total de la compra
            'productes' => array() // Una array on hi haurà tots els productes i els seus detalls
        );
    }
    $compres[$id]['productes'][] = $fila; // Afegim a la compra, dins de productes, els detalls (la fila) del producte  
}

Mostra de les compres

Finalment, per cada compra a $compres, mostrarem un "bloc" on:

  • Es mostrarà la ID de compra
  • Es mostrarà la data i el total de la compra
  • Es mostrarà una taula on, a partir de l'array "productes" s'obtindrà tots els seus valors, que son els detalls de cada producte
// Mostrem cada compra amb les seves dades generals i el detall de productes
foreach ($compres as $id_compra => $dades): // Per cada compra (on hi és desat la data, el total, i els detalls de cada producte)
?>
    <h2>Compra #<?php echo (int)$id_compra; ?></h2> <!-- Títol per identificar la compra -->
    <center>
    <p>
        <strong>Data:</strong> <?php echo htmlspecialchars($dades['data']); ?><br> <!-- Mostrem la data -->
        <strong>Total compra:</strong> <?php echo number_format($dades['total'], 2); ?> € <!-- Mostrem el total -->
    </p>
    </center>

    <table> <!-- Creem una taula per mostrar els detalls dels productes. Una fila per cada producte -->
        <thead>
            <tr>
                <th>Producte</th>
                <th>Categoria</th>
                <th>Preu unitari</th>
                <th>Quantitat</th>
                <th>Total producte</th>
            </tr>
        </thead>
        <tbody>
        <?php foreach ($dades['productes'] as $p): ?> <!-- Per cada producte dins la compra -->
            <tr>
                <td><?php echo htmlspecialchars($p['nom_producte']); ?></td> <!-- Mostrem el nom del producte -->
                <td><?php echo htmlspecialchars($p['categoria']); ?></td> <!-- La categoria -->
                <td><?php echo number_format($p['preu_unitari'], 2); ?> €</td> <!-- El preu unitari -->
                <td><?php echo (int)$p['quantitat']; ?></td> <!-- La quantitat -->
                <td><?php echo number_format($p['total_producte'], 2); ?> €</td> <!-- El total (amb descompte inclòs) -->
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
<?php endforeach; ?>

Un exemple d'una compra seria la següent

Eliminació de l'històric

A la pàgina es troba un botó per esborrar l'històric de compres

<form method="POST" action="">
    <button name="borrarCompres" type="submit">
        <?php echo "Esborrar registre de compres" ?> <!-- Botó per esborrar històric de compres -->
    </button>
</form>

Quan es prem, únicament esborra els registres de les taules compres i compres_detall

// Borrar tots els registres de la taula if (isset($_POST['borrarCompres'])) { // En cas de prémer el botó d'esborrar l'historial

   try {
       $stmt = $pdo->prepare("DELETE FROM compres_detall");
       $stmt->execute();
       $stmt = $pdo->prepare("DELETE FROM compres");
       $stmt->execute();
   } catch (PDOException $e) {
       echo "<p>Error al eliminar els registres: " . htmlspecialchars($e->getMessage()) . "</p>";
   }

}

Codi complet

<?php
require_once "../connexioBD/connexioRW.php";

// Borrar tots els registres de la taula
if (isset($_POST['borrarCompres'])) { // En cas de prémer el botó d'esborrar l'historial
    try {
        $stmt = $pdo->prepare("DELETE FROM compres_detall");
        $stmt->execute();
        $stmt = $pdo->prepare("DELETE FROM compres");
        $stmt->execute();
    } catch (PDOException $e) {
        echo "<p>Error al eliminar els registres: " . htmlspecialchars($e->getMessage()) . "</p>";
    }
}

// Recuperació de l'històric de compres a partir de diferents taules de la BD
try {
    // Obtenim totes les compres amb els seus detalls i dades del producte
    // Fem JOIN per tenir-ho tot en una sola consulta i relacionar noms amb IDs, compres i detalls de compres
    $sql = "
        SELECT
            c.id AS compra_id,
            c.data_compra,
            c.total AS total_compra,
            cd.producte_id,
            cd.quantitat,
            cd.preu_unitari,
            cd.total_producte,
            p.nom AS nom_producte,
            p.categoria
        FROM compres c
        INNER JOIN compres_detall cd ON c.id = cd.compra_id
        INNER JOIN productes p ON cd.producte_id = p.id 
        ORDER BY c.data_compra DESC, c.id DESC
    ";

    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $resultats = $stmt->fetchAll();

} catch (PDOException $e) {
    die("Error BD: " . htmlspecialchars($e->getMessage()));
}
?>


<!-- HTMl que mostra l'històric -->

<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <title>Històric de Compres</title>
    <link rel="stylesheet" href="../css/stylesHistorial.css"> <!-- Definim el full d'estils -->
    <style>
    </style>
</head>
<body>

<h1>Històric de Compres</h1>
<form method="POST" action="">
    <button name="borrarCompres" type="submit">
        <?php echo "Esborrar registre de compres" ?> <!-- Botó per esborrar històric de compres -->
    </button>
</form>

<?php
if (empty($resultats)) { // En cas de no haver-hi resultats a la consulta SQL
    echo "<center><p>No hi ha compres registrades.</p></center>";
    exit;
}

// Agrupem resultats per compra. Cada fila no és una compra, és un producte d'una compra
$compres = array(); // Definim un array per desar les compres i dins tots els productes

foreach ($resultats as $fila) { // Cada fila és un producte. Per cada producte
    $id = $fila['compra_id']; // Recuperem la ID de la compra a la que correspon
    if (!isset($compres[$id])) { // Si la compra no existeix a l'array, la creem 
        $compres[$id] = array(
            'data' => $fila['data_compra'], // Desem la data de la compra
            'total' => $fila['total_compra'], // El total de la compra
            'productes' => array() // Una array on hi haurà tots els productes i els seus detalls
        );
    }
    $compres[$id]['productes'][] = $fila; // Afegim a la compra, dins de productes, els detalls (la fila) del producte  
}

// Mostrem cada compra amb les seves dades generals i el detall de productes
foreach ($compres as $id_compra => $dades): // Per cada compra (on hi és desat la data, el total, i els detalls de cada producte)
?>
    <h2>Compra #<?php echo (int)$id_compra; ?></h2> <!-- Títol per identificar la compra -->
    <center>
    <p>
        <strong>Data:</strong> <?php echo htmlspecialchars($dades['data']); ?><br> <!-- Mostrem la data -->
        <strong>Total compra:</strong> <?php echo number_format($dades['total'], 2); ?> € <!-- Mostrem el total -->
    </p>
    </center>

    <table> <!-- Creem una taula per mostrar els detalls dels productes. Una fila per cada producte -->
        <thead>
            <tr>
                <th>Producte</th>
                <th>Categoria</th>
                <th>Preu unitari</th>
                <th>Quantitat</th>
                <th>Total producte</th>
            </tr>
        </thead>
        <tbody>
        <?php foreach ($dades['productes'] as $p): ?> <!-- Per cada producte dins la compra -->
            <tr>
                <td><?php echo htmlspecialchars($p['nom_producte']); ?></td> <!-- Mostrem el nom del producte -->
                <td><?php echo htmlspecialchars($p['categoria']); ?></td> <!-- La categoria -->
                <td><?php echo number_format($p['preu_unitari'], 2); ?> €</td> <!-- El preu unitari -->
                <td><?php echo (int)$p['quantitat']; ?></td> <!-- La quantitat -->
                <td><?php echo number_format($p['total_producte'], 2); ?> €</td> <!-- El total (amb descompte inclòs) -->
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
<?php endforeach; ?>

</body>
</html>

Exemple de model de dades de l'array $compres

$compres = array(
    101 => array( // Compra 1
        'data' => '2025-01-10 18:32:00',
        'total' => 45.90,
        'productes' => array( // Detalls dels productes
            array( // Detalls Producte 1
                'compra_id'     => 101,
                'data_compra'   => '2025-01-10 18:32:00',
                'total_compra'  => 45.90,
                'producte_id'   => 1,
                'nom_producte'  => 'Teclat mecànic',
                'quantitat'     => 1,
                'preu_unitari'  => 29.90
            ),
            array( // Detalls Producte 2
                'compra_id'     => 101,
                'data_compra'   => '2025-01-10 18:32:00',
                'total_compra'  => 45.90,
                'producte_id'   => 2,
                'nom_producte'  => 'Ratolí òptic',
                'quantitat'     => 1,
                'preu_unitari'  => 16.00
            )
        )
    ),

    102 => array( // Compra 2
        'data' => '2025-01-12 09:15:00',
        'total' => 120.00,
        'productes' => array( // Detalls dels productes
            array( // Producte 1
                'compra_id'     => 102,
                'data_compra'   => '2025-01-12 09:15:00',
                'total_compra'  => 120.00,
                'producte_id'   => 3,
                'nom_producte'  => 'Auriculars sense fil',
                'quantitat'     => 2,
                'preu_unitari'  => 60.00
            )
        )
    )
);