SIGESA: Procesos modificación

  • Primero la tarea es la PPI-265
  • Descripción:
    • Yo como Analista de planificación operativa requiero verificar el funcionamiento de proceso finalización de etapa.
    • Criterios de aceptación:
    • Debe ejecutarse automáticamente el día registrado en la ejecución de procesos de la etapa correspondiente.
    • Debe enviarse a las unidades ejecutoras que tengan vinculación de plan y cuyos planes no estén en estado:
      • Aprobado Un Solo Nivel
      • Aprobado Unidad Integradora
    • Revisar la estructura del correo:
      • Título:
      • Asunto:
      • Cuerpo:
    • Será enviado a los roles de aprobación de primera y segunda instancia.
      • APROBADOR_UNIDAD_EJECUTORA
      • APROBADOR_UNIDAD_INTEGRADORA
    • No tomar en cuenta los planes en estado anulado.
  • Lo primero es que este proceso se encuentra en:
    • PPI – Planificación Institucional
      • PPO – Planificación Operativa
        • PPO – Procesos
          • Proceso de Aviso de Finalización de Etapas PPO
  • Lo primero es que el nombre del proceso se modificó entonces para esto debemos ingresar a «Lista de procesos»
  • Lo siguiente que se debe hacer es modificar el nombre dentro del recurso
  • Ahora los procesos trabajan con un archivo que se ubica en:
    • Proyecto
      • resources
        • META-INF
          • spring
  • El contenido es el siguiente además aquí es necesario realizar el cambio del nombre del proceso
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:batch="http://www.springframework.org/schema/batch"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

 

    <batch:job id="procesoPPIFinalizacionEtapasPPOJob">
        <batch:step id="simpleTaskletStepProcesoPPIFinalizacionEtapasPPOJob">
            <batch:tasklet ref="procesoPPIFinalizacionEtapasPPO" />
            <batch:listeners>
                <batch:listener ref="batchJobStepListener" />
            </batch:listeners>
        </batch:step>
    </batch:job>
    
    
    
    <bean id="procesoPPIFinalizacionEtapasPPO" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
        <property name="targetObject" ref="planOperativoServiceImpl"  />
        <property name="targetMethod" value="procesoFinalizacionEtapasPPO" />
        <property name="arguments">
            <list>           
                <value>#{stepExecution.id}</value>
            </list>
        </property>
    </bean>
  
  

    <bean id="procesoPPIFinalizacionEtapasPPOJobLauncher" class="cr.ac.una.cgi.sdkuna.service.BatchJobLauncherService" scope="prototype">
        <property name="jobLauncher" ref="jobLauncher"></property>
        <property name="job" ref="procesoPPIFinalizacionEtapasPPOJob"></property>
    </bean>
    
</beans>
  • Aqupi lo importante es la siguiente sección que no indica donde esta definido el servicio y el método que va a atender el proceso
<bean id="procesoPPIFinalizacionEtapasPPO" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
        <property name="targetObject" ref="planOperativoServiceImpl"  />
        <property name="targetMethod" value="procesoFinalizacionEtapasPPO" />
        <property name="arguments">
            <list>           
                <value>#{stepExecution.id}</value>
            </list>
        </property>
    </bean>
  • Actualmente el proceso es el siguiente
