scieee AI-readable full text Open interactive document viewer

Stock-3 metagestión de stock multiagencia y multiusuario

Terrés Cayuelas, Darío

Abstract

La aplicación Stock3 fue desarrollada como aplicación de gestión, fácilmente accesible, de una infraestructura logística de transporte y distribución ya existente de la empresa Duco. Se basa en el paradigma de servidor-cliente centralizando todas las operaciones y estructura de datos en el servidor de la aplicación. Para conseguir una mayor accesibilidad e implantación de la herramienta, utiliza tecnologías web que precisan únicamente un navegador que cumpla al menos los estándares básicos y una conexión a Internet. La herramienta de gestión representa el funcionamiento real de la empresa y su relación con otras empresas (agencias) con las que mantiene un contrato de gestión de sus clientes y mercancías. Así la aplicación mantiene un macro-modelo de gestión de almacenaje con modelos más básicos visibles a través de los clientes y las agencias gestionadas. El interfaz básico con la gestión del modelo lógico subyacente es a través de las operaciones disponibles de un usuario autentificado. Se crea así una jerarquía de usuarios para los que hay disponible un conjunto de operaciones determinada y a su vez esas operaciones tienen un ámbito de acción limitado a su espectro y entidad a la que pertenecen. Existen varios roles, desde lo alto de la pirámide de nivel, que es el Superusuario, a los usuarios no administradores de clientes. Ésta organización obedece a las premisas de los tipos de usuarios que van a utilizar la herramienta. Por ejemplo, hay operarios de almacén que no han de poder modificar datos críticos de acceso y otros que son administradores, por tanto se han implementado usuarios administradores de agencia y de clientes y usuarios no administradores de ambos.

Full text

PROYECTO FINAL DE CARRERA Stock-3 Metagestión de Stock Multiagencia y Multiusuario. Director: Sergio Saez Barona Alumno: Darío Terrés Cayuelas Titulación: Ingeniería en Informática Fecha: 28-09-2011 2 3 Índice de contenidos 1. Introducción …………………………………………………………………………………………………………….… 5 1.1 Objetivos y resumen del proyecto …………………………………………..……………………...... 5 1.2 Problema planteado ……………………………………………………………………………..…………… 6 1.3 Estructura del proyecto ……………………………………………………………………………………… 6 2. Especificación de requisitos………. …............................................................................... 7 2.1. Introducción……..................................................................................................... 7 2.1.1. Propósito ……................................................................................................ 7 2.1.2. Ámbito .......................................................................................................... 7 2.1.3. Definiciones …………………………………………………………………………………….…..…… 8 2.1.4. Referencias.................................................................................................... 9 2.1.5. Apreciación global ........................................................................................10 2.2. Descripción global .............................................................................................. 10 2.2.1. Perspectiva del producto ........................................................................... 11 2.2.2. Funciones del producto .................................................................................11 2.2.3. Características del usuario ............................................................................12 2.2.4. Restricciones generales ................................................................................13 2.2.5. Supuestos y dependencias .......................................................................... 13 2.2.6. Requisitos pendientes……………………………….…………………………………..………… 13 2.3. Requisitos Específicos .......................................................................................... 13 2.3.1. Requisitos de interfaces externos ……………….............................................. 13 2.3.2. Requisitos funcionales …………….....................................................................14 2.3.3. Requisitos de eficiencia ……......................................................................... 14 2.3.4. Restricciones de diseño ............................................................................... 14 2.3.4.1. Limitaciones del hardware................................................................ 15 2.3.5. Atributos ……………………............................................................................... 14 2.3.5.1. Seguridad........................................................................................... 14 2.3.5.2. Mantenimiento.................................................................................. 15 2.3.6. Otros requisitos........................................................................................... 15 2.3.7. Bases de datos............................................................................................. 15 2.3.8. Operaciones y adaptación de situaciones ...................................................15 3. Análisis ………………………………………………………………………………………………………………………21 3.1. Diagrama de clases ..………………………………………………………………………………………….21 3.1.1. Diagrama de clases UML …………………………………………………………………………..22 3.2. Casos de uso ……………………………………………………………………………………………………..23 3.2.1. Caso General …………………………………………………………………………………………….23 3.2.2. Casos de uso de usuarios de un Cliente …………………………………………………….24 3.2.3. Casos de uso de usuarios de una Agencia …………………………………………………25 3.2.4. Casos de uso de Superadministrador ……………………………………………………….26 3.2.5. Casos de uso principales desarrollados …………………………………………………….27 3.2.6. Diagramas de secuencia …………………………………………………………………………..33 4. Diseño ………………………….…………………………………………………………………………………………..35 4.1. Arquitectura …………………………………………………………………………………………………….35 4.2. Arquitectura en 3 capas……………………………………………………………………………………36 4.2.1. Capa de presentación……………………………………………………………………………….37 4.2.1.1. Interfaz de Usuario………………………………………………………………………….37 4.2.1.2. Diseño gráfico…………………………………………………………………………………38 4.2.2. Capa de lógica de negocio………………………………………………………………………..39 4 4.2.3. Capa de Datos………………………………………………………………………………………….40 4.2.3.1. Diseño de la base de datos…………………………………………………………….40 4.2.3.1.1. Modelo relacional………………………………………………………………..40 5. Implementación ………………………………………………………………………………………………………43 5.1. Tecnologías empleadas…………………………………………………………………………………….43 5.1.1. ¿Porqué usar software libre?........................................................................43 5.1.2. Parte Cliente……………………………………………………………………………………………..44 5.1.2.1. XHTML…………………………………………………………………………………………....44 5.1.2.2. CSS…………………………………………………………………………………………………..44 5.1.2.3. Javascript…………………………………………………………………………………………44 5.1.2.4. Prototype………………………………………………………………………………………..45 5.1.3. Parte servidor……………………………………………………………………………………………45 5.1.3.1. PHP………………………………………………………………………………………………….45 5.1.3.2. MySQL…………………………………………………………………………………………….46 5.1.3.3. Apache……………………………………………………………………………………………47 5.1.3.4. Plantillas ITX……………………………………………………………………………………47 5.1.4. Comunicación Cliente Servidor…………………………………………………………………47 5.1.4.1. AJAX……………………………………………………………………………………………….48 5.2. Interfaces software implementadas ………………………………………………………………..48 5.2.1. Diagrama de alcanzabilidad desde el menú …………………………………………….49 5.2.2. Diagrama del servicio web AJAX ……………………………………………………………..50 5.2.2.1. Secuencia de llamadas del servicio web ………………………………………...51 5.2.3. Javascript en el cliente …………………………………………………………………………….52 6. Manual de Usuario …………………………………………………………………………………………………..53 6.1. Agencias …………………………………………………………………………………………………………..56 6.1.1. Superusuario y Administrador ………….……………………………………………………..56 6.1.1.1. Gestión de Cuentas ………….…………………………………………………………….63 6.1.2. Operador ………….……………………………………………………………………………………..67 6.2. Clientes …………………………………………………………………………………………………………….68 6.2.1. Usuario General ………….……………………………………………………………………………68 6.2.2. Administrador …………..………………………………………………………………………………72 7. Conclusiones ……………………………………………………………………………………………………………..73 8. Referencias………………………………………………………………………………………………………………..76 9. Anexo…………………………………………………………………………………………………………………………77 5 1. Introducción 1.1. Objetivos y resumen del proyecto La aplicación Stock3 fue desarrollada como aplicación de gestión, fácilmente accesible, de una infraestructura logística de transporte y distribución ya existente de la empresa Duco. Se basa en el paradigma de servidor-cliente centralizando todas las operaciones y estructura de datos en el servidor de la aplicación. Para conseguir una mayor accesibilidad e implantación de la herramienta, utiliza tecnologías web que precisan únicamente un navegador que cumpla al menos los estándares básicos y una conexión a Internet. La herramienta de gestión representa el funcionamiento real de la empresa y su relación con otras empresas (agencias) con las que mantiene un contrato de gestión de sus clientes y mercancías. Así la aplicación mantiene un macro-modelo de gestión de almacenaje con modelos más básicos visibles a través de los clientes y las agencias gestionadas. El interfaz básico con la gestión del modelo lógico subyacente es a través de las operaciones disponibles de un usuario autentificado. Se crea así una jerarquía de usuarios para los que hay disponible un conjunto de operaciones determinada y a su vez esas operaciones tienen un ámbito de acción limitado a su espectro y entidad a la que pertenecen. Existen varios roles, desde lo alto de la pirámide de nivel, que es el Superusuario, a los usuarios no administradores de clientes. Ésta organización obedece a las premisas de los tipos de usuarios que van a utilizar la herramienta. Por ejemplo, hay operarios de almacén que no han de poder modificar datos críticos de acceso y otros que son administradores, por tanto se han implementado usuarios administradores de agencia y de clientes y usuarios no administradores de ambos. 1.2. Problema planteado La aplicación tiene que representar una estructura funcional basada en un comportamiento logístico no informatizado hasta ahora. Luego tiene que modelizar el sistema del mundo real en un sistema bien definido y acotado. Ésta labor supone un esfuerzo inicial de análisis, siempre necesario, de forma que las necesidades del cliente y el modelizado del sistema queden bien definidos. 6 En ésta fase la comunicación es crucial y en éste caso no fue óptima desde un principio al contar con intermediarios y escasa interacción en ambas direcciones, lo que dio lugar a modificaciones tardías en algunos aspectos. 1.3. Estructura del proyecto El proyecto por tanto se dividió en una primera fase de análisis y comunicación con el cliente, una segunda fase de diseño y una tercera fase de desarrollo. La primera y segunda fase se solaparon de forma que conforme se iban acotando y definiendo los detalles del proyecto se creaban diseños funcionales, casos de uso (se confeccionó un documento siguiendo la especificación IEEE-830 de requisitos) y diseños de datos que se correspondieran con las ideas transmitidas del proyecto para poner a prueba la realización de tales requisitos e implicaciones, que se contrastaban en comunicaciones posteriores con el cliente. Un error inicial en el desarrollo del proyecto fue partir de una aplicación previamente realizada para el mismo cliente pero con requisitos bastante más simples, lo que propició que la fase de desarrollo atravesase una mala implementación parcial inicial hasta que se decidió rediseñar correctamente casi de cero la estructura, adoptando en este nuevo rediseño tecnología AJAX de comunicación con el servidor. No obstante ese error costó mucho tiempo de desarrollo desperdiciado. 7 2. Especificación de requisitos 2.1. Introducción 2.1.1. Propósito El propósito de la presente ERS es definir los requisitos que debe cumplir el sistema de información de gestión de almacenaje por agencia y cliente de Duco. Está dirigida al departamento correspondiente, si bien puede ser leída también por cualquier persona que quiera entender el funcionamiento del sistema implementado. 2.1.2 Ámbito: El producto que vamos a describir es un sistema de información asociado a la gestión de almacenaje de la compañía Duco. Esta compañía gestiona diferentes agencias de transporte para clientes que poseen almacenadas mercancías en alguna de ellas. Al mismo tiempo los clientes envían órdenes de transporte de dichas mercancías a otras empresas/consignatarios. Mediante el presente producto se podrá gestionar el almacenaje y envío de todas las mercancías que cada cliente tenga, al consignatario que quiera. Duco gestionará las agencias que operan con ella, sus clientes que serán globales y los históricos de cada uno, así como el análisis de las operaciones realizadas por cada usuario asociado a cada entidad, ya sea cliente o agencia. Se les facilita a estas, con el presente sistema, una forma de gestionar el almacenaje y los envíos de cada uno de los clientes que trabaje con ellos y Duco. Cada agencia podrá insertar lotes de mercancías que cada cliente les envíe o que hayan sido enviadas a estos y generar un informe/albarán de recepción. Consultar dichos lotes y sus fechas de inserción y manufactura/creación del producto que contiene. Definir nuevos tipos de 8 productos en la base de datos general. Generar expediciones con las peticiones de envío de los clientes y su correspondiente informe/albarán imprimible y almacenable. También pueden generar facturas para sus clientes incluyendo las expediciones que deseen y exportarlas en archivos de contabilidad. 2.1.3 Definiciones Cliente: Cliente de alguna de las agencias gestionadas por Duco y a la vez cliente de Duco. Es global y único ya que se le referenciará de la misma forma desde las agencias y Duco. Agencia: Empresa de almacenaje y envío de mercancías que trabaja con Duco para gestionar y enviar sus mercancías. Lote: Elemento de almacenaje y transporte, divisible en unidades individuales. Formado por elementos de un Artículo determinado. Describe la mercancía y está asociado a cada cliente y su correspondiente agencia donde se almacena. Artículo: Clasificación de elementos que pueden componer los lotes. Poseen una relación palets/unidad asociada que permite saber cuantos palets y unidades de picking se necesitan para unas unidades de un lote de un tipo de artículo. Estas clases son también globales ya que ayudan a identificar qué contienen los lotes y ha de guardarse una relación general. Envío: Solicitud de envío de mercancías almacenadas en alguna o varias agencias por parte de un Cliente. También referenciable como Petición de envío. Expedición: Envío de mercancías parcial o total referente a una 9 Petición de Envío de un Cliente realizado por una Agencia para suplir tal petición. Informe/Albarán: Informe concreto sobre datos como recepción de mercancías de un cliente, justificante de envío/expedición de mercancías a un consignatario, etc. Usuario: Empleado/operador autorizado para acceder a la aplicación que forma parte de una Agencia, una empresa/entidad Cliente o Duco. Existen diferentes niveles de permisos de acceso para los usuarios de cada entidad, así como existen diferentes tipos para los usuarios de una misma entidad. pej.: Un usuario de Duco es capaz de listar históricos de todas las agencias, cuando un usuario de una agencia no. Un usuario administrador de un Cliente o Agencia puede crear otros usuarios para otros empleados de la misma entidad. Consignatario: Destinatario de una Petición de Envío. Se asocia a cada Cliente y es referenciable una vez introducido. ERS: Especificación de Requisitos, documento presente. Describe formalmente las funcionalidades del producto y lo que el cliente (quien adquiere el derecho de uso del producto) debe esperar de éste. Este documento tiene cierta validez legal una vez aceptado por el cliente, dependiendo de la legislación de cada país según lo establecido en el IEEE830. 2.1.4. Referencias [1] IEEE Std 830-IEEE Guide to Software Requirements Specifications. IEEE Standards Board. 345 Eas 47th Street. New York, NY 10017, USA. 1984. [2] Javier Ibáñez, Germán Vidal. Ingeniería de Requisitos (INR) (prácticas) 16 2.3.2.11. Dar de alta la recepción de un Lote de mercancías. La aplicación permite a las agencias insertar/dar de alta nuevos lotes de mercancías que reciban para un cliente. Será necesario dar de alta el cliente que recibe el lote en la agencia en caso de no existir el cliente en la base de datos. En caso de existir, bastará con especificar cual es mediante su número de Cliente. Será necesario añadir un nuevo tipo de artículo si no existe el que describa el contenido del lote. En caso de existir, bastará con indicar el código de artículo. Para insertar el nuevo lote se necesitará incluir datos como el código de artículo, fecha de llegada, fecha de manufactura/creación (por motivos de dar salida primero a los que mas interesen o si es una mercancía perecedera), número de unidades y opcionalmente observaciones. 2.3.2.12. Crear una Expedición correspondiente a unidades de una Petición de Envío. La aplicación permitirá a las Agencias crear expediciones de unidades de lotes de un cliente que haya solicitado una Petición de Envío. El número de unidades enviadas en la expedición no excederá el número de unidades pendientes de envío de un lote para una petición de envío concreta. Se puede especificar en la misma expedición unidades de todos los lotes implicados en una misma petición de envío. Los datos necesarios para la creación de la expedición serán el código de la petición de envío, los códigos de los lotes de los que se envíen unidades, el número de unidades a enviar y la fecha de la expedición. Opcionalmente se puede documentar la expedición con la fecha de recepción cuando ésta esté disponible. La creación de expediciones cambiará el estado de las Peticiones de Envío de los Clientes, viendo éstos la información reflejada en sus consultas de Peticiones de Envíos. 2.3.2.13. Generar facturas/albaranes para un Cliente. La aplicación permitirá la generación de facturas imprimibles y almacenables externamente para las operaciones facturadas a un Cliente. 17 Estas facturas también pueden ser almacenadas en la aplicación para su regeneración cuando sea preciso y su consulta. Los archivos de exportación de las facturas imprimibles serán en formato PDF. 2.3.2.14. Generar informes/albaranes de una Recepción de Lotes. Las agencias tendrán la posibilidad de generar informes/albaranes imprimibles y almacenables externamente de las recepciones de lotes para un cliente. Éstos incluirán datos del cliente como número, nombre, telef. de contacto y de cada uno de los lotes recibidos, con los datos insertados sobre estos. El formato de los archivos será Adobe PDF. 2.3.2.15. Generar informes/albaranes de una Expedición. A modo de documentación externa y justificante de envío de una expedición, la aplicación permitirá generar informes/albaranes imprimibles y almacenables externamente a la aplicación. El formato será archivos Adobe PDF. 2.3.2.16. Exportar datos facturación en ficheros de contabilidad. La aplicación permitirá a una Agencia exportar datos de la facturación de un Cliente para trabajar con estos datos en otras aplicaciones. Los formatos están por definir y quedan pendientes para futuras revisiones. El tipo de fichero de exportación soportado será de Hojas de Cálculo Microsoft Excel. 2.3.2.17. Crear una Petición de Envío. La aplicación ofrece la funcionalidad a los Clientes de crear Peticiones de Envío para un número de unidades de cada uno de los lotes que posee en diferentes agencias. 18 Se precisa la especificación del consignatario/destinatario. En caso de no ser la primera vez que se crea un envío para el mismo consignatario, se puede elegir ya que la aplicación facilita una lista de los consignatarios anteriormente introducidos. Los consignatarios precisan de los siguientes datos para su validez: CIF, nombre, nombre de la persona de contacto, dirección, localidad, provincia, código postal, un teléfono de contacto y opcionalmente prefijo telefónico, dos teléfonos más y un fax. Será imposible crear peticiones de Envío que no posean alguna unidad de algún lote o no especifiquen consignatarios con los datos mínimos. 2.3.2.18. Consultar Lotes en todas las Agencias. Los usuarios de Clientes pueden consultar todos los lotes que tengan en todas las agencias, y filtrar su búsqueda con criterios como fechas de creación o recepción, periodos entre dos fechas, agencia, tipo de artículo y demás atributos de los lotes, y los atributos de las agencias asociadas. Los usuarios de Duco pueden seleccionar un cliente para listar sus lotes. 2.3.2.19. Consultar estado de las Peticiones de Envío. Los usuarios de Clientes pueden consultar el estado de todas las peticiones de envío correspondientes al Cliente. El programa permite filtrar las búsquedas por fechas de creación de la petición, envío de expediciones (parciales o completas con respecto a la petición de envío) y recepción de la petición de envío por parte del consignatario. Los usuarios de Duco también pueden consultar estos datos para cada cliente. 19 2.3.3. Requisitos de eficiencia. El producto permite ser manejado por múltiples usuarios simultáneamente, ya sean correspondientes a Duco, Agencias o Clientes. La información manejada será igual al tamaño de la base de datos y residirá en los servidores de Disbase. Cada terminal puede ser una máquina distinta o sesión distinta y estar situada en cualquier parte del globo es totalmente dependiente del sistema. La información será actualizada para cada sesión cada vez que haga una consulta. La eficiencia de concurrencia depende del número de usuarios que intenten acceder al sistema a la vez y las conexiones y terminales que usen. 2.3.4. Restricciones de diseño. 2.3.4.1. Limitaciones hardware. Las limitaciones hardware asociadas al uso del programa dependen de cuantas peticiones de servicio reciba el servidor central y datos puedan transmitir las conexiones involucradas. 2.3.5. Atributos. 2.3.5.1. Seguridad. Los datos transferidos son confiados a usuarios identificados en el sistema de información, siendo estos responsables de que sus terminales no comprometan la seguridad de estos y sus redes tampoco. Un nivel superior de seguridad podría implementarse en próximas revisiones eliminando la posibilidad de compromiso de la seguridad de la información por usar redes poco fiables. Los datos en la base de datos no se encuentran tampoco encriptados, pero el servidor no se encuentra accesible desde fuera de la aplicación, aislándolo así de intentos de acceso no autorizados. 20 2.3.5.2. Mantenimiento. Los técnicos de mantenimiento de Disbase mantendrán el sistema operativo en caso de alguna incidencia. Los usuarios de Duco y los administradores de cada entidad deberán mantener la organización y administración de todas las entidades y sus usuarios. Así como identificar posibles problemas y solventarlos o notificar a Disbase en caso de no tener los medios para hacerlo. 2.3.6. Otros requisitos. 2.3.6.1. Bases de Datos. El tipo de bases de datos utilizados será almacenado en el servidor de Disbase para tal efecto. Los técnicos de Disbase gestionarán estas bases de datos para cualquier operación de copia por mantenimiento o reparación. Se usará un gestor de base de datos relacional y concurrente de código libre y gran rendimiento, MySQL en la versión que Disbase considere oportuna. 2.3.6.2. Operaciones y adaptación de situaciones. Este programa se ha pensado para ser utilizado por múltiples usuarios simultáneamente, si bien es posible que un usuario que esté modificando unos datos se encuentre que mientras los introducía, otro usuario ha modificado los datos de los que partía. Esto se verá reflejado en el correspondiente diálogo de confirmación y/o notificación, imposibilitando falta de coherencia en los datos. 21 3. Análisis 3.1. Diagrama de clases El diagrama de clases UML es la columna del análisis y diseño orientado a objetos. El diagrama de clases UML muestra las clases del sistema, su interrelación (incluyendo herencia, agregación y asociación), las operaciones y atributos de éstas. 22 3.1.1 DIAGRAMA DE CLASES UML: -CIF : string -nombre -nombre_responsable -email -tel1 -tel2 -tel3 -fax Cliente +Consultar Lotes() +Crear Envio() +Consultar Estado Envio() +Modificar Perfil Propio() -usuario -contrasenya -nombre Usuario +Generar Informes de Lotes Propios() +Generar Informes de Envios Propios() +Generar Informes de Expediciones Propias() Usuario Cliente +Crear/Modificar un Artículo de Cliente Propio() +Crear/Modificar un Lote de Cliente Propio() +Crear/modificar Expediciones de Clientes Propios() +Generar Informes de Lotes de Clientes Propios() +Generar Informes de Envios de Clientes Propios() +Generar Informes de Expediciones Propias() Usuario Agencia +Crear Usuarios de Agencias y Clientes() +Borrar Usuarios de Agencias y Clientes() +Modificar Usuarios de Agencias y Clientes() +Crear Clientes() +Crear Agencias() +Generar Informes de Lotes() +Generar Informes de Expediciones() +Generar facturas de Clientes() +Exportar los Informes() Super -CIF : string -nombre -localidad -dirección -email -tel1 -tel2 -tel3 -fax Agencia -mi_cod_articulo -nombre -marca -unid_medida -unid_de_envase -unid_por_envase -peso_envase -vol_envase -precio_unitario -precio_envase -es_embalaje -envases_palet -stock_minimo -desc_comp -ns_lote Artículo -mi_num_lote -num_inicial_unidades -unidades_restantes -fecha_llegada -fecha_caducidad -observacion Lote -fecha_creacion -fecha_envio -fecha_entrega Envio -CIF -nombre -nombre_persona_contacto -direccion -localidad -provincia -cod_postal -pref_telefonico -tel1 -tel2 -tel3 -fax Consignatario -fecha_creacion -fecha_envio -fecha_entrega -num_consignatario -incidencia Expedición -nombre -calles -tramos -niveles -unid_bloque Almacén * 1 * 1 1 * -posee 1 -pertenece* 1 * 1 *1 * {xor} * * 1 * 1 * -unidades Parte de Expedición * -Refiere 1 -Forma parte * 1 +Crear Usuarios Propios() +Borrar Usuarios Propios() +Modificar Usuarios Propios() Administrador Usuario Normal Cliente Activo -cambio_estado : Date Cliente Bloqueado Agencia Activa -cambio_estado : Date Agencia Bloqueada -calle -tramo -nivel -unidades lote en almacén * -aloja 1 -alojado en -unidades -unid_no_disponibles ClaseAsociación1 * -compuesto de * -parte de * 1 23 3.2. Casos de uso Los casos de uso son una técnica de identificación y especificación del comportamiento de un sistema independientemente de cómo se vaya a implementar. Describe las operaciones que cada usuario, llamado actor en la nomenclatura UML, puede realizar además de sistemas externos que interactuaran con el sistema. 3.2.1. Caso General Podemos identificar el siguiente caso general: En él vemos la relación de herencia de operaciones entre diferentes tipos de usuarios identificados. Pasaremos a analizar en detalle los casos base de diferentes escenarios. Sistema de gestión de Stock Usuario Administrador Administrador Agencia Administrador Cliente Super Administrador «inherits» «inherits» «inherits» «inherits» «inherits» Super Usuario Agencia Usuario Cliente Usuario Agencia «inherits» «inherits» «uses» «uses» «uses» «uses» «uses» «inherits» 24 3.2.2. Casos de uso de usuarios de un Cliente. «inherits» «inherits» Usuario Administrador Consulta Lotes Entidad Propia Iniciar/ Cerrar Sesión «uses» Crear Envio Consultar estado Envio Entidad Propia Modificar Cuenta Propia «uses» «uses» «uses» «uses» Generar Informes de Lotes Propios Generar Informes de Envios Propios Generar Informe de Expediciones Propias «extends» «extends» «uses» «uses» «uses» Administrador Cliente «inherits» Usuario Cliente Crear Usuario Entidad Propio «uses» Modificar Usuarios Entidad Propia «extends» «extends» «uses» Borrar Usuario Entidad Propia «uses» Crear Modificar Consignatario «uses» 25 3.2.3. Casos de uso de usuarios de una Agencia Nota: El actor usuario asumimos que tiene los casos de uso del anterior diagrama que se omiten en éste para no redundar. En general asumiremos esto para todos los actores en diagramas posteriores. «inherits» «inherits» «inherits» «inherits» Usuario Usuario Agencia Crear/Modificar Artículo Propio Crear/Modificar un Lote de Clientes Propios Generar Informes de Lotes de Clientes Propios Generar Informes de Envios de Clientes Propios Generar Informes de Expediciones Propias Crear/Modificar Expedición de Envio con Lotes Propios Consultar Lotes Entidad Propia Consultar Lotes de Clientes Propios Consultar Envios de Clientes Propios Consultar Envios Entidad Propia Consultar Expediciones Propias «extends» «uses» «uses» «uses» «uses» «uses» «uses» «extends» «uses» «uses» «extends» «extends» «uses» «uses» «uses» «extends» Administrador Agencia Administrador Crear/Modificar Clientes Propios Crear/Modificar Usuarios Clientes Propios Crear/Modificar Usuarios Entidad Propios «uses» «extends» «uses» «uses» Borrar Usuarios Entidad Propia «uses» Borrar Usuarios Clientes Propios «uses» «extends» Desactivar Cliente Propio «uses» Crear/Modificar Almacenes Propios «uses» Crear Envio Modificar/Borrar Envios Clientes Propios «uses» «extends» «uses» 32 añadiendo la fecha de envío de la expedición. El envío ya no puede ser editado. 8. El sistema comprueba si han cambiado los datos del consignatario y los actualiza en caso afirmativo. 9. Por último confirma si todas las operaciones se han realizado sin error o las deshace todas si una ha fallado. Extensiones síncronas En 6, 7, 8 puede emitirse un error al incumplir las condiciones de los datos. Extensiones asíncronas - 33 3.2.6. Diagramas de secuencia. A continuación se presenta un diagrama de secuencia de uno de los procesos complejos y principales del sistema, crear un envío a base de unidades de lotes almacenados y un consignatario: Agente::Usuario Interfaz Web Interfaz XML/AJAX Persistencia BDD Crear Envio ConsultaLotes() Lotes:Lista Selecciona Artículo Consulta Artículos ConsultaArticulos() Articulos:ListaArticulos:XML Consulta Clientes ConsultaClientes() Clientes:ListaClientes:XML Muestra Clientes Selecciona Primer Cliente Selecciona Cliente loop Cliente Seleccionado Consulta Lotes Lotes:XML Muestra Articulos Muestra Lotes loop Selecciona Unidades Lote Actualiza Lotes Seleccionados Actualiza Unidades Disponibles de Lotes loop alt alt [ Usuario::Usuario Agencia] Introduce datos Consignatario [ else ] [ Usuario introduce nuevo Consignatario ] Selecciona Consignatario Existente Consulta Datos Consignatario ConsultaConsignatario() Datos:XMLMuestra Datos Consignatario Confirma Envio Envia Datos Lotes y Consignatario NuevoConsignatario() ¿No Existe Consignatario? GuardarEnvio() 34 Otro de los procesos principales y complejos del sistema es el siguiente que representa el crear una expedición: Agente::Usuario Interfaz Web Interfaz XML/AJAX Persistencia BBDD Seleccionar Cliente alt Listar Envios de Cliente ConsultaEnviosCliente() Envios:ListaEnvios:XML loop Selecciona Envio Consulta Datos de Envio ConsultaLotesEnvio() Lotes:Lista ConsultaConsignatario() ConsultaEnvio() Envio:Objeto Envio:XML Consulta Datos Consignatario Consignatario:ObjetoConsignatario:XML alt Modificar datos de Consignatario Seleccionar otro Consignatario Cargar Datos Consignatario ConsultaConsignatario() Consignatario:ObjetoConsinatario:XMLMensaje1 loop alt Seleccionar fecha envio Expedición Fecha actual como fecha de envio Confirmar / Guardar ExpediciónGuardar Expedición / Datos Expedición GuardaExpedcicion() ok / error<ok> / <error> 35 4. Diseño. El diseño de la aplicación se ha hecho siguiendo una distribución de 3 capas lógicas, interfaz de usuario, gestión o control y capa de persistencia. Si bien, al implementar un funcionamiento basado en consultas asíncronas por AJAX y mejorar la retroalimentación en la comprobación de errores y usabilidad de la aplicación, la capa de gestión de negocio se distribuye entre la parte ejecutada en el cliente y el servidor, que vuelve a comprobar además la corrección de los datos suministrados antes. 4.1 Arquitectura. Arquitectura de tres niveles: Ésta arquitectura permite desarrollar el sistema en niveles aislados y por tanto hace posible modificar un nivel sin necesidad de cambiar el código de los demás ya que se comunican usando un API (Aplication Program Interface o Interfaz de Programación de Aplicaciones) sin necesidad de saber cómo se han implementado los otros niveles. El diseño de la arquitectura de tres niveles es la mejor opción entre complejidad, mantenimiento y reusabilidad, además de permitir aislar la Cliente Servidor CAPA DE PRESENTACIÓN CAPA DE NEGOCIO/ APLICACIÓN CAPA DE PERSISTENCIA XHTML 1.0 Javascript <XML> SQL 36 base de datos de datos erróneos, mal intencionados (al estar expuesto el sistema a Internet) y reforzar las restricciones de diseño de los datos. Como se puede observar, las capas y su implementación no son homogéneas en cuanto al soporte/lenguaje de implementación. Los corchetes que engloban cada capa también engloban varias partes del sistema como la capa de negocio que engloba parte del cliente y del servidor. En éste caso la capa de negocio al estar dividida posee dos APIs internos, uno en cada parte del punto de comunicación. En la parte cliente se interpreta el XML que suministra la parte del servidor y la parte del servidor posee una convención de llamadas y bloques que se cargan bajo demanda. En el funcionamiento del sistema, como ya se ha comentado antes, hay parte de la funcionalidad implementada en el cliente, aparte de la Interfaz de Usuario, una parte de la funcionalidad de la aplicación y una primera comprobación de las restricciones de corrección. Por lo tanto no nos encontramos en el caso de un cliente “tonto” lo que mejora la interacción con el usuario y la velocidad de respuesta, que aparte de los mensajes de comprobación y modificaciones del interfaz que realice la parte de cliente, posibilita la comunicación de los datos en formato XML reduciendo la sobrecarga de redibujar la página entera y simplificando el funcionamiento de la parte servidor al evitar la gestión de formularios multipaso, ya que cada vez que se carga una página/módulo la ejecución del código del servidor comienza y termina y habría que aumentar la complejidad para guardar el estado y retomarlo. Éste diseño posibilitaría cambiar por ejemplo el tipo de servidor de base de datos sin por ello tener que modificar las otras capas. De todas formas, al usar el estándar SQL, casi cualquier Sistema Gestor de Bases de Datos (DBMS en inglés) que cumpla con él sería apto con mínimas modificaciones. 4.2. Arquitectura en 3 capas La organización del desarrollo de un proyecto en tres capas lógicas diferenciadas en capa de acceso a datos, capa de negocio y capa de presentación. Permite el desarrollo separado, mantenible y mejor adaptable de proyectos de tamaño medio a grande. Dicha separación propicia que un cambio en el diseño no afecte a todas las partes, si no a una de las capas. También propicia que, mientras se concrete una interfaz de comunicación entre cada capa, se desarrollen simultáneamente las capas. La separación en capas también propicia la escalabilidad de la aplicación. Si la complejidad de las capas de negocio o datos se torna 37 demasiado compleja o reciben demasiada carga, pueden dividirse en varias máquinas servidoras, tanto de capa de negocio como de datos. Pudiendo tener así llegar a tener varias máquinas que ejecutan la capa de negocio y varias la de datos. 4.2.1. Capa de presentación La capa de presentación concentra el interfaz de usuario, cómo se interactúa con éste y cómo se muestra la información. Esta es la capa que debe mostrar la funcionalidad de la aplicación de forma que sea fácil de usar. Esta capa sólo se comunicará con la capa de negocio. En la aplicación de Stock3, la capa de presentación incluye parte del servidor que genera el XHML y los datos en XML a partir de plantillas y en la parte cliente gestiona los eventos de usuario y se comunica con la capa de negocio que está en el servidor. 4.2.1.1. Interfaz de Usuario La interfaz de usuario de Stock3 usa elementos clásicos de formularios web parcialmente rediseñados para reducirlos de tamaño y dotarlos de coherencia con el diseño de bloques que usa la aplicación. También dota a ciertos bloques de funcionalidad o interactividad, normalmente indicándolo con un icono y el cambio del cursor. Se ha optado por una disposición de la aplicación en 3 partes principales, dos de ellos destinados a la navegación. 38 Dichas partes o bloques principales son “frames”, estructuras de HTML que cargan el contenido de otro recurso web. Se ha dividido la página en: 1. La cabecera estática con decoración gráfica e identidad empresarial. 2. El menú dinámico de acciones disponibles para el usuario actual. 3. El bloque de la acción seleccionada con el formulario pertinente. 4.2.1.2. Diseño gráfico Aplicando los estilos CSS se han modelado botones y cajas de texto de forma que se integran con los bloques en los que se organiza la información. Se han usado varios iconos para indicar funcionalidades contextuales como el calendario para desplegar un calendario en el que elegir la fecha y el de Excel con el que descargar el listado del envío, expedición, etc., en el formato de hoja de cálculo de dicho programa. A continuación se muestra un ejemplo de cada tipo de elemento mostrando en el centro un bloque típico de la aplicación. 39 También se ha utilizado un código de colores para distinguir el tipo de elemento con el que se está trabajando, dependiendo de si se trata de un lote, un envío o una expedición y una incidencia sobre éstos. A continuación se muestra un ejemplo de dicha distinción: En la cabecera se ha incluido la identidad empresarial además de varios enlaces de utilidad como el de “inicio”, cerrar sesión “logout” y un enlace al resto de la web de la empresa Duco. Para indicar que un elemento de formulario es obligatorio, se mostrará un asterisco rojo con un mensaje al posicionar el puntero sobre él. A continuación podemos observar un ejemplo: 4.2.2. Capa de lógica de negocio La capa de negocio es la encargada de comprobar que todas las restricciones se cumplen y comunicar las otras dos capas. Por lo tanto aglutina todas las restricciones y datos correspondientes a las características/funcionalidades solicitadas, los casos de uso identificados y las relaciones entre entidades. En Stock3, además se comprueba la validez de los datos recibidos de la capa de presentación que pueden ser modificados y enviados intentando sobrepasar alguna restricción como el nivel de usuario o la propiedad de stock. También se evita así el envío de código SQL malintencionado conocido como inyección SQL, un ataque común en las páginas y aplicaciones web dinámicas respaldadas por bases de datos. 40 4.2.3. Capa de Datos La capa de datos es la que se encarga de almacenar (dar persistencia) y recuperar los datos de la aplicación. La capa de negocio es la encargada de comunicarse con ésta capa que suele ser un sistema gestor de base de datos. En el caso de la aplicación de Stock3 ésta capa incluye el SGBD MySQL que es una base de datos relacional y la capa de negocio se comunica con ésta en SQL. Y gracias a dicha comunicación en el estándar SQL, sería posible la sustitución de dicho SGBD por otro que también cumpliera con SQL. 4.2.3.1. Diseño de la base de datos Para la implementación de la base de datos se consideró usar un sistema que cumpliera con el modelo relacional y diera soporte a las restricciones que se pueden aplicar con las relaciones entre entidades que éste propone. Así que basándonos en las opciones de software libre con las que contamos, dentro de MySQL, se optó por el motor de bases de datos que mejores características ofrecía frente a los demás que soportaba MySQL, InnoDB. InnoDB soporta relaciones de claves ajenas, actualizaciones y borrados en cascada y transacciones atómicas: o se ejecutan correctamente todas las órdenes o podemos revertir los cambios. Al mismo tiempo mejora el rendimiento del ya obsoleto conjunto de operaciones ISAM desarrollado por IBM. 4.2.3.1.1 Modelo Relacional. El modelo relacional es un modelo de datos basado en la lógica de predicados y en la teoría de conjuntos. Concibe relaciones entre entidades como tablas o tuplas de datos. Gracias a su facilidad para la representación de modelos reales y relativa facilidad para ser asimilado, se convirtió en el paradigma principal de las bases de datos desde su postulado en los años 70. Hoy en día, sin embargo, para sistemas de alto rendimiento y saturación de carga, está poniéndose en duda su validez y buscando alternativas como tablas llave-valor o columna-familia para los cuales la coherencia de resultados en búsquedas no sea vital, como el proyecto 41 Cassandra, liberado por Facebook en 2008 y mantenido por la Apache Foundation desde entonces. No obstante, para las dimensiones de uso y cumplimiento de las restricciones, el modelo relacional se ajusta perfectamente a las necesidades de Stock3 y es el modelo de datos usado. En la etapa de Análisis creamos un modelo UML con las clases que representaban el problema de estudio, indicando las diversas entidades y relaciones encontradas en el proceso. Usando éste modelo, en ésta etapa de diseño creamos un nuevo modelo orientado a la implementación de la solución del problema, el modelo relacional, en el cual se especifica cómo se materializan en tablas de tipos de datos específicos, las entidades y relaciones de nuestro primer modelo una vez normalizado. La normalización es un proceso en el que se aplican varias reglas para evitar la redundancia de datos, problemas en la actualización de éstos y problemas en la integridad de éstos al pasar del modelo entidad-relación al modelo relacional. Una representación del modelo usando notación de MySQL Workbench Crow’s foot o “pata de cuervo” puede observarse en la siguiente figura: 48 5.1.4.1. AJAX AJAX es el mecanismo de comunicación asíncrono que usa Stock3 y que viene de las siglas en inglés “Asynchronous JAvaScript XML” que transmite consultas HTTP y respuestas en XML. Es un servicio que ofrecen los navegadores a través de JavaScript y que usando librerías como Prototype y más tarde JSQuery, simplifica la comunicación de fragmentos de datos sin representación gráfica definida o con una representación asociada si se usan hojas de estilo para XML XSL. De esta forma, se agilizan las modificaciones de datos en la aplicación web y su representación al transmitir sólo los datos necesarios y cuando hacen falta bajo los eventos desatados por el usuario o temporizados. El resultado es un funcionamiento mucho más parecido a las aplicaciones de escritorio y una simplificación de la generación de las páginas de datos, que no necesitan recargar todo y mantener todo el estado coherente en variables no volátiles del servidor. 5.2. Interfaces software implementadas Con la mayor parte de funcionalidad de la aplicación implementada con comunicaciones cortas cliente/servidor vía AJAX, era conveniente implementar un modelo de servicio web de llamada de operación con un único punto de entrada “xml.php” y que éste sirviera de interfaz con la operación pedida. Así se logran invocar todas las microoperaciones de carga y modificación de datos con consultas rápidas y transparentes al usuario, sin forzar recargas de la página. Un ejemplo de llamadas puede ser el de la carga de datos de un envío, evento lanzado al hacer click en una fila de envío del resumen o de la gestión de envíos. La página desde el lado cliente realiza la consulta a xml.php con los siguientes parámetros env=ID_ENVIO, esto desencadena que xml.php cargue la batería de funciones de acceso a base de datos “funciones.php” y la de presentación “muestra.php” y llame a la función “MuestraEnvio(ID_ENVIO, $envios)”. Otras operaciones como borrado de un envío al pulsar el botón de “Borrar” en el formulario de un envío ya cargado llamarían a xml.php con “del_envio” e “id=ID_ENVIO”. Sin embargo, la carga inicial de las páginas completas sigue una lógica ligeramente diferente al cargar el menú y las plantillas generales también con un único punto de entrada “index.php” pero sin ofrecer el 49 modelo de servicio web de llamada remota de operaciones. Éstos archivos accesibles desde el menú rellenan la información inicial en las plantillas correspondientes y devuelven la página de la opción de menú ya compuesta. A continuación se muestran los diagramas de alcanzabilidad en el caso de las páginas de las opciones de menú y de llamadas en el caso del interfaz de servicio web de xml.php. 5.2.1. Diagrama de alcanzabilidad desde el menú: Index.php Cabecera.html Menu01.php Resumen.php Articulos.php Envios.php Expediciones.php Lotes.php Almacenes.php Cuentas_this.php Login.php Cuentas_agencias.php Cuentas_agencias_usrs.php Cuentas_clientes.php Cuentas_clientes_usrs.php Cuentas_usuarios.php Cuentas_asocia_cliente.php Resumen.php 50 5.2.2. Diagrama del servicio web AJAX:  Existe un interfaz casi idéntico al que ofrece xml.php pero que sólo realiza las consultas de datos para devolver un archivo XLS(MSExcel) por cada consulta, el xls.php. Xml.php Carga librerias db.php Muestra.php Funciones.php Navegador Web – Parte en el Cliente Petición de consulta de datos / operación de datos MuestraEnvio() MuestraExpedición() MuestraArticulo() MuestraCliente() MuestraAgencia() MuestraLote() MuestraLoteXLS() MuestraMovimientosXLS() MuestraEnvioXLS() MuestraExpedicionXLS() MuestraConsignatario() Autentificado() CheckForACU() CheckForAuth() NuevoUsuario() NuevoCliente() BorraCliente() NuevaAgencia() ModAgencia() ModCliente() ModSelf() NuevoAlmacen() BorrarCliente() BorrarAgencia() BorrarUsuario() BorrarAlmacen() Funciones de gestión de cuentas y acceso NuevoArticulo() CreateMod_Envio() NuevoLote() RestauraValoresLotes() NuevaRelacion() BorrarEnvio() CreateMod_Exp() BorrarExpedicion() BorrarArticulo() BorrarLote() SimpleQuery_Logged() ConsultaArticulo() ConsultaLote() ConsultaMov() ConsultaCliente() Check4CIFCliente() ConsultaAgencia() ConsultaUsuario() ConsultaConsignatario() ConsultaEnvio() ConsultaExpedicion() ConsultaAlmacen() CompruebaConsig() Version() 51 5.2.2.1 Secuencia de llamadas del servicio web: A continuación podemos observar cómo el interfaz ofrecido por el servicio web a través de xml.php realiza una secuencia de llamadas para servir los datos de un envío en XML. La secuencia explicada en orden sería la siguiente: 1. En la parte cliente, el usuario hace click sobre la línea informativa de un envío. 2. Se realiza una llamada XMLHttpRequest() a xml.php con los parámetros env=ID_DEL_ENVIO. 3. xml.php comprueba que la sesión del usuario es de un usuario autentificado llamando a Autentificado(). 3. Luego identifica que la operación es consultar un envío y llama a la función de MuestraEnvío() con el ID del envío transformado en entero para evitar inyección de SQL. 4. MuestraEnvio() a su vez llama a ConsultaEnvio() que comprueba además si se tienen permisos sobre el envío que pertenece a un cliente y puede estar asociado a varias agencias. Xml.php Carga librerias db.php Muestra.php Funciones.php Navegador Web – Parte en el Cliente Coonsulta un envío de un cliente: xml.php?env=ID MuestraEnvio() MuestraExpedición() MuestraArticulo() MuestraCliente() MuestraAgencia() MuestraLote() MuestraLoteXLS() MuestraMovimientosXLS() MuestraEnvioXLS() MuestraExpedicionXLS() MuestraConsignatario() Autentificado() CheckForACU() CheckForAuth() NuevoUsuario() NuevoCliente() BorraCliente() NuevaAgencia() ModAgencia() ModCliente() ModSelf() NuevoAlmacen() BorrarCliente() BorrarAgencia() BorrarUsuario() BorrarAlmacen() Funciones de gestión de cuentas y acceso NuevoArticulo() CreateMod_Envio() NuevoLote() RestauraValoresLotes() NuevaRelacion() BorrarEnvio() CreateMod_Exp() BorrarExpedicion() BorrarArticulo() BorrarLote() SimpleQuery_Logged() ConsultaArticulo() ConsultaLote() ConsultaMov() ConsultaCliente() Check4CIFCliente() ConsultaAgencia() ConsultaUsuario() ConsultaConsignatario() ConsultaEnvio() ConsultaExpedicion() ConsultaAlmacen() CompruebaConsig() Version() 52 5. Finalmente con los datos de ConsultaEnvio(), MuestraEnvio() los compone en una plantilla XML de envíos que carga usando ITXTemplates y se devuelve al navegador del cliente. 5.3 Javascript en el cliente En la parte del cliente tenemos tres archivos principales de javascript que implementan toda la funcionalidad. La base es la librería Prototype.js ya explicada, el nucleo de la parte cliente de la aplicación es ajax.js y se apoya en cal.js para mostrar un desplegable con un calendario para seleccionar de forma cómoda las fechas de los campos indicados. Ajax.js es un gran repositorio de funciones que a su vez encapsulan dentro las funciones asíncronas de éxito o error en la carga de datos. Es una estructura posible gracias a que para Javascript las funciones son objetos en sí mismas. De forma que tendríamos una estructura del éste estilo por cada función que realice una operación: function CargaEnvio(id){ var onSuccess = function (xmlRes){ if (getChild(xmlResp,’ok’)){ var envio = getChild(xmlResp,’envio’); ... } } var onError = function(){ alert(document.messages[‘error_cargando_envio’]); } Ajax.request(‘xml/xml.php’,{‘env’:id},{method:’post’, ‘onsuccess’: onSuccess, ‘onerror’: onError }); } 53 6. Manual de Usuario A continuación se dan unas guías de uso de la aplicación dependiendo del nivel de usuario. Existen varias distinciones de usuarios en la aplicación dependiendo de a qué entidad pertenezca cada usuario. Para las Agencias los usuarios se dividen en usuarios básicos u operarios, administradores y superusuarios. La existencia de superusuarios es restringida a sólo uno y sólo para la agencia Duco que supervisa a las demás. Para los Clientes, sólo existen los usuarios básicos y los administradores. Para poder acceder a la aplicación se necesita un nombre de usuario y una contraseña. Captura de inicio de sesión. Las operaciones disponibles para cada usuario estarán representadas en el menú de navegación izquierdo. 54 Captura de vista general al iniciar sesión como Superusuario. Algunos bloques aparecerán contraídos para mayor comodidad y serán desplegados y replegados pinchando en sus encabezados. Un bloque colapsable/descolapsable se identificará con unas flechas hacia abajo como en el ejemplo siguiente. Captura de ejemplo: click en un bloque descolapsable. 55 Captura de ejemplo: el bloque colapsado se descolapsa. 6.1. Agencias Las agencias son capaces de administrar sus propios clientes, artículos, lotes, envíos y expediciones. Además, pueden visualizar clientes y artículos vinculados a dichos clientes por algún lote y creados por otras agencias si el superadministrador enlaza dicho cliente a la agencia. 6.1.1. Superusuario y Administradores El supeusuario dispone de todas las operaciones posibles y su menú así lo refleja: Las operaciones realizables por diferentes usuarios comparten la misma funcionalidad, así que tomaremos al usuario Superusuario como referencia para repasar todas las operaciones disponibles. Los administradores poseen un subconjunto de opciones del superadministrador Revisaremos a continuación cada una de las operaciones y su 2 - Menú de operaciones disponibles para Superusuarios. 1 - Opciones disponibles Administradores 56 interfaz. Resumen General La pantalla de resumen general da una visión de los últimos envíos pendientes de enviar o rechazar. Podemos observar el interfaz general de gestión de envíos. La diferencia principal del resumen frente a la gestión de envíos es que por defecto aparecen los envíos de todos los clientes de la agencia. Por encima del primer bloque encontramos un filtro por cliente de la agencia o cliente asociado, un enlace de impresión/descarga en formato Excel del envío seleccionado si hemos seleccionado alguno y un enlace rápido a crear nuevo artículo, ya que es un paso indispensable en la creación de lotes y envíos. El primer bloque lista los envíos en sí, además de dar unas opciones de filtrado por estado y fecha de creación del envío. Los filtros son un segmento de tiempo, o una fecha inicial a partir de la cual mostrar los envíos y los filtros rápidos de estado son los siguientes: “todos”, “en espera”, “enviados”, “entregados” y “con incid.” (con incidencias o problemas para ser servidos). 57 También podemos observar una opción de limitar el número de envíos listados y un icono de descargar el listado en un fichero de formato de hoja de cálculo Excel. En el segundo bloque colapsable encontramos los lotes disponibles dependiendo de qué cliente y artículo seleccionemos. Por defecto aparecen todos los disponibles y nuevamente un enlace a crear un artículo nuevo. En dicho bloque podemos seleccionar el número de elementos de un lote del/los artículos disponibles para añadirlo a un envío. Con los botones de “Add”. En el tercer bloque encontramos las unidades de los lotes que componen el envío actual. Un enlace a crear nuevo lote nos da la posibilidad de ir directamente si necesitamos introducir un nuevo lote en el sistema. En este bloque podemos revisar las unidades que realmente se pueden enviar de un lote o suprimir directamente dichas unidades. En el cuarto bloque se pueden visualizar, modificar o seleccionar los datos del consignatario o destinatario del envío y de envío. En los campos de fecha de envío y entrega podemos introducir en qué fecha se envió realmente el envío seleccionado y cuando se recibió la confirmación de entrega. Para dichas fechas se dispone de la ayuda de un calendario desplegable al pulsar sobre el icono de calendario. Una vez todos los datos han sido revisados o introducidos, podemos pulsar sobre el botón de “Guardar” que se encuentra también en el último bloque. Si pulsamos en “Limpiar” los cambios que hayamos realizado se perderán. 64 Clientes En esta sección podemos crear o editar los clientes de la agencia del superusuario o administrador y visualizar los clientes asociados a nuestra agencia. Usuarios Esta interfaz permite administrar los usuarios de la agencia del superusuario o administrador. 65 No permite cambiar el nivel de los usuarios ya que se asume que cada agencia sólo tiene un usuario Administrador y el resto son operarios que gestionan el resto de datos que no tengan que ver con cuentas. Almacenes Esta interfaz permite gestionar los almacenes de todas las agencias de almacenamiento. Actualmente esta información es meramente de consulta ya que la localización de los lotes y sus unidades en los pasillos de los almacenes está propuestas para una futura ampliación. Los administradores carecen de la pestaña de selección de agencia, ya que sólo pueden administrar los almacenes de su propia agencia. 66 Usuarios de Clientes En esta interfaz los administradores y superusuario puede gestionar los usuarios de sus clientes o clientes asociados. Agencias La interfaz de gestión de agencias, es única del superadministrador y permite crear y editar las agencias y su usuario administrador. 67 Usuarios de Agencias De la misma forma que “Usuarios de Clientes” permite gestionar los usuarios básicos de los clientes, esta interfaz permite gestionar los usuarios básicos de las agencias. Este interfaz es exclusivo del superusuario. Asociación de Clientes y Agencias Un interfaz único del superusuario que permite asociar clientes que no sean propios de una agencia para que ésta trabaje con ellos y sus artículos. 6.1.3. Operador El operador encontrará en el menú izquierdo las operaciones siguientes: 68 Como se ha mencionado antes, el operario o usuario básico de las agencias posee las mismas operaciones generales del administrador prescindiendo de toda la gestión de cuentas. 6.2. Clientes A continuación exploramos las opciones disponibles para los usuarios de los clientes. 6.2.1. Usuario General El usuario básico de cliente o general dispone de un menú gráfico diferente de los usuarios de agencias más vistoso y simplificado. Encontramos las opciones básicas de los clientes, consultar el resumen, crear envío, consultar todos los envíos, consultar sus lotes, las propiedades de su cuenta y extraer listados en formato de hoja de cálculo Excel. 69 Estado Actual La opción de “Estado Actual” permite ver el estado de sus envíos sin estar en ruta, consultar los envíos con incidencias, revocar/borrar los que no han sido enviados y solicitar nuevos. Es la vista por defecto donde entra el usuario y da de un solo vistazo una visión del estado de sus movimientos. Encontramos las mismas opciones de filtrado que en los administradores a excepción de que no podemos filtrar por cliente ya que sólo podemos visualizar nuestros propios envíos. Crear Envio En la línea del mismo interfaz del resumen, encontramos que los bloques no necesarios para la creación de envíos aparecen plegados, aunque podemos desplegarlos para consultarlos o utilizar su funcionalidad. En esta interfaz podemos seleccionar alguno de los artículos de los que tengamos lotes con unidades disponibles e ir formando un envío añadiendo unidades de dichos lotes. Las unidades de los lotes añadidas se verán reflejadas en el bloque de “Lotes Seleccionados”. En el último bloque de “Datos Extra y Consignatario” introduciremos los datos del consignatario del envío o seleccionaremos un consignatario que hayamos introducido previamente. 70 Consultar Envíos En éste interfaz vemos todos los envíos hasta el máximo de 50, incluyendo los enviados o en curso, los entregados, con incidencias, etc. Disponemos del mismo conjunto de filtros habituales para envíos. Al pulsar sobre un envío con incidencia, se nos muestran las unidades que hay realmente disponibles para ese envío y podemos elegir enviar las disponibles o mantener con incidencia el envío. 71 Consulta Lotes La opción de consultar lotes, permite revisar de qué lotes dispone el cliente y cuantas unidades tiene cada uno. Éste interfaz posee los mismos filtros que el interfaz de administrador de agencia a excepción de que no existe desplegable para seleccionar cliente ya que estamos limitados a nuestra entidad de cliente y tampoco se nos modificar datos de los lotes, encontraremos los botones de “Guardar”,”Limpiar” y “Borrar” desactivados. Propiedades de Cuenta Encontramos el interfaz limitado que comentamos tienen los usuarios básicos, de forma que sólo podemos modificar el nombre de usuario con el que aparecemos y la contraseña. Podemos consultar el resto de datos que el administrador haya introducido de nuestra cuenta. Listados Excel En esta opción encontramos el mismo interfaz de generación de listados en el formato de hoja de cálculo Excel del que disponían los usuarios de las agencias con excepción de que el desplegable de selección de cliente ha sido omitido al ceñirse a nuestra entidad como cliente. 72 6.2.2. Administrador El usuario administrador de la entidad de clientes sólo se diferencia del usuario básico de su misma entidad en que dispone de una opción de gestión de usuarios no administradores. 73 8. Conclusiones Este proyecto ha sido un reto complejo, al inicio de mi carrera profesional, y con varios problemas en el proceso que han enseñado algunas lecciones. Como comentaba en la introducción de esta memoria, el mayor problema que se planteó fue el de transformar lo que era sólo una pequeña parte, la gestión de envíos (petición de expeditar) por parte de los clientes de varias agencias independientemente del resto, en un sistema de gestión global de todas las agencias con todos sus clientes y una agencia supervisora. El problema en sí no fue sólo el reto del salto cualitativo en complejidad si no el no haber adoptado la decisión correcta y a tiempo con respecto a qué hacer con el código que ya estaba desarrollado en la primera entrega antes de que se planteara el actual proyecto. Impulsado por acortar tiempo opté, y se me instó, por intentar hacer crecer el código, bastante clásico en el aspecto de CGI: formularios, envío, página con el resultado del envío del formulario o el siguiente paso/confirmación y vuelta a la página inicial. A un código que contemplara todos los casos de uso nuevos, casos para cada nivel de usuario, agencias, administradores, expediciones, reportes Excel, artículos, lotes (que en principio se introducían procesando un reporte Excel para los usuarios), etc. Fue una tarea engorrosa, llena de errores, lenta y finalmente me di cuenta que ese proceso, paradigma y el mantener el funcionamiento de lo que estaba hecho eran erróneos. Así que algo más de 8 meses se desecharon y empecé casi desde cero. Ésta fue la decisión que debería haber tomado 8 meses antes al analizar la dimensión de los nuevos requisitos, ahora ya no tengo miedo de desechar lo que no es salvable y empezar de cero, pero gracias también a un cambio hacia mayor modularidad, micro operaciones/micro transacciones al estilo de las aplicaciones de escritorio con AJAX, es más fácil también la reutilización en aplicaciones web y no es tan frecuente el tener que desechar desarrollos enteros. También fue decisiva y acertada la decisión de separar la carga del bloque pesado de las páginas frente al planteamiento de servicio web de las consultas AJAX. Teniendo dos sistemas de carga, el que carga las páginas con los bloques, el menú, CSS, Javascript y que usa las plantillas de estilo HTML vía index.php y varios archivos PHP y el que realiza las peticiones de datos y operaciones al interfaz de servicio web vía el archivo xml.php. Más tarde también me di cuenta que en lugar de usar múltiples archivos PHP en el primer caso de carga de las páginas, podía haber creado un sistema de menús en BBDD con llamada dinámica de las plantillas y/o archivos PHP o 80 CREATE TABLE `envio` ( `num_envio` int(11) unsigned NOT NULL auto_increment, `num_cliente` int(11) unsigned NOT NULL default '0', `num_consignatario` int(11) unsigned NOT NULL default '0', `fecha_creacion` date NOT NULL default '0000-00-00', `fecha_envio` date default NULL, `fecha_entrega` date default NULL, PRIMARY KEY (`num_envio`), KEY `num_cliente` (`num_cliente`), KEY `num_consignatario` (`num_consignatario`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=37 ; -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `envio_formado_de` -- CREATE TABLE `envio_formado_de` ( `num_envio` int(11) unsigned NOT NULL default '0', `num_lote` int(11) unsigned NOT NULL default '0', `unidades` int(11) unsigned NOT NULL default '0', `no_disponibles` int(11) unsigned NOT NULL default '0', PRIMARY KEY (`num_envio`,`num_lote`), KEY `num_lote` (`num_lote`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci; -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `expedicion` -- CREATE TABLE `expedicion` ( `num_expedicion` int(10) unsigned NOT NULL auto_increment, `cod_agencia` int(10) unsigned NOT NULL, `num_envio` int(11) unsigned NOT NULL, `fecha_creacion` date NOT NULL, `fecha_envio` date default NULL, `fecha_entrega` date default NULL, `num_consignatario` int(10) unsigned NOT NULL, `incidencia` varchar(255) collate latin1_spanish_ci default NULL, PRIMARY KEY (`num_expedicion`,`cod_agencia`), KEY `num_consignatario` (`num_consignatario`), KEY `cod_agencia` (`cod_agencia`), KEY `num_envio` (`num_envio`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=3 ; -- -------------------------------------------------------- 81 -- -- Estructura de tabla para la tabla `lote` -- CREATE TABLE `lote` ( `num_lote` int(11) unsigned NOT NULL auto_increment, `num_cliente` int(11) unsigned NOT NULL default '0', `cod_agencia` int(11) unsigned NOT NULL default '0', `cod_articulo` int(11) unsigned NOT NULL default '0', `mi_num_lote` varchar(20) collate latin1_spanish_ci NOT NULL, `num_inicial_unidades` int(11) unsigned NOT NULL default '0', `unidades_restantes` int(11) unsigned NOT NULL default '0', `fecha_llegada` date NOT NULL default '0000-00-00', `fecha_caducidad` date default '0000-00-00', `observacion` varchar(200) collate latin1_spanish_ci default NULL, PRIMARY KEY (`num_lote`), KEY `num_cliente` (`num_cliente`), KEY `cod_agencia` (`cod_agencia`), KEY `cod_articulo` (`cod_articulo`), KEY `mi_cod_lote` (`mi_num_lote`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=244 ; -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `lote_en_almacen` -- CREATE TABLE `lote_en_almacen` ( `num_lote` int(10) unsigned NOT NULL, `id_almacen` int(10) unsigned NOT NULL, `cod_agencia` int(10) unsigned NOT NULL, `num_bloque` int(10) unsigned NOT NULL, `calle` int(10) unsigned NOT NULL, `tramo` int(10) unsigned NOT NULL, `nivel` int(10) unsigned NOT NULL, `unidades` int(10) unsigned NOT NULL, PRIMARY KEY (`num_lote`,`id_almacen`,`cod_agencia`,`num_bloque`), KEY `id_almacen` (`id_almacen`,`cod_agencia`), KEY `cod_agencia` (`cod_agencia`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci; -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `parte_de_expedicion` -- CREATE TABLE `parte_de_expedicion` ( `num_lote` int(10) unsigned NOT NULL, 82 `num_envio` int(10) unsigned NOT NULL, `num_expedicion` int(10) unsigned NOT NULL, `unidades` int(10) unsigned NOT NULL, PRIMARY KEY (`num_lote`,`num_envio`,`num_expedicion`), KEY `num_expedicion` (`num_expedicion`), KEY `num_envio` (`num_envio`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci; -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `usuario` -- CREATE TABLE `usuario` ( `num_cliente` int(11) unsigned default NULL, `cod_agencia` int(11) unsigned default NULL, `usuario` char(20) collate latin1_spanish_ci NOT NULL default '', `contrasenya` char(20) collate latin1_spanish_ci NOT NULL default '', `Nombre` char(50) collate latin1_spanish_ci default NULL, `categoria` char(1) collate latin1_spanish_ci NOT NULL default '', PRIMARY KEY (`usuario`), KEY `num_cliente` (`num_cliente`), KEY `cod_agencia` (`cod_agencia`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci; -- -- Filtros para las tablas descargadas (dump) -- -- -- Filtros para la tabla `agencia_adhiere_cliente` -- ALTER TABLE `agencia_adhiere_cliente` ADD CONSTRAINT `agencia_adhiere_cliente_ibfk_2` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `agencia_adhiere_cliente_ibfk_3` FOREIGN KEY (`num_cliente`) REFERENCES `cliente` (`num_cliente`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `almacen` -- ALTER TABLE `almacen` ADD CONSTRAINT `almacen_ibfk_1` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `articulo` -- ALTER TABLE `articulo` ADD CONSTRAINT `articulo_ibfk_1` FOREIGN KEY (`num_cliente`) REFERENCES `cliente` (`num_cliente`) ON DELETE CASCADE ON UPDATE CASCADE, 83 ADD CONSTRAINT `articulo_ibfk_2` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `cliente` -- ALTER TABLE `cliente` ADD CONSTRAINT `cliente_ibfk_1` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `consignatario` -- ALTER TABLE `consignatario` ADD CONSTRAINT `consignatario_ibfk_1` FOREIGN KEY (`num_cliente`) REFERENCES `cliente` (`num_cliente`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `envio` -- ALTER TABLE `envio` ADD CONSTRAINT `envio_ibfk_1` FOREIGN KEY (`num_cliente`) REFERENCES `cliente` (`num_cliente`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `envio_ibfk_2` FOREIGN KEY (`num_consignatario`) REFERENCES `consignatario` (`num_consignatario`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `envio_formado_de` -- ALTER TABLE `envio_formado_de` ADD CONSTRAINT `envio_formado_de_ibfk_1` FOREIGN KEY (`num_envio`) REFERENCES `envio` (`num_envio`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `envio_formado_de_ibfk_2` FOREIGN KEY (`num_lote`) REFERENCES `lote` (`num_lote`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `expedicion` -- ALTER TABLE `expedicion` ADD CONSTRAINT `expedicion_ibfk_1` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `expedicion_ibfk_2` FOREIGN KEY (`num_consignatario`) REFERENCES `consignatario` (`num_consignatario`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `expedicion_ibfk_3` FOREIGN KEY (`num_envio`) REFERENCES `envio_formado_de` (`num_envio`) ON UPDATE CASCADE; -- -- Filtros para la tabla `lote` -- ALTER TABLE `lote` ADD CONSTRAINT `lote_ibfk_1` FOREIGN KEY (`num_cliente`) REFERENCES `cliente` (`num_cliente`) ON DELETE CASCADE ON UPDATE CASCADE, 84 ADD CONSTRAINT `lote_ibfk_2` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `lote_ibfk_3` FOREIGN KEY (`cod_articulo`) REFERENCES `articulo` (`cod_articulo`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `lote_en_almacen` -- ALTER TABLE `lote_en_almacen` ADD CONSTRAINT `lote_en_almacen_ibfk_3` FOREIGN KEY (`num_lote`) REFERENCES `lote` (`num_lote`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `lote_en_almacen_ibfk_4` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `parte_de_expedicion` -- ALTER TABLE `parte_de_expedicion` ADD CONSTRAINT `parte_de_expedicion_ibfk_3` FOREIGN KEY (`num_lote`) REFERENCES `envio_formado_de` (`num_lote`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `parte_de_expedicion_ibfk_4` FOREIGN KEY (`num_envio`) REFERENCES `envio_formado_de` (`num_envio`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `parte_de_expedicion_ibfk_5` FOREIGN KEY (`num_expedicion`) REFERENCES `expedicion` (`num_expedicion`) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Filtros para la tabla `usuario` -- ALTER TABLE `usuario` ADD CONSTRAINT `usuario_ibfk_1` FOREIGN KEY (`num_cliente`) REFERENCES `cliente` (`num_cliente`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `usuario_ibfk_2` FOREIGN KEY (`cod_agencia`) REFERENCES `agencia` (`cod_agencia`) ON DELETE CASCADE ON UPDATE CASCADE;