creación de un sistema de almacén con c#

61
Creación de un sistema de almacén con C# (Parte 1) Creación del Proyecto Nuestro proyecto lo realizaremos con Visual Studio 2010. También puede utilizarse Visual C# 2010 Express el cual puede descargarse desde la página: http://www.microsoft.com/visualstudio/en-us/products/2010- editions/visual-csharp-express 1. Creamos un nuevo proyecto: 2. Eliminamos el formulario y la clase: 3. Agregamos varias carpetas las cuales nos servirán para organizar nuestro proyecto:

Upload: florapatricia

Post on 03-Mar-2015

905 views

Category:

Documents


4 download

TRANSCRIPT

Creación de un sistema de almacén con C# (Parte 1)Creación del Proyecto

Nuestro proyecto lo realizaremos con Visual Studio 2010.

También puede utilizarse Visual C# 2010 Express el cual puede descargarse desde la página: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-csharp-express

1. Creamos un nuevo proyecto:

2. Eliminamos el formulario y la clase:

3. Agregamos varias carpetas las cuales nos servirán para organizar nuestro proyecto:

4. Ahora agregamos cinco formularios y una clase, así como se muestra en la figura:

Nota: Por favor ignorar la carpeta llamada "Turorial", es la que estoy utilizando para generar este documento.Una vez hecho esto, continuaremos con el diseño de la base de datos

Creación de un sistema de almacén con C# (Parte 2)

Creación de la Base de datos

Creamos una base de datos con Microsoft Access, con las siguientes tablas:

users

Nombre del Campo Tipo de Datos Descripción

user_login Texto(50) Nombre de inicio de sesión

user_password Texto(255) Contraseña del usuario

nombre Texto(255) Nombre del usuario

activo Si/No Si está activo

administrar Si/No Si puede administrar el sistema

reportes Si/No Si puede ver reportes

articulos

Nombre del Campo Tipo de Datos Descripción

id_articulo Texto(50) Id del artículo

articulo Texto(255) Nombre del artículo

localizacion Texto(255) Ubicación en el almacén

grupo Texto(255) Grupo del articulo

unidad_medida Texto(255) Unidad de medida

existencia Número(Doble) Existencia

cant_min Número(Doble) Existencia mínima

costo_promedio Número(Doble) Costo promedio

entradas

Nombre del Campo Tipo de Datos Descripción

id_entrada Autonumérico Id de la entrada

fecha_registro Fecha/Hora Fecha de registro en el sistema

fecha_entrada Fecha/Hora Fecha de la entrada en el almacen

proveedor Texto(255) Nombre del proveedor

folio_factura Texto(50) Folio de la factura de compra

fecha_factura Fecha/Hora Fecha de la factura

user_login Texto(50) Usuario que registra la entrada

entradas_detalle

Nombre del Campo Tipo de Datos Descripción

id_entrada_detalle Autonumérico Id del detalle de la entrada

id_entrada Número Id de la entrada

id_articulo Texto(50) Id del artículo

cantidad Número(Doble) Cantidad que entra al almacén

precio_compra Número(Doble) Precio de compra (segun factura)

iva Número(Doble)Impuesto que cobra el proveedor (en porcentaje)

salidas

Nombre del Campo Tipo de Datos Descripción

id_salida Autonumérico Id de la salida

fecha_registro Fecha/Hora Fecha de registro en el sistema

fecha_salida Fecha/Hora Fecha de la salida

responsable Texto(255) Responsable de la salida

user_login Texto(50) Usuario que registra la salida

salidas_detalle

Nombre del Campo Tipo de Datos Descripción

id_salida_detalle Autonumérico Id del detalle de la salida

id_salida Número Id de la salida

id_articulo Texto(50) Id del artículo

cantidad Número(Doble) Cantidad que sale

Una vez que diseñamos nuestras tablas, las relacionamos. Las relaciones deben de quedar

así:

Especificaciones técnicas:

Todos los nombres de los campos son con minúsculas. Esto no afecta en la

programación, pero deseamos poder llevar un estándar en todo lo que vayamos

desarrollando.

Deberá respetar los tipos de datos, eso nos evitará posibles errores en tiempo de

ejecución.

Creación de un sistema de almacén con C# (Parte 3)Entradas al Almacén

Diseño de la pantalla

Empezaremos diseñando la pantalla de entradas (formulario frmEntrada), la apariencia debe de

quedar mas o menos así:

A continuacion una tabla descriptiva con los nombres de los objetos:

Objeto Propiedad Valor

Label

Name lblFechaEntrada

Text Fecha Entrada:

DateTimePicker

Name dtpFechaEntrada

Format Custom

CustomFormatdd/MM/yyyy

Label

Name lblFechaFactura

Text Fecha Factura:

DateTimePicker

Name dtpFechaFactura

Format Custom

CustomFormatdd/MM/yyyy

Label

Name lblFolioFactura

Text Folio Factura:

TextBox Name txtFolioFactura

Label

Name lblNombreProveedor

Text Nombre del Proveedor:

