domingo, marzo 06, 2011

PHP - Carrito de Compras Parte II - Creación de la Capa de Datos


"Si usa algún código del siguiente tutorial, den el icono de ME GUSTA del Facebook que se encuentra en su mano derecha, para que se vuelva Seguidor del Blog y también comentenos que tal les pareció el tutorial"


1. Entorno


  • NetBeans IDE 6.9.1
  • WampServer 2.1.

2. Introducción


2.1. Programación por capas

La programación por capas es un estilo de programación en el que el objetivo primordial es la separación de la lógica de negocios de la lógica de diseño. La ventaja principal de este estilo es que el desarrollo se puede llevar a cabo en varios niveles y, en caso de que sobrevenga algún cambio, sólo se ataca al nivel requerido sin tener que revisar entre código mezclado. Un buen ejemplo de este método de programación sería el modelo de interconexión de sistemas abiertos

2.2. Programación en tres capas

  • Capa de presentación: es la que ve el usuario (también se la denomina "capa de usuario"), presenta el sistema al usuario, le comunica la información y captura la información del usuario en un mínimo de proceso (realiza un filtrado previo para comprobar que no hay errores de formato). Esta capa se comunica únicamente con la capa de negocio. También es conocida como interfaz gráfica y debe tener la característica de ser "amigable" (entendible y fácil de usar) para el usuario.
  • Capa de negocio: es donde residen los programas que se ejecutan, se reciben las peticiones del usuario y se envían las respuestas tras el proceso. Se denomina capa de negocio (e incluso de lógica del negocio) porque es aquí donde se establecen todas las reglas que deben cumplirse. Esta capa se comunica con la capa de presentación, para recibir las solicitudes y presentar los resultados, y con la capa de datos, para solicitar al gestor de base de datos para almacenar o recuperar datos de él. También se consideran aquí los programas de aplicación.
  • Capa de datos: es donde residen los datos y es la encargada de acceder a los mismos. Está formada por uno o más gestores de bases de datos que realizan todo el almacenamiento de datos, reciben solicitudes de almacenamiento o recuperación de información desde la capa de negocio.

3. Desarrollo


3.1. Creando el Proyecto

Primero debemos de crear un proyecto en Netbeans 6.9.1., para eso abrimos el Netbeans y nos vamos al menú de "File-->New Proyect" y escogemos una aplicación PHP.














A nuestro proyecto lo llamaremos "CarritoCompras"














Y hacemos que se cree una copia de nuestro proyecto en la carpeta "WWW" del WampServer y presionamos el botón "Finish".













Y finalmente creamos una carpeta que se llamara "CapaDatos"

















3.2. La clase Conexion

Para agregar una clase en PHP debemos hacer clic derecho en la carpeta "CapaDatos" que hemos creado y nos vamos a la opción "New->PHP Class" y a nuestra clase lo llamamos "Conexion.php"

















Su código fuente seria el siguiente:

<?php
class Conexion {
    var $BaseDatos;
    var $Servidor;
    var $Usuario;
    var $Clave;
    var $Conexion_ID;
    var $Consulta_ID;
    var $Errno = 0;
    var $Error = "";
    //Constructor de la clase Conexion
    function  Conexion() {
        $this->BaseDatos = "bdtutorial";
        $this->Servidor = "localhost";
        $this->Usuario = "root";
        $this->Clave = "";
    }
    //Metodo para conectarnos a la base de datos
    function conectar() {
        $this->Conexion_ID = mysql_connect($this->Servidor, $this->Usuario, $this->Clave);
        if (!$this->Conexion_ID) {
            $this->Error = "Ha fallado la conexion.";
            return 0;
        }

        if (!@mysql_select_db($this->BaseDatos, $this->Conexion_ID)) {
            $this->Error = "Imposible abrir " . $this->BaseDatos;
            return 0;
        }
        return $this->Conexion_ID;
    }
}

?>

3.3. La clase Producto

Esta clase se encarga de conectar la clase Producto con MySQL

