Vous êtes sur la page 1sur 12

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 1

Aplicacin PHP-MVC para el manejo de gastos personales


1.
2.

El objetivo de esta prctica es crear una aplicacin web MVC con el lenguaje PHP para el manejo de gastos
personales (registro de facturas de gastos vlidas en Ecuador). Se requiere tener instalado el stack de aplicaciones
XAMPP.
El siguiente diseo muestra la arquitectura de la aplicacin:
ARQUITECTURA DEL SISTEMA PHP-MVC-CRUD

VIEW

CONTROLLER

MODEL

BDD

index.html

Pgina inicial, nicamente sirve de para


redireccionar a la pgina view/index.php

index.php

Pgina inicial para


presentacin facturas.

controller.php

Componente controlador que maneja la


navegacin entre pginas y la ejecucin
de la lgica del sistema.

GastosModel.php

Clase para el manejo de lgica de la


aplicacin. En este caso implementa las
operaciones
CRUD
utilizando
componentes PDO (PHP Data Objects).

Proveedor.php,
Factura.php

Clases que representan a la tablas de la


base de datos. Tambin se los llama
objetos de dominio o entidades.

Database.php

Manejo de conexiones con PDO (PHP


Data Objects).

MySQL

Tablas: proveedor, factura

el

ingreso

3. Mediante el administrador de la base de datos MySQL (phpMyAdmin) crear una nueva base de datos de nombre
anexogastos y dos nuevas tablas proveedor y factura (utilizar el script indicado):
CREATETABLEproveedor(
rucVARCHAR(13)PRIMARYKEYCOMMENT'Registrounicodecontribuyentes',
razon_socialVARCHAR(300)notnulluniqueKEYCOMMENT'Elnombredelproveedor'
)COMMENT'Tabladeproveedores.';
CREATETABLEfactura(
id_facturaintegerNOTNULLPRIMARYKEYAUTO_INCREMENTCOMMENT'Identificadorinternounicodelafactura.',
rucVARCHAR(13)NOTNULLCOMMENT'RUCdelproveedor.',
numero_facturaVARCHAR(17)NOTNULLCOMMENT'NumerodefacturaenformatoNNNNNNNNNNNNNNN.',
fecha_emisionDATENOTNULLCOMMENT'Fechadeemisiondelafactura.',
valor_baseFLOATNOTNULLCOMMENT'Valorendolaresdelabasedelafactura.'
)COMMENT='Tabladeregistrodefacturasdegasto.';
ALTERTABLEfacturaADDCONSTRAINTfact_prov_fkFOREIGNKEY(ruc)
REFERENCESanexogastos.proveedor(ruc)ONDELETERESTRICTONUPDATERESTRICT;
INSERTINTOproveedor(ruc,razon_social)VALUES('1006598457001','SupermercadoLaVecina');
INSERTINTOproveedor(ruc,razon_social)VALUES('1008574854001','FarmaciaElSano');
INSERTINTOproveedor(ruc,razon_social)VALUES('1007845124001','ModasRosita');
INSERTINTOfactura(ruc,numero_factura,fecha_emision,valor_base)VALUES('1006598457001','001001000004566'
,'2015/02/17',103.45);
INSERTINTOfactura(ruc,numero_factura,fecha_emision,valor_base)VALUES('1006598457001','001001000004567'
,'2015/02/18',215.23);
INSERTINTOfactura(ruc,numero_factura,fecha_emision,valor_base)VALUES('1008574854001','006003000012745'
,'2015/01/10',45.03);

Prctica: Anexo de gastos personales

4. Luego en el IDE Netbeans, creamos un nuevo proyecto PHP anexogastos:

mrea@utn.edu.ec 2

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 3

5. Para organizar los componentes de la aplicacin, creamos las carpetas model, view y controller y tambin movemos
la pgina index.php que fue creada por el asistente hacia la carpeta view. Tenemos el proyecto as:

