ref #3 Casi terminado el proceso de importación de datos, incluida la gestión de transacciones. Falta mostrar progreso de la importación o no.

This commit is contained in:
2014-02-24 00:11:41 +01:00
parent 37a2afa9f4
commit 8392f5bfad
8 changed files with 224 additions and 108 deletions

220
Csv.php
View File

@@ -48,6 +48,16 @@ class Csv {
*/ */
private $numRegistros; private $numRegistros;
/**
* @var array Cabecera del archivo csv
*/
private $cabecera;
/**
* @var array los datos del fichero csv en memoria
*/
private $datosFichero;
/** /**
// El constructor necesita saber cuál es la opción actual // El constructor necesita saber cuál es la opción actual
/** /**
@@ -75,6 +85,10 @@ class Csv {
fputcsv($this->fichero, $datos, ',', '"') or die("No puedo escribir en el fichero csv"); fputcsv($this->fichero, $datos, ',', '"') or die("No puedo escribir en el fichero csv");
} }
public function __destruct() {
$this->cierra();
}
public function cierra() { public function cierra() {
fclose($this->fichero) or die("No puedo cerrar el archivo csv"); fclose($this->fichero) or die("No puedo cerrar el archivo csv");
} }
@@ -86,7 +100,7 @@ class Csv {
public function ejecutaConsulta($fichero) { public function ejecutaConsulta($fichero) {
$consulta = simplexml_load_file($fichero) or die("No puedo cargar el fichero xml " . $fichero . " al csv"); $consulta = simplexml_load_file($fichero) or die("No puedo cargar el fichero xml " . $fichero . " al csv");
// Escribe la cabecera del fichero // Escribe la cabecera del fichero
$this->escribeLinea(array($consulta->Pagina->Cabecera,$consulta->Titulo['id'],$consulta->Titulo['Texto'])); $this->escribeLinea(array($consulta->Pagina->Cabecera, $consulta->Titulo['id'], $consulta->Titulo['Texto']));
foreach ($consulta->Pagina->Cuerpo->Col as $campo) { foreach ($consulta->Pagina->Cuerpo->Col as $campo) {
$campos[] = utf8_decode($campo['Titulo']); $campos[] = utf8_decode($campo['Titulo']);
} }
@@ -101,48 +115,7 @@ class Csv {
$this->escribeLinea($campos); $this->escribeLinea($campos);
} }
} }
private function quitaComillas($dato) {
//return substr($dato, 1, -1);
return str_replace("\"", "", $dato);
}
/**
*
* @param String $ficheroCSV Nombre del archivo csv
*/
public function cargaCSV2($ficheroCSV) {
$this->nombre = $ficheroCSV;
$this->fichero = fopen($this->nombre, "r") or die('No puedo abrir el archivo ' . $this->nombre . " para lectura.");
$linea = fgets($this->fichero);
$datos = explode(",", $linea);
$cabecera = $this->quitaComillas($datos[0]);
$idCabecera = $this->quitaComillas($datos[1]);
\fgets($this->fichero);
$linea = fgets($this->fichero);
$linea = $this->quitaComillas($linea);
$linea = explode(",", $linea);
$linea = explode(" ", $linea[0]);
$archivo = trim($linea[2]);
$ficheroXML = "xml/inventario" . ucfirst($archivo) . "CSV.xml";
$consulta = simplexml_load_file($ficheroXML) or die("No puedo cargar el fichero xml " . $ficheroXML . " al cargar csv");
\fgets($this->fichero);
$lineas = 0; $datosFichero = array();
//var_dump($consulta);
while ($linea = fgets($this->fichero)) {
$datos = explode(",", $linea);
$i = 1;
$lineas++;
$datosFichero["Baja"][] = $this->quitaComillas($linea[0]);
foreach ($consulta->Pagina->Cuerpo->Col as $campo) {
$datosFichero[utf8_decode($campo['Titulo'])][] = $this->quitaComillas($datos[$i++]);
//echo "datosfichero"; var_dump($datosFichero);
//echo "campo=[$campo]";
}
$datosFichero["Cant Real"] = $linea[$i];
}
$this->numRegistros = $lineas;
return $this->Resumen($cabecera, $idCabecera, $archivo, $datosFichero, $consulta);
}
/** /**
* *
* @param String $ficheroCSV Nombre del archivo csv * @param String $ficheroCSV Nombre del archivo csv
@@ -154,34 +127,175 @@ class Csv {
while ($linea = fgetcsv($this->fichero)) { while ($linea = fgetcsv($this->fichero)) {
$datosFichero[] = $linea; $datosFichero[] = $linea;
} }
return $this->Resumen($cabecera, $idCabecera, $archivo, $datosFichero); $this->cabecera[] = $archivo;
$this->cabecera[] = $idCabecera;
$this->cabecera[] = $cabecera;
$this->datosFichero = $datosFichero;
} }
public function Resumen($cabecera, $idCabecera, $archivo, $datosFichero) { /**
* Muestra un resumen de los datos del fichero csv cargado por pantalla
*
*/
public function resumen() {
//$mensaje .= //$mensaje .=
$mensaje = "<center><h1>Archivo [inventario".utf8_decode($archivo)."]</h1>"; $mensaje = "<center><h1>Archivo [inventario" . utf8_decode($this->cabecera[0]) . "]</h1>";
$mensaje .= "<h2>id=[$idCabecera] Descripci&oacute;n=[".utf8_decode($cabecera)."]</h2><br>"; $mensaje .= "<h2>id=[" . $this->cabecera[1] . "] Descripci&oacute;n=[" . utf8_decode($this->cabecera[2]) . "]</h2><br>";
$mensaje .= '<table border=1 class="table table-striped table-bordered table-condensed table-hover"><theader>'; $mensaje .= '<table border=1 class="table table-striped table-bordered table-condensed table-hover"><theader>';
foreach ($datosFichero[0] as $campo) { foreach ($this->datosFichero[0] as $campo) {
$dato = $campo; $dato = $campo;
$mensaje .= "<th><b>$dato</b></th>"; $mensaje .= "<th><b>$dato</b></th>";
} }
$mensaje .= "<th><b>Acci&oacute;n</b></th>";
$mensaje .="</theader><tbody>"; $mensaje .="</theader><tbody>";
//echo "$mensaje contar Datosfichero=[".count($datosFichero)."]"; //echo "$mensaje contar Datosfichero=[".count($datosFichero)."]";
for ($i=1; $i < count($datosFichero); $i++) { try {
for ($i = 1; $i < count($this->datosFichero); $i++) {
$mensaje .= "<tr>"; $mensaje .= "<tr>";
foreach($datosFichero[$i] as $dato) { $primero = true;
$mensaje .= "<td>".$dato."</td>"; foreach ($this->datosFichero[$i] as $dato) {
if ($primero) {
$primero = false;
switch ($dato) {
case 'S': $estado = "-Baja-";
$color = "danger";
break;
case 'Alta': $estado = "-Alta-";
$color = "primary";
break;
case "N" : $estado = $this->compruebaCantidades($this->datosFichero[$i]);
if ($estado != 0) {
$color = "warning";
if ($estado > 0) {
$estado = "+".$estado;
} }
} else {
$estado = "igual";
$color = "info";
}
break;
default: throw new Exception("El archivo csv tiene un formato incorrecto.<br>Bajas=[$dato]");
}
}
$mensaje .= "<td>" . $dato . "</td>";
}
$mensaje .= '<td align="center"><label class="label label-' . $color . '">' . $estado . '</label></td>';
$mensaje .= "</tr>"; $mensaje .= "</tr>";
} }
} catch (Exception $e) {
$mensaje = "Se ha producido el error [" . $e->getMessage() . "]<br>NO se ha realizado ning&uacute;n cambio en la Base de Datos.";
return $mensaje;
}
$mensaje .= "</tbody></table></p><br>"; $mensaje .= "</tbody></table></p><br>";
$mensaje .= '<form method="post" name="Aceptar" action="index.php?Importacion&opc=Ejecutar"> $mensaje .= $this->panelMensaje('Si se produce cualquier error en el procesamiento del fichero, no se aplicar&aacute; ning&uacute;n cambio en la base de datos.');
<input type="button" name="Cancelar" value="Cancelar" onClick="location.href=' . "'index.php'" .'" class="btn btn-danger">
<input type="submit" name="Aceptar" value="Aceptar" class="btn btn-primary"></form></center>'; $mensaje .= '<form method="post" name="Aceptar" action="index.php?importacion&opc=ejecutar">
<input type="button" name="Cancelar" value="Cancelar" onClick="location.href=' . "'index.php'" . '" class="btn btn-danger">
<input type="submit" name="Aceptar" value="Aceptar" class="btn btn-primary">
<input type="hidden" name="ficheroCSV" value="' . $this->nombre . '">
</form></center>';
return $mensaje; return $mensaje;
} }
/**
*
* @param $array línea de datos del fichero csv para comprobar las cantidades si se han modificado o no
* @return string
*/
private function compruebaCantidades($datos) {
$ultimo = count($datos);
return $datos[$ultimo - 2] - $datos[$ultimo - 1];
}
private function panelMensaje($info) {
$mensaje = '<div class="panel panel-danger"><div class="panel-heading">';
$mensaje .= '<h3 class="panel-title">ATENCI&Oacute;N</h3></div>';
$mensaje .= '<div class="panel-body">';
$mensaje .= $info;
$mensaje .= '</div>';
$mensaje .= '</div>';
return $mensaje;
}
private function escribeFic($comando)
{
$fp = fopen("tmp/comandos","a");
fputs($fp,$comando);
fclose($fp);
}
private function bajaElemento($i)
{
$id = $this->datosFichero['idElem'][$i];
$comando = 'delete from Elementos where id="'.$id.'";';
$this->escribeFic($comando);
}
private function modificaElemento($i)
{
$id = $this->datosFichero['idElem'][$i];
$comando = 'update Elementos set Cantidad="'.$datosFichero['cantidadReal'][$i].'" where id="'.$id.'";';
$this->escribeFic($comando);
}
private function altaElemento($i)
{
if ($this->cabecera[0] == "Articulo") {
$idUbicacion = $this->datosFichero['idUbic'][$i];
$idArticulo = $this->cabecera[1];
} else {
$idUbicacion = $this->cabecera[1];
$idArticulo = $this->datosFichero['idArt'][$i];
}
$idArt = $datosFichero['idArt'][$i];
$comando = 'insert into Elementos () values (null,"'.$idArticulo.'","'.$idUbicacion.'","'.$this->datosFichero['N Serie'][$i]
.'",'.$this->datosFichero['Cant. Real'][$i].',"'.$this->datosFichero['Fecha C.'].'");';
$this->escribeFic($comando);
}
/**
* Procesa contra la base de datos todas las acciones del archivo
*/
public function ejecutaFichero() {
//Realiza una transacción para que no se ejecute parcialmente una actualización
try {
$this->bdd->comienzaTransaccion();
$campos = $this->datosFichero[0];
for ($i = 1; $i < count($this->datosFichero); $i++) {
switch ($this->datosFichero[$i][0]) {
case 'S':
$this->bajaElemento($i);
break;
case 'Alta':
$this->altaElemento($this->datosFichero[$i]);
break;
case 'N':
if ($this->compruebaCantidades($this->datosFichero[$i]) != 0) {
$this->modificaElemento($this->datosFichero[$i]);
}
break;
default: throw new Exception("Acci&oacute;n no reconocida en la importacion [" . $this->datosFichero[0] . "]");
}
}
} catch (Exception $e) {
$this->bdd->abortaTransaccion();
$mensaje = "Se ha producido el error [" . $e->getMessage() . "]<br>NO se ha realizado ning&uacute;n cambio en la Base de Datos.";
return $this->panelMensaje($mensaje);
}
}
public function ejecutaFichero2() {
echo '<script>visualizaProgreso();</script>';
for ($i = 1; $i < 80; $i++) {
//sleep(1);
$progreso = $i;
echo '<script>actProgreso('.$progreso.');</script>';
//echo str_repeat(' ',1024*64);
flush();
//echo '$(".bar").css("width", "'.$progreso.'");';
}
}
} }
?> ?>