@Override
    public void procesoFinalizacionEtapasPPO(Long jobId) {

        /*PPI-198 se habló con Laura y para el año 2022 no son necesarias las evaluaciones, para el 2023 verificar este método
        //evaluacionOperativaService.procesoFinalizacionEvaluacion(jobId);
         */
        Date diaHoy = eventoService.fechaFormatoSinHoras(new Date());
        Date diaAyer = eventoService.calcularFecha(diaHoy,-eventoService.fechaMenosNDiasHabiles(diaHoy, 1));
        PeriodoAnual periodoAnualVigente = periodoAnualService.findAnoFormulacion();

        String ids = parametroService.findOneByLlave("param_ppi_ppo_estados_formulacion_correo").getValor();
        String[] arrayIds = ids.split(",");

        List<Long> idsEstados = new ArrayList();
        for (String s : arrayIds) {
            idsEstados.add(Long.valueOf(s));
        }

        List<PlanOperativo> planesSinFinalizar = findByPeriodoAnualAndEstadoNotAprobadoSegundaInstaciaAndEventoFinalizado(periodoAnualVigente, idsEstados, diaAyer);

        if (!planesSinFinalizar.isEmpty()) {

            Rol rolAprobadorUnidadEjecutora = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_aprobador_unidad_ejecutora").getValor()));
            List<Usuario> usuariosUnidadEjecutora = rolUsuarioService.getByRolActivo(rolAprobadorUnidadEjecutora);
            
            Rol rolAprobadorUnidadIntegradora = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_aprobador_unidad_integradora").getValor()));
            List<Usuario> usuariosUnidadIntegradora = rolUsuarioService.getByRolActivo(rolAprobadorUnidadIntegradora);
                       
            Rol rolPPIAdmin = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_admin").getValor()));
            List<Usuario> usuariosPPIAdmin = rolUsuarioService.getByRolActivo(rolPPIAdmin);
                      
            Rol rolPPIAnalista = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_analista").getValor()));
            List<Usuario> usuariosPPIAnalista = rolUsuarioService.getByRolActivo(rolPPIAnalista);
            
            for (PlanOperativo planOperativo : planesSinFinalizar) {
                List<Usuario> usuariosUE = this.obtieneUsuariosPorRolAcl(planOperativo.getUnidadEjecutora().getCodigo());
                List<Usuario> usuariosEnviarCorreo = new ArrayList();
                usuariosEnviarCorreo.addAll(usuariosPPIAnalista);
                for (Usuario usuarioACL : usuariosUE) {
                    if ((usuariosUnidadEjecutora.contains(usuarioACL) || usuariosUnidadIntegradora.contains(usuarioACL)) && !usuariosEnviarCorreo.contains(usuarioACL)) {
                        usuariosEnviarCorreo.add(usuarioACL);
                    }
                }
                for (Usuario usuario : usuariosPPIAdmin) {
                    if (!usuariosEnviarCorreo.contains(usuario)) {
                        usuariosEnviarCorreo.add(usuario);
                    }
                }

                this.enviarCorreoVencimiento(usuariosEnviarCorreo, planOperativo);

            }
        }

    }
  • Ahora lo primero que debemos hacer es agregarle un parametro «EtapaPlan» al proceso
  • Para esto lo primero que vamos hacer es buscar SIGESA el proceso y le indicamos que va requerir un parametro
    • SAS – Seguridad y Administración
      • SAS – Seguridad y Administración
        • SAS – Mantenimiento
          • Lista de Procesos
            • procesoPPIFinalizacionEtapasPPOJob
  • Agregamos
    • etapaPlan
    • Etapa de Planificación
    • Objeto
    • Requerido
  • Agregamos
    • cr.ac.una.cgi.sigesa.ppi.ppo.domain.EtapaPlan
    • nombre
    • EtapaPlanBean
    • EtapaPlanProcesoService
  • Ya con esto si ingresamos al proceso podemos ver que pide el parametro

applicationContext-procesoFinalizacionEtapasPPOJob.xml

  • Ahora vamos a modifica el proceso para que reciba el parametro
  • Para esto abrimos el archivo y buscamos la sección donde se invoca el servicio
<bean id="procesoPPIFinalizacionEtapasPPO" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
        <property name="targetObject" ref="planOperativoServiceImpl"  />
        <property name="targetMethod" value="procesoFinalizacionEtapasPPO" />
        <property name="arguments">
            <list>           
                <value>#{stepExecution.id}</value>
            </list>
        </property>
    </bean>
  • Y le indicamos que vamos a recibir uno nuevo, agregando la siguiente linea
<value>#{jobParameters['etapaPlan']}</value>
  • Quedando así
  • NOTA: es importante el orden de los parametros
<bean id="procesoPPIFinalizacionEtapasPPO" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
        <property name="targetObject" ref="planOperativoServiceImpl"  />
        <property name="targetMethod" value="procesoFinalizacionEtapasPPO" />
        <property name="arguments">
            <list>           
                <value>#{stepExecution.id}</value>
                <value>#{jobParameters['etapaPlan']}</value>
            </list>
        </property>
    </bean>

PlanOperativoServiceImpl.java

  • Ahora vamos hacer que el servicio reciba el parametro
  • NOTA: los parametros vienen como String por tanto para poder obtener el objeto debemos:
    • Recibir un String
    • Y obtener el objeto con find convirtiendo el String en Long
  • Ejemplo
public void procesoFinalizacionEtapasPPO( Long jobId, String idEtapaPlan) {

        //Obtenemos la etapa plan
        EtapaPlan etapaPlan = etapaPlanService.find(Long.parseLong(idEtapaPlan));
  • Ahora lo que debemos hacer es modificar este metodo
findByPeriodoAnualAndEstadoNotAprobadoSegundaInstaciaAndEventoFinalizado
  • Por este
findByEtapaPlanAndFlujoNotFinalizado
  • Para hacer esto vamos a copiar el anterior y crea un método nuevo
  • Actual
public List<PlanOperativo> findByPeriodoAnualAndEstadoNotAprobadoSegundaInstaciaAndEventoFinalizado(PeriodoAnual periodoAnual, List<Long> idsEstados, Date dia) {
        Specification specPeriodoAnual = PlanOperativoSpecs.periodoAnualEqual(periodoAnual);
        Specification specEstadoNotEqual = PlanOperativoSpecs.estadosNotIn(idsEstados);
        Specification specEventoFinalizado = PlanOperativoSpecs.isEventoFinalizado(eventoService.fechaFormatoSinHoras(dia));

        Specification specFinal = Specification.where(specPeriodoAnual).and(specEstadoNotEqual).and(specEventoFinalizado);
        return repository.findAll(specFinal);

    }
  • Creamos el nuevo metodo
/**
     * Método que retorna un List<PlanOperativo> según etapa plan y flujo no finalizado
     * 
     * @param etapaPlan : etapaPlan por buscar
     * @param idsEstados : lista de estados de formulación de etapas no finalizadas
     * @author Gustavo Matamoros González
     * @fechaCreacion: 20/02/2023
     * @fechaModificacion: 20/02/2023
     * @Version: 1.0.0
     * @modulo: PPI-PPO
     * @issue: PPI-265
     */
    public List<PlanOperativo> findByEtapaPlanAndFlujoNotFinalizado(EtapaPlan etapaPlan, List<Long> idsEstados) {
        Specification specEtapaPlan = PlanOperativoSpecs.etapaPlanEqual(etapaPlan);
        Specification specEstadoNotEqual = PlanOperativoSpecs.estadosNotIn(idsEstados);
       
        Specification specFinal = Specification.where(specEtapaPlan).and(specEstadoNotEqual);
        return repository.findAll(specFinal);
    }
  • Ahora como vemos se modificarón las específicaciones eliminando la de specPeriodoAnual y agregando una nueva
Specification specEtapaPlan = PlanOperativoSpecs.etapaPlanEqual(etapaPlan);

PlanOperativoSpecs.java

  • Por tanto debemos agregar esta nueva especificación
public static Specification<PlanOperativo> etapaPlanEqual(final EtapaPlan etapaPlan) {
        return (Root<PlanOperativo> root, CriteriaQuery<?> cq, CriteriaBuilder cb) -> {
            Expression etaPlan = root.get("etapaPlan");
            Expression etaPlanLiteral = cb.literal(etapaPlan);
            return cb.equal(etaPlan, etaPlanLiteral);
        };
    }

PlanOperativoServiceImpl.java

  • Ahora moficamos el método
Date diaHoy = eventoService.fechaFormatoSinHoras(new Date());
        Date diaAyer = eventoService.calcularFecha(diaHoy,-eventoService.fechaMenosNDiasHabiles(diaHoy, 1));
        PeriodoAnual periodoAnualVigente = periodoAnualService.findAnoFormulacion();
  • Y renombramos los nombres de variables
@Override
    public void procesoFinalizacionEtapasPPO(Long jobId, String idEtapaPlan) {

        // Obtenemos la etapa plan
        EtapaPlan etapaPlan = etapaPlanService.find(Long.parseLong(idEtapaPlan));

        // Obtenemos los id de estados de formulacion que no es necesario enviar correo
        String ids = parametroService.findOneByLlave("param_ppi_ppo_estados_formulacion_correo").getValor();
        
        // Hacemos un split 
        String[] arrayIds = ids.split(",");

        // creamos una lista de estados
        List<Long> idsEstados = new ArrayList();

        // Recorremos la lista
        for (String s : arrayIds) {
            
            // agregamos el valor a lista
            idsEstados.add(Long.valueOf(s));
        }

        // Obtenemos todos los planes que no hayan terminado el flujo
        List<PlanOperativo> planesSinFinalizar = findByEtapaPlanAndFlujoNotFinalizado(etapaPlan, idsEstados);

        if (!planesSinFinalizar.isEmpty()) {

            Rol rolAprobadorUnidadEjecutora = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_aprobador_unidad_ejecutora").getValor()));
            List<Usuario> usuariosUnidadEjecutora = rolUsuarioService.getByRolActivo(rolAprobadorUnidadEjecutora);
            
            Rol rolAprobadorUnidadIntegradora = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_aprobador_unidad_integradora").getValor()));
            List<Usuario> usuariosUnidadIntegradora = rolUsuarioService.getByRolActivo(rolAprobadorUnidadIntegradora);
                       
            Rol rolPPOAdmin = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_admin").getValor()));
            List<Usuario> usuariosPPOAdmin = rolUsuarioService.getByRolActivo(rolPPOAdmin);
                      
            Rol rolPPOAnalista = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_analista").getValor()));
            List<Usuario> usuariosPPOAnalista = rolUsuarioService.getByRolActivo(rolPPOAnalista);
            
            for (PlanOperativo planOperativo : planesSinFinalizar) {
                List<Usuario> usuariosUE = this.obtieneUsuariosPorRolAcl(planOperativo.getUnidadEjecutora().getCodigo());
                List<Usuario> usuariosEnviarCorreo = new ArrayList();
                usuariosEnviarCorreo.addAll(usuariosPPOAnalista);
                for (Usuario usuarioACL : usuariosUE) {
                    if ((usuariosUnidadEjecutora.contains(usuarioACL) || usuariosUnidadIntegradora.contains(usuarioACL)) && !usuariosEnviarCorreo.contains(usuarioACL)) {
                        usuariosEnviarCorreo.add(usuarioACL);
                    }
                }
                for (Usuario usuario : usuariosPPOAdmin) {
                    if (!usuariosEnviarCorreo.contains(usuario)) {
                        usuariosEnviarCorreo.add(usuario);
                    }
                }

                this.enviarCorreoVencimiento(usuariosEnviarCorreo, planOperativo, etapaPlan.getNombre());

            }
        }

    }
  • Modificamos la función del envió de correo, para agregarle los parametros de
    • planOperativo
    • TipoPlan
public void enviarCorreoVencimiento(List<Usuario> usuarios, PlanOperativo planOperativo, String nombreEtapaPlan) {
        try {
            List<Persona> personas = new ArrayList();
            personas = agregarPersonasPorUsuarios(personas, usuarios);

            if (!personas.isEmpty()) {

                for (Persona persona : personas) {

                    String subject;
                    String body;

                    String nombreUnidad = planOperativo.getUnidadEjecutora().getNombre();
                    String estado = planOperativo.getEstadoFormulacionOpe().getNombre();
                    List<String> correos = new ArrayList();
                    Map<String, String> parametros = new HashMap<>();

                    subject = i18nService.findOneByLlaveAndIdioma("param_ppi_ppo_planesOperativos_sinFinalizar", "es").getValor();

                    persona.getPersonaCorreos().stream()
                            .filter(personaCorreo -> ((personaCorreo.getActivo() == 1) && (personaCorreo.getPrioridad() == 1)))
                            .map(personaCorreo -> personaCorreo.getCorreoElectronico())
                            .forEachOrdered(destinatario -> {
                                correos.add(destinatario);
                            });

                    parametros.put("nombreUnidad", nombreUnidad);
                    parametros.put("nombreEtapaPlan", nombreEtapaPlan);
                    parametros.put("estado", estado);
                    parametros.put("planOperativo", planOperativo.getCodigo());
                    parametros.put("tipoPlan", planOperativo.getTipoPlan().getNombre());

                    body = plantillaCorreoService.getHtmlContent("TPPIPPOPLANESSINFINALIZAR", parametros);

                    if (!correos.isEmpty()) {
                        mailService.sendMail(MailMessageData.builder()
                                .to(correos)
                                .subject(subject)
                                .body(body)
                                .build());
                    }
                }
            }

        } catch (Exception ex) {
        }
    }

PlanOperativoService

  • Renombramos el método
public void procesoFinalizacionEtapasPPO(Long jobId, String idEtapaPlan);