TextBox Name txtNombreProveedor

Label

Name lblIdArticulo

Text Articulo:

TextBox Name txtIdArticulo

Label

Name lblCantidad

Text Cantidad:

TextBox Name txtCantidad

Label

Name lblPrecioCompra

Text Precio:

TextBox Name txtPrecioCompra

Button Name btnAgregar

Text Agregar

Button

Name btnGrabar

Text Grabar

Button

Name btnCancelar

Text Cancelar

ListView

Name lvEntrada

FullRowSelect True

GridLines True

HideSelection False

Programación

La parte de la programación es la mas enredada. Voy a considerar que el lector es un novato con

nociones bastante

básicas e insuficientes como para comprender la estructura de la programación C#. Recomiendo al

lector poner mucha atención

a los pasos que aqui se describan y no omitir nada, leer y re-leer hasta que haya comprendido

lo que tiene que hacer.

Comprendiendo el código de un formulario C#

Con mucho cuidado haremos doble clic sobre el formulario asegurándonos de no tocar con el

puntero del mouse ningun objeto. Veremos un código

muy parecido al siguiente:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace almacen.Formularios

{

public partial class frmEntrada : Form

{

public frmEntrada()

{

InitializeComponent();

}

private void frmEntrada_Load(object sender, EventArgs e)

{

}

}

}

A continuación incluiré comentarios en esta misma porción de código con la finalidad de que

podamos identificar claramente

su organización:

/**

* Aqui se agrupan los espacios de nombres

* Son necesarios para facilitarnos el acceso

* a ciertas librerias o DLLs

*/

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

//Aqui inicia nuestro espacio de nombres

namespace almacen.Formularios

{

//aqui inicia la clase

public partial class frmEntrada : Form

{

//este es el constructor predeterminado

public frmEntrada()

{

InitializeComponent();

}

//Aqui declararemos nuestras variables

private void frmEntrada_Load(object sender, EventArgs e)

{

/**

* Aqui incia la ejecución del Formulario

*/

}

//Aqui se ubican los procedimientos y funciones

}

//Fin de la clase, normalmente no se utiliza

}

/**

* Fin del Espacio de Nombres

* Este espacio no lo utilizaremos,

* normalmente no se utiliza

*/

Así se organiza el código de un formulario C#. Debemos notar que todo inicia y termina con las

llaves { }, existen algunos casos en los que

puede omitirse el uso de las llaves, principalmente en las estructuras de desición if, pero

para este tutorial, me aseguraré de escribir tanto mucho o tanto poco (mucho o poco) código segun

sea necesario para evitar confusiones.

Ahora comenzaremos a programar, iniciamos nuestra tarea declarando todas las variables que

vamos a utilizar.

En la zona de declaraciones, declaramos las siguientes variables:

DataTable tmpEntrada = new DataTable();

string CnnStr = @" Provider=Microsoft.Jet.OLEDB.4.0; "+

"Data Source=D:\\DOCS\\tyrodeveloper\\almacen.mdb; "+

"Jet OLEDB:Database Password=; Persist Security Info=False;";

Ahora escribiremos el código de las funciones y procedimientos:

void generaColumnas()

{

lvEntrada.Clear();

lvEntrada.View = View.Details;

lvEntrada.Columns.Add("", 0, HorizontalAlignment.Left);

lvEntrada.Columns.Add("Id ", 100, HorizontalAlignment.Left);

lvEntrada.Columns.Add("Producto", 240, HorizontalAlignment.Left);

lvEntrada.Columns.Add("Cantidad", 60, HorizontalAlignment.Right);

lvEntrada.Columns.Add("Precio", 60, HorizontalAlignment.Right);

lvEntrada.Columns.Add("Total", 80, HorizontalAlignment.Right);

}

void mostrarEntrada()