<?php
include_once("Conexion.php");
//Declaracion
class Producto {
    //Variable de la clase
    private $codigoProducto;
    private $nombre;
    private $precio;
    //Metodo utilizado para obtener el codigo siguiente del producto
    function codigoSiguiente($cn) {
        $cod = 0;
        $sql = "SELECT IFNULL(MAX(codigoProducto),0)+1 as codigo FROM Producto";
        try {
            $result = mysql_query($sql, $cn);
            $registros = array();
            while ($reg = mysql_fetch_array($result)) {
                $cod = $reg['codigo'];
                break;
            }
        } catch (exception $e) {

        }
        return $cod;
    }
    //Metodo utilizado para insertar un producto a la base de datos
    function insertarProducto() {
        $rpta;
        try {
            //Creamos un objeto de la clase conexion
            $miconexion = new Conexion();
            //Obtenemos la conexion
            $cn = $miconexion->conectar();
            //Comenzamos la transaccion
            mysql_query("BEGIN", $cn);
            //Obtenemos el codigo del siguiente producto
            $this->codigoProducto =$this->codigoSiguiente($cn);
            //Elaboramos la sentencia
            $sql = "INSERT INTO Producto VALUES($this->codigoProducto,'$this->nombre',$this->precio)";
            //Ejecutamos la sentencia
            $result = mysql_query($sql, $cn);
            if (!$result) {
                //Si no obtiene resultados anulamos la transaccion
                mysql_query("ROLLBACK", $cn);
                $rpta = false;
            } else {
                //Si obtiene resultados confirmamos la transaccion
                mysql_query("COMMIT", $cn);
                $rpta = true;
            }
            //Cerramos la conexion
            mysql_close($cn);
        } catch (exception $e) {
            try {
                mysql_query("ROLLBACK", $cn);
            } catch (exception $e1) {

            }
            try {
                mysql_close($cn);
            } catch (exception $e1) {

            }
            $rpta = false;
        }
        return $rpta;
    }
    //Metodo utilizado para actualizar un producto
    function actualizarProducto() {
        $rpta;
        try {
            //Creamos un objeto de la clase conexion
            $miconexion = new Conexion();
            //Obtenemos la conexion
            $cn = $miconexion->conectar();
            //Comenzamos la transaccion
            mysql_query("BEGIN", $cn);
            //Elaboramos la sentencia
            $sql = "UPDATE Producto SET nombre='$this->nombre', precio=$this->precio WHERE codigoProducto=$this->codigoProducto";
            //Ejecutamos la sentencia
            $result = mysql_query($sql, $cn);
            $rpta;
            if (!$result) {
                //Si no obtiene resultados anulamos la transaccion
                mysql_query("ROLLBACK", $cn);
                $rpta = false;
            } else {
                //Si obtiene resultados confirmamos la transaccion
                mysql_query("COMMIT", $cn);
                $rpta = true;
            }
            //Cerramos la conexion
            mysql_close($cn);
        } catch (exception $e) {
            try {
                mysql_query("ROLLBACK", $cn);
            } catch (exception $e1) {

            }
            try {
                mysql_close($cn);
            } catch (exception $e1) {

            }
            $rpta = false;
        }
        return $rpta;
    }
    //Metodo utilizado para obtener un producto
    function buscarProducto() {
        //Le deciamos que la locacion es lenguaje español
        setlocale(LC_CTYPE, 'es');
        //La sentencia a ejecutar
        $sql = "SELECT * FROM Producto WHERE codigoProducto=$this->codigoProducto";
        try {
            //Creamos un objeto de la clase conexion
            $miconexion = new Conexion();
            //Obtenemos la conexion
            $cn = $miconexion->conectar();
            //Ejecutamos la sentencia
            $rs = mysql_query($sql, $cn);
            //Creamos un array que almacenara los datos de la sentencia
            $registros = array();
            //Recorremos el resultado de la consulta y lo almacenamos en el array
            while ($reg = mysql_fetch_array($rs)) {
                array_push($registros, $reg);
            }
            //Liberamos recursos
            mysql_free_result($rs);
            mysql_close($cn);
        } catch (exception $e) {
            try {
                mysql_free_result($rs);
            } catch (exception $e) {

            }
            try {
                mysql_close($cn);
            } catch (exception $e) {

            }
        }
        return $registros;
    }
    //Metodo utilizado para obtener todos los productos
    function buscarProductoTodos() {
        //Le deciamos que la locacion es lenguaje español
        setlocale(LC_CTYPE, 'es');
        //La sentencia a ejecutar
        $sql = "SELECT * FROM Producto ORDER BY nombre";
        try {
            //Creamos un objeto de la clase conexion
            $miconexion = new Conexion();
            //Obtenemos la conexion
            $cn = $miconexion->conectar();
            //Ejecutamos la sentencia
            $rs = mysql_query($sql, $cn);
            //Creamos un array que almacenara los datos de la sentencia
            $registros = array();
            //Recorremos el resultado de la consulta y lo almacenamos en el array
            while ($reg = mysql_fetch_array($rs)) {
                array_push($registros, $reg);
            }
            //Liberamos recursos
            mysql_free_result($rs);
            mysql_close($cn);
        } catch (exception $e) {
            try {
                mysql_free_result($rs);
            } catch (exception $e) {

            }
            try {
                mysql_close($cn);
            } catch (exception $e) {

            }
        }
        return $registros;
    }
    //Get y Set de la clase
    function getCodigoProducto() {
        return $this->codigoProducto;
    }

