xTrela.Catalogo Web

marzo 24, 2011 11:36 by AlbertoBasalo

Aplicación web -compatible con iPad, iPhone, Windows-  para la consulta de información comercial y de márquetin –revistas, noticias, folletos, notas de producto,…- organizada por fechas y categorías configurables.

La información visualizada permite navegar hasta los productos del catálogo: Así desde una publicación se accede a los productos relacionados y desde estos a la nota comercial de producto o colección.  También se pueden pasar los documentos seleccionados como si de un libro se tratara.

 

Pensado para que los vendedores dispongan de un centro de información comercial y de márquetin sobre los productos de la compañía, o para que los clientes en la tienda o en una feria puedan conocer los productos de la compañía utilizando dispositivos con una buena experiencia de usuario, como el iPad.

Las consultas básicas más comunes pueden ser últimas publicaciones, publicaciones de un medio determinado, últimas colecciones,… . El usuario puede también combinar los criterios de búsqueda para localizar tipos de artículos determinados, con un acabado, color, año, temporada….

 

 

 

Esta aplicación se puede desplegar en intranets, en tiendas, e incluso en internet. Permitiendo áreas de uso restringido a usuarios internos.  

 

 

 

En definitiva una herramienta que aporta valor y facilita el acceso al gran volumen de información que toda empresa genera, recaba, maneja y distribuye para aumentar sus ventas, dar a conocer sus productos y mejorar su imagen de marca, pero que no llega de manera efectiva a empleados y clientes.


Actualmente calificado con 3.0 por 10 personas

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Identificadores Universales

diciembre 23, 2010 11:14 by AlbertoBasalo

Cuando trabajamos con bases de datos relacionales, los identificadores únicos de registro son imprescindibles. Es verdad que siempre se pueden encontrar claves candidatas semánticas, pero para establecer relaciones entre tablas, nada como usar un solo campo numérico. Esto mejora la velocidad y simplifica las consultas.  Si además ese campo no tiene valor para el negocio, no habrá que preocuparse de renumeraciones, huecos, lotes …

En sistemas centralizados la generación de identificadores únicos no representa mayor problema, ya que los fabricantes nos ofrecen mecanismos de generación secuencial de números para identificar nuevos registros. Pero si quisiéramos un mayor control que evitase huecos o aportase algún valor  semántico a los códigos, nos bastaría con implementar algún sistema de contadores personal. El más común, se basa en una tabla en la que se almacena el último número emitido. Dicha tabla de contadores debe estar protegida y sólo debe ser accesible a través de un procedimiento que calcule, devuelva y registre el valor siguiente para un contador.

Las bases de datos distribuidas complican la generación de identificadores únicos, pues  tanto los autonuméricos como los contadores personalizados son irrepetibles sólo dentro de un ámbito, ya sea este una instancia de base de datos personal, un servidor de bases de datos dedicado o una red local de servidores. Pero esto no es válido para sistemas desconectados como pueda ser la red de tiendas de una multinacional que requiera la consolidación cuasi online de los datos producidos.

De nuevo, hay soluciones estándar como el UUID y la implementación GUID de Microsoft que garantizan razonablemente la universalidad de los códigos generados. A cambio, el coste es tremendo: ¡cada código ocupa 16 bytes!. Conviene recordar que el tipo de datos estándar int ocupa sólo 4 bytes, y que para tablas realmente enormes podríamos usar el bigint de 8 bytes. Además, aunque el gigantesco GUID se almacena en 4 bytes, no se muestra como un número, si no como un churro de 32 caracteres muy poco user friendly a la hora de realizar consultas directas contra la base de datos.

La solución por la que hemos optado en Lusco combina la generación local de contadores, con un identificador del terminal que los generó. El resultado es un número único dentro del universo de nuestra aplicación. Este patrón obliga a registrar cada instancia de base de datos en un servidor central, pero esto, lejos de ser un inconveniente ayuda a gestionar un parque numeroso de instalaciones… aunque eso ya es materia para otro post.


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Operaciones de datos con DataServices vs Custom WCF Services

abril 21, 2009 10:44 by albertobasalo

ADO.Net DataServices facilita el desarrollo N-Tier de aplicaciones que se apoyen en ADO.Net Entity Framework, exponiendo una fachada de servicios CRUD que mediante una interface REST muy sencilla de usar. Para mayor comodidad dispone de librerías cliente para llamar a esa interfaz y consultarla mediante LINQ.

Los programadores pueden extender la funcionalidad básica del servicio mediante métodos interceptores, como el siguiente, en el que validamos o completamos la entidad antes de la operación :

[ChangeInterceptor("Fichas")]
public void OnChangeFichas(Ficha ficha, UpdateOperations action)
{
    try
    {
        switch (action)
        {
            case UpdateOperations.Add:
                Logic.Fichas.Validate(ficha);
                ficha.IdFicha = Logic.Fichas.GetNewGUID();
                break;
            case UpdateOperations.Change:
                Logic.Fichas.Validate(ficha);
                break;
        }
    }
    catch(Exception ex)
    {
        throw new DataServiceException("No se ha podido realizar la operacion", ex);
    }
}

Esto puede ser suficiente en muchos casos, pero también tiene limitaciones. Al ser métodos sin valor de retorno nos dificulta la obtención del estado del objeto posterior a la ejecución, por ejemplo no dispondríamos del GUID en el cliente. Además este interceptor se ejecuta antes de la operación y no ofrece ningún evento a posteriori, esto impide llamar a lógicas de negocio en el servidor que se ejecuten transaccionalmente con la operación o después de esta.

Por el contrario los servicios WCF ofrecen flexibilidad total tanto en funcionalidad como en infraestructura, a costa de un poco más de código y una configuración mas tediosa.

El ejemplo anterior puede resolverse con los siguientes métodos:

public Ficha AddFicha(Ficha ficha)
{
    try
    {
        Logic.Fichas.Validate(ficha);
        ficha.IdFicha = Logic.Fichas.GetNewGUID();
        using (var context = new Context())
        {
            context.Attach(ficha);
            context.SaveChanges();
        }
        return ficha;
    }
    catch (Exception ex)
    {
        Log.Excepcion(ex);
        throw new FaultException("No se ha podido agregar la ficha por " + ex.Message);
    }
}

Para actualizar entidades se usa un método extensor que asegure que la entidad inicialmente desatachada se persista en base de datos, según explica Cesar De La Torre en su blog

public Ficha UpdateFicha(Ficha ficha)
{
    try
    {
        Logic.Fichas.Validate(ficha);
        using (var context = new Context())
        {
            context.Attach(ficha);
            ficha.SetAllModified(context);
            using (var transaction = context.Connection.BeginTransaction())
            {
                context.SaveChanges();
                Logic.Fichas.PostProcess(ficha);
                transaction.Commit();
            }
        }
        return ficha;
    }
    catch (Exception ex)
    {
        Log.Excepcion(ex);
        throw new FaultException("No se ha podido actualizar la ficha por " + ex.Message);
    }
}

En fin, una vez mas .Net ofrece alternativas para un mismo fin y depende de las circunstancias el elegir la más directa o la más flexible.

Agradecimiento  especial a los consultores de Plain Concepts cuyos conocimientos sobre arquitectura de software y tecnologías Microsoft son apabullantes. Espero vuestros comentarios.

Actualmente calificado con 4.0 por 1 personas

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5