miércoles, 10 de junio de 2015

Miercoles 10/06/2015 (Análisis de Resultados)

Información general, análisis de resultados del desarrollo del proyecto:
Con un total de 67 horas laboradas, aproximadamente, se logró resolver cada problema encontrado durante la abstracción de todos los puntos sobresalientes de la tarea programada. Se consiguió elaborar la estructura, procedimientos y funciones necesarias.

- Programación de actividades y el control de costos para cada lote (en un ciclo específico) en una empresa que administra varias fincas.

+ Solicitud de suministros, servicios o maquinaria (Web app): Completo.
+ Aprobación de solicitudes: Completo.
- Manejo de transacciones de base de datos (actualización de saldos).
+ Historial de las gestiones o actividades que se realizan conforme el
procedimiento por cada lote: Completo.
- Administración completa de una finca. Poner a disposición la selección
del lote y el ciclo para realizar las operaciones y consultas. (Completado)
- Cálculo de subtotales de costos por cada actividad, previamente
seleccionada como parte del filtro. (No completado)
- Filtro de todas las actividad y cálculos de costos subtotales por los 
encargados. (Parcialmente completo)
- Filtros por tipo de cosecha, rango de fechas, lote o tipos de solicitudes. (Completado)
Pendiente:
+ Estado de  la última gestión realizada: Completado.
+ Filtro de costos por actividad(es), cálculo de subtotales: Completado.
+ Generalizar consulta para la información de la finca, en rango de fechas: Incompletado.
+ Migración: Completado (Faltó optimizar).
+ Transacción
- Fincas.
- Tipos de Cultivos.
- Ciclos.
- Encargados.
- Tipos de Actividad.
- Servicios
- Maquinaria
- Suministros
- Lotes
- Lote X Ciclo
- Solicitudes
Servicio.
Maquinaria.
Suministro.
- Historial
- Movimientos
Servicio.
Maquinaria.
Suministro.
- Actualización de saldos.
+ App Escritorio: Completo.
+ Modificar Solicitudes.
- Tipo de Actividad
- Cantidad
- Solicitud
+ Aprobar Solicitudes (Transacción)
- Actualización del Estado
- Cargar Movimiento (Inserción)
- Actualización de saldos

martes, 9 de junio de 2015

Martes 09/06/2015 (Afinacion de detalles)

Tiempo invertido: 2 horas y 30 minutos, aproximadamente.
16:00-18:30 

Al ya tener la mayoría del proyecto terminado nos dedicamos a optimizar el código, esto consto en eliminar código redundante o sin ninguna utilidad (el cual fue creado al inicio del proyecto por si acaso lo necesitabamos en el desarrollo de la misma). Esto se realizo para disminuir el tamaño del proyecto y para que el proyecto se vea mas "elegante".

Una de las mayores modificaciones se dio en el código para la aprobacion de las solicitudes ya que este redundaba en los if's lo que creaba una seguridad innecesaria.También se eliminaron algunos Store Procedures que redundaban en información o que no se utilizaban ya que fueron cambiadas algunas funcionalidades del proyecto o por que simplemente se crearon al inicio "por si acaso se necesitaban".

En resumen este tiempo se invirtió en optimizar el proyecto lo cual importante ya que reduce el espacio de almacenaje que requiere la computadora para almacenar el proyecto y también para que el proyecto funcionara de una manera mejor y mas rápida.


lunes, 8 de junio de 2015

Lunes 08/06/2015 (Filtros Manejo de nulos)

Tiempo invertido: 4 horas y 30 minutos, aproximadamente.

16:00-20:30

En este proyecto de programacion, como en cualquier otro proyecto se debe realizar se debe tener en cuenta el manejo de nulos, ya que si no se tomo en cuenta el manejo de nulos en un proyecto puede que surgan muchos problemas o conflictos en la programacion a causa de nulos.
Para no contar con problemas por no administrar bien los nulos, se decidio utilizar la funcion de SQL llamada ISNULL, la cual compara si un atributo es o no nulo.

Esta funcion de SQL la utilizamos en el Store Procedure por medio del cual realizamos para obtener el historial para una finca. Acontinuacion explicaremos un poco mas este SP.

Lo primero que se debe hacer es declarar una variable tabla en la cual se almacenara todos los datos requeridos para hacer el historial de una finca, y se declara una costoParcial tipo FLOAT.

        DECLARE @QueryResult TABLE(ID INT, ActivityDate VARCHAR(10), ActivityName VARCHAR(50), Attendant VARCHAR(50), RequestType VARCHAR(50), RequestDescription VARCHAR(150), RequestState VARCHAR(50))
        DECLARE @PartialCost FLOAT