6. Creamos una nueva pgina index.html en la raz del proyecto, nos servir nicamente para redireccionar la
navegacin hacia la pgina view/index.php:
index.html:
<!DOCTYPEhtml>
<html>
<head>
<title>anexogastos</title>
<metacharset="UTF8">
<metahttpequiv="refresh"content="0;url=view/index.php"/>
</head>
<body>
</body>
</html>

7.

El proyecto debera verse as:

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 4

8. Iniciamos la implementacin de la capa modelo. Creamos una nueva clase PHP llamada Database. Esta clase
mantendr los mtodos necesarios para manejar la conexin a la base de datos. Para optimizar este recurso, utiliza el
patrn de diseo singleton, que asegura que se mantenga una sola conexin en las transacciones. Crear una nueva
clase PHP en el archivo Database.php y que deber almacenarse en la carpeta model:
model/Database.php:
<?php
/**
*Claseutilitariaquemanejalaconexion/desconexionalabasededatos
*mediantelasfuncionesPDO(PHPDataObjects).
*Utilizaelpatrondedisenosingletonparaelmanejodelaconexion.
*@authormrea
*/
classDatabase{
//Propiedadesestaticasconlainformaciondelaconexion(DSN):
privatestatic$dbName='productos';
privatestatic$dbHost='localhost';
privatestatic$dbUsername='root';
privatestatic$dbUserPassword='';
//Propiedadparacontroldelaconexion:
privatestatic$conexion=null;
/**
*Nosepermiteinstanciarestaclase,seutilizansuselementos
*detipoestatico.
*/
publicfunction__construct(){
exit('Nosepermiteinstanciarestaclase.');
}
/**
*Metodoestaticoquecreaunaconexionalabasededatos.
*@returntype
*/
publicstaticfunctionconnect(){
//Unasolaconexionparatodalaaplicacion(singleton):
if(null==self::$conexion){
try{
self::$conexion=newPDO("mysql:host=".self::$dbHost.";"."dbname=".self::
$dbName,self::$dbUsername,self::$dbUserPassword);
}catch(PDOException$e){
die($e>getMessage());
}
}
returnself::$conexion;
}
/**
*Metodoestaticoparadesconexiondelabdd.
*/
publicstaticfunctiondisconnect(){
self::$conexion=null;
}
}
?>

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 5

9. Dentro del mismo model creamos las clases Proveedor y Factura (objetos de dominio) que representan a las tablas
proveedor y factura . Estas clases tendrn tantas propiedades como campos tenga las tablas:
model/Proveedor.php:
<?php
/**
*ClaseProveedor
*@authormrea
*/
classProveedor{
private$ruc;
private$razonSocial;

function__construct($ruc,$razonSocial){
$this>ruc=$ruc;
$this>razonSocial=$razonSocial;
}
publicfunctiongetRuc(){
return$this>ruc;
}
publicfunctiongetRazonSocial(){
return$this>razonSocial;
}
publicfunctionsetRuc($ruc){
$this>ruc=$ruc;
}
publicfunctionsetRazonSocial($razonSocial){
$this>razonSocial=$razonSocial;
}
}

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 6

model/Factura.php:
<?php
/**
*ClaseFactura
*@authormrea
*/
classFactura{
private$idFactura;
private$ruc;
private$numeroFactura;
private$fechaEmision;
private$valorBase;
function__construct($idFactura,$ruc,$numeroFactura,$fechaEmision,$valorBase){
$this>idFactura=$idFactura;
$this>ruc=$ruc;
$this>numeroFactura=$numeroFactura;
$this>fechaEmision=$fechaEmision;
$this>valorBase=$valorBase;
}
publicfunctiongetIdFactura(){
return$this>idFactura;
}
publicfunctiongetRuc(){
return$this>ruc;
}
publicfunctiongetNumeroFactura(){
return$this>numeroFactura;
}
publicfunctiongetFechaEmision(){
return$this>fechaEmision;
}
publicfunctiongetValorBase(){
return$this>valorBase;
}
publicfunctionsetIdFactura($idFactura){
$this>idFactura=$idFactura;
}
publicfunctionsetRuc($ruc){
$this>ruc=$ruc;
}
publicfunctionsetNumeroFactura($numeroFactura){
$this>numeroFactura=$numeroFactura;
}
publicfunctionsetFechaEmision($fechaEmision){
$this>fechaEmision=$fechaEmision;
}
publicfunctionsetValorBase($valorBase){
$this>valorBase=$valorBase;
}
}

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 7

10. La lgica de la aplicacin la implementamos en la clase GastosModel. Esta clase se encarga de las funciones CRUD
del sistema (Create,Read,Update,Delete) con la base de datos. Adicionalmente, se encarga de transformar los registros
de la bdd a objetos (Proveedor y Factura) y viceversa. Esto permite que luego en la capa de la vista, se mantenga un
modelo uniforme de informacin. Inicialmente la clase GastosModel implementa una funcin de consulta de facturas
para posteriormente poder visualizar la informacin en la vista:
model/GastosModel.php:
<?php
include'Database.php';
include'Proveedor.php';
include'Factura.php';
/**
*ObjetodenegocioGastosModel.ImplementafuncionesCRUD
*yvariasfuncionesdenegociodelaaplicacionAnexode
*gastospersonales.
*
*@authormrea
*/
classGastosModel{
/**
*Retornalalistadefacturasdelabdd.
*@returnarray
*/
publicfunctiongetFacturas(){
//obtenemoslainformaciondelabdd:
$pdo=Database::connect();
$sql="select*fromfacturaorderbyid_facturadesc";
$resultado=$pdo>query($sql);
//transformamoslosregistrosenobjetosdetipoFactura:
$listado=array();
foreach($resultadoas$res){
$factura=newFactura($res['id_factura'],$res['ruc'],$res['numero_factura'],$res['fecha_emision'],
$res['valor_base']);
array_push($listado,$factura);
}
Database::disconnect();
//retornamosellistadoresultante:
return$listado;
}
}

11. La siguiente es la capa de controladores. El controlador tiene la funcin de administrar la navegacin entre pginas, al
mismo tiempo que invoca a la capa de lgica (modelo). Mantiene la informacin disponible para la capa de la vista
mediante el uso de sesiones (session). Implementamos el componente controller.php en la carpeta controller:

controller/controller.php:

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 8

<?php
///////////////////////////////////////////////////////////////////////
//Componentecontrollerqueverificalaopcionseleccionada
//porelusuario,ejecutaelmodeloyenrutalanavegaciondepaginas.
///////////////////////////////////////////////////////////////////////
require_once'../model/GastosModel.php';
session_start();
$gastosModel=newGastosModel();
//recibimoslaopciondesdelavista:
$opcion=$_REQUEST['opcion'];
switch($opcion){
case"listar":
//obtenemoslalistadefacturas:
$listado=$gastosModel>getFacturas();
//ylosguardamosensesion:
$_SESSION['listado']=serialize($listado);
//redireccionamosalapaginaindexparavisualizar:
header('Location:../view/index.php');
break;
default:
//sinoexistelaopcionrecibidaporelcontrolador,siempre
//redirigimoslanavegacionalapaginaindex:
header('Location:../view/index.php');
}

12. Finalmente en la capa de la vista creamos la pgina view/index.php. Esta pgina se encargar de implementar la
visualizacin de datos, botones y enlaces (links) de opciones y el formulario donde el usuario pueda ingresar
informacin de nuevas facturas. La manera en que estas pginas interactan con el controlador es mediante controles
de tipo hidden que indican la opcin seleccionada por el usuario (en los formularios) o mediante enlaces generados
dinmicamente (<a href>) que permiten que un usuario seleccione una factura determinada para eliminarla por
ejemplo. A continuacin el cdigo de la pgina:
view/index.php:
<!DOCTYPEhtml>
<?php
session_start();
include'../model/Factura.php';
?>
<html>
<head>
<metacharset="UTF8">
<title>Anexodegastospersonales</title>
</head>
<body>
<table>
<tr><td><formaction="../controller/controller.php">
<inputtype="hidden"name="opcion"value="listar">
<inputtype="submit"value="Consultarlistado">
</form></td></tr>
</table>
<tableborder="1">
<tr>
<th>ID_FACT</th>
<th>RUC</th>
<th>NUM_FACTURA</th>
<th>FECHAEMISION</th>
<th>VALORBASE</th>
</tr>
<?php
//verificamossiexisteensesionellistadodefacturas:
if(isset($_SESSION['listado'])){
$listado=unserialize($_SESSION['listado']);
foreach($listadoas$fact){
echo"<tr>";
echo"<td>".$fact>getIdFactura()."</td>";
echo"<td>".$fact>getRuc()."</td>";
echo"<td>".$fact>getNumeroFactura()."</td>";
echo"<td>".$fact>getFechaEmision()."</td>";
echo"<td>".$fact>getValorBase()."</td>";
echo"</tr>";
}
}else{
echo"Nosehancargadodatos.";
}
?>
</table>
</body>
</html>

