J. Carpeta « srv / bd »

Versión para imprimir.

1. srv / bd / bdCrea.php

1<?php
2
3function bdCrea(PDO $con)
4{
5 $con->exec(
6 'CREATE TABLE IF NOT EXISTS VENTA (
7 VENT_ID INTEGER,
8 VENT_EN_CAPTURA INTEGER NOT NULL,
9 CONSTRAINT VENT_PK
10 PRIMARY KEY(VENT_ID)
11 )'
12 );
13 $con->exec(
14 'CREATE TABLE IF NOT EXISTS PRODUCTO (
15 PROD_ID INTEGER,
16 PROD_NOMBRE TEXT NOT NULL,
17 PROD_EXISTENCIAS REAL NOT NULL,
18 PROD_PRECIO REAL NOT NULL,
19 CONSTRAINT PROD_PK
20 PRIMARY KEY(PROD_ID),
21 CONSTRAINT PROD_NOM_UNQ
22 UNIQUE(PROD_NOMBRE)
23 )'
24 );
25 $con->exec(
26 'CREATE TABLE IF NOT EXISTS DET_VENTA (
27 VENT_ID INTEGER NOT NULL,
28 PROD_ID INTEGER NOT NULL,
29 DTV_CANTIDAD REAL NOT NULL,
30 DTV_PRECIO REAL NOT NULL,
31 CONSTRAINT DTV_PK
32 PRIMARY KEY (VENT_ID, PROD_ID),
33 CONSTRAINT DTV_VENT_FK
34 FOREIGN KEY (VENT_ID) REFERENCES VENTA(VENT_ID),
35 CONSTRAINT DTV_PROD_FK
36 FOREIGN KEY (PROD_ID) REFERENCES PRODUCTO(PROD_ID)
37 )'
38 );
39}
40

2. srv / bd / Bd.php