View File

@@ -31,11 +31,15 @@ class Importacion {
} }
public function ejecuta() { public function ejecuta() {
$opc = '';
if (isset($_GET['opc'])) {
$opc = $_GET['opc']; $opc = $_GET['opc'];
}
switch ($opc) { switch ($opc) {
case 'form':return $this->formulario(); case 'form':return $this->formulario();
case 'importar':return $this->importarFichero(); case 'importar':return $this->importarFichero();
case 'ejecutar':return "Ok"; case 'ejecutar':return $this->ejecutaFichero();
default: return "Importacion: No entiendo qué me has pedido.";
} }
} }
@@ -45,26 +49,35 @@ class Importacion {
die('No se pudo subir el fichero ' . $_FILES['userfile']['tmp_name']); die('No se pudo subir el fichero ' . $_FILES['userfile']['tmp_name']);
} }
$csv = new Csv($this->bdd); $csv = new Csv($this->bdd);
return $csv->cargaCSV($uploadfile); $csv->cargaCSV($uploadfile);
return $csv->resumen();
} }
private function formulario() { private function formulario() {
$accion = "index.php?importacion&opc=importar"; $accion = "index.php?importacion&opc=importar";
$salida = '<form enctype="multipart/form-data" name="importacion.form" method="post" action="' . $accion . '">' . "\n"; $salida = '<form enctype="multipart/form-data" name="importacion.form" method="post" action="' . $accion . '">' . "\n";
$salida .="<fieldset style=\"width: 96%;\"><p><legend style=\"color: red;\"><b>Elige Archivo</b></legend>\n"; $salida .= "<fieldset style=\"width: 96%;\"><p><legend style=\"color: red;\"><b>Elige Archivo</b></legend>\n";
$salida .= '<input type="file" name="fichero" id="fichero" onClick="seleccionFichero(this);">'; $salida .= '<input type="file" name="fichero" id="fichero" onChange="seleccionFichero(this);">';
$salida .='<p align="center"><button class="btn btn-primary" type=submit>Aceptar</button></p><br>' . "\n"; $salida .= '<p align="center"><button class="btn btn-primary" type=submit>Aceptar</button></p><br>' . "\n";
$salida .="<script type='text/javascript'> $mensaje = utf8_decode('Sólo se permiten archivos con extensión CSV');
$salida .= "<script type='text/javascript'>
function seleccionFichero(obj) { function seleccionFichero(obj) {
var filePath = obj.value; var filePath = obj.value;
var ext = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase(); var ext = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase();
if(ext != 'csv') { if(ext != 'csv') {
alert('S&oacute;lo se permiten archivos con extensi&oacute;n CSV'); alert('".$mensaje."');
} location.reload();
}}
</script>"; </script>";
return $salida; return $salida;
} }
private function ejecutaFichero() {
$archivo = $_POST['ficheroCSV'];
$csv = new Csv($this->bdd);
$csv->cargaCSV($archivo);
return $csv->ejecutaFichero();
}
} }
?> ?>

