Crear un punto de venta (8 de 10)

InicioAnteriorSiguienteFinal

Pantalla de Ventas

Hemos llegado a la parte más difícil de esta serie de 10 ejercicios, las ventas. Todo tiene que estar bien en los ejercicios anteriores ya que nos serviremos de ellos para tener éxito en lo subsiguiente.
Para no tener problemas, recomiendo que lean los textos que voy a exponer, ya que antes de empezar a escribir algún código explicaré e intentaré dejar claro que es lo que se va a hacer, por que se va a hacer así y, de ser posible, haré aclaraciones de el por que es la mejor manera de hacerlo así.

Antes de comenzar, demos un vistazo sobre el funcionamiento de la aplicación:

Iniciando sesión:



Aquí se pone el nombre de usuario y la contraseña. No tiene gran dificultad.

Si por algún motivo nuestra aplicación está en RED, podemos ubicar el archivo de base de datos por medio del link que está subrayado de azul:



Solo bastará buscar la ruta de la base de datos entre las ubicaciones de red disponibles y listo.

Cuando entramos, lo primero que vemos es lo siguiente:



Tiene varios menús los cuales nos llevan a diferentes opciones del sistema. Nos centraremos en el de Ventas:





Si presionamos el botón buscar producto:



Al seleccionar uno, y haciéndole doble clic:



En este momento podemos ponerle otra cantidad para que, al presionar Enter:



Luego, presionamos el Botón Realizar venta:



Podemos presionar Enter y ocurre lo siguiente:



Si elegimos “Yes”



Es una visión general de lo que lograremos una vez terminado este ejercicio.

Iniciemos de una vez…

Vamos a intentar lograr lo imposible, intentaremos entender la mentalidad de un desarrollador profesional, nos enredaremos la cabeza con código avanzado que probablemente no entenderemos por más que nos expliquen. Solo vamos a centrar nuestra atención en hacer las cosas al pié de la letra y os aseguro que tendremos éxito.

Diseñaremos frmVentas como se muestra a continuación:



Agregaremos un Listview, 5 Label, 4 TextBox y 4 Button, como se muestra en la tabla:


El cuarto botón solo es para dar una mejor vista, se pone debajo de los otros tres, para efectos prácticos puede ser omitido.

Agregaremos un constructor, justo debajo del constructor que ofrece predeterminadamente:

public frmVentas(string prmUSER_LOGIN,int prmID_CAJA){
InitializeComponent();
varID_CAJA = prmID_CAJA;
varUSER_LOGIN = prmUSER_LOGIN;
}


Luego declaramos unas variables:

//Declaraciones
string varUSER_LOGIN = frmLogin._USER_NAME;
int varID_CAJA=1;


La primera variable nos servirá para saber el nombre con el que inició sesión el usuario, la segunda es por que nuestro sistema podría soportar un indefinido número de cajas, claro que para este caso solo será una.

Ahora pondremos lo siguiente en el Form_Load:

//Form_Load
Headers();
ReadData(varUSER_LOGIN, varID_CAJA);
this.txtCANTIDAD.KeyPress +=
new System.Windows.Forms.
KeyPressEventHandler(this.txtCANTIDAD_KeyPress);
this.txtCANTIDAD.KeyDown +=
new System.Windows.Forms.
KeyEventHandler(this.txtCANTIDAD_KeyDown);
this.txtID_PRODUCTO.KeyPress +=
new System.Windows.Forms.
KeyPressEventHandler(this.txtID_PRODUCTO_KeyPress);
this.txtID_PRODUCTO.KeyDown +=
new System.Windows.Forms.
KeyEventHandler(this.txtID_PRODUCTO_KeyDown);


El código anterior nos sirve para mandar llamar varios procedimientos que son importantes al momento de que sea llamado el formulario. Claro que es necesario lo siguiente para que lo anterior tenga sentido:

void Headers()
{
//Encabezados del litView
lvVenta.View = View.Details;
lvVenta.Columns.Add("Producto", 100,
HorizontalAlignment.Left);
lvVenta.Columns.Add("Descripcion", 250,
HorizontalAlignment.Left);
lvVenta.Columns.Add("Cant", 75,
HorizontalAlignment.Right);
lvVenta.Columns.Add("Prec", 75,
HorizontalAlignment.Right);
lvVenta.Columns.Add("Iva", 75,
HorizontalAlignment.Right);
lvVenta.Columns.Add("Total", 100,
HorizontalAlignment.Right);
}


void txtCANTIDAD_KeyPress(object sender,KeyPressEventArgs e){
try{
lblMensaje.Text = "";
if (!((txtID_PRODUCTO.Text == "") ||
(txtCANTIDAD.Text == ""))){
if (e.KeyChar == 13){
//Insertar código aqui
SaveTemp_Ventas(txtID_PRODUCTO.Text,
Convert.ToDouble(txtCANTIDAD.Text));
txtID_PRODUCTO.Focus();
}
}
else{
lblMensaje.Text = "Debe introducir una "+
"clave de producto y/o una cantidad";
}
}
catch (Exception ex){
MessageBox.Show(ex.Message);
}
}
void txtCANTIDAD_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.F5) {
RealizaVenta();
}
}
void txtID_PRODUCTO_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.F5) {
RealizaVenta();
}
}

void txtID_PRODUCTO_KeyPress(object sender, KeyPressEventArgs e) {
lblMensaje.Text = "";
try {
if (!((txtID_PRODUCTO.Text == "") ||
(txtCANTIDAD.Text == ""))) {
if (e.KeyChar == 13){
//Inserttar código aqui
SaveTemp_Ventas(txtID_PRODUCTO.Text,
Convert.ToDouble(txtCANTIDAD.Text));
txtID_PRODUCTO.Focus();
}
}
else {
lblMensaje.Text = "Debe introducir una "+
"clave de producto y/o una cantidad";
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}


El código anterior actúa dependiendo del objeto del que se trate. Por ejemplo los que dicen KeyPress, controlan el momento en que es presionada una tebla sobre el objeto, lo mismo ocurre con KeyDown, solo que en este caso se trata de teclas especiales como las teclas F1-F12.

void SaveTemp_Ventas(string prmID_PRODUCTO,double prmCANTIDAD) {
double[] varProductDetails = new double[1];
varProductDetails =
FindProductDetails(prmID_PRODUCTO);
double varPRECIO = varProductDetails[0];
try {
if (varPRECIO ==0.0) {
lblMensaje.Text =
"El producto no existe!!!";
}
else {
Temp_Ventas(varUSER_LOGIN , varID_CAJA ,
prmID_PRODUCTO , prmCANTIDAD, varPRECIO);
ReadData(varUSER_LOGIN , varID_CAJA );
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}


void ReadData(string prmUSER_NAME,int prmID_CAJA) {
lblMensaje.Text = "";
double varIVA = 0.0;
double varGRAND_TOTAL = 0.0;
try {
OleDbConnection cnnReadData =
new OleDbConnection(Class.clsMain.CnnStr);
string varSQL = "SELECT CAT_PRODUCTOS.ID_PRODUCTO, "+
" CAT_PRODUCTOS.DESC_PRODUCTO," +
" TEMP_VENTAS.CANTIDAD, "+
" TEMP_VENTAS.P_UNITARIO, "+
" TEMP_VENTAS.IVA,"+
" (TEMP_VENTAS.CANTIDAD*"+
" TEMP_VENTAS.P_UNITARIO) AS TOTAL" +
" FROM CAT_PRODUCTOS "+
" INNER JOIN TEMP_VENTAS" +
" ON CAT_PRODUCTOS.ID_PRODUCTO = "+
" TEMP_VENTAS.ID_PRODUCTO "+
" WHERE TEMP_VENTAS.USER_NAME ='" +
prmUSER_NAME + "'";
int I = 0;
OleDbCommand cmdReadData =
new OleDbCommand(varSQL, cnnReadData);
OleDbDataReader drReadData;
if(cnnReadData.State == ConnectionState.Open)
cnnReadData.Close();
cnnReadData.Open();
drReadData = cmdReadData.ExecuteReader();
lvVenta.Items.Clear();
while (drReadData.Read()) {
lvVenta.Items.
Add(drReadData["ID_PRODUCTO"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["DESC_PRODUCTO"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["CANTIDAD"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["P_UNITARIO"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["IVA"].ToString() + " %");
lvVenta.Items[I].SubItems.
Add(String.Format("{0:C}", drReadData["TOTAL"]));
//Obtenemos el Grand Total y el Iva
varGRAND_TOTAL += Convert.ToDouble(drReadData[5]);
varIVA += Convert.ToDouble(drReadData["IVA"]) *
((Convert.ToDouble(drReadData["TOTAL"]))/100);
I += 1;
}
drReadData.Close();
cmdReadData.Dispose();
cnnReadData.Close();
cnnReadData.Dispose();
txtGRAND_TOTAL.Text =
String.Format("{0:C}",
varGRAND_TOTAL);
txtIVA.Text =
String.Format("{0:C}", varIVA);
}
catch (Exception ex) {
MessageBox.Show (ex.Message);
}
}

void Temp_Ventas(string prmUSER_LOGIN,int prmID_CAJA,
string prmID_PRODUCTO,double prmCANTIDAD,
double prmPRECIO) {
//Para cargar la venta tenporal
string varSQL = "";
try {
OleDbConnection cnnTempVentas =
new OleDbConnection(Class.clsMain.CnnStr);
if (GetSale(prmUSER_LOGIN, prmID_CAJA,
prmID_PRODUCTO) == 0){
varSQL = "INSERT INTO TEMP_VENTAS(USER_NAME,"+
"ID_PRODUCTO,CANTIDAD,P_UNITARIO,IVA)" +
" VALUES('" + prmUSER_LOGIN + "','" +
prmID_PRODUCTO +
"'," + prmCANTIDAD + "," +
prmPRECIO + ",0)";
}
else {
varSQL = "UPDATE TEMP_VENTAS "+
"SET CANTIDAD = CANTIDAD + "+
prmCANTIDAD +"" +
" WHERE USER_NAME = '"+
prmUSER_LOGIN +"'" +
" AND ID_PRODUCTO = '"+
prmID_PRODUCTO +"'";
}
OleDbCommand cmdTempVentas =
new OleDbCommand(varSQL, cnnTempVentas);
if (cnnTempVentas.State == ConnectionState.Open)
cnnTempVentas.Close();
cnnTempVentas.Open();
cmdTempVentas.ExecuteNonQuery();
cnnTempVentas.Close();
cmdTempVentas.Dispose();
cnnTempVentas.Dispose();
txtID_PRODUCTO.Text = "";
txtCANTIDAD.Text = "1";
}
catch(Exception ex) {
MessageBox.Show(ex.Message,"TempVentas");
}
}

double[] FindProductDetails(string prmID_PRODUCTO){
double[] Retorno = new double[2];
try {
OleDbConnection cnnFindProductDetails =
new OleDbConnection(Class.clsMain.CnnStr);
string varSQL = "SELECT count(*) "+
"FROM CAT_PRODUCTOS "+
"WHERE ID_PRODUCTO = '" +
prmID_PRODUCTO + "'";
OleDbCommand cmdFindProductDetails =
new OleDbCommand();
cmdFindProductDetails.Connection =
cnnFindProductDetails;
cmdFindProductDetails.CommandText = varSQL;
if (cnnFindProductDetails.State == ConnectionState.Open)
cnnFindProductDetails.Close();
cnnFindProductDetails.Open();

if (!(Convert.ToInt32(cmdFindProductDetails.ExecuteScalar()) == 0)) {
varSQL = "SELECT P_U_VENTA "+
" FROM CAT_PRODUCTOS "+
"WHERE ID_PRODUCTO ='" +
prmID_PRODUCTO + "'";
cmdFindProductDetails.CommandText = varSQL;
Retorno[0] = Convert.
ToDouble(cmdFindProductDetails.ExecuteScalar());
varSQL = "SELECT IVA "+
"FROM CAT_PRODUCTOS "+
"WHERE ID_PRODUCTO ='" +
prmID_PRODUCTO + "'";
cmdFindProductDetails.CommandText = varSQL;
Retorno[1] = Convert.
ToDouble(cmdFindProductDetails.ExecuteScalar());
}
else {
Retorno[0] = 0.0;
Retorno[1] = 0.0;
}
cmdFindProductDetails.Dispose();
cnnFindProductDetails.Close();
cnnFindProductDetails.Dispose();
return (Retorno);
}
catch (Exception ex) {
MessageBox.Show(ex.Message,
"FindProductDetails");
return (Retorno);
}
}

double GetSale(string prmUSER_LOGIN,int prmID_CAJA,
string prmID_PRODUCTO){
//Para cargar la venta tenporal
double Retorno;
try {
OleDbConnection cnnGetSale =
new OleDbConnection(Class.clsMain.CnnStr);
string varSQL = "SELECT COUNT(*) FROM TEMP_VENTAS " +
" WHERE USER_NAME = '"+ prmUSER_LOGIN +"' " +
" AND ID_PRODUCTO = '"+ prmID_PRODUCTO +"'";
OleDbCommand cmdGetSale =
new OleDbCommand(varSQL, cnnGetSale);
if (cnnGetSale.State == ConnectionState.Open)
cnnGetSale.Close();
cnnGetSale.Open();
Retorno = Convert.
ToDouble(cmdGetSale.ExecuteScalar());
cmdGetSale.Dispose();
cnnGetSale.Close();
cnnGetSale.Dispose();
return (Retorno);
}
catch (Exception ex){
MessageBox.Show(ex.Message,"GetSale");
return (0);
}
}

private void RealizaVenta() {
if (lvVenta.Items.Count != 0)
{
int varFolio = RealizaVenta(varUSER_LOGIN, varID_CAJA);
if (varFolio != 0)
{
frmCobrar _frmCobrar = new frmCobrar(varFolio);
_frmCobrar.StartPosition = FormStartPosition.CenterScreen;
_frmCobrar.ShowDialog();
}
}
}

private int RealizaVenta(string prmUSER_LOGIN, int prmID_CAJA){
int varFolio = 0;
try{
OleDbConnection cnnInsert =
new OleDbConnection(Class.clsMain.CnnStr);
cnnInsert.Open();
OleDbCommand cmdInsert = new OleDbCommand();
cmdInsert.Connection = cnnInsert;
//insertamos el registro padre
cmdInsert.CommandText =
"INSERT INTO VENTAS (USER_NAME,ID_CAJA,FECHA) " +
"VALUES('" + prmUSER_LOGIN +
"'," + prmID_CAJA + ",NOW())";
cmdInsert.ExecuteNonQuery();
//obtenemos el autonumerico
cmdInsert.CommandText = "SELECT @@IDENTITY";
varFolio = Convert.ToInt32(cmdInsert.ExecuteScalar());
//GENERAMOS LA VENTA
cmdInsert.CommandText =
"INSERT INTO DETALLE_VENTAS "+
" (ID_PRODUCTO,FOLIO,CANTIDAD,P_UNITARIO,IVA)"+
" SELECT ID_PRODUCTO,"+ varFolio +","+
" CANTIDAD,P_UNITARIO,IVA "+
" FROM TEMP_VENTAS "+
" WHERE USER_NAME ='"+ prmUSER_LOGIN +"'";
cmdInsert.ExecuteNonQuery();
//ACTUALIZAMOS LAS EXISTENCIAS
cmdInsert.CommandText = "UPDATE CAT_PRODUCTOS "+
" INNER JOIN TEMP_VENTAS "+
" ON CAT_PRODUCTOS.ID_PRODUCTO = "+
" TEMP_VENTAS.ID_PRODUCTO "+
" SET CAT_PRODUCTOS.CANTIDAD = "+
" CAT_PRODUCTOS.CANTIDAD-[TEMP_VENTAS].[CANTIDAD]"+
" WHERE (([TEMP_VENTAS].[USER_NAME]= "+
" '"+ prmUSER_LOGIN +"'));";
cmdInsert.ExecuteNonQuery();
//borramos las ventas temporales
cmdInsert.CommandText = "DELETE FROM TEMP_VENTAS " +
" WHERE USER_NAME = '" + prmUSER_LOGIN + "'";
cmdInsert.ExecuteNonQuery();
//LIBERAMOS LOS RECUSROS
cnnInsert.Close();
cnnInsert.Dispose();
cmdInsert.Dispose();
//mostramos la info
ReadData(varUSER_LOGIN, varID_CAJA);
return (varFolio);
}
catch (Exception ex){
MessageBox.Show(ex.Message, "RealizaVenta");
return (0);
}
}

private void DeshacerVenta(string prmUSER_LOGIN,int prmID_CAJA) {           
OleDbConnection conDeshacerVenta;
OleDbCommand cmdDeshacerVenta;
string strSQL_Delete = "DELETE FROM TEMP_VENTAS " +
" WHERE USER_NAME = '" + prmUSER_LOGIN + "' ";
try{
conDeshacerVenta =
new OleDbConnection(Class.clsMain.CnnStr);
conDeshacerVenta.Open();
cmdDeshacerVenta =
new OleDbCommand(strSQL_Delete, conDeshacerVenta);
cmdDeshacerVenta.ExecuteNonQuery();
cmdDeshacerVenta.Dispose();
conDeshacerVenta.Close();
ReadData(varUSER_LOGIN, varID_CAJA);
}
catch(Exception ex){
MessageBox.Show(ex.Message,"DeshacerVenta");
}

}


Hacemos doble clic sobre btnBuscarProducto:

try{
frmBuscaProducto myForm = new frmBuscaProducto();
myForm.StartPosition = FormStartPosition.CenterScreen;
myForm.ShowDialog();
if (!(myForm.varID_PRODUCTO == "")){
txtID_PRODUCTO.Text = myForm.varID_PRODUCTO;
txtID_PRODUCTO.Focus();
}
myForm.Dispose();
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "btnBuscaProducto", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtID_PRODUCTO.Text = "";
}


Luego sobre btnRealizarVenta:

RealizaVenta();


Para btnCerrar:

this.Close();


Vamos a suponer que todo lo anterior lo hemos hecho bien; lo que resta es poner en mdiMain el código correspondiente para mandar llamar al formulario de las ventas. Para conseguirlo deberemos hacer lo siguiente:

Hacemos doble clic sobre el menú “Punto de venta”:



Le ponemos el siguiente código:

frmVentas _frmVentas = 
new frmVentas(frmLogin._USER_NAME,1);
_frmVentas.MdiParent = this;
_frmVentas.StartPosition =
FormStartPosition.Manual;
_frmVentas.Show();


Si todo nos ha salido bien,… Hemos terminado

28 comentarios:

  1. que tal, que tengas buen dia, sabes estoy haciewndo al pie de la letra todos los pasos que tienes ya lo que no me abre es la ventana de ventas desde el menu, a que crees que se pueda deber, espero tu respesta gracias...

    ResponderEliminar
  2. hola, buenisimo manual. Me sale un error en el formulario de ventas. Puedo buscar el producto,
    pongo la cantidad,pero cuando doy al enter, sale el error de: no coinciden los tipos de datos en la expresion de criterios, en el dialogo findProductDetails.
    Agradeceria mucho que me contestaras. gracias
    calasalguer@hotmail.com

    ResponderEliminar
  3. Felicitaciones, exelente manual. Hoy lo leo de pie a cabeza. Saludos

    ResponderEliminar
  4. Hola nuevamente bueno que te digo hoy me pasa todo el dia en mi computadora y logre realizarl el ejercicio es muy complicado de entender el codigo pero es un buen manual es que realizaste voy por el siguiente ok mi correo es richardt_2000@hotmail.com

    ResponderEliminar
  5. Hola, exelente manual, el que tienes aqui, ya realize todo, solo que cuando escojo el producto y le ingreso una cantidad, me dice que el producto no existe no se en que procedimiento pueda estar mal, soy nuevo en c# y no entiendo todo el codigo, pero si la estructura y uno que otras funciones, si me podrias o asistir en que esta mal te lo agradeceria mi correo es ali_efendir@hotmail.com

    De antemano gracias

    ResponderEliminar
  6. Buen tutorial al= q todos e seguido cada uno de los pasos y toda va bien hasta el moneto de seleccionar el producto y poner la cantidad pero la darle enter me aparece el siguiente mensage: no coinciden los tipos de datos en la expresion de criterios, en el dialogo findProductDetails. Si hay alguien q tubo el mismo problema y lo aya resuelto espero me pueda apoyar con eso de antmano gracias y gracias por el tutorial.

    mi msn es link_987@hotmail.com si me pueden ayudar.

    ResponderEliminar
  7. exelente tutorial, pero no me aparece el form cobrar. y en usuarios no puedo agregar mas. solo se modifica el mismo.

    ojala alguien me pueda ayudar con esto gracias.

    ResponderEliminar
  8. a mi tambien me sale "no coinciden los tipos de datos en la expresion de criterios" busco en internet y dice que puede ser por los tipos de dato de la base de datos, que tipos de datos deve tener cada tabla?????
    o cual seria el problema aver si mandas un correo porfa

    alan_1382667@hotmail.com

    ResponderEliminar
  9. q tal esta muy bien tu tutorial, solo ay alguno detalles me gustaria saber si se puede y no es mucha molestia, Los datos de las demas tablas, pues al inicio dice q son 10 pero la verdad yo solo vi q se creara la de usuarios, de ai me da un error en las lineas donde aparese Clss.xxxx.xxxx si puedes facilitarme el sistema funcionando te lo agradeseria pues me marca varios error =/ gracias de antemano te dejo mi correo por si puedes mandarmelo

    what_316_mx@hotmail.com

    ResponderEliminar
  10. buen tutorial, solo que tengo un problema no puedo llenar el listview por que estoy utilizando sql server, me podrias ayudar a como se llenaria el listview para sql server
    o si alguien sabe que me pueda ayudar por fa
    rafavelaz_55@yahoo.com.mx

    ResponderEliminar
  11. Hola, excelente tutorial he seguido los pasos y aunque con un par de problema al final logre que corriera, solo tengo un problema al abrir la ventana de ventas me dice "no se han especificado algunos valores para algunos de los parametros especificados" pienso que es problema con las tablas de la base de datos, me podrías apoyar con eso ?.

    muchas gracias.

    frank_sxs@hotmail.com

    ResponderEliminar
  12. q tal esta muy bien tu tutorial, solo ay alguno detalles me gustaria saber si se puede y no es mucha molestia, Los datos de las demas tablas, pues al inicio dice q son 10 pero la verdad yo solo vi q se creara la de usuarios, de ai me da un error en las lineas donde aparese Clss.xxxx.xxxx si puedes facilitarme el sistema funcionando te lo agradeseria pues me marca varios error =/ gracias de antemano te dejo mi correo por si puedes mandarmelo

    ResponderEliminar
  13. quisiera saber los tipos de datos de la base de datos porque solo tiene la de usuario

    ResponderEliminar
  14. Alguien tendría el proyecto completo funcionando ? me gustaria tenerlo para probarlo y seguir agregandole cosas.
    Dejo mi correo por si alguien lo tiene, lo comprime y me lo pasa, le agradecería muchísimo.
    Saludos
    Esteban
    edcsuscrib@yahoo.com.ar

    ResponderEliminar
  15. HOLA YO TENGO EL ERROR DE LA CLASE NO TIENE UN CONTEXTO TEXTUAL COMO SOLUCIONO ESTE.?

    ResponderEliminar
  16. HOLA YA TERMINE EL PROGRAMA PERO EN EL FORMULARIO VENTAS MUESTRA ERROR " no se han especificado valores algunos de los parrametros requeridos" ME PODRIA DECIR PORQUE ME MARCA ESTE MENSAJE.

    ResponderEliminar
  17. Alguien me podria facilitar la base de datos??

    S_Juanito@outlook.com

    ResponderEliminar
  18. En el procedimiento de realizarVenta podrías usar un objeto Transaction del SqlCommand, así te aseguras que si hay un error en un insert, te haga un rollback y deshaga lo que hizo antes.
    Una pregunta, se podría hacer que vaya imprimiendo línea por línea en vez que imprima todo el ticket?

    ResponderEliminar
  19. Muchas Gracias, muy buen tutorial, yo lo hize pero con BD MYSQL si deseas te paso el codigo fuente.

    ResponderEliminar
  20. amigo ya lo termine solo me sale el siguiete error me podrias ayudar:

    Error 1 'Ticket.mPrintDocument' no es accesible debido a su nivel de protección

    ResponderEliminar
  21. muchas gracias Juan Gabriel .. ahora al hacer publica la clase me aparece este error:
    Error 3 Se requiere una referencia de objeto para el campo, método o propiedad no estáticos 'Ticket.mPrintDocument.PrintPreview()'

    en el formulario de cobrar.

    ResponderEliminar
  22. Amigo ya termine el proyecto pero necesito saber que pasa con lo de reportes consultas pues esos menus no funcionan ni muestran nada

    ResponderEliminar
  23. hola que tal.
    excelente tutorial, he realizado todos los paso pero al correrlo me marca un error desde el login esto es lo que me dice:
    fnLogin.
    No se puede convertir un objeto DBNull en otros tipos.
    espero me puedan ayudar mi mail es elefectivolagarton@gmail.com saludos

    ResponderEliminar
    Respuestas
    1. me sale lo mismo alguien sabe como lo corrijo solo me falta esto para acabar el proyecto se los agradezco

      Eliminar