    function getNombre() {
        return $this->nombre;
    }

    function getPrecio() {
        return $this->precio;
    }

    function setCodigoProducto($codigoProducto) {
        $this->codigoProducto = $codigoProducto;
    }

    function setNombre($nombre) {
        $this->nombre = $nombre;
    }

    function setPrecio($precio) {
        $this->precio = $precio;
    }
}
?>

3.4. Clase DetalleVenta

El código fuente de la clase seria el siguiente

<?php
include_once("Conexion.php");

class DetalleVenta {
    private $codigoVenta;
    private $codigoProducto;
    private $cantidad;
    private $descuento;
    //Metodo utilizado para insertar un detalle de venta a la base de datos
    //como variable pide la conexion que va a usar
    function insertarDetalleVenta($cn) {
        $rpta;
        try {
            //Elaboramos la sentencia
            $sql = "INSERT INTO DetalleVenta VALUES($this->codigoVenta, $this->codigoProducto,$this->cantidad,$this->descuento)";
            //Ejecutamos la sentencia
            $result = mysql_query($sql, $cn);
            if (!$result) {
                $rpta = false;
            } else {
                $rpta = true;
            }

        } catch (exception $e) {
            $rpta = false;
        }
        return $rpta;
    }

    function getCodigoVenta() {
        return $this->codigoVenta;
    }

    function getCodigoProducto() {
        return $this->codigoProducto;
    }

    function getCantidad() {
        return $this->cantidad;
    }
    function getDescuento() {
        return $this->descuento;
    }

    function setCodigoVenta($codigoVenta) {
        $this->codigoVenta= $codigoVenta;
    }

    function setCodigoProducto($codigoProducto) {
        $this->codigoProducto = $codigoProducto;
    }

    function setCantidad($cantidad) {
        $this->cantidad = $cantidad;
    }

    function setDescuento($descuento) {
        $this->descuento = $descuento;
    }
}
?>

3.5. Clase Venta

El código fuente de la clase Venta seria el siguiente

<?php
include_once("Conexion.php");
include_once("DetalleVenta.php");

class Venta {
    private $codigoVenta;
    private $cliente;
    private $fecha;
    private $detalleVenta;
    //Metodo utilizado para obtener el codigo siguiente del producto
    function codigoSiguiente($cn) {
        $cod = 0;
        $sql = "SELECT IFNULL(MAX(codigoVenta),0)+1 as codigo FROM Venta";
        try {
            $result = mysql_query($sql, $cn);
            $registros = array();
            while ($reg = mysql_fetch_array($result)) {
                $cod = $reg['codigo'];
                break;
            }
        } catch (exception $e) {

        }
        return $cod;
    }
    //Metodo utilizado para insertar una venta a la base de datos
    function insertarVenta() {
        $rpta;
        try {
            //Creamos un objeto de la clase conexion
            $miconexion = new Conexion();
            //Obtenemos la conexion
            $cn = $miconexion->conectar();
            //Comenzamos la transaccion
            mysql_query("BEGIN", $cn);
            //Obtenemos el codigo del siguiente producto
            $this->codigoVenta=$this->codigoSiguiente($cn);
            //Elaboramos la sentencia
            $sql = "INSERT INTO Venta VALUES($this->codigoVenta,'$this->cliente',CURDATE())";
            //Ejecutamos la sentencia
            $result = mysql_query($sql, $cn);
            if (!$result) {
                //Si no obtiene resultados anulamos la transaccion
                mysql_query("ROLLBACK", $cn);
                $rpta = false;
            } else {
                //Recorremos el detalle y lo insertamos
                foreach($this->detalleVenta as $k => $v){
                    $detalle=new DetalleVenta();
                    $detalle->setCodigoVenta($this->codigoVenta);
                    $detalle->setCodigoProducto($v['codigo']);
                    $detalle->setCantidad($v['cantidad']);
                    $detalle->setDescuento($v['descuento']);
                    $rpta=$detalle->insertarDetalleVenta($cn);
                    if(!$rpta){
                        break;
                    }
                }
                if($rpta){
                    //Confirmamos la transaccion si se registra todos los detalles
                    mysql_query("COMMIT", $cn);
                }else{
                    //Negamos al transaccion si no se registra algun detalle
                    mysql_query("ROLLBACK", $cn);
                }
            }
            //Cerramos la conexion
            mysql_close($cn);
        } catch (exception $e) {
            try {
                mysql_query("ROLLBACK", $cn);
            } catch (exception $e1) {

            }
            try {
                mysql_close($cn);
            } catch (exception $e1) {

            }
            $rpta = false;
        }
        return $rpta;
    }