View File

@@ -150,7 +150,7 @@ class InformeInventario {
$salida.=$lista; $salida.=$lista;
$salida.="<br><br><label for='salida'>Salida del informe por:</label>"; $salida.="<br><br><label for='salida'>Salida del informe por:</label>";
$salida.='<div class="radio"><label><input type="radio" name="salida" value="pantalla" checked>Pantalla</label></div>'; $salida.='<div class="radio"><label><input type="radio" name="salida" value="pantalla" checked>Pantalla</label></div>';
$salida.='<div class="radio"><label><input type="radio" name="salida" value="Hoja de cálculo">Hoja de c&aacute;lculo</label></div>'; $salida.='<div class="radio"><label><input type="radio" name="salida" value="csv">Archivo CSV</label></div>';
$salida.="<br><br></fieldset><p>"; $salida.="<br><br></fieldset><p>";
$salida.='<p align="center"><button type=submit class="btn btn-primary">Aceptar</button></p><br></div>' . "\n"; $salida.='<p align="center"><button type=submit class="btn btn-primary">Aceptar</button></p><br></div>' . "\n";
return $salida; return $salida;

14
Sql.php
View File

@@ -193,6 +193,20 @@ class Sql {
{ {
return $this->bdd; return $this->bdd;
} }
public function comienzaTransaccion()
{
return $this->bdd->autocommit(false);
}
public function abortaTransaccion()
{
return $this->bdd->rollback();
}
public function finalizaTransaccion()
{
$codigo = $this->bdd->commit();
$this->bdd->autocommit(true);
return $codigo;
}
} }
?> ?>