1<?php
2
3require_once __DIR__ . "/../modelo/Venta.php";
4require_once __DIR__ . "/../modelo/Producto.php";
5require_once __DIR__ . "/bdCrea.php";
6require_once __DIR__ . "/productoCuenta.php";
7require_once __DIR__ . "/productoAgrega.php";
8require_once __DIR__ . "/ventaCuenta.php";
9require_once __DIR__ . "/ventaAgrega.php";
10
11class Bd
12{
13
14 private static ?PDO $conexion = null;
15
16 public static function getConexion(): PDO
17 {
18 if (self::$conexion === null) {
19 self::$conexion = new PDO(
20 // cadena de conexión
21 "sqlite:srvcompras.db",
22 // usuario
23 null,
24 // contraseña
25 null,
26 // Opciones: conexiones persistentes y lanza excepciones.
27 [PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
28 );
29
30 bdCrea(self::$conexion);
31 if (productoCuenta() === 0) {
32 productoAgrega(
33 new Producto(nombre: "Sandwich", existencias: 50, precio: 15)
34 );
35 productoAgrega(
36 new Producto(nombre: "Hot dog", existencias: 40, precio: 30)
37 );
38 productoAgrega(
39 new Producto(nombre: "Hamburguesa", existencias: 30, precio: 40)
40 );
41 }
42
43 if (ventaCuenta() === 0) {
44 ventaAgrega(new Venta(enCaptura: true));
45 }
46 }
47
48 return self::$conexion;
49 }
50}
51

3. srv / bd / detalleDeVentaAgrega.php

1<?php
2
3require_once __DIR__ . "/../../lib/php/ProblemDetails.php";
4require_once __DIR__ . "/../modelo/DetalleDeVenta.php";
5require_once __DIR__ . "/Bd.php";
6require_once __DIR__ . "/ventaEnCapturaBusca.php";
7require_once __DIR__ . "/productoBusca.php";
8
9function detalleDeVentaAgrega(DetalleDeVenta $modelo)
10{
11 $con = Bd::getConexion();
12 $producto = productoBusca($modelo->producto->id);
13 if ($producto === false) {
14 $htmlId = htmlentities($modelo->producto->id);
15 throw new ProblemDetails(
16 status: ProblemDetails::BadRequest,
17 type: "/error/productonoencontrado.html",
18 title: "Producto no encontrado.",
19 detail: "No se encontró ningún producto con el id $htmlId.",
20 );
21 }
22 $venta = ventaEnCapturaBusca();
23 if ($venta === false)
24 throw new ProblemDetails(
25 status: ProblemDetails::BadRequest,
26 type: "/error/ventaencapturanoencontrada.html",
27 title: "Venta en captura no encontrada.",
28 detail: "No se encontró ninguna venta en captura.",
29 );
30 $modelo->venta = $venta;
31 $modelo->precio = $producto->precio;
32 $modelo->producto = $producto;
33 $modelo->valida();
34 $stmt = $con->prepare(
35 "INSERT INTO DET_VENTA
36 (VENT_ID, PROD_ID, DTV_CANTIDAD, DTV_PRECIO)
37 VALUES
38 (:ventId, :prodId, :cantidad, :precio)"
39 );
40 $stmt->execute(
41 [
42 ":ventId" => $venta->id,
43 ":prodId" => $producto->id,
44 ":cantidad" => $modelo->cantidad,
45 ":precio" => $producto->precio
46 ]
47 );
48}
49

4. srv / bd / detalleDeVentaBusca.php

1<?php
2
3require_once __DIR__ . "/../modelo/DetalleDeVenta.php";
4require_once __DIR__ . "/Bd.php";
5require_once __DIR__ . "/ventaEnCapturaBusca.php";
6require_once __DIR__ . "/productoBusca.php";
7
8function detalleDeVentaBusca(int $prodId)
9{
10 $venta = ventaEnCapturaBusca();
11 if ($venta === false) {
12 return false;
13 }
14 $producto = productoBusca($prodId);
15 if ($producto === false) {
16 return false;
17 }
18 $con = Bd::getConexion();
19 $stmt = $con->prepare(
20 "SELECT
21 DV.PROD_ID AS prodId,
22 P.PROD_NOMBRE AS prodNombre,
23 DV.DTV_CANTIDAD AS cantidad,
24 DV.DTV_PRECIO AS precio
25 FROM DET_VENTA DV, PRODUCTO P
26 WHERE
27 DV.PROD_ID = P.PROD_ID
28 AND DV.VENT_ID = :ventId
29 AND DV.PROD_ID = :prodId"
30 );
31 $stmt->execute([
32 ":ventId" => $venta->id,
33 ":prodId" => $prodId
34 ]);
35 $stmt->setFetchMode(PDO::FETCH_OBJ);
36 $obj = $stmt->fetch();
37 if ($obj === false) {
38 return false;
39 } else {
40 $dtv = new DetalleDeVenta();
41 $dtv->venta = $venta;
42 $dtv->producto = $producto;
43 $dtv->cantidad = $obj->cantidad;
44 $dtv->precio = $obj->precio;
45 return $dtv;
46 }
47}
48

5. srv / bd / detalleDeVentaConsulta.php

1<?php
2
3require_once __DIR__ . "/../../lib/php/recibeFetchAll.php";
4require_once __DIR__ . "/../modelo/Venta.php";
5require_once __DIR__ . "/../modelo/DetalleDeVenta.php";
6require_once __DIR__ . "/../modelo/Producto.php";
7require_once __DIR__ . "/Bd.php";
8
9function detalleDeVentaConsulta(Venta $venta)
10{
11 $con = Bd::getConexion();
12 $stmt = $con->query(
13 "SELECT
14 DV.PROD_ID AS prodId,
15 P.PROD_NOMBRE AS prodNombre,
16 P.PROD_EXISTENCIAS AS prodExistencias,
17 P.PROD_PRECIO AS prodPrecio,
18 DV.DTV_CANTIDAD AS cantidad,
19 DV.DTV_PRECIO AS precio
20 FROM DET_VENTA DV, PRODUCTO P
21 WHERE
22 DV.PROD_ID = P.PROD_ID
23 AND DV.VENT_ID = :ventId
24 ORDER BY P.PROD_NOMBRE"
25 );
26 $stmt->execute([":ventId" => $venta->id]);
27 $resultado = $stmt->fetchAll(PDO::FETCH_OBJ);
28 $objs = recibeFetchAll($resultado);
29 /** @var DetalleDeVenta[] */
30 $detalles = [];
31 foreach ($objs as $obj) {
32 $producto = new Producto(
33 id: $obj->prodId,
34 nombre: $obj->prodNombre,
35 existencias: $obj->prodExistencias,
36 precio: $obj->prodPrecio
37 );
38 $detalle = new DetalleDeVenta(
39 venta: $venta,
40 producto: $producto,
41 cantidad: $obj->cantidad,
42 precio: $obj->precio
43 );
44 $detalles[] = $detalle;
45 }
46 return $detalles;
47}
48

6. srv / bd / detalleDeVentaElimina.php

1<?php
2
3require_once __DIR__ . "/Bd.php";
4require_once __DIR__ . "/ventaEnCapturaBusca.php";
5
6function detalleDeVentaElimina(int $prodId)
7{
8 $venta = ventaEnCapturaBusca();
9 if ($venta !== false) {
10 $con = Bd::getConexion();
11 $stmt = $con->prepare(
12 "DELETE FROM DET_VENTA
13 WHERE VENT_ID = :ventId
14 AND PROD_ID = :prodId"
15 );
16 $stmt->execute([
17 ":ventId" => $venta->id,
18 ":prodId" => $prodId,
19 ]);
20 }
21}
22

7. srv / bd / detalleDeVentaModifica.php

1<?php
2
3require_once __DIR__ . "/../../lib/php/ProblemDetails.php";
4require_once __DIR__ . "/../modelo/DetalleDeVenta.php";
5require_once __DIR__ . "/Bd.php";
6require_once __DIR__ . "/ventaEnCapturaBusca.php";
7require_once __DIR__ . "/productoBusca.php";
8
9
10function detalleDeVentaModifica(DetalleDeVenta $modelo)
11{
12 $con = Bd::getConexion();
13 $producto = productoBusca($modelo->producto->id);
14 if ($producto === false) {
15 $htmlId = htmlentities($modelo->producto->id);
16 throw new ProblemDetails(
17 status: ProblemDetails::BadRequest,
18 type: "/error/productonoencontrado.html",
19 title: "Producto no encontrado.",
20 detail: "No se encontró ningún producto con el id $htmlId.",
21 );
22 }
23 $venta = ventaEnCapturaBusca();
24 $venta = ventaEnCapturaBusca();
25 if ($venta === false)
26 throw new ProblemDetails(
27 status: ProblemDetails::BadRequest,
28 type: "/error/ventaencapturanoencontrada.html",
29 title: "Venta en captura no encontrada.",
30 detail: "No se encontró ninguna venta en captura.",
31 );
32 $modelo->venta = $venta;
33 $modelo->producto = $producto;
34 $modelo->precio = $producto->precio;
35 $modelo->valida();
36 $stmt = $con->prepare(
37 "UPDATE DET_VENTA
38 SET
39 DTV_CANTIDAD = :cantidad,
40 DTV_PRECIO = :precio
41 WHERE
42 VENT_ID = :ventId
43 AND PROD_ID = :prodId"
44 );
45 $stmt->execute(
46 [
47 ":ventId" => $venta->id,
48 ":prodId" => $producto->id,
49 ":cantidad" => $modelo->cantidad,
50 ":precio" => $modelo->precio
51 ]
52 );
53}
54

8. srv / bd / productoAgrega.php

1<?php
2
3require_once __DIR__ . "/../modelo/Producto.php";
4require_once __DIR__ . "/Bd.php";
5
6function productoAgrega(Producto $modelo)
7{
8 $modelo->valida();
9 $con = Bd::getConexion();
10 $stmt = $con->prepare(
11 "INSERT INTO PRODUCTO
12 (PROD_NOMBRE, PROD_EXISTENCIAS, PROD_PRECIO)
13 VALUES
14 (:nombre, :existencias, :precio)"
15 );
16 $stmt->execute([
17 ":nombre" => $modelo->nombre,
18 ":existencias" => $modelo->existencias,
19 ":precio" => $modelo->precio
20 ]);
21 /* Si usas una secuencia para generar el id,
22 * pasa como parámetro de lastInsertId el
23 * nombre de dicha secuencia, debes
24 * ejecutarlo antes del INSERT y pasarle el
25 * id generado al SQL. */
26 $modelo->id = $con->lastInsertId();
27}
28

9. srv / bd / productoBusca.php

1<?php
2
3require_once __DIR__ . "/../modelo/Producto.php";
4require_once __DIR__ . "/Bd.php";
5
6function productoBusca(int $id): false|Producto
7{
8 $con = Bd::getConexion();
9 $stmt = $con->prepare(
10 "SELECT
11 PROD_ID AS id,
12 PROD_NOMBRE AS nombre,
13 PROD_PRECIO AS precio,
14 PROD_EXISTENCIAS AS existencias
15 FROM PRODUCTO
16 WHERE PROD_ID = :id"
17 );
18 $stmt->execute([":id" => $id]);
19 $stmt->setFetchMode(
20 PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE,
21 Producto::class
22 );
23 return $stmt->fetch();
24}
25

10. srv / bd / productoConsulta.php

1<?php
2
3require_once __DIR__ . "/../../lib/php/recibeFetchAll.php";
4require_once __DIR__ . "/../modelo/Producto.php";
5require_once __DIR__ . "/Bd.php";
6
7/** @return Producto[] */
8function productoConsulta(): array
9{
10 $con = Bd::getConexion();
11 $stmt = $con->query(
12 "SELECT
13 PROD_ID as id,
14 PROD_NOMBRE as nombre,
15 PROD_PRECIO as precio,
16 PROD_EXISTENCIAS as existencias
17 FROM PRODUCTO
18 ORDER BY PROD_NOMBRE"
19 );
20 $resultado = $stmt->fetchAll(
21 PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE,
22 Producto::class
23 );
24 return recibeFetchAll($resultado);
25}
26

11. srv / bd / productoCuenta.php

1<?php
2
3require_once __DIR__ . "/Bd.php";
4
5function productoCuenta(): false|int
6{
7 $con = Bd::getConexion();
8 $stmt = $con->query("SELECT COUNT(*) FROM PRODUCTO");
9 return $stmt->fetchColumn();
10}
11

12. srv / bd / ventaAgrega.php

1<?php
2
3require_once __DIR__ . "/../modelo/Venta.php";
4require_once __DIR__ . "/Bd.php";
5
6function ventaAgrega(Venta $modelo)
7{
8 $modelo->valida();
9 $con = Bd::getConexion();
10 $stmt = $con->prepare(
11 "INSERT INTO VENTA
12 (VENT_EN_CAPTURA)
13 VALUES
14 (:enCaptura)"
15 );
16 $stmt->execute(([":enCaptura" => $modelo->enCaptura]));
17 /* Si usas una secuencia para generar el id,
18 * pasa como parámetro de lastInsertId el
19 * nombre de dicha secuencia, debes
20 * ejecutarlo antes del INSERT y pasarle el
21 * id generado al SQL. */
22 $modelo->id = $con->lastInsertId();
23}
24

13. srv / bd / ventaCuenta.php

1<?php
2
3require_once __DIR__ . "/Bd.php";
4
5function ventaCuenta(): false|int
6{
7 $con = Bd::getConexion();
8 $stmt = $con->query("SELECT COUNT(*) FROM VENTA");
9 return $stmt->fetchColumn();
10}
11

14. srv / bd / ventaEnCapturaBusca.php

1<?php
2
3require_once __DIR__ . "/../modelo/Venta.php";
4require_once __DIR__ . "/Bd.php";
5require_once __DIR__ . "/detalleDeVentaConsulta.php";
6
7function ventaEnCapturaBusca()
8{
9 $con = Bd::getConexion();
10 $stmt = $con->query(
11 "SELECT VENT_ID as id
12 FROM VENTA
13 WHERE VENT_EN_CAPTURA = 1"
14 );
15 $stmt->setFetchMode(PDO::FETCH_OBJ);
16 $obj = $stmt->fetch();
17 if ($obj === false) {
18 return false;
19 } else {
20 $venta = new Venta(id: $obj->id, enCaptura: true);
21 $venta->detalles = detalleDeVentaConsulta($venta);
22 return $venta;
23 }
24}
25

15. srv / bd / ventaEnCapturaProcesa.php

1<?php
2
3require_once __DIR__ . "/../modelo/Venta.php";
4require_once __DIR__ . "/Bd.php";
5require_once __DIR__ . "/ventaEnCapturaBusca.php";
6require_once __DIR__ . "/ventaAgrega.php";
7
8function ventaEnCapturaProcesa()
9{
10 $con = Bd::getConexion();
11 $con->beginTransaction();
12 $modelo = ventaEnCapturaBusca();
13 if ($modelo === false)
14 throw new Exception("Venta no encontrada.");
15 $modelo->valida();
16 $detalles = $modelo->detalles;
17 $stmt = $con->prepare(
18 "UPDATE PRODUCTO
19 SET PROD_EXISTENCIAS = :existencias
20 WHERE PROD_ID = :prodId"
21 );
22 foreach ($detalles as $dtv) {
23 $producto = $dtv->producto;
24 $stmt->execute(([
25 ":prodId" => $producto->id,
26 ":existencias" => $producto->existencias - $dtv->cantidad
27 ]));
28 }
29 $stmt = $con->prepare(
30 "UPDATE VENTA
31 SET VENT_EN_CAPTURA = 0
32 WHERE VENT_ID = :id"
33 );
34 $stmt->execute([":id" => $modelo->id]);
35 ventaAgrega(new Venta(enCaptura: true));
36 $con->commit();
37}
38