     //Metodo utilizado para obtener un producto
    function buscarVenta() {
        //Le deciamos que la locacion es lenguaje español
        setlocale(LC_CTYPE, 'es');
        //La sentencia a ejecutar
        $sql="SELECT ";
        $sql.="v.codigoVenta AS CodigoVenta, ";
        $sql.="v.cliente AS Cliente, ";
        $sql.="v.fecha AS Fecha, ";
        $sql.="d.codigoProducto AS CodigoProducto, ";
        $sql.="p.nombre AS Nombre, ";
        $sql.="p.precio AS Precio, ";
        $sql.="d.cantidad AS Cantidad, ";
        $sql.="d.descuento AS Descuento, ";
        $sql.="p.precio*d.cantidad AS Parcial, ";
        $sql.="((p.precio*d.cantidad)-d.descuento) AS SubTotal, ";
        $sql.="( ";
        $sql.="SELECT ";
        $sql.="SUM((dT.cantidad * pT.precio)-dT.descuento) AS TotalPagar ";
        $sql.="FROM ";
        $sql.="DetalleVenta AS dT INNER JOIN ";
        $sql.="Producto AS pT ON dT.codigoProducto = pT.codigoProducto ";
        $sql.="WHERE ";
        $sql.="dT.codigoVenta=v.codigoVenta ";
        $sql.=") AS TotalPagar ";
        $sql.="FROM ";
        $sql.="Venta AS v INNER JOIN ";
        $sql.="DetalleVenta AS d ON v.codigoVenta = d.codigoVenta INNER JOIN ";
        $sql.="Producto AS p ON d.codigoProducto = p.codigoProducto ";
        $sql.="ORDER BY ";
        $sql.="CodigoVenta, Nombre";
        try {
            //Creamos un objeto de la clase conexion
            $miconexion = new Conexion();
            //Obtenemos la conexion
            $cn = $miconexion->conectar();
            //Ejecutamos la sentencia
            $rs = mysql_query($sql, $cn);
            //Creamos un array que almacenara los datos de la sentencia
            $registros = array();
            //Recorremos el resultado de la consulta y lo almacenamos en el array
            while ($reg = mysql_fetch_array($rs)) {
                array_push($registros, $reg);
            }
            //Liberamos recursos
            mysql_free_result($rs);
            mysql_close($cn);
        } catch (exception $e) {
            try {
                mysql_free_result($rs);
            } catch (exception $e) {

            }
            try {
                mysql_close($cn);
            } catch (exception $e) {

            }
        }
        return $registros;
    }

    function getCodigoVenta() {
        return $this->codigoVenta;
    }

    function getCliente() {
        return $this->cliente;
    }
 
    function getFecha() {
        return $this->fecha;
    }

    function getDetalleVenta() {
        return $this->detalleVenta;
    }

    function setCodigoVenta($codigoVenta) {
        $this->codigoProducto = $codigoVenta;
    }

    function setCliente($cliente) {
        $this->cliente = $cliente;
    }

    function setFecha($fecha) {
        $this->fecha = $fecha;
    }

    function setDetalleVenta($detalleVenta) {
        $this->detalleVenta = $detalleVenta;
    }
}

?>

4. Resumen


Al final deberíamos tener la siguiente estructura

4 comentarios:

Gracias por el tutorial esta muy bueno! :)

Amigo que excelente tutorial.
Saludos desde Venezuela.

Gracias Brother un abrazo