View File

@@ -33,7 +33,7 @@
<a class="navbar-brand" href="index.php">{aplicacion}</a> <a class="navbar-brand" href="index.php">{aplicacion}</a>
</div> </div>
<div class="navbar-brand"> <div class="navbar-brand">
<span class="label label-primary">{opcion}</span> <span class="label label-primary col-sm-14 col-sm-offset-3">{opcion}</span>
<!--<label class="warn">{opcion}</label>--> <!--<label class="warn">{opcion}</label>-->
</div> </div>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
@@ -57,6 +57,23 @@
</div> </div>
<div class="col-sm-10 col-sm-offset-1 col-md-11 col-md-offset-1 main"> <div class="col-sm-10 col-sm-offset-1 col-md-11 col-md-offset-1 main">
<!--<h1 class="page-header">{opcion}</h1>--> <!--<h1 class="page-header">{opcion}</h1>-->
<div id="divBarra" class="progress progress-striped active">
<div class="progress-bar" id="barra" role="progressbar" aria-valuenow="0" aria-valuemin="40" aria-valuemax="100" style="width: 0%">
<span id="barra-valor">0% Completado</span>
</div>
</div>
<script>
function actProgreso(valor) {
$('.progress-bar').width(valor+"%")
$("#barra-valor").text(valor+"% Completado");
}
function visualizaProgreso() {
$('#divBarra').style.visibility = "visible";
}
function escondeProgreso() {
$('#divBara').style.visibility = "hidden";
}
</script>
{contenido} {contenido}
</div> </div>
</div> </div>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<Informe>
<Titulo Texto="Informe de Ubicaciones" />
<Datos>
<Consulta>select * from Ubicaciones order by Descripcion;</Consulta>
</Datos>
<Pagina Orientacion="P" Formato="A4">
<Cabecera>Relación alfabética</Cabecera>
<Cuerpo>
<Col Nombre="id" Ancho="10" Ajuste="D" Titulo="id"/>
<Col Nombre="Descripcion" Ancho="80" Ajuste="I" Titulo="Descripción"/>
</Cuerpo>
</Pagina>
</Informe>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<Informe>
<Titulo Texto="Informe de Ubicaciones" />
<Datos>
<Consulta>select * from Ubicaciones order by Descripcion;</Consulta>
</Datos>
<Pagina Orientacion="P" Formato="A4">
<Cabecera>Relación alfabética</Cabecera>
<Cuerpo>
<Col Nombre="id" Ancho="10" Ajuste="D" Titulo="id"/>
<Col Nombre="Descripcion" Ancho="80" Ajuste="I" Titulo="Descripción"/>
</Cuerpo>
</Pagina>
</Informe>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<Informe>
<Titulo Texto="Informe de Ubicaciones" />
<Datos>
<Consulta>select * from Ubicaciones order by Descripcion;</Consulta>
</Datos>
<Pagina Orientacion="P" Formato="A4">
<Cabecera>Relación alfabética</Cabecera>
<Cuerpo>
<Col Nombre="id" Ancho="10" Ajuste="D" Titulo="id"/>
<Col Nombre="Descripcion" Ancho="80" Ajuste="I" Titulo="Descripción"/>
</Cuerpo>
</Pagina>
</Informe>