Interfaces Complejas - Facturacion - Parte Ii
Interfaces Complejas - Facturacion - Parte Ii
Interfaces Complejas - Facturacion - Parte Ii
1 INFORMACIÓN GENERAL
Las interfaces complejas son aquellas donde se realizan múltiples procesos, y generalmente, se trabaja con
las funcionalidades principales de las aplicaciones.
En estas interfaces normalmente se tienen que utilizar múltiples clases y se requiere de una lógica completa
y compleja para lograr poner a funcionar el proceso.
En este documento se presentará la información para construir la clase de facturación y los eventos para
invocar la gestión de la factura. A continuación se presenta la página funcional.
Página Facturación
2 CLASE FACTURA
La clase de factura “clsFacturacion” debe modificar dos tablas: la tabla tblFactura y la tabla
tblDetalleFactura, en la primera se encuentra la información del encabezado de la factura: El cliente que
compra, el empleado que la atiende, la fecha y el número de la factura.
En la tabla de detalle se almacena la información del producto comprado, su cantidad y el valor unitario.
El valor unitario está tanto en la tabla tblProducto como en la tabla de detalle, esto se hace porque en la
tabla producto se almacena el valor unitario en tiempo real, es decir el valor en el momento de la compra,
pero en la tabla de detalle se debe almacenar siempre el valor unitario para poder garantizar que en
consultas históricas se pueda saber con qué precio se compró el producto.
Tablas Factura y Detalle
Tabla Producto
Todo el proceso se realiza en una sola clase “clsFacturacion” porque aunque en la base de datos las dos
tablas se encuentran separadas, esto se debe a que el SQL Server es una base de datos relacional, y los
atributos multi – valuados no se admiten, mientras que en las clases se pueden utilizar múltiples modelos
para poder implementar este proceso:
En nuestro caso utilizaremos la segunda forma porque es más simple y garantiza que todos los productos
que se graben se conserven, independiente si hay algún problema en la interfaz.
El primer método es más práctico cuando se quiere manejar el proceso de facturación como una
transacción, donde todo se ejecute o no se ejecute nada.
La clase factura utiliza las librerías comunes de datos y de objetos, la primera para modificar los datos en
las tablas, y la segunda para llenar el grid de la facturación.
Encabezado de la clase
using System;
using System.Web.UI.WebControls;
using libComunes.CapaDatos;
using libComunes.CapaObjetos;
La clase factura utiliza las librerías comunes de datos y de objetos, la primera para modificar los datos en
las tablas, y la segunda para llenar el grid de la facturación.
En el constructor se inicia el número de la factura en “0”, para garantizar que si no se recibe esta propiedad
se inicie en “0”.
4 MÉTODOS
El primer método público es “Grabar()”, el cual utiliza la propiedad de Número Factura para identificar si ya
se hizo la primera grabación o no. Si es la primera grabación se deben grabar en las dos tablas: tblFactura y
tblDetalleFactura.
Esto se hace al validar si el número de la factura es “0”, esto indica que es la primera vez que se graba, de
lo contrario sólo se graba en la tabla tblDetalleFactura.
Método Grabar
En este método se invoca adicionalmente el método de CalcularTotalFactura(), para que se pueda presentar
el total de la factura en la interfaz.
if (oConexion.EjecutarSentencia())
{
//La sentencia ejecutó correctamente y retornar true
return true;
}
else
{
//Hubo un error, se debe leer de la clase conexión y retornar false
Error = oConexion.Error;
return false;
}
}
else
{
return false;
}
}
Para grabar el encabezado, lo primero que se hace es consultar cuál es número de la factura
que se debe grabar, esto se hace calculando el máximo número de factura y sumándole 1, para
obtener la nueva factura:
La función “isnull”, permite identificar si no hay resultados, es decir si la tabla está vacía, por lo tanto el
valor será de 0, para que al sumarle 1, quede como la primera factura.
if (oConexion.Consultar())
{
if (oConexion.Reader.HasRows)
{
//Hay datos, se invoca el método Read, y se leen los datos
oConexion.Reader.Read();
NumeroFactura = oConexion.Reader.GetInt32(0);
oConexion.CerrarConexion();
oConexion = null;
return true;
}
else
{
Error = "No se pudo generar el número de factura";
oConexion.CerrarConexion();
oConexion = null;
return false;
}
}
else
{
oConexion.CerrarConexion();
oConexion = null;
return false;
}
}
if (oConexion.EjecutarSentencia())
{
//La sentencia ejecutó correctamente y retornar true
return true;
}
else
{
//Hubo un error, se debe leer de la clase conexión y retornar false
Error = oConexion.Error;
return false;
}
}
if (oConexion.Consultar())
{
if (oConexion.Reader.HasRows)
{
//Hay datos, se invoca el método Read, y se leen los datos
oConexion.Reader.Read();
TotalFactura = oConexion.Reader.GetInt32(0);
oConexion.CerrarConexion();
return true;
}
else
{
Error = "No se pudo generar el número de factura";
oConexion.CerrarConexion();
return false;
}
}
else
{
oConexion.CerrarConexion();
oConexion = null;
return false;
}
}
La consulta en SQL Server se debe hacer en una vista:
Los métodos de actualizar y eliminar detalle permiten modificar los productos grabados.
if (oConexion.EjecutarSentencia())
{
//La sentencia ejecutó correctamente y retornar true
if (CalcularTotalFactura())
{
return true;
}
else
{
return false;
}
}
else
{
//Hubo un error, se debe leer de la clase conexión y retornar false
Error = oConexion.Error;
return false;
}
}
if (oConexion.EjecutarSentencia())
{
//La sentencia ejecutó correctamente y retornar true
if (CalcularTotalFactura())
{
return true;
}
else
{
return false;
}
}
else
{
//Hubo un error, se debe leer de la clase conexión y retornar false
Error = oConexion.Error;
return false;
}
}
Al actualizar o eliminar siempre se debe invocar el método de CalcularTotalFactura(), porque hay una
modificación de los valores.
5 INTERFAZ FACTURACIÓN
La interfaz para invocar el proceso de grabación se maneja en los botones: “GRABAR”, “TERMINAR”,
“ACTUALIZAR” y “ELIMINAR”, así como el grid y el label de Total.
Después de llenar los datos básicos de la factura: Cliente, empleado, producto y cantidad se debe hacer clic
en el botón “GRABAR”, que permite ingresar un dato en la tabla Encabezado y en la de detalle.
El primer paso es validar si el label del número de factura está lleno o no, si no está lleno se define el número
de factura en 0, para que la clase entienda que se debe grabar en las dos tablas, de lo contrario para que
sólo grabe en la tabla de detalle.
Adicionalmente, se deben bloquear tanto el textbox de cédula, como el combo de empleado, para que
después de iniciar el proceso de grabación de la factura, no se haga un cambio de ninguno de estos
elementos.
Código Grabar
if (lblNumeroFactura.Text == "")
{
NumeroFactura = 0;
}
else
{
NumeroFactura = Convert.ToInt32(lblNumeroFactura.Text);
}
Empleado = Convert.ToInt32(cboEmpleado.SelectedValue);
Producto = Convert.ToInt32(cboProducto.SelectedValue);
Cantidad = Convert.ToInt32(txtCantidad.Text);
ValorUnitario = Convert.ToInt32(lblValor.Text);
DocumentoCliente = txtDocumento.Text;
FechaFactura = DateTime.Now;
oFactura.NumeroFactura = NumeroFactura;
oFactura.Empleado = Empleado;
oFactura.Producto = Producto;
oFactura.Cantidad = Cantidad;
oFactura.ValorUnitario = ValorUnitario;
oFactura.DocumentoCliente = DocumentoCliente;
oFactura.Fecha = FechaFactura;
if (oFactura.Grabar())
{
//LLena el número de factura y presenta el total
lblNumeroFactura.Text = oFactura.NumeroFactura.ToString();
lblTotal.Text = "$ " + oFactura.TotalFactura.ToString("#,###");
lblError.Text = "";
txtDocumento.Enabled = false;
cboEmpleado.Enabled = false;
//Llena el grid
LlenarGridFactura();
}
else
{
lblError.Text = oFactura.Error;
}
}
El proceso de “Terminar”, cierra la factura, que se refleja básicamente en borrar el número de factura, al
cliente y libera el combo de empleado, libera el textbox del documento de empleado, borra el total. Es
decir, limpia la información de la factura.
Código Terminar
Para la modificación de productos, se debe adicionar una columna Tipo “Select” en el grid.
En el evento del grid se captura la información del producto seleccionado, y adicionalmente se ocultan los
botones de “GRABAR” y de “TERMINAR”.
El código de los botones “ACTUALIZAR” y “ELIMINAR” sólo tienen la particularidad de ocultar los botones
de “ACTUALIZAR” y de “ELIMINAR” y de presentar lo botones de “GRABAR” y “TERMINAR”.
Código ACTUALIZAR
DetalleFactura = Convert.ToInt32(txtDetalleFactura.Text);
NumeroFactura = Convert.ToInt32(lblNumeroFactura.Text);
Producto = Convert.ToInt32(cboProducto.SelectedValue);
Cantidad = Convert.ToInt32(txtCantidad.Text);
ValorUnitario = Convert.ToInt32(lblValor.Text);
oFactura.Producto = Producto;
oFactura.Cantidad = Cantidad;
oFactura.ValorUnitario = ValorUnitario;
oFactura.CodigoDetalleFactura = DetalleFactura;
oFactura.NumeroFactura = NumeroFactura;
if (oFactura.ActualizarDetalleFactura())
{
//LLena el número de factura y presenta el total
lblTotal.Text = "$ " + oFactura.TotalFactura.ToString("#,###");
lblError.Text = "";
//Llena el grid
LlenarGridFactura();
//Oculta los botones de actualizar y eliminar y muestra los botones de
grabar y terminar
btnActualizar.Visible = false;
btnEliminar.Visible = false;
btnGrabar.Visible = true;
btnTerminar.Visible = true;
}
else
{
lblError.Text = oFactura.Error;
}
}
Código ELIMINAR
DetalleFactura = Convert.ToInt32(txtDetalleFactura.Text);
NumeroFactura = Convert.ToInt32(lblNumeroFactura.Text);
oFactura.CodigoDetalleFactura = DetalleFactura;
oFactura.NumeroFactura = NumeroFactura;
if (oFactura.EliminarDetalleFactura())
{
//LLena el número de factura y presenta el total
lblTotal.Text = "$ " + oFactura.TotalFactura.ToString("#,###");
lblError.Text = "";
//Llena el grid
LlenarGridFactura();
//Oculta los botones de actualizar y eliminar y muestra los botones de
grabar y terminar
btnActualizar.Visible = false;
btnEliminar.Visible = false;
btnGrabar.Visible = true;
btnTerminar.Visible = true;
}
else
{
lblError.Text = oFactura.Error;
}
oFactura = null;
}