[ Foro de C# ]

Generar Tique-Factura (Comprobante "A") en Controladora Fiscal EPSON TM-U220 utilizando Visual Studio con C#

31-Mar-2016 00:57
Guillermo Reinoso
1 Respuestas

Hola gente! Soy de Argentina y mi consulta es la siguiente:

Estoy desarrollando una aplicación de escritorio en Visual Studio 2012 con C#, la cual funcionará en un equipo con Windows 8 de 64 bits. La misma, es para un comercio de Alimentos para mascotas.

Dicha aplicación se encuentra conectada a una controladora Fiscal EPSON TM-U220 AFII para llevar a cabo la facturación de las ventas realizadas.

Al momento de registrar una venta, el sistema consulta si se desea emitir un tique (comprobante "B" para Consumidor Final) o un tique-factura (comprobante "A" para Responsable Inscripto), por lo que la emisión del comprobante de pago correspondiente dependerá del tipo de factura que se desee emitir. Para conseguir esto, he agregado al formulario de Venta el control "axPrinterFiscal2" (el cual tengo disponible al agregar el OCX IFEpson Fiscal como referencia a la solución), luego, el código utilizado es el siguiente:

1. Si el comprobante que se desea emitir es un Comprobante "B", la aplicación recorre la grilla que contiene el detalle de venta y envía toda la información a la controladora, la cual emite el comprobante sin ningún inconveniente:

 
                        if (Convert.ToInt16(cboTipoComprobante.SelectedValue) == 2) //Se trata de un TIQUE B
                        {
                            iva = "2100";
                            venta = "M";
                            bultos = "0";
                            ImpuestosInternos = "0";
                            printer = "P";
                            texto = "SUB";
                            pago = "Efectivo";
                            calculoMonto = Convert.ToDouble(txtTotal.Text); //TextBox que tiene el Total de la Venta
                            calculoMonto = calculoMonto * 100;
                            monto = (calculoMonto).ToString();
                            descripcion = "T";
                            axPrinterFiscal2.PortNumber = 2;  //Numero de Puerto al cual se encuentra conectado la controladora fiscal a mi PC
                            axPrinterFiscal2.BaudRate = "9600";
                            axPrinterFiscal2.OpenTicket(); //Abro un Tique, ya que el comprobante, para este caso, será del tipo "B"
                            //Recorro el DataGridView que contiene el detalle de la venta (Cantidad, Descripcion, Precio Unitario y Subtotal) para ir enviando los ítems de la venta al ticket
                            for (int i = 0; i < grdDetalleVenta.Rows.Count; i++)
                            {
                                string sqlArticulo = "SELECT ISNULL(P.codigo + ' - ' + PE.nombre,'') FROM Producto P, Peso PE, DetalleVenta DV WHERE DV.idProducto=P.idProducto AND P.idPeso=PE.idPeso AND DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                                string articulo = producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlArticulo, "Error al conocer el nombre del Artículo");
                                string sqlCantidad = "SELECT ISNULL(DV.cantidad,'') FROM DetalleVenta DV WHERE DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                                string cantidad = (Convert.ToDouble(producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlCantidad, "Error al conocer el nombre del Artículo")) * 1000).ToString();
                                string sqlPrecioUnitario = "SELECT ISNULL(DV.precioUnitario,'') FROM DetalleVenta DV WHERE DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                                string precioUnitario = (Convert.ToDouble(producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlPrecioUnitario, "Error al conocer el precio unitario del Artículo")) * 100).ToString();
                                string sqlSubtotal = "SELECT ISNULL(DV.subtotal,'') FROM DetalleVenta DV WHERE DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                                string subtotal = (Convert.ToDouble(producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlSubtotal, "Error al conocer el subtotal del Detalle")) * 100).ToString();
                                axPrinterFiscal2.SendTicketItem(ref articulo, ref cantidad, ref precioUnitario, ref iva, ref venta, ref bultos, ref ImpuestosInternos);
                            }
                            //Una vez cargados todos los ítem que conforman la VENTA, agrego los subtotales del Tique y cierro el mismo
                            axPrinterFiscal2.GetTicketSubtotal(ref printer, ref texto);
                            axPrinterFiscal2.SendTicketPayment(ref pago, ref monto, ref descripcion);
                            axPrinterFiscal2.CloseTicket();
                        }
 


NOTA: La controladora responde al instante y emite el Comprobante o Tique ("B", en este caso) perfectamente!!

2. Si el comprobante que se desea emitir es un Comprobante "A", la aplicación recorre la grilla que contiene el detalle de venta y envía toda la información a la controladora, pero no hay respuesta de aquella. El código utilizado para ello, es el siguiente:

 
                    if (Convert.ToInt16(cboTipoComprobante.SelectedValue) == 1) //Se trata de un TIQUE FACTURA "A"
                    {
                        string tipoDocumentoFiscal = "T";
                        string salidaImpresora = "C";
                        string letraFactura = "A";
                        string cantidadCopias = "1";
                        string tipoFormulario = "P";
                        string tipoLetra = "12";
                        string IVA_Emisor = "I";
                        string IVA_Comprador = "F";
                        string nombreCliente1 = nombreCliente;
                        string nombreCliente2 = razonSocialCliente;
                        string tipoDocumento = "CUIT";
                        string numeroDocumento = ClienteCUIT;
                        string bienDeUso = "N";
                        string domicilioComprador1 = domicilioCliente;
                        string domicilioComprador2 = "";
                        string domicilioComprador3 = "98";
                        string remito1 = "REM 1";
                        string remito2 = "REM 2";
                        string tipoTablaItem = "C";
                        string parametroVacio = "";
                        string incrementoTasa = "";
                        axPrinterFiscal2.PortNumber = 2; //Nuevamente, el numero de puerto al cual se encuentra conectada la Controladora Fiscal
                        axPrinterFiscal2.BaudRate = "9600";
                        //Función que debería dar apertura a un tique-factura A, la cual recibe los siguientes parámetros por referencia
 
                        axPrinterFiscal2.OpenInvoice(ref tipoDocumentoFiscal, ref salidaImpresora, ref letraFactura, ref cantidadCopias, ref tipoFormulario, ref tipoLetra, ref IVA_Emisor, ref IVA_Comprador, ref nombreCliente1, ref nombreCliente2, ref tipoDocumento, ref numeroDocumento, ref bienDeUso, ref domicilioComprador1, ref domicilioComprador2, ref domicilioComprador3, ref remito1, ref remito2, ref tipoTablaItem);
                        //LUEGO DE ESTA INSTRUCCIÓN NO HAY ACTIVDAD EN LA CONTROLADORA FISCAL
                        //Nuevamente, al igual con el Tique "B", recorro la grilla para cargar el detalle al cuerpo del Tique Factura
                        for (int i = 0; i < grdDetalleVenta.Rows.Count; i++)
                        {
                            string sqlArticulo = "SELECT ISNULL(P.codigo + ' - ' + PE.nombre,'') FROM Producto P, Peso PE, DetalleVenta DV WHERE DV.idProducto=P.idProducto AND P.idPeso=PE.idPeso AND DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                            string articulo = producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlArticulo, "Error al conocer el nombre del Artículo");
                            string sqlCantidad = "SELECT ISNULL(DV.cantidad,'') FROM DetalleVenta DV WHERE DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                            string cantidad = (Convert.ToDouble(producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlCantidad, "Error al conocer el nombre del Artículo")) * 1000).ToString();
                            string sqlPrecioUnitario = "SELECT ISNULL(DV.precioUnitario,'') FROM DetalleVenta DV WHERE DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                            string precioUnitario = (Convert.ToDouble(producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlPrecioUnitario, "Error al conocer el precio unitario del Artículo")) * 100).ToString();
                            string sqlSubtotal = "SELECT ISNULL(DV.subtotal,'') FROM DetalleVenta DV WHERE DV.idDetalleVenta=" + Convert.ToInt64(grdDetalleVenta.Rows[i].Cells[0].Value);
                            string subtotal = (Convert.ToDouble(producto.conocerCampoRegistro(cadena.cadenaConexion.ToString(), sqlSubtotal, "Error al conocer el subtotal del Detalle")) * 100).ToString();
                            //La siguiente línea, debería cargar un nuevo detalle en el Tique Factura, pero nuevamente, la Controladora Fiscal no presenta actividad
                            axPrinterFiscal2.SendInvoiceItem(ref articulo, ref cantidad, ref precioUnitario, ref iva, ref venta, ref bultos, ref ImpuestosInternos, ref parametroVacio, ref parametroVacio, ref parametroVacio, ref incrementoTasa, ref ImpuestosInternos);
                        }
                        //Las siguientes líneas cargan los totales del Tique Factura, pero tampoco se advierte actividad en la Controladora Fiscal al ejecutarse las mismas
                        axPrinterFiscal2.GetInvoiceSubtotal(ref printer, ref texto);
                        axPrinterFiscal2.SendInvoicePayment(ref pago, ref monto, ref descripcion);
                        axPrinterFiscal2.CloseInvoice(ref descripcion, ref letraFactura, ref parametroVacio);
                    }
 


Para este caso (al precisar emitir un tique-factura "A"), la controladora, directamente, no responde en absoluto (no hace nada). Me contacté con el Soprte Técnico de EPSON y me respondieron que puede pasar que haya otro formulario de la aplicación que esté accediendo al mismo puerto y esto haga que no se emita el tique-factura. Por lo que intenté modificando el número de puerto a través del cual envío el tique-factura a la controladora (pero aún así no imprime el comprobante "A"). También intenté apagando el equipo para volver a ejecutar la aplicación y emitir, en primer lugar, un Tique-Factura (de manera de asegurarme que el puerto indicado no estuviese siendo usado por otro proceso), pero aún así no respondió como esperaba. Reitero, una vez más, que con el mismo control (axPrinterFiscal2) y el puerto indicado (el 2), puedo emitir los tique (o comprobantes "B") sin problemas, las veces que deseo.

Alguna ayuda que me permita solucionar mi inconveniente?

Saludos.-


03-Apr-2016 23:59
Nacho Cabanes (+31)

En primer lugar, me tomo la libertad de eliminar tu dirección de correo electrónico. Recuerda que dejar tu correo a la vista en foros públicos puede ser una fuente de Spam.

En segundo lugar, tu fuente supera por mucho las 80 columnas de anchura recomendables, de modo que resulta muy difícil de leer.

Aun así, faltan detalles para ver qué falla. Por ejemplo, quizá no estés liberando el puerto con los métodos "Close". Comprueba qué diferencias internas hay entre ".CloseTicket()" y ".CloseInvoice()". Por otra parte, comprueba qué ocurre con diferentes secuencias de envío, como por ejemplo:

- Imprimir sólo ticket B (con equipo e impresora recién encendidos)
- Imprimir sólo ticket A (en las mismas circunstancias)
- Imprimir dos tickets B seguidos (ídem)
- Imprimir B y luego A (ídem)
...

El hacer eso de forma ordenada te puede ayudar a descubrir dónde está el problema. El otro paso que deberías dar es crear una nueva versión "de pruebas" del proyecto en la que sólo se escriba "Ticket B" o "Ticket A", según lo que se escoja; si va bien, vas ampliando cada vez con más texto hasta reconstruir el método original; si no va bien, te será mucho más fácil rastrear a partir de ahí.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)