Luego de declarar la variable tabla se debe realizar un filtro para poder obtener los datos que se necesitan en el cual de hacen varios inner join para obtener el FK_LotXCycle.

        SELECT R.ID, CONVERT(VARCHAR(10), H.ActivityDate, 103) AS ActivityDate, AT.Name AS ActivityName, A.Name AS Attendant, RT.Name AS RequestType, SUBSTRING(R.RequestDescription, CHARINDEX(' ', R.RequestDescription) + 1, LEN(R.RequestDescription)) AS RequestDescription, R.RequestState FROM dbo.AP_Historical H
            inner join dbo.AP_Request R ON R.ID = H.FK_Request
            inner join dbo.AP_Attendant A ON A.ID = R.FK_Attendant
            inner join dbo.AP_ActivityType AT ON AT.ID = R.FK_ActivityType
            inner join dbo.AP_RequestType RT ON RT.ID = R.FK_RequestType
            WHERE R.FK_LotXCycle = @FK_LotXCycle

Luego de ralizar esto es donde entra en uso la funcion ISNULL la cual nos ayuda a comparar varios valores que debemos filtar para que no se den conflictos con nulos.
En este caso lo que realizamos en la comparacion es:

AT.Name = ISNULL(@ActivityType, AT.Name)
                and A.Name = ISNULL(@Attendant, A.Name)

Estos son dos ejemplos para tener una idea mas clara de como trabaja esta Funcion, la primera es para obtener el nombre del tipo de actividad que se realio, si esta actividad es igual a nulo se compara con ella misma para que de esta forma la funcion nos de como resultado TRUE y no haya ningun inconveniente, si este no es nulo se compara con el nombre que fue dado como parametro en el Store Procedure.
De esta forma es que se da la utilizacion de la funcion ISNULL para poder asi de una mejor forma resolver el manejo de nulos en este proyecto.

viernes, 5 de junio de 2015

Viernes 05/06/2015 (Migracion Conflictos)

Tiempo invertido: 3 horas y 30 minutos, aproximadamente

16:00-19:30

Mientras se realizaba el parseo de los diferentes datos que se encuentran en el archivo XML, topamos con una serie de multiples conflictos, la mayoria de estos conflictos se dieron por la estructuracion y construccion del archivo XML, uno de los primeros conflictos que nos dio el archivo es que a la hora de empezar a parsear el archivo no aceptaba palabras con tildes o que tuviera la letra ñ, este error se pudo resolver de una forma exitosa pero muy tediosa, ya que se tuvieron que remplazar todas las palabras que tiene tildes o la letra ñ.

Otro de los conflictos que tuvimos a la hora de realizar la migracion de datos fue, que a la hora de realizar los insert a las variables tablas creadas para parsear los datos, nos daba un error que dice que se devolvian mas de datos, este problema era ya que el insert que estamos realizando se necesitaba hacer un SELECT DISTINCT y esto lo que hace es que no deja que se inserten datos repetidos, y dentro del archivo habian muchos datos que se repetian, un ejemplo de ellos fue que habian codigos de compañias repetidos, los cuales deberian ser unicos, este error tambien se pudo arreglar de la mejor forma, lo que se tuvo que hacer fue remplazar los codigos que se repetian.

Estos dos conflictos fueron unos de los mas principales y los cuales nos tomo mas tiempo de arreglar, apesar de que el archivo XML tuviera varias complicaciones y distintos errores pudimos reparar de una forma exitosa los conflictos que nos dio a la hora de la migracion.

jueves, 4 de junio de 2015

Jueves 04/06/2015 (Migracion Transaccion de BD)

Tiempo invertido: 3 horas y 30 minutos, aproximadamente
17:00-20:30

Al finalizar el dia de ayer el parceo, hoy terminamos la transaccion de bases de datos, primero se parsean los datos del archivo XML despues se utlizan esos datos para guardarlos en la base de datos. Para realizar esta accion se utiliza una transaccion  dee base de datos.

Esta transaccion se divide en tres pasos:
El primero es insersion en tablas catalogo, estas se realizan primero ya que estas solo poseen datos que no cerran modificados.
En segunda instancia se insertan los datos de las tablas de tipos de solicitudes (maquinaria, suministros y servicios) estos si cambian pero no poseen tanta importancia como las tablas insertadas en la tercera instancia.
En la tercer y ultima instancia se insertan toda la informacion "sensible" de la base de datos como los movimientos efecutados, los saldos se actualizan y se inserta informacion en tablas de extension consderable como los es la tabla de LotXCycle.

Los indices tienen que considir ya que si un indice no concide la base de datos quedara dessordenada y esto atentaria contra el orden que se debe seguir en una base de datos. A si mismo los foreign keys deben de "calzar" ya que si no existe ese foreign key SQL nos devolveria un error de incopabilidad de keys. Se utiliza un nivel del aislamineto de read uncommited ya que este es el mas rapido en escritura y ya que no manejamos muchas informacion sencible se sacrifica la seguridad por la rapides.

En resumen se inserta toda la informacion debidamente parceada, en tres diferentes instancias tomando en cuenta importancia de la informacion y tamaño de la tabla (se inserta de menor a mayor importancia).

miércoles, 3 de junio de 2015

Miercoles 03/06/2015 (Migracion Parseo de informacion)

Tiempo invertido: 4 horas y 30 minutos, aproximadamente

17:00-21:30

Antes de poder empezar a parsear la informacion que se encuentra en el archivo XML, debemos saber como se estructura el archivo XML, una archivo XML esta conformado por nodos, estos nodos pueden ser padres de otro nodos o hermanos de uno de ellos, para poder entender esto de una forma mas clara podemos asociarlo con el proyecto de programacion que estamos realizando.
El nodo padre o el nodo principal es el nodo llamado <company> el cual tiene un nodo hijo llamado <period>  y el cual tiene un nodo hijo llamado <farm> y este tiene un nodo hijo llamado <lot> y este tambien tiene un nodo hijo llamado <activity>, este ultimo tiene varios nodos hijos los cuales son <supply>, <service>, <machinery> acontinuacion se puede ver de una mejor forma:

 <company>  

     <period startDate="07/12/2014" endDate="08/06/2015">

        <farm name="Santander" code="25282" >

            <lot name="Cisneros" code="23986" cropType="Frijol">

                <activity description="Reciclaje de residuos organicos">

                    <machinery></machinery>

                    <service></service>

                    <supply></supply>

 Para empezar a parsear todos los datos que se encuentran en el archivo XML se deben crear variables tablas para poder guardar de una forma temporal los diferentes datos que luego seran insertado de una forma masiva a la base de datos.

        DECLARE @Property TABLE(ID INT IDENTITY(1, 1), Name VARCHAR(50))
        DECLARE @CropType TABLE(ID INT IDENTITY(1, 1), Name VARCHAR(50))
        DECLARE @Cycle TABLE(ID INT IDENTITY(1, 1), StartDate DATE, EndDate DATE)
        DECLARE @ActivityType TABLE(ID INT IDENTITY(1, 1), Name VARCHAR(50))

Estos son ejemplos de las variables tablas creadas para poder parsear los datos.

Una vez creadas las tablas se empezara a recorrer el archivo XML para ir obteniendo los datos que se requieren, para poder ingresar a los diferentes nodos ya antes mencionados se debe hacer el uso de unas instrucciones de SQL las cuales son las necesarias para poder ir accediendo nodo por nodo hasta encontrar el dato que se necesita.

        INSERT INTO @Property(Name)
        SELECT DISTINCT
            farm.value('@name', 'VARCHAR(50)')
        FROM @Doc.nodes('/company') AS x1(company)
        cross apply x1.company.nodes('./period') AS x2(period)
        cross apply x2.period.nodes('./farm') AS x3(farm)

Este es un ejeplo de como acceder al archivo en un nodo especifico y asi obtener la informacion que se requiere.

martes, 2 de junio de 2015

Martes 2/06/2015 (Finalizacion de la aplicación de Escritorio)

Tiempo invertido: 5 horas y 30 minutos, aproximadamente.
17:00-21:00

El grupo se propuso a terminar la aplicacion de escritorio, la cual le hacian falta completar la vista y el modelo. Por otro lado tambien le hacia falta toda la parte del controlador.    

Gracias a las funciones y procedimientos realizados con antelacion por el grupo la programacion de las llamadas a la base de datos se implementaron de forma rapida, ya que los mismos ya existian y no tubieron que ser programados. 

Al finalizar la parte visual se cumplio la expectativa de 3 paneles, de los cuales uno realizaba toda la parte de filtrado, el siguiente realiza modificaciones y la ultima aprueba las solicitudes. 

La parte del modelo se finalizo satisfactoriamente con la inclusion de algunas funciones y procedimientos los cuales se encargan de modificar y aprobar solicitudes. Estos son llamados por la vista, mediante un controlador el cual determina cual modelo llamara al procedimiento de SQL, un ejemplo de esto es:

public void modifyRequest(String pOldDesc,String pModDesc,String pModType ,Float pModAmount) throws SQLException {
         ArrayList<String> grupos = new ArrayList<>();
        try{
            this.stm.executeQuery(String.format("dbo.APSP_ModifyRequest '%s', '%s', '%s','%s'", pOldDesc, pModDesc,pModType, pModAmount));
        }catch (SQLException ex) {
            System.out.println(" ");
        }
    }

Por ultimo el controlador son clases las cuales como se menciono antes llaman a procedimientos del modelo, los cuales aseguran el cumplimiento del modelo MVC. Un ejemplo de los controladores es la siguiente clase:
private void jBtnRegistrarActionPerformed(java.awt.event.ActionEvent evt) {                                             
        try {
           
            if (approveRequest()){
                JOptionPane.showMessageDialog(rootPane, "Pedido aprobado");
            }
            else{
                JOptionPane.showMessageDialog(rootPane, "Faltan Datos o no existe una solicitud");
            }
        } catch (SQLException ex) {
           
            Logger.getLogger(JDlgApprove.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.setVisible(false);
    }

Por lo tanto se cumplio el objetivo de implementar una aplicacion de escritorio en Java utilizando el modelo MVC.