sábado, 26 de diciembre de 2015

Conexión de FireBird desde .NET (unable to complete network request to host)


Firebird es un gestor de base de datos que ha ganado popularidad y que en lo personal me gusta bastante, pues es muy ligero así que decidí hacer algunas pruebas con .NET y al principio resulto bastante complicado encontrar la información para conexión remota pero después de varias horas logré realizar la conexión 

Aquí les dejo una lista de pasos que deben realizar para poder conectarse desde .NET. Los primeros pasos son para configurar el servidor Firebird, y permitir atender peticiones provenientes de la red. 


En esta entrada mencionare los pasos que se requieren para realizar una conexión a una base de datos remota con el servidor de base de datos Firebird. 

1.-Instalar el Servidor Firebird (Super Clasic o Super Server) 

2.-Verificar que FireBbird se ejecute como un servicio

3.-Modificar el archivo de configuración, debemos descomentar las siguientes lineas:

  RemoteServiceName=gds_db
  RemoteServicePort=3050

4.-Crear un alias de la base de datos ( esto se hace en el archivo aliases.config) 

     MiAliasDeBaseDeDatos = C:\directorio\base.bdf
    
5.-Agregar(si aún no existe) una regla en el firewall de Windows para permitir la conexión al puerto 3050 (TCP)

6.- Reiniciar el servicio de Firebird Server (no confundir con Firebird Guardian) 


Con esto deberemos estar listos para conectarnos, de manera remota,  a nuestro servidor de base de 