13. Ejecutamos la pgina index.html:

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 9

14. Requerimiento: ajustar la fecha de emisin al centro y el valor base hacia la derecha.
15. Ahora adicionamos la funcionalidad para ingresar nuevas facturas. Primero incrementamos el mtodo necesario en
GastosModel:
model/GastosModel.php:
<?php
include'Database.php';
include'Proveedor.php';
include'Factura.php';
/**
*ObjetodenegocioGastosModel.ImplementafuncionesCRUD
*yvariasfuncionesdenegociodelaaplicacionAnexode
*gastospersonales.
*
*@authormrea
*/
classGastosModel{
/**
*Retornalalistadefacturasdelabdd.
*@returnarray
*/
publicfunctiongetFacturas(){
...
}
/**
*Insertaunanuevafacturaenlabdd.
*@paramtype$rucRUCdelproveedor.
*@paramtype$numeroFacturaNumerodefactura.
*@paramtype$fechaEmisionLafechadeemision.
*@paramtype$valorBaseElvalorbasedelafactura.
*@throwsException
*/
publicfunctioninsertarFactura($ruc,$numeroFactura,$fechaEmision,$valorBase){
$pdo=Database::connect();
$sql="insertintofactura(ruc,numero_factura,fecha_emision,valor_base)values(?,?,?,?)";
$consulta=$pdo>prepare($sql);
//Ejecutamosypasamoslosparametros:
try{
$consulta>execute(array($ruc,$numeroFactura,$fechaEmision,$valorBase));
}catch(PDOException$e){
Database::disconnect();
thrownewException($e>getMessage());
}
Database::disconnect();
}
}

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 10

16. Creamos la opcin en el controlador:


controller/controller.php:
<?php
///////////////////////////////////////////////////////////////////////
//Componentecontrollerqueverificalaopcionseleccionada
//porelusuario,ejecutaelmodeloyenrutalanavegaciondepaginas.
///////////////////////////////////////////////////////////////////////
require_once'../model/GastosModel.php';
session_start();
$gastosModel=newGastosModel();
//recibimoslaopciondesdelavista:
$opcion=$_REQUEST['opcion'];
switch($opcion){
case"listar":
//obtenemoslalistadefacturas:
$listado=$gastosModel>getFacturas();
//ylosguardamosensesion:
$_SESSION['listado']=serialize($listado);
//redireccionamosalapaginaindexparavisualizar:
header('Location:../view/index.php');
break;
case"insertar":
//obtenemoslosparametrosdelformulario:
$ruc=$_REQUEST['ruc'];
$numeroFactura=$_REQUEST['numeroFactura'];
$fechaEmision=$_REQUEST['fechaEmision'];
$valorBase=$_REQUEST['valorBase'];
$gastosModel>insertarFactura($ruc,$numeroFactura,$fechaEmision,$valorBase);
//actualizamoslistadefacturas:
$listado=$gastosModel>getFacturas();
$_SESSION['listado']=serialize($listado);
header('Location:../view/index.php');
break;
default:
//sinoexistelaopcionrecibidaporelcontrolador,siempre
//redirigimoslanavegacionalapaginaindex:
header('Location:../view/index.php');
}

17. Finalmente adicionamos el formulario en la vista:


view/index.php:
<!DOCTYPEhtml>
<?php
session_start();
include'../model/Factura.php';
?>
<html>
<head>
<metacharset="UTF8">
<title>Anexodegastospersonales</title>
</head>
<body>
<formaction="../controller/controller.php">
<inputtype="hidden"name="opcion"value="insertar">
<table>
<tr>
<td>RUC</td>
<td><inputtype="text"name="ruc"size="13"maxlength="13"></td>
</tr>
<tr>
<td>NUM.FACTURA</td>
<td><inputtype="text"name="numeroFactura"size="17"maxlength="17">(NNNNNNNNNNNNNNN)</td>
</tr>
<tr>
<td>FECHAEMISION</td>
<td><inputtype="text"name="fechaEmision"size="10"maxlength="10">(yyyy/mm/dd)</td>
</tr>
<tr>
<td>VALORBASE</td>
<td><inputtype="text"name="valorBase"></td>
</tr>
<tr><td><inputtype="submit"value="Insertarnuevafactura"></td></tr>
</table>
</form>
<table>
<tr><td><formaction="../controller/controller.php">
<inputtype="hidden"name="opcion"value="listar">
<inputtype="submit"value="Consultarlistado">
.......
</html>

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 11

18. Ejecutamos e ingresamos varias facturas nuevas, se debe tener precaucin y utilizar nicamente nmeros de RUC que
existan en la base de datos:

19. Requerimiento: Establecer los cuatro campos como obligatorios mediante HTML5.
20. Creacin de una lista de opciones. En lugar de solicitar al usuario en un cuadro de texto abierto el RUC del proveedor,
podemos crear una lista dinmica de opciones con la informacin de la tabla proveedores. Para ello creamos el
respectivo mtodo en el GastosModel para obtener el listado de proveedores:
model/GastosModel.php:
/**
*Obtieneunalistadetodoslosproveedores.
*@returnarray
*/
publicfunctiongetProveedores(){
//obtenemoslainformaciondelabdd:
$pdo=Database::connect();
$sql="select*fromproveedororderbyrazon_social";
$resultado=$pdo>query($sql);
//transformamoslosregistrosenobjetosdetipoProveedor:
$listado=array();
foreach($resultadoas$res){
$proveedor=newProveedor($res['ruc'],$res['razon_social']);
array_push($listado,$proveedor);
}
Database::disconnect();
//retornamosellistadoresultante:
return$listado;
}

Prctica: Anexo de gastos personales

mrea@utn.edu.ec 12

21. En este caso, vamos a prescindir del controller, y directamente desde la vista accedemos a GastosModel para obtener
la lista de proveedores y crear la lista (ntese que ahora los archivos de clases son incluidos con include_once para
evitar problemas de compilacin duplicada):
view/index.php:
<!DOCTYPEhtml>
<?php
session_start();
include_once'../model/Factura.php';
include_once'../model/Proveedor.php';
include_once'../model/GastosModel.php';
?>
<html>
<head>
<metacharset="UTF8">
<title>Anexodegastospersonales</title>
</head>
<body>
<formaction="../controller/controller.php">
<inputtype="hidden"name="opcion"value="insertar">
<table>
<tr>
<td>RUC</td>
<td>
<selectname="ruc">
<?php
$gastosModel=newGastosModel();
$listado=$gastosModel>getProveedores();
foreach($listadoas$prov){
echo"<optionvalue='".$prov>getRuc()."'>".$prov>getRazonSocial()."</option>";
}
?>
</select>
</td>
</tr>
<tr>
<td>NUM.FACTURA</td>
<td>
<inputtype="text"name="numeroFactura"size="17"maxlength="17"required="true">
(NNNNNNNNNNNNNNN)
</td>
</tr>

......

22. Ejecutamos la pgina index.php:

23. Requerimiento: Adicionar la opcin de eliminar una factura especfica (mediante enlaces dinmicos).
24. Requerimiento: Implementar la funcionalidad necesaria para que el sistema no permita ingresar dos veces la misma
factura de un proveedor.

Vous aimerez peut-être aussi