{

try

{

double varIVA = 0;

double varTOTAL = 0;

lvEntrada.Items.Clear();

for (int i = 0; i < tmpEntrada.Rows.Count; i++)

{

lvEntrada.Items.Add(tmpEntrada.Rows[i]["id"].ToString());

lvEntrada.Items[i].SubItems.Add(tmpEntrada.Rows[i]

["id_articulo"].ToString());

lvEntrada.Items[i].SubItems.Add(tmpEntrada.Rows[i]

["articulo"].ToString());

lvEntrada.Items[i].SubItems.Add(String.Format("{0:N}",

Convert.ToDouble(tmpEntrada.Rows[i]["cantidad"])));

lvEntrada.Items[i].SubItems.Add(String.Format("{0:C}",

Convert.ToDouble(tmpEntrada.Rows[i]["precio_compra"])));

lvEntrada.Items[i].SubItems.Add(String.Format("{0:C}",

(Convert.ToDouble(tmpEntrada.Rows[i]["precio_compra"]) *

Convert.ToDouble(tmpEntrada.Rows[i]["cantidad"]))));

varTOTAL += Convert.ToDouble(tmpEntrada.Rows[i]

["precio_compra"]) *

Convert.ToDouble(tmpEntrada.Rows[i]["cantidad"]);

varIVA += (Convert.ToDouble(tmpEntrada.Rows[i]["cantidad"]) *

Convert.ToDouble(tmpEntrada.Rows[i]["precio_compra"])) -

((Convert.ToDouble(tmpEntrada.Rows[i]["cantidad"]) *

Convert.ToDouble(tmpEntrada.Rows[i]["precio_compra"])) /

(1.16));

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

bool agregarArticulo(string prmId, double prmCantidad, double

prmPrecioCompra, double prmIVA)

{

try

{

string varId = "";

string varNombre = "";

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

string strSQL="select articulo from articulos "+

"where id_articulo='"+ prmId +"'";

OleDbCommand cmd = new OleDbCommand(strSQL, cnn);

OleDbDataReader dr = cmd.ExecuteReader();

if (dr.Read())

{

varId = prmId;

varNombre = dr["articulo"].ToString(); ;

//agregamos la venta a la tabla temporal

DataRow row = tmpEntrada.NewRow();

row["id_articulo"] = varId;

row["articulo"] = varNombre;

row["cantidad"] = prmCantidad;

row["precio_compra"] = prmPrecioCompra;

row["iva"] = prmIVA;

tmpEntrada.Rows.Add(row);

}

else

{

MessageBox.Show("El articulo no existe", "Error",

MessageBoxButtons.OK, MessageBoxIcon.Error);

return (false);

}

dr.Close();

cnn.Close();

return (true);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

return (false);

}

}

bool grabarEntrada(string prmFechaEntrada, string prmFechaFactura, string

prmFolioFactura,

string prmNombreProveedor, string prmUserLogin)

{

try

{

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

OleDbTransaction tran = cnn.BeginTransaction();

OleDbCommand cmd = new OleDbCommand();

cmd.Connection = cnn;

cmd.Transaction = tran;

//insertamos el registro de la Entrada

try

{

cmd.CommandText = "insert into

entradas(fecha_entrada,fecha_factura,folio_factura,proveedor,user_login)

" +

" values (#" + prmFechaEntrada + "#,#" + prmFechaFactura +

"#,'" +

prmFolioFactura + "','" + prmNombreProveedor + "','" +

prmUserLogin + "')";

cmd.ExecuteNonQuery();

//obtenemos el folio

int _FolioEntrada = 0;

cmd.CommandText = "select @@identity";

_FolioEntrada = Convert.ToInt32(cmd.ExecuteScalar());

//insertamos el detalle de laentrada

for (int i = 0; i < tmpEntrada.Rows.Count; i++)

{

string _IdArticulo = Convert.ToString(tmpEntrada.Rows[i]

["id_articulo"]);

double _Cantidad = Convert.ToDouble(tmpEntrada.Rows[i]

["cantidad"]);

double _IVA = Convert.ToDouble(tmpEntrada.Rows[i]["iva"]);

double _PrecioCompra = Convert.ToDouble(tmpEntrada.Rows[i]

["precio_compra"]);

double _CostoPromedio = 0;

//insertamos el articulo

cmd.CommandText = "insert into

entradas_detalle(id_entrada,id_articulo,cantidad,precio_compra,iva) " +

"values(" + _FolioEntrada + ",'" + _IdArticulo + "'," +

_Cantidad + "," +

_PrecioCompra + "," + _IVA + ")";

cmd.ExecuteNonQuery();

//actualizamosexistencias

cmd.CommandText = "update articulos set " +

" existencia=existencia + " + _Cantidad + "" +

" where id_articulo='" + _IdArticulo + "'";

cmd.ExecuteNonQuery();

//establecemos el costo promedio

cmd.CommandText = "select avg(precio_compra) " +

" from entradas_detalle " +

" where id_articulo='" + _IdArticulo + "'";

_CostoPromedio = Convert.ToDouble(cmd.ExecuteScalar());

cmd.CommandText = "update articulos set " +

" costo_promedio=" + _CostoPromedio + "" +

" where id_articulo='" + _IdArticulo + "'";

cmd.ExecuteNonQuery();

}

//finalizamos la transaccion

tran.Commit();

cnn.Close();

MessageBox.Show("Entrada grabada correctamente",

"Información del Sistema", MessageBoxButtons.OK,

MessageBoxIcon.Information);

return (true);

}

catch (OleDbException errEntrada) {

tran.Rollback();

cnn.Close();

MessageBox.Show(errEntrada.Message);

return (false);

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

return (false);

}

}

Ahora damos doble clic sobre el botón Agregar (btnAgregar) y escribimos el siguiente código:

try {

if (agregarArticulo(txtIdArticulo.Text,

Convert.ToDouble(txtCantidad.Text),

Convert.ToDouble(txtPrecioCompra.Text),

0.16)) {

mostrarEntrada();

}

}

catch (Exception ex) {

MessageBox.Show(ex.Message);

}

Ahora, agregaremos el código para grabar la entrada, hacemos doble clic sobre el botón Grabar

(btnGrabar) y escribimos el siguiente código:

if (grabarEntrada(dtpFechaEntrada.Value.ToShortDateString(),

dtpFechaFactura.Value.ToShortDateString(),

txtFolioFactura.Text, txtNombreProveedor.Text,"admin")) {

this.Close();

}

El código que pondremos en el Form_Load es el siguiente:

//>Definimos la tabla para las ventas Temporales

DataColumn idColumn = new DataColumn("id", typeof(int));

idColumn.Unique = true;

idColumn.AutoIncrement = true;

idColumn.AutoIncrementSeed = 1;

idColumn.AutoIncrementStep = 1;

tmpEntrada.Columns.Add(idColumn);

//declaramos el resto de los campos

tmpEntrada.Columns.Add("id_articulo", typeof(string));

tmpEntrada.Columns.Add("articulo", typeof(string));

tmpEntrada.Columns.Add("cantidad", typeof(Double));

tmpEntrada.Columns.Add("precio_compra", typeof(Double));

tmpEntrada.Columns.Add("iva", typeof(Double));

//agregamos un primary key

tmpEntrada.PrimaryKey = new DataColumn[] { tmpEntrada.Columns["id"] };

//<termina la deficinicón de la tabla temporal

generaColumnas();

mostrarEntrada();

En el botón Salir (btnSalir) escribimos esto:

this.Close();

Para efectos de aprendizaje basico me aseguré de no poner funcionalidad demasiado complicada.

Lo que tratamos de desarrollar es un sistema de almacén

sencillo, no se trata de desarrollar un sistema comercial cero errores, tratamos de sentar las bases

técnicas para, en un futuro, lograr un gran sistema de almacén

con toda la funcionalidad comercial.

Aqui un ejemplo de la pantalla funcionando:

Creación de un sistema de almacén con C# (Parte 4)Reporte de Entradas

Diseño de la pantalla

Para comenzar, le daremos diseño al formulario "frmEntradasLista" el cual nos servirá para mostrar

un listado de las entradas que se hayan registrado, la apariencia debe de quedar mas o menos así:

Se agregaron tres Button, un ListView y un Label, las propiedades están descritas en la siguiente

tabla:

Objeto Propiedad Valor

ButtonName btnNueva

Text Nueva

ButtonName btnMostrar

Text Mostrar

ButtonName btnSalir

Text Salir

ListView

Name lvEntradas

FullRowSelect True

GridLines True

HideSelection False

Label Name lblMensaje

Text Doble clic para imprimir.

Ahora procedemos con el diseño del reporte de entradas, lo primero que haremos será crear un

DataSet el cual nos servirá para el posterior diseño del reporte.

Agregamos un nuevo objeto del tipo DataSet y le asignamos el nombredsRptEntrada como se

muestra:

Le damos diseño para que quede como se muestra:

El DataSet aparece vacío, debemos agregar un DataTable y

darle el diseño para que

quede como se muestra en la imagen. De entre las propiedades que debemos destacares que el tipo de datos de los campos cantidad, precio_compra e iva son System.Double.

Los tipos de datos para los campos id_articulo y articulo son System.String.

Una vez terminado el diseño del DataSet agregamos un Reporte, pero utilizaremos un asistente,

aqui muestro con imagenes todo el proceso:

Selecionamos que nuestro origen de datos es un objeto:

En la siguiente ventana, expanda todo y ubique el DataSet que acaba de crear anteriormente,

como se muestra a continuación:

Luego, escriba un nombre para el DataSet (propiedad Name), se recomienda poner el mismo que

puso anteriormente:

Arrastre los campos que desea mostrar en el reporte a la sección Values como se muestra en la

imagen:

Agregue los parametros prmFechaEntrada, prmFechaFactura, prmFolioFactura y

prmProveedor

Ejemplo de como agregar un parametro (Repitalo con los demás):

Agregue cuatro TextBox al encabezado y organicelos ordenadamente:

Agregaremos un nuevo formulario llamado frmVerReporte al cual agregaremos un control

ReportViewer al cual estableceremos una propiedad Modifiers=Public (En la ventana de

propiedades), aqui se muestra una imagen:

Hasta aqui todo ha sido diseño, ahora escribiremos el código que hace todo posible:

Declaramos las siguientes variables (En el formulario frmEntradasLista):

string CnnStr = @" Provider=Microsoft.Jet.OLEDB.4.0; " +

"Data Source=D:\\DOCS\\tyrodeveloper\\almacen.mdb; " +

"Jet OLEDB:Database Password=; Persist Security Info=False;";

string reportFile = @"D:\\DOCS\\tyrodeveloper\\almacen\\almacen\\

Reportes\\rptEntrada.rdlc";

Ahora agregamos los siguientes procedimientos:

void generaColumnas()

{

lvEntradas.Clear();

lvEntradas.View = View.Details;

lvEntradas.Columns.Add("Folio ", 40, HorizontalAlignment.Left);

lvEntradas.Columns.Add("Fecha Entrada", 85, HorizontalAlignment.Left);

lvEntradas.Columns.Add("Fecha Factura", 85, HorizontalAlignment.Left);

lvEntradas.Columns.Add("Folio Factura", 85, HorizontalAlignment.Left);

lvEntradas.Columns.Add("Proveedor", 200, HorizontalAlignment.Left);

}

void mostrarEntradas() {

try {

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

OleDbCommand cmd = new OleDbCommand();

cmd.Connection = cnn;

cmd.CommandText = "select * from entradas";

OleDbDataReader dr = cmd.ExecuteReader();

int i = 0;

lvEntradas.Items.Clear();

while (dr.Read()) {

//mostramos los datos

lvEntradas.Items.Add(dr["id_entrada"].ToString());

lvEntradas.Items[i].SubItems.Add(String.Format

("{0:dd/MM/yyyy}",dr["fecha_entrada"]));

lvEntradas.Items[i].SubItems.Add(String.Format("{0:dd/MM/yyyy}",

dr["fecha_factura"]));

lvEntradas.Items[i].SubItems.Add(dr["folio_factura"].ToString());

lvEntradas.Items[i].SubItems.Add(dr["proveedor"].ToString());

i++;

}

dr.Close();

cnn.Close();

}

catch (Exception ex) {

MessageBox.Show(ex.Message);

}

}

void mostrarReporte(int prmIdEntrada)

{

try

{

if (!File.Exists(reportFile))

{

MessageBox.Show(String.Format("No se encuentra \n{0}\nRevise por

favor", reportFile));

return;

}

//AHORA MOSTRAMOS EL REPORTE

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

DataSet dsReporte = new DataSet();

OleDbDataAdapter da = new OleDbDataAdapter("select d.*,a.articulo "+

" from entradas_detalle d,articulos a "+

" where a.id_articulo=d.id_articulo and id_entrada="+

prmIdEntrada +"", cnn);

da.Fill(dsReporte, "rptentrada");

if (dsReporte.Tables["rptEntrada"].Rows.Count == 0)

{

cnn.Close();

MessageBox.Show("No hay Datos");

return;

}

Formularios.frmVerReporte frm = new Formularios.frmVerReporte();

frm.reportViewer1.LocalReport.DataSources.Clear();

frm.reportViewer1.LocalReport.Dispose();

frm.reportViewer1.Reset();

frm.reportViewer1.LocalReport.DataSources.Add(new

ReportDataSource("dsRptEntrada",

dsReporte.Tables["rptEntrada"]));

frm.reportViewer1.LocalReport.ReportPath = reportFile;

//parametros

List<ReportParameter> param = new List<ReportParameter>();

OleDbCommand cmd = new OleDbCommand("select * from entradas where

id_entrada=" + prmIdEntrada + "", cnn);

OleDbDataReader dr = cmd.ExecuteReader();

while (dr.Read())

{

//folio_factura

ReportParameter pFolioFactura = new ReportParameter();

pFolioFactura.Name = "prmFolioFactura";

pFolioFactura.Values.Add(dr["folio_factura"].ToString());

param.Add(pFolioFactura);

//fecha_entrada

ReportParameter pFechaEntrada = new ReportParameter();

pFechaEntrada.Name = "prmFechaEntrada";

pFechaEntrada.Values.Add(dr["fecha_entrada"].ToString());

param.Add(pFechaEntrada);

//fecha_factura

ReportParameter pFechaFactura = new ReportParameter();

pFechaFactura.Name = "prmFechaFactura";

pFechaFactura.Values.Add(dr["fecha_factura"].ToString());

param.Add(pFechaFactura);

//proveedor

ReportParameter pProveedor = new ReportParameter();

pProveedor.Name = "prmProveedor";

pProveedor.Values.Add(dr["proveedor"].ToString());

param.Add(pProveedor);

}

dr.Close();

//agregamos los parametros a la coleccion

frm.reportViewer1.LocalReport.SetParameters(param);

frm.reportViewer1.RefreshReport();

frm.ShowDialog();

cnn.Close();

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error loading report",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

Agregamos sl siguiente código en el Form_Load:

lvEntradas.DoubleClick += new EventHandler(lvEntradas_DoubleClick);

generaColumnas();

mostrarEntradas();

Luego, agregamos el siguiente código:

void lvEntradas_DoubleClick(object sender, EventArgs e)

{

if (lvEntradas.SelectedItems.Count != 0) {

int _FolioEntrada =

Convert.ToInt32(lvEntradas.SelectedItems[0].Text);

mostrarReporte(_FolioEntrada);

}

}

El código para el botón btnNueva:

frmEntrada entrada = new frmEntrada();

entrada.StartPosition = FormStartPosition.CenterScreen;

entrada.ShowDialog();

El código para el botón btnMostrar:

mostrarEntradas();

El código para el botón btnSalir

this.Close();

Creación de un sistema de almacén con C# (Parte 5)Salidas del Almacén

Diseño de la pantalla

Empezaremos diseñando la pantalla de salidas (formulario frmSalida), la apariencia debe de

quedar mas o menos así:

A continuacion una tabla descriptiva con los nombres de los objetos:

Objeto Propiedad Valor

LabelName lblFechaSalida

Text Fecha Salida:

DateTimePicker

Name dtpFechaSalida

Format Custom

CustomFormat dd/MM/yyyy

LabelName lblResponsable

Text Responsable de la Salida:

TextBox Name txtResponsable

LabelName lblIdArticulo

Text Articulo:

TextBox Name txtIdArticulo

LabelName lblCantidad

Text Cantidad:

TextBox Name txtCantidad

ButtonName btnAgregar

Text Agregar

ButtonName btnGrabar

Text Grabar

ButtonName btnCancelar

Text Cancelar

ListView

Name lvSalida

FullRowSelect True

GridLines True

HideSelection False

Programación

La parte de la programación es la mas enredada. Voy a considerar que el lector es un novato con

nociones bastante

básicas e insuficientes como para comprender la estructura de la programación C#. Recomiendo al

lector poner mucha atención

a los pasos que aqui se describan y no omitir nada, leer y re-leer hasta que haya comprendido

lo que tiene que hacer.

Declaramos las siguientes variables:

//Variables

DataTable tmpEntrada = new DataTable();

string CnnStr = @" Provider=Microsoft.Jet.OLEDB.4.0; " +

"Data Source=D:\\DOCS\\tyrodeveloper\\almacen.mdb; " +

"Jet OLEDB:Database Password=; Persist Security Info=False;";

Escribiremos el código de las funciones y procedimientos:

void generaColumnas()

{

lvSalida.Clear();

lvSalida.View = View.Details;

lvSalida.Columns.Add("", 0, HorizontalAlignment.Left);

lvSalida.Columns.Add("Id ", 100, HorizontalAlignment.Left);

lvSalida.Columns.Add("Producto", 240, HorizontalAlignment.Left);

lvSalida.Columns.Add("Cantidad", 60, HorizontalAlignment.Right);

}

void mostrarEntrada()

{

try

{

lvSalida.Items.Clear();

for (int i = 0; i < tmpEntrada.Rows.Count; i++)

{

lvSalida.Items.Add(tmpEntrada.Rows[i]["id"].ToString());

lvSalida.Items[i].SubItems.Add(tmpEntrada.Rows[i]

["id_articulo"].ToString());

lvSalida.Items[i].SubItems.Add(tmpEntrada.Rows[i]

["articulo"].ToString());

lvSalida.Items[i].SubItems.Add(String.Format("{0:N}",

Convert.ToDouble(tmpEntrada.Rows[i]["cantidad"])));

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

bool agregarArticulo(string prmIdArticulo, double prmCantidad)

{

try

{

string varId = "";

string varNombre = "";

double varExistencia = 0;

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

string strSQL = "select articulo,existencia from articulos " +

"where id_articulo='" + prmIdArticulo + "'";

OleDbCommand cmd = new OleDbCommand(strSQL, cnn);

OleDbDataReader dr = cmd.ExecuteReader();

if (dr.Read())

{

varId = prmIdArticulo;

varNombre = dr["articulo"].ToString();

varExistencia =Convert.ToDouble(dr["existencia"]);

if (varExistencia >= prmCantidad)

{

//agregamos la venta a la tabla temporal

DataRow row = tmpEntrada.NewRow();

row["id_articulo"] = varId;

row["articulo"] = varNombre;

row["cantidad"] = prmCantidad;

tmpEntrada.Rows.Add(row);

}

else {

MessageBox.Show("No hay suficientes existencias");

}

}

else

{

MessageBox.Show("El articulo no existe", "Error",

MessageBoxButtons.OK, MessageBoxIcon.Error);

return (false);

}

dr.Close();

cnn.Close();

return (true);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

return (false);

}

}

bool grabarSalida(string prmFechaSalida, string prmResponsable, string

prmUserLogin)

{

try

{

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

OleDbTransaction tran = cnn.BeginTransaction();

OleDbCommand cmd = new OleDbCommand();

cmd.Connection = cnn;

cmd.Transaction = tran;

//insertamos el registro de la Entrada

try

{

cmd.CommandText = "insert into

salidas(fecha_salida,responsable,user_login) " +

" values (#" + prmFechaSalida + "#,'" +

prmResponsable + "','" + prmUserLogin + "')";

cmd.ExecuteNonQuery();

//obtenemos el folio

int _FolioSalida = 0;

cmd.CommandText = "select @@identity";

_FolioSalida = Convert.ToInt32(cmd.ExecuteScalar());

//insertamos el detalle de laentrada

for (int i = 0; i < tmpEntrada.Rows.Count; i++)

{

string _IdArticulo = Convert.ToString(tmpEntrada.Rows[i]

["id_articulo"]);

double _Cantidad = Convert.ToDouble(tmpEntrada.Rows[i]

["cantidad"]);

//insertamos el articulo

cmd.CommandText = "insert into

salidas_detalle(id_salida,id_articulo,cantidad) " +

"values(" + _FolioSalida + ",'" + _IdArticulo + "'," +

_Cantidad + ")";

cmd.ExecuteNonQuery();

//actualizamosexistencias

cmd.CommandText = "update articulos set " +

" existencia=existencia - " + _Cantidad + "" +

" where id_articulo='" + _IdArticulo + "'";

cmd.ExecuteNonQuery();

}

//finalizamos la transaccion

tran.Commit();

cnn.Close();

MessageBox.Show("Salida grabada correctamente",

"Información del Sistema", MessageBoxButtons.OK,

MessageBoxIcon.Information);

return (true);

}

catch (OleDbException errEntrada)

{

tran.Rollback();

cnn.Close();

MessageBox.Show(errEntrada.Message);

return (false);

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

return (false);

}

}

Ahora damos doble clic sobre el botón Agregar (btnAgregar) y escribimos el siguiente código:

try

{

if (agregarArticulo(txtIdArticulo.Text,

Convert.ToDouble(txtCantidad.Text)))

{

mostrarEntrada();

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

Ahora, agregaremos el código para grabar la entrada, hacemos doble clic sobre el botón Grabar

(btnGrabar) y escribimos el siguiente código:

if (grabarSalida(dtpFechaSalida.Value.ToShortDateString(),

txtResponsable.Text, "admin"))

{

this.Close();

}

El código que pondremos en el Form_Load es el siguiente:

//>Definimos la tabla para las salida Temporal

DataColumn idColumn = new DataColumn("id", typeof(int));

idColumn.Unique = true;

idColumn.AutoIncrement = true;

idColumn.AutoIncrementSeed = 1;

idColumn.AutoIncrementStep = 1;

tmpEntrada.Columns.Add(idColumn);

//declaramos el resto de los campos

tmpEntrada.Columns.Add("id_articulo", typeof(string));

tmpEntrada.Columns.Add("articulo", typeof(string));

tmpEntrada.Columns.Add("cantidad", typeof(Double));

//agregamos un primary key

tmpEntrada.PrimaryKey = new DataColumn[] { tmpEntrada.Columns["id"] };

//<termina la deficinicón de la tabla temporal

generaColumnas();

mostrarEntrada();

En el botón Salir (btnSalir) escribimos esto:

this.Close();

Aqui un ejemplo de la pantalla funcionando:

Creación de un sistema de almacén con C# (Parte 6)Reporte de Entradas

Diseño de la pantalla

Para comenzar, le daremos diseño al formulario "frmSalidasLista" el cual nos servirá para mostrar

un listado de las salidas que se hayan registrado, la apariencia debe de quedar mas o menos así:

Se agregaron tres Button, un ListView y un Label, las propiedades están descritas en la siguiente

tabla:

Objeto Propiedad Valor

ButtonName btnNueva

Text Nueva

ButtonName btnMostrar

Text Mostrar

ButtonName btnSalir

Text Salir

ListView

Name lvSalidas

FullRowSelect True

GridLines True

HideSelection False

LabelName lblMensaje

Text Doble clic para imprimir.

Ahora procedemos con el diseño del reporte de salidas, este proceso se muestra en la parte 4 de

este tutorial, el cual deberá quedar mas o menos así:

Ahora agregamos los siguientes procedimientos:

void generaColumnas(){

lvSalidas.Clear();

lvSalidas.View = View.Details;

lvSalidas.Columns.Add("Folio ", 40, HorizontalAlignment.Left);

lvSalidas.Columns.Add("Fecha Salida", 85, HorizontalAlignment.Left);

lvSalidas.Columns.Add("Responsable", 200, HorizontalAlignment.Left);

}

void mostrarSalidas(){

try {

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

OleDbCommand cmd = new OleDbCommand();

cmd.Connection = cnn;

cmd.CommandText = "select * from salidas";

OleDbDataReader dr = cmd.ExecuteReader();

int i = 0;

lvSalidas.Items.Clear();

while (dr.Read()) {

//mostramos los datos

lvSalidas.Items.Add(dr["id_salida"].ToString());

lvSalidas.Items[i].SubItems.Add(String.Format("{0:dd/MM/yyyy}",

dr["fecha_salida"]));

lvSalidas.Items[i].SubItems.Add(dr["responsable"].ToString());

i++;

}

dr.Close();

cnn.Close();

}

catch (Exception ex) {

MessageBox.Show(ex.Message);

}

}

void mostrarReporte(int prmIdSalida){

try{

if (!File.Exists(reportFile)){

MessageBox.Show(String.Format("No se encuentra \n{0}\nRevise

por favor", reportFile));

return;

}

//AHORA MOSTRAMOS EL REPORTE

OleDbConnection cnn = new OleDbConnection(CnnStr);

cnn.Open();

DataSet dsReporte = new DataSet();

OleDbDataAdapter da = new OleDbDataAdapter("select d.*,a.articulo "

+

" from salidas_detalle d,articulos a " +

" where a.id_articulo=d.id_articulo and id_salida=" +

prmIdSalida + "", cnn);

da.Fill(dsReporte, "rptSalida");

if (dsReporte.Tables["rptSalida"].Rows.Count == 0) {

cnn.Close();

MessageBox.Show("No hay Datos");

return;

}

Formularios.frmVerReporte frm = new Formularios.frmVerReporte();

frm.reportViewer1.LocalReport.DataSources.Clear();

frm.reportViewer1.LocalReport.Dispose();

frm.reportViewer1.Reset();

frm.reportViewer1.LocalReport.DataSources.Add(new

ReportDataSource("dsRptSalida",

dsReporte.Tables["rptSalida"]));

frm.reportViewer1.LocalReport.ReportPath = reportFile;

//parametros

List<ReportParameter> param = new List<ReportParameter>();

OleDbCommand cmd = new OleDbCommand("select * from salidas where

id_salida=" + prmIdSalida + "", cnn);

OleDbDataReader dr = cmd.ExecuteReader();

while (dr.Read()){

//fecha_salida

ReportParameter pFechaEntrada = new ReportParameter();

pFechaEntrada.Name = "prmFechaSalida";

pFechaEntrada.Values.Add(dr["fecha_salida"].ToString());

param.Add(pFechaEntrada);

//responsable

ReportParameter pProveedor = new ReportParameter();

pProveedor.Name = "prmResponsable";

pProveedor.Values.Add(dr["responsable"].ToString());

param.Add(pProveedor);

}

dr.Close();

//agregamos los parametros a la coleccion

frm.reportViewer1.LocalReport.SetParameters(param);

frm.reportViewer1.RefreshReport();

frm.ShowDialog();

cnn.Close();

}

catch (Exception ex){

MessageBox.Show(ex.Message, "Error al cargar el reporte",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

Agregamos sl siguiente código en el Form_Load:

lvSalidas.DoubleClick += new EventHandler(lvSalidas_DoubleClick);

generaColumnas();

mostrarSalidas();

Luego, agregamos el siguiente código:

void lvSalidas_DoubleClick(object sender, EventArgs e)

{

if (lvSalidas.SelectedItems.Count != 0){

int _FolioSalida =

Convert.ToInt32(lvSalidas.SelectedItems[0].Text);

mostrarReporte(_FolioSalida);

}

}

El código para el botón btnNueva:

frmSalida salida = new frmSalida();

salida.StartPosition = FormStartPosition.CenterScreen;

salida.ShowDialog();

El código para el botón btnMostrar:

mostrarSalidas();

El código para el botón btnSalir

this.Close();

Aqui un ejemplo de la pantalla funcionando:

Aqui un ejemplo del reporte:

Hasta este punto ya hemos desarrollado la funcionalidad básica. En la siguiente parte haremos que

aparesca una pantalla pricipal desde la que mandaremos llamar las que hasta hoy hemos

desarrollado.

Creación de un sistema de almacén con C# (Parte 7)Pantalla principal

Le daremos diseño al formulario frmPrincipal agregando un MenuStrip, un ToolStrip y

estableciendo su pripiedad IsMdiContainer = true para que quede de la siguiente manera:

A continuación una tabla que describe los objetos:

Objeto Propiedad Valor

MenuStrip Name mnuPrincipal

ToolStripMenuItemName mnuArchivo

Text Archivo

ToolStripMenuItemName mnuAyuda

Text Ayuda

ToolStripMenuItemName mnuEntradas

Text Entradas

ToolStripMenuItemName mnuSalidas

Text Salidas

ToolStripMenuItemName mnuSalir

Text Salir del Sistema

ToolStrip Name barPrincipal

ToolStripButton

Name btnEntradas

Text Entradas

DisplayStyle ImageAndText

TextImageRelation

ImageAboveText

Image (A su gusto)

ToolStripButton

Name btnSalidas

Text Salidas

DisplayStyle ImageAndText

TextImageRelation

ImageAboveText

Image (A su gusto)

ToolStripButton

Name btnSalir

Text Salir

DisplayStyle ImageAndText

TextImageRelation

ImageAboveText

Image (A su gusto)

Ahora crearemos los siguientes procedimientos:

void entradas() {

frmEntradasLista entradas = new frmEntradasLista();

entradas.MdiParent = this;

entradas.Show();

}

void salidas() {

frmSalidasLista salidas = new frmSalidasLista();

salidas.MdiParent = this;

salidas.Show();

}

void salir() {

this.Close();

}

Ahora solo resta poner el código en cada uno de los botones y menús, los ponemos de uno por

uno, dando doble clic sobre cada uno, iniciamos con mnuEntradas:

entradas();

Seguimos con mnuSalidas:

salidas();

Asi lo hacemos también con los botones btnEntradas y btnSalidas

Ahora, el toque final de nuestra aplicación, abrimos la clase InicioAplicacion y nos aseguramos que

esté como se muestra a continuación:

using System;

using System.Windows.Forms;

namespace almacen.Clases

{

class InicioAplicacion

{

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new Formularios.Principal());

}

}

}

Aqui un ejemplo de la pantalla funcionando:

Hemos terminado este tutorial, espero que les sea de utilidad... Dios los Bendiga