Ahora para poder conectarnos desde .NET (en mi caso en particular uso C#) debemos realizar los siguientes pasos 

    1- Obtener el proveedor de datos nativo de FireBird 
         
        La manera más sencilla de instalarlo es desde la Consola del Administrador de Paquetes de Visual Estudio.

         Herramientas>>Administrador de Paquetes de Biblioteca>>Consola del Administrador de Paquetes. 

        En la consola que se mostrará (parte inferior) escribimos 

        Install-Package FirebirdSql.Data.FirebirdClient
      
       Esperamos a que termine la instalación que no suele tardar más de dos minutos y ahora ya podemos incluir el espacio de nombres en los archivos que sean necesarios 

       using FirebirdSql.Data.FirebirdClient;


    2.- Crear la cadena de conexión,

        private void testConnection()
       {
            string strCnn = "data source=192.168.0.2; initial catalog=MiAliasDeBaseDeDatos;user id=SYSDBA;password=masterkey;port number=3050"

           FbConnection cnn = new FbConnection();
           cnn.ConnectionString = strCnn;
    
            try
            {
                cnn.Open();
                cnn.Close();
                MessageBox.Show("Conexión Exitosa","Información");
            }
            catch (Exception er)
            {
                MessageBox.Show("Error al tratar de abrir la base dedatos. " + er.Message.ToString(), "Error");
            }

}



martes, 8 de diciembre de 2015

VPN Error 800. Habilitar Conexión L2LP o PPTP detrás de un NAT en Windows XP, Vista ó 7

Ya que tenemos configurado nuestro servidor VPN es común que al intentar conectarnos a la VPN desde un equipo con windows XP, Vista o 7 usando  el protocolo PPT o L2LP se genera un error 800. Este error puede tener muchas causas pero quizás la mas común es que Windos, (Xp, vista y 7)  de manera predeterminad no permite el uso de IPSEC en equipos que se encuentran detrás de un NAT (en este caso el ruteador ) . para solventar el problema hay que realizar los siguientes pasos.

1 Abrir el registro de Windows (Inicio->>Ejecuta "RegEdit" )

2.-Navegas hasta HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent

3.-Agregar la siguiente clave AssumeUDPEncapsulationContextOnSendRuley (Edicin->>Nuevo->>Valor Dword 32 bits)

4.-Establecer el valor de la entrada creada en 2 (Dar doble clic en la entrada creada para poder modificar el valor).

Reiniciar nuestro equipo

Con esto debemos poder conectarnos a nuestra VPN.

Saludos cordiales.



miércoles, 18 de noviembre de 2015

Nomenclatura Tablas Aspel Caja 3.5

Como lo he mencionado en otra entrada Aspel Caja  crea, diariamente, varias tablas para su funcionamiento cosa que es bastante ineficiente, creo que eso también ya lo he dicho en la entrada anterior pero no me cansaré de decirlo.

Siempre es importante saber la nomenclatura que usa CAJA, para nombrar a sus tablas

XCCDDMMX

Dónde

X : Puede ser

               V  = Tabla que contiene las notas de Ventas
               D  =  Tabla que contiene el Detalle de las notas de Venta  (es decir las partidas de cada nota)
                I   =  Tabla que contiene el detalle de los Impuestos cobrados en cada Nota
                B  = Tabla que contiene una Bitácora de los movimientos realizados en el sistema

CC: Número de caja o sucursal (esto depende si se esta administrando por caja o por sucursal)

DD: Día de operación  (dos dígitos)

MM= Mes de Operación (dos digitos)

X = Año de la operación ( una letra que representa el año de la operación  S= 2013, T=2015, U=2015 ...)

Sin duda a la gente de Aspel les gusta complicar las cosas, pues de entrada no hay necesidad de crear una tabla para cada día de operación y luego la nomenclatura que usaron (especialmente en los años), bueno eso no tiene perdón.

Finalmente les dejo una pequeña función en VBA que  Toma una fecha y devuelve una cadena que con el formato usado Por aspel caja, para que en caso de tener que hacer una consulta dinámica ustedes solo agreguen la tabla que desean consultar y el numero de caja o sucursal.

Este es un ejemplo de como se podría construir una consulta para obtener los datos de las notas de Venta de Aspel Caja para la tienda o caja 01 (V= Ventas , 01= No Caja o Sucursal)

qry = "         SELECT *  FROM  V01" +  FechaCaja(ToDay());


'-------------------------------------------------------------------------------------------------
'Devuelve una cadena que representa la fecha con la nomenclatura usada por Caja35 en el formato usado por aspel caja 3.5
'Formato de fecha Caja: ddmmx
'           Donde: dd= 2 digitos para dia mm= 2 digitos para mes x=  1  letra para año (S= 2013, T=2014)
'
'-------------------------------------------------------------------------------------------------
Private Function FechaCaja(Fecha As Date) As String
    Dim FecCaja As String
         
    'Obtiene el dìa al nombre de talba
    If Day(Fecha) < 10 Then
        FecCaja = "0" & CStr(Day(Fecha))
    Else
        FecCaja = FecCaja & CStr(Day(Fecha))
 
    End If
 
    'agrega el mes (mm) al nombre de la tabla
    If Month(Fecha) < 10 Then
        FecCaja = FecCaja & "0" & CStr(Month(Fecha))
    Else
        FecCaja = FecCaja & CStr(Month(Fecha))
    End If
 
    'Agrega la letra correspondiente al año, tomando en cuenta que en el sistena
    'El año 2013 corresponde a la letra S --1930 Representa el incremento inicial--
 
    FecCaja = FecCaja & Chr(Year(Fecha) - 1930)
 
    FechaCaja = FecCaja
 
End Function

sábado, 24 de octubre de 2015

UPS: AVR Regulación Automática de Energia


En esencia un UPS o NO-BREAK, es un dispositivo que provee energía eléctrica a los equipos que se encuentran conectados a el durante un corte o interrupción de energía eléctrica. 

 De manera adicional estos aparatos normalmente cuentan con un sistema de regulación automática de energía (AVR), este sistema tiene como función mantener el voltaje dentro de los limites aceptables es decir evita bajos voltajes o picos de voltajes.  Si el sistema de regulación automática no es capaz de mantener el voltaje en n valor aceptable entonces dejara de suministrar la energía de la fuente principal y entrarán en funcionamiento las baterías. 

 


viernes, 10 de julio de 2015

CONFIGURACIÓN AUTOMÁTICA SERVIDOR PROXY



Ya hemos hablado y definido que es un Servidor Proxy WEB, de los beneficios que nos puede brindar y de las opciones que tenemos para instalar, así que en esta ocasión hablaré de los requisitos para, que los clientes Web, puedan configurar automáticamente el el servidor proxy que deben usar estando en nuestra red local


Un problema al momento de instalar nuestro servidor Proxy es que si lo instalamos en modo transparente (sin configuración explicita en el cliente), el filtrado no suele ser eficaz, pues las peticiones https normalmente no pueden ser manejadas por el servidor  Proxy. Por otro lado si optamos por la configuración explicita en el lado del cliente, nos encontramos con el problema de tener que configurar cada cliente con la dirección y puerto del proxy imagina que  debemos configurar manualmente 200 clientes (computdoras). 

Aquí es cuando entra en acción el WPAD o Protocolo para la Detección Automática del Servidor Proxy. Este protocolo tiene como objetivo permitir a los clientes Web conocer la ubicación de un "archivito" llamado  proxy auto-config; este archivo es el encargado de brindar la "Configuración que el cliente debe usar para configurar el uso del Servidor Proxy"

El protocolo o mejor dicho el estándar (ya que se publicó solo como borrador)  WPAP indica que hay dos maneras de "informarle" al cliente Web dónde se encuentra este archivo, la primer manera es mediante la configuracion DHCP , si así es en este caso el servidor DHCP (si es que se tiene configurado uno) , no solo proporcionara la información de la configración IP que el cliente debe usar para el acceso a al red sino que tambien indica donde se encuentra el archivo proxy auto-config (.pac), la otra opción es mediante el servidor DNS


Desde mi punto de vista la mejor manera de hacerlo es mediante la opción DNS, pues en el caso de DHCP no todos los clientes Web lo soportan por ejemplo Mizilla y Google solo soportan la configuración mediante DNS y no mediante DHCP en el caso de IE, soport aambas.


Ejemplo del Archivo Proxy Autoconfig

function FindProxyForURL(url, host)
{
if (isPlainHostName(host))
return "DIRECT";
else
return "PROXY proxy:80";
}


Nota acerca del modo transparente:

Cuando el Proxy está configurado en modo transparente Squid  no es capas de aplicar las reglas de filtrado, es debido, entre otras cosas,  a que la conexión no se hace a través del puerto 80 sino de un puerto seguro 443, (Existe una técnica llamada SSL Bump, que ofrece una posible solución a este problema pero por el momento no la tocaremos; y si estas pensando en usarla solo ten cuidado de avisar a tus usuarios pues podríamos incurrir en una violación a la privacidad). 




martes, 2 de junio de 2015

C# Filtrando un DataGrid

En esta entrada explicaré como filtrar un GridView en C#.

Hay varias formas de filtrar el contenido de un GridView

1.- Modificando la consulta del DataSource y volver a llenar o enlazar el Grid o Rejilla
    El problema de este método es que se genera carga innecesaria al servidor, trafico en la red y posiblemente el usuario experimente cierta lentitud.

2.- Aplicando un filtro al DataSource (Tratandolo como una Tabla)
   En este caso solo se filtran los datos de manera local , no se realiza una nueva consulta a la base de datos.

Para poder realizar este tipo de filtrado lo único que debemos hacer es tratar al DataSet como una Tabla (cast) y una aplicar RowFilter de la propiedad DefaultView

Ejemplo Básico:

  (grdVieComprobantesListado.DataSource as DataTable).DefaultView.RowFilter = 'SERIE = AB"



Ejemplo Complejo

Para este ejemplo partiremos de un formulario que uso para visualizar las facturas emitidas, El formulario tiene en la primer parte todos los filtros, posibles y en la segunda todas las facturas emitidas que cumplan con los filtros.




Lo mas laborioso es crear el procedimiento que nos devolverá la cadena con  el filtro que vamos a aplicar, en este caso podemos filtrar por Serie por Folio POR UUID, por fechas etc.


 /// <summary>
 /// Analiza los valores de los TextBox usados para el filtro 
 /// y devuelve una cadena con el filtro Resultante (Sólo toma        encuenta los cuadros de texto que tiene un valor en la propiedad Text)
/// La operación lógica de concatenación es AND 
/// La operación lógica de comparacion es = (Igual) excepto para los caos del Nombre del Receptor y el UUID en cuyo caso se usa el operador LIKE  
/// </summary>
private string CrearFiltro()
{
    string filtro = "1=1 ";
    
    if (!string.IsNullOrEmpty(txtSerie.Text))
        filtro += " AND Serie = " + "'" + txtSerie.Text +"'" ;

    if(!String.IsNullOrEmpty(txtFolio.Text))
        filtro += "AND Folio = " + txtFolio.Text;

    if (!String.IsNullOrEmpty(txtReferencia.Text))
        filtro += "AND Referencia = " +(""+txtReferencia.Text+""+);

    if (!String.IsNullOrEmpty(txtRfcReceptor.Text))
         filtro += " AND RfcReceptor = " +(""+txtRfcReceptor.Text+"");

    if (!String.IsNullOrEmpty(txtNomReceptor.Text))
         filtro += " AND Receptor like " +( ("'%" + txtNomReceptor.Text + "%'"));
           
    if (!String.IsNullOrEmpty(txtUUID.Text))
         filtro += " AND UUID like " + "'%" + txtUUID.Text + "%'"));

    if (chkFilFechas.Checked)
    {
         filtro += "AND FechaEmision >= " + "" +( dtpFecEmiInicial.Value.Date.ToString() + "");
                filtro += "AND FechaEmision <= " + ""+ dtpFecEmiFinal.Value.Date.AddHours(23.999).ToString() +""+);
            }


    return filtro;

        }

/// <summary>
        /// Aplica los filtros al grid
        /// </summary>
        private void FiltrarGrid()
        {
            (grdVieComprobantesListado.DataSource as DataTable).DefaultView.RowFilter = CrearFiltro(); 

        }


Finalmente en cada uno de los controles en el evento Lave o Change podemos invocar al método CrearFiltro


sábado, 4 de abril de 2015

Facturación Electrónica

Desde hace  algún tiempo en México es obligatorio la facturación electrónica que a groso modo es la obligación del contribuyen de emitir facturas, notas de crédito, recibos de nómina  y demás comprobantes fiscales en un formato electrónico siguiendo cuidadosamente un conjunto de reglas establecidas por el SAT,  (Anexo 20); firmar el archivo con nuestro Certificado de Sello Digital (CDS) y enviarlo a  un PAC para que nos lo valide y firme el SAT.

Si bien existen infinidad de soluciones en el mercado para la generación de facturas y demás comprobantes Digitales por Internet (CFDIs), muchas veces nos vemos en la necesidad de tener que desarrollar una solución propia para dar respuesta a requerimientos muy específicos de nuestros usuario o lograr la integración con los actuales sistemas que se encuentran en la empresa, sea cual sea el caso si tu estas interesado en aprender a generar por tus propios medios el archivo XML y la representación impresa del mismo este blog te será de gran ayuda.

Dimensionando el trabajo

Si bien es cierto que la generación de Facturas electrónicas no es un proceso sencillo tampoco te dejes espantar ni mucho menos te desanimes solo debes armarte con paciencia, curiosidad y algunas herramientas informáticas. ¿Si  somos los que lo hemos logrado por que tu no lo harías?.
Las herramientas que utilizaremos son las siguientes pero no te preocupes por tenerlas todas en este momento con forme avance en tu proyecto las puedes ir descargando

1.-Visual estudio 2012 (Preferentmente)
2.-Heramienta XSD en línea de comandos
3.-Open SSL
4.-Itex Sharp

Pasos Para crear el CFDI

1.- Crear el archivo XML con toda la información requerida por el SAT (emisor, receptor, conceptos etc. Descarga el anexo 20 que será tu libro de cabecera durante casi todo el proyecto)

2.-Crear la cadena de verificación (esto es un resumen del documento creado  en el paso anterior)

3.-Firmar la cadena de verificación con la FIEL o el CSD (Aquí las cosas se pondrían un poco ruda pero gracias a Dios hay mucha gente que colabora en la red y disponemos de una librería open source para esta tarea,Open SSL)

4.-Incorporar la cadena Firmada al XML creado

5.-Enviar el   XML para ser sellado por el SAT
Si no hubo ningún error debemos crear la representación impresa del XML

Divide y Vencerás
Lo primero en lo que nos enfocaremos en crear el archivo XML, despues en sellar el documento y finalmente en crear el PDF.

Para la creación del XML hay varias alternativas, en nuestro caso optaremos por la serialización-deserialización que en pocas palabras podemos definir de la siguiente manera:


Serializar: Consisten en representar un objeo y su estado en un lenguaje especifico, los lenguajes mas comunes para la serialización son JSON y XML.

Deserializar: Consiste en el proceso inverso, es decir tomar la definición del XML o JSON y crear un
objeto o instancia de clase.

Junto con estos conceptos entra en escena nuestra primer herramienta

xsd.exe tool  Esta es una herramienta que viene integrada en el  .Net Framework Software Developmen Kit y nos permite crear una clase a paritr de un XSD. Asi es partiendo de una definicion en XML podemos obtener una o más clases que representen el esquema definido en el archivo XSD


Esta es la manera en la que obtendremos nuestras clases a partir del XSD que nos da el SAT (desde http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd)

viernes, 6 de marzo de 2015

Agregar el xsi:schemaLocation XML a partir de la serialización


       Actualmente estoy trabajando en un proyecto para implementar la facturación electrónica o CFDI. en mi caso  el XML lo obtengo a partir de la serializacion (convertir una clase en un XML) y uno de mis dolores de cabeza fue lograr que el XML contenga el xsi:schemaLocation;

Para solucionarlo es muy sencillo en la clase generada por la herramienta xsd hay que agregar una propiedad o campo quedando de la siguiente manera, marcado como instancia del Namespace:

public partial class Comprobante {

    [XmlAttribute(Namespace = XmlSchema.InstanceNamespace)]    public string schemaLocation = "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd";