Tarea:
- El correo debe ser remitido al rol digitador y aprobador
- El correo debe venir con copia a los analistas de PPO
- El correo debe indicar la fecha de inicio y la fecha de fin de la etapa de planificación
- El correo debe indicar:
- Lista de códigos presupuestarios vinculados a metas operativas en la etapa de formulación sin presupuesto asignado.
- Lista de códigos presupuestarios en ejecución que tienen dinero y que no han sido incluidos en la formulación operativa.
Paso01: Crear Proceso
- Lo primero que vamos hacer es crear el archivo que va manejar el proceso
- Para esto
- Debemos ubicarnos en la ruta
- Proyecto-> Service->src->main->resources->META-INF->spring
- Aquí se encuentran todos los archivos que manejan procesos
- Podríamos crear uno nuevo o copiar uno y modificarlo
- Creamos el archivo
applicationContext-procesoPPIAvisoInicioFinalizacionEtapasPPOJob.xml
- El contenido basico es:
<?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">
</beans>
Paso1.1 Relación SIGESA -> Proceso
- Ahora debemos agregarle el código necesario para crear un listener que relaciona
- procesoPPIAvisoInicioFinalizacionEtapasPPOJob
- Con
- procesoPPIAvisoInicioFinalizacionEtapasPPO
<batch:job id="procesoPPIAvisoInicioFinalizacionEtapasPPOJob">
<batch:step id="simpleTaskletStepProcesoPPIAvisoInicioFinalizacionEtapasPPOJob">
<batch:tasklet ref="procesoPPIAvisoInicioFinalizacionEtapasPPO" />
<batch:listeners>
<batch:listener ref="batchJobStepListener" />
</batch:listeners>
</batch:step>
</batch:job>
- NOTA:
- Notar que los nombres son diferentes
- procesoPPIFinalizacionEtapasPPOJob:
- este referecia al nombre del proceso en la interfaz de SIGESA
<batch:job id="procesoPPIAvisoInicioFinalizacionEtapasPPOJob">
- procesoPPIFinalizacionEtapasPPO:
- Y este se refiere al bean que contiene la información de servicio que debe ejecutar
<batch:tasklet ref="procesoPPIAvisoInicioFinalizacionEtapasPPO" />
Paso 1.2: relación Proceso -> Servicio
- Ahora debemos agregarle el bean que contiene la información de cual servicio debe ejecutar al invocarse el proceso
- Y ademas va establecer donde esta el servicio y el método que va a ejecutar
- Y tambien va establecer cuales parametros se van a pasar desde la interfaz de SIGESA
- #{stepExecution.id}: siempre se pasa es el id del proceso
- #{jobParameters[‘etapaPlan’]} y este es uno adicional que se le debe pasar para el funcionamiento del proceso
- Codigo:
<bean id="procesoPPIAvisoInicioFinalizacionEtapasPPO" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
<property name="targetObject" ref="planOperativoServiceImpl" />
<property name="targetMethod" value="procesoPPIAvisoInicioFinalizacionEtapasPPO" />
<property name="arguments">
<list>
<value>#{stepExecution.id}</value>
<value>#{jobParameters['etapaPlan']}</value>
</list>
</property>
</bean>
Paso 1.3: lanzador del proceso
- Además es necesario crear el lanzador del proceso para esto agregamos
- NOTAR que es con JOB
procesoPPIAvisoInicioFinalizacionEtapasPPO
- Agregamos
<bean id="procesoPPIAvisoInicioFinEtapasPPOJobLauncher" class="cr.ac.una.cgi.sdkuna.service.BatchJobLauncherService" scope="prototype">
<property name="jobLauncher" ref="jobLauncher"></property>
<property name="job" ref="procesoPPIAvisoInicioFinEtapasPPOJob"></property>
</bean>
Paso 1.4: Resultado Final
- Resultado
<?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="procesoPPIAvisoInicioFinalizacionEtapasPPOJob">
<batch:step id="simpleTaskletStepProcesoPPIAvisoInicioFinalizacionEtapasPPOJob">
<batch:tasklet ref="procesoPPIAvisoInicioFinalizacionEtapasPPO" />
<batch:listeners>
<batch:listener ref="batchJobStepListener" />
</batch:listeners>
</batch:step>
</batch:job>
<bean id="procesoPPIAvisoInicioFinalizacionEtapasPPO" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
<property name="targetObject" ref="planOperativoServiceImpl" />
<property name="targetMethod" value="procesoPPIAvisoInicioFinalizacionEtapasPPO" />
<property name="arguments">
<list>
<value>#{stepExecution.id}</value>
<value>#{jobParameters['etapaPlan']}</value>
</list>
</property>
</bean>
<bean id="procesoPPIAvisoInicioFinEtapasPPOJobLauncher" class="cr.ac.una.cgi.sdkuna.service.BatchJobLauncherService" scope="prototype">
<property name="jobLauncher" ref="jobLauncher"></property>
<property name="job" ref="procesoPPIAvisoInicioFinEtapasPPOJob"></property>
</bean>
</beans>
Paso2: reportar el proceso
Paso 2.1: Reportar proceso
- Ahora debemos reportar el proceso dentro de SIGESA
- Para esto ingresamos a SIGESA -> SAS – Seguridad y administración -> SAS – Mantenimiento -> Lista de Procesos
- Le damos agregar
- Le agregamos los datos:
- Nombre del trabajo: procesoPPIAvisoInicioFinalizacionEtapasPPOJob
- Descripción: Proceso que enviá un correo a los usuarios con rol PPO Analista, PPO Aprobador Unidad Ejecutora, Aprobador Unidad Integradora y PPO Digitador para avisarles el inicio o finalización de una etapa y errores en los códigos presupuestarios.
- Ahora le agregamos los parametros
- EtapaPlan:
- datos:
- Parametro: etapaPlan
- Descripción: Etapa de Planificación
- Tipo parametro: objeto
- Requerido: true
- Le damos agregar
- Regresamos y le damos guardar y retornamos a configurar el parametro
- le damos en propiedades
- Datos:
- Clase Mapeada: cr.ac.una.cgi.sigesa.ppi.ppo.domain.EtapaPlan
- Propiedad objeto: nombre
- Título del LOV Bean: etapa_list_form_title
- Nombre bean: EtapaPlanBean
- Servicio clase: EtapaPlanService
- NOTA: Ahora como no seleccionamos el «método de filtrado» ni «Método filtrado LOV» va mostrar todas las etapas
- Regresamos y guardamos todo
PASO2.2: Reportar el recurso
- Ahora debemos reportar el proceso como un recurso
- Para esto ingresamos a SAS – Seguridad y Administración->SAS – Mantenimiento -> «Lista de recursos»
- Datos:
- Nombre: /pages/batchJobLauncher.xhtml?proceso=procesoPPIAvisoInicioFinalizacionEtapasPPOJob (NOTA: ES EL NOMBRE DEL ARCHIVO XML)
- Tipo de recurso: Página
- Visible: true
- Secuencia: 1
- Notas: Proceso que enviá un correo a los usuarios con rol PPO Analista, PPO Aprobador Unidad Ejecutora, Aprobador Unidad Integradora y PPO Digitador para avisarles el inicio o finalización de una etapa y errores en los códigos presupuestarios.
- Estado: Activo
- rol: UNA_PPI_PPO_ADMIN
Paso3: crear menú
- Ahora que ya definimos el proceso y definimos el recurso debemos crear la opción de menú
- Ingresamos a SAS – Seguridad y Administración -> SAS – Mantenimiento -> «Lista de Menú»
- Le damos nuevo
- Datos:
- Crear menú de un menú padre:
- Menú: PPO – Procesos
- Recurso: /pages/batchJobLauncher.xhtml?proceso=procesoPPIAvisoInicioFinalizacionEtapasPPOJob
- Nombre: Proceso Aviso Inicio Finalización de Etapas PPO
- Notas: Proceso que enviá un correo a los usuarios con rol PPO Analista, PPO Aprobador Unidad Ejecutora, Aprobador Unidad Integradora y PPO Digitador para avisarles el inicio o finalización de una etapa y errores en los códigos presupuestarios.
- Estado: Activo
- Secuencia 2
Paso 2.3: Volver a ingresar
- Ahora debemos salir del sistema y volver a ingresar
- Y podemos ingresar a PPI -> PPO-> PPO – Procesos -> «Proceso Aviso Inicio Finalización de Etapas PPO»
Paso3: Creación de funciones en PlanOperativoRepository
- Para la tarea específica se debio crear los siguientes metodos en el repository
/**
*
* Defnición que retorna una lista de Planes Operativos según:
*
* @param periodoAnual
* @param unidadEjecutora
* @author Gustavo Matamoros González
* @since 13/03/2023
* @issue: PPI-275
* @return List<PlanOperativo>
*/
public List<PlanOperativo> findByPeriodoAnualAndUnidadEjecutora (PeriodoAnual periodoAnual, UnidadEjecutora unidadEjecutora);
Paso4: creación de la definición del servicio (planOperativoService)
/**
* Definición del proceso que envia un correo de notificacion a usuarios con rol de digitador, aprobador y analista PPO sobre:
* * Códigos presupuestarios Sin presupuesto vínculados a metas
* * Códigos presupuestarios Con presupuesto No vículados a metas
*
* @param jobId : Id del proceso
* @param etapaPlan : etapaPlan a notificar
* @author Gustavo Matamoros González
* @fechaCreacion: 10/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
public void procesoPPIAvisoInicioFinalizacionEtapasPPO(Long jobId, String idEtapaPlan);
/**
* Definición de método que obtiene los planes operativos por PeriodoAnual y Unidad Ejecutora:
*
* @param periodoAnual
* @param unidadEjecutora
* @author Gustavo Matamoros González
* @fechaCreacion: 10/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
public List<PlanOperativo> findByPeriodoAnualAndUnidadEjecutora(PeriodoAnual periodoAnual, UnidadEjecutora unidadEjecutora);
/**
* Definición de método que obtiene los códigos presupuestarios sin presupuesto asignados a Metas de un plan operativo
*
* @param planOperativo
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
public List<CodigoPresupuestario> obtenerCodigosPresupuestariosSinPresupuestoAsignadosAMetas(PlanOperativo planOperativo);
/**
* Definición de método que obtiene los códigos presupuestarios con presupuesto sin asignar a Metas de un plan operativo
*
* @param planOperativo
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
public List<CodigoPresupuestario> obtenerCodigosPresupuestariosConPresupuestoSinAsignarAMetas(PlanOperativo planOperativo);
/**
* Definición que obtiene el plan operativo duplicado
*
* @param planOperativo
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
public PlanOperativo obtenerPlanOperativoDuplicadoPorPlanOperativo( PlanOperativo planOperativo);
Paso4: creación de la definición del servicio (planOperativoServiceImpl)
/**
* Proceso que envia un correo de notificacion a usuarios con rol de digitador, aprobador y Analista sobre:
* * Códigos presupuestarios Sin presupuesto vínculados a metas
* * Códigos presupuestarios Con presupuesto No vículados a metas
*
* @param jobId : Id del proceso
* @param etapaPlan : etapaPlan a notificar
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
@Override
public void procesoPPIAvisoInicioFinalizacionEtapasPPO(Long jobId, String idEtapaPlan) {
// *************************************************
// Variables Necesarias
// *************************************************
// Etapa plan pasada por parametro
EtapaPlan etapaPlan = etapaPlanService.find(Long.parseLong(idEtapaPlan));
TipoEtapa tipoEtapaModificacion = tipoEtapaService.findTipoEtapaByParametro("param_ppi_ppo_tipoEtapa_modificacion");
TipoPlanOperativo tipoPlanUnidad = tipoPlanOperativoService.findTipoPlanUnidad();
// Creamos una lista de planes operativos por notificar
List<PlanOperativo> planesOperativosPorNotificar = new ArrayList();
// Cuerpo del correo
String bodyCorreo="";
// *************************************************
// Crear lista de planOperativos por notificar (Si existe duplicado o sino formulado)
// *************************************************
// Obtenemos los planes activos
List<PlanOperativo> planesOperativosActivos = repository.findByActivo(Boolean.TRUE);
// Si existen planes activos
if (!planesOperativosActivos.isEmpty()) {
// Recorremos los planes activos
for (PlanOperativo planOperativoActivo : planesOperativosActivos) {
// Obtenemos el duplicado del plan
PlanOperativo planOperativoDuplicado = obtenerPlanOperativoDuplicadoPorPlanOperativo(planOperativoActivo);
// Existe duplicado
if(planOperativoDuplicado != null){
planesOperativosPorNotificar.add(planOperativoDuplicado);
// Si no existe duplicado utilizamos el formulado
}else{
planesOperativosPorNotificar.add(planOperativoActivo);
}
}
// *************************************************
// Si la lista no esta vacia
// *************************************************
if (!planesOperativosPorNotificar.isEmpty()) {
// *************************************************
// Obtener los roles necesarios
// *************************************************
// Obtenemos los usuarios con rol de Aprobador Unidad Ejecutora
Rol rolPPOAprobadorUnidadEjecutora = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_aprobador_unidad_ejecutora").getValor()));
List<Usuario> usuariosPPOUnidadEjecutora = rolUsuarioService.getByRolActivo(rolPPOAprobadorUnidadEjecutora);
// Obtenemos los usuarios con rol de Aprobador Unidad Integradora
Rol rolPPOAprobadorUnidadIntegradora = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_aprobador_unidad_integradora").getValor()));
List<Usuario> usuariosPPOUnidadIntegradora = rolUsuarioService.getByRolActivo(rolPPOAprobadorUnidadIntegradora);
// Obtenemos los usuarios con rol de Analista PPO
Rol rolPPOAnalista = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_analista").getValor()));
List<Usuario> usuariosPPOAnalista = rolUsuarioService.getByRolActivo(rolPPOAnalista);
// Obtenemos los usuarios con rol de Digitador PPO
Rol rolPPODigitador = rolService.findOne(Long.parseLong(parametroService.findOneByLlave("param_ppi_ppo_rol_digitador").getValor()));
List<Usuario> usuariosPPODigitador = rolUsuarioService.getByRolActivo(rolPPODigitador);
// *************************************************
// Crea asunto correo
// *************************************************
// Año de la etapa
String etapaPlanAnno = Integer.toString(etapaPlan.getPeriodoAnual().getAno());
// Variable para el asunto del correo
String subject="";
// Obtenemos el parametro del subject
String titulo = i18nService.findOneByLlaveAndIdioma("param_ppi_ppo_AvisoInicioFinalizacionEtapasPPO_subject", "es").getValor();
// Subject
subject = titulo + ": " + etapaPlan.getNombre() + " " + etapaPlanAnno;
// *************************************************
// Recorrer los planes operativos activos
// *************************************************
for (PlanOperativo planOperativo : planesOperativosPorNotificar) {
// *************************************************
// Parametros Correo
// *************************************************
Map<String, String> parametros = new HashMap<>();
parametros.put("etapaPlanNombre", etapaPlan.getNombre());
parametros.put("etapaPlanFechaInicial", etapaPlan.getFechaInicialStr());
parametros.put("etapaPlanFechaFinal", etapaPlan.getFechaFinalStr());
parametros.put("etapaPlanAnno", etapaPlanAnno);
// Variable para almacenar los codigos presupuestarios Sin Presupuesto Asignados a Metas
String mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta = "";
// Variable para almacenar los codigos Presupuestarios Con Presupuesto Sin Asignar a Metas
String mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta = "";
// *************************************************
// Obtener usuarios ACL por Unidad Ejecutora
// *************************************************
// Obtenemos los usuarios por Rol ACL
List<Usuario> usuariosUE = this.obtieneUsuariosPorRolAcl(planOperativo.getUnidadEjecutora().getCodigo());
// Creamos una lista de usuarios para envió de correo
List<Usuario> usuariosEnviarCorreo = new ArrayList();
// Le agregamos la lista de usuarios de analista a la lista de envió de correo
usuariosEnviarCorreo.addAll(usuariosPPOAnalista);
// Que corremos la lista de usuarios ACL
for (Usuario usuarioACL : usuariosUE) {
// Si el el usuarioACL esta dentro de de la lista de unidadEjecutora o unidadIntegradora o digitador o no esta en la lista de envió de correo
if (
(
usuariosPPOUnidadEjecutora.contains(usuarioACL) ||
usuariosPPOUnidadIntegradora.contains(usuarioACL)||
usuariosPPODigitador.contains(usuarioACL)
)
&&
(
!usuariosEnviarCorreo.contains(usuarioACL)
)) {
// Agregue el usuario a la lista
usuariosEnviarCorreo.add(usuarioACL);
}
}
// *************************************************
// PASO2.1 Si es tipo Modificación y Plan de Unidad
// *************************************************
if(etapaPlan.getTipoEtapa().equals(tipoEtapaModificacion) && (planOperativo.getTipoPlanOperativo().equals(tipoPlanUnidad) )){
// ****************************************************************
// Lista de Codigos Presupuestarios Sin Presupuesto Asignado a Meta
// ****************************************************************
List<CodigoPresupuestario> listaCodigosPresupuestariosSinPresupuestoAsignadosAMetas = this.obtenerCodigosPresupuestariosSinPresupuestoAsignadosAMetas(planOperativo);
// Si la lista no esta vacia
if (!listaCodigosPresupuestariosSinPresupuestoAsignadosAMetas.isEmpty()) {
for(CodigoPresupuestario codigoPresupuestario : listaCodigosPresupuestariosSinPresupuestoAsignadosAMetas) {
if (codigoPresupuestario.equals(listaCodigosPresupuestariosSinPresupuestoAsignadosAMetas.get(0))) {
mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta += i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_titleWarnnig", "es").getValor()+"<br/>";
}
if(codigoPresupuestario.getSubprogramaPresupuestario().getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioAcademico()) && (!mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta.contains(i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_programaPresupuestarioAcademico_titleWarnnig", "es").getValor() + "<br/>"))){
mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta += i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_programaPresupuestarioAcademico_titleWarnnig", "es").getValor() + "<br/>";
} else if(codigoPresupuestario.getSubprogramaPresupuestario().getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioVidaEstudiantil()) && (!mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta.contains(i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_programaPresupuestarioVidaUniversitaria_titleWarnnig", "es").getValor()+ "<br/>"))){
mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta += i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_programaPresupuestarioVidaUniversitaria_titleWarnnig", "es").getValor() + "<br/>";
} else if(codigoPresupuestario.getSubprogramaPresupuestario().getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioAdministrativo()) && (!mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta.contains(i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_programaPresupuestarioAdministrativo_titleWarnnig", "es").getValor()+ "<br/>"))){
mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta += i18nService.findOneByLlaveAndIdioma("planOperativo_codigosSinPresupuesto_programaPresupuestarioAdministrativo_titleWarnnig", "es").getValor()+ "<br/>";
}
mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta += codigoPresupuestario.getCodigo() + " " + codigoPresupuestario.getNombre() + "<br />";
}
parametros.put("mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta", mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta);
} else {
parametros.put("mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta", "");
}
// ****************************************************************
// Lista de Codigos Presupuestarios Con Presupuesto Sin Asignar a Meta
// ****************************************************************
List<CodigoPresupuestario> listaCodigosPresupuestariosConPresupuestoSinAsignarAMeta = this.obtenerCodigosPresupuestariosConPresupuestoSinAsignarAMetas(planOperativo);
// Si la lista no esta vacia
if(!listaCodigosPresupuestariosConPresupuestoSinAsignarAMeta.isEmpty()){
for(CodigoPresupuestario codigoPresupuestario : listaCodigosPresupuestariosConPresupuestoSinAsignarAMeta){
if (codigoPresupuestario.equals(listaCodigosPresupuestariosConPresupuestoSinAsignarAMeta.get(0))) {
mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta += i18nService.findOneByLlaveAndIdioma("planOperativo_codigosConPresupuesto_titleWarnnig", "es").getValor()+"<br/>";
}
mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta += codigoPresupuestario.getCodigo() + " " + codigoPresupuestario.getNombre() + "<br />";
}
parametros.put("mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta", mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta);
}else{
parametros.put("mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta", "");
}
// Verificar si almenos una lista tiene datos
if( (!mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta.equals("")) || (!mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta.equals(""))){
parametros.put("mensajeListaCodigosPresupuestarios", "Se le informa que el plan operativo código: '"+ planOperativo.getCodigo()+"' contiene lo siguiente:");
}else{
parametros.put("mensajeListaCodigosPresupuestarios", "");
}
// *************************************************
// Si no es etapa modificacion
// *************************************************
}else{
// Oculte las siguientes variables del mensaje
parametros.put("mensajeListaCodigosPresupuestarios", "");
parametros.put("mensajeCodigosPresupuestariosSinPresupuestoAsignadoMeta", "");
parametros.put("mensajeCodigosPresupuestariosConPresupuestoSinAsignarAMeta", "");
}
bodyCorreo = plantillaCorreoService.getHtmlContent("TPPIPPOAVISOINICIOFINALIZACIONETAPASPPO", parametros);
// Verificamos si existe un plan
this.enviarCorreoAvisoInicioFinalizacionEtapasPPO(
usuariosEnviarCorreo,
bodyCorreo,
subject);
}
}
}
}
/**
* Metodo que envia un correo de notificacion a usuarios con rol de digitador, aprobador y Analista sobre:
* * Códigos presupuestarios Sin presupuesto vínculados a metas
* * Códigos presupuestarios Con presupuesto No vículados a metas
*
* @param usuariosEnviarCorreo
* @param bodyCorreo
* @param subject
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
public void enviarCorreoAvisoInicioFinalizacionEtapasPPO(
List<Usuario> usuariosEnviarCorreo,
String bodyCorreo,
String subject) {
try {
// Creamos una lista vacia de personas
List<Persona> personas = new ArrayList();
// Agregamos personas por usuario
personas = agregarPersonasPorUsuarios(personas, usuariosEnviarCorreo);
// Si la lista no esta vacia
if (!personas.isEmpty()) {
// Recorremos la lista de personas a enviar correo
for (Persona persona : personas) {
// Crear lista de correos
List<String> correos = new ArrayList();
// *************************************************
// PASO3: Enviar correo
// *************************************************
// Obtenemos los correos de las personas
persona.getPersonaCorreos().stream()
.filter(personaCorreo -> ((personaCorreo.getActivo() == 1) && (personaCorreo.getPrioridad() == 1)))
.map(personaCorreo -> personaCorreo.getCorreoElectronico())
.forEachOrdered(destinatario -> {
correos.add(destinatario);
});
// Enviamos el correo
if (!correos.isEmpty()) {
mailService.sendMail(MailMessageData.builder()
.to(correos)
.subject(subject)
.body(bodyCorreo)
.build());
}
}
}
} catch (Exception ex) {
}
}
/**
* Método que obtiene los códigos presupuestarios sin presupuesto asignados a metas de un plan operativo
*
* @param planOperativo
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
@Override
public List<CodigoPresupuestario> obtenerCodigosPresupuestariosSinPresupuestoAsignadosAMetas(PlanOperativo planOperativo) {
//*************************************************************
// Declaración de Variables
//*************************************************************
List<CodigoPresupuestario> listaCodigosPresupuestarios = new ArrayList();
List<CodigoPresupuestario> listaCodigosPresupuestariosAC = new ArrayList();
List<CodigoPresupuestario> listaCodigosPresupuestariosVU = new ArrayList();
List<CodigoPresupuestario> listaCodigosPresupuestariosAD = new ArrayList();
List<CodigoPresupuestario> listaCodigosFormuladosSinPresupuesto = new ArrayList();
List<CodigoPresupuestario> listaCodigosEnPlanOperativo = new ArrayList();
List<MetaPoa> listaMetasEnPlanOperativoAcademico = new ArrayList();
List<MetaPoa> listaMetasEnPlanOperativoAdministrativo = new ArrayList();
List<MetaPoa> listaMetasEnPlanOperativoVidaUniversitaria = new ArrayList();
List<ObjetivoPOA> listaObjetivosPoa = planOperativo.getListaObjetivosPOA();
TipoPlanOperativo tipoPlanUnidad = tipoPlanOperativoService.findTipoPlanUnidad();
VinculacionPoa vinculacionPoaActual = vinculacionPoaService.findByUnidadEjecutoraAndPeriodoAnualAndTipoPlanOperativo(planOperativo.getUnidadEjecutora(), planOperativo.getPeriodoAnual(), tipoPlanUnidad);
List<VinPoaUnidadEjecutora> listaVinPoaUnidadEjecutora = new ArrayList();
List<CodigoPresupuestario> listaCodigosPresupuestariosConPresupuesto = new ArrayList();
//*************************************************************
// Si Existe vinculación POA: Obtenemos Los códigos Presupuestarios Con Presupuesto
//*************************************************************
if (vinculacionPoaActual != null) {
if (vinculacionPoaActual.getId() != null) {
listaVinPoaUnidadEjecutora.addAll(vinculacionPoaActual.getListaVinPoaUnidadEjecutora());
} else {
listaVinPoaUnidadEjecutora.clear();
}
for (ObjetivoPOA objetivoPoa : planOperativo.getListaObjetivosPOA()) {
listaCodigosPresupuestariosConPresupuesto.addAll(codigoPresupuestarioService.findByUnidadEjecutoraAndProgramaPresupuestarioAndPeriodoAnual(planOperativo.getUnidadEjecutora(), objetivoPoa.getProgramaPresupuestario(), planOperativo.getPeriodoAnual()));
if (!listaVinPoaUnidadEjecutora.isEmpty()) {
for (VinPoaUnidadEjecutora uniVin : listaVinPoaUnidadEjecutora) {
listaCodigosPresupuestariosConPresupuesto.addAll(codigoPresupuestarioService.findByUnidadEjecutoraAndProgramaPresupuestarioAndPeriodoAnual(uniVin.getUnidadEjecutora(), objetivoPoa.getProgramaPresupuestario(), planOperativo.getPeriodoAnual()));
}
}
}
}
//*************************************************************
// Se eliminan Repetidos
//*************************************************************
Set setConPresupuesto = new HashSet<>(listaCodigosPresupuestariosConPresupuesto);
listaCodigosPresupuestariosConPresupuesto.clear();
listaCodigosPresupuestariosConPresupuesto.addAll(setConPresupuesto);
//*************************************************************
// Obtener las Metas por Programa Presupuestario Y Códigos Presupuestarios por Metas
//*************************************************************
for (ObjetivoPOA objetivo : listaObjetivosPoa) {
for (MetaPoa meta : objetivo.getListaMetasPoa()) {
for (MetaPoaPresupuesto presupuesto : meta.getListaMetaPoaPresupuestos()) {
listaCodigosEnPlanOperativo.add(presupuesto.getCodigoPresupuestario());
}
if (objetivo.getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioAcademico())) {
listaMetasEnPlanOperativoAcademico.add(meta);
} else if (objetivo.getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioAdministrativo())) {
listaMetasEnPlanOperativoAdministrativo.add(meta);
} else if (objetivo.getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioVidaEstudiantil())) {
listaMetasEnPlanOperativoVidaUniversitaria.add(meta);
}
}
}
//*************************************************************
// Obtener las Excepciones Presupuestarias y removerlas
//*************************************************************
EtapaPlan etapaPlan = planOperativo.getEtapaPlan();
UnidadEjecutora unidadEjecutora = planOperativo.getUnidadEjecutora();
List<ExcepcionPresupuestaria> listaExcepcionPresupuestaria = excepcionPresupuestariaService.findAllExcepcionPresupuestariaByEtapaPlanAndUnidadEjecutora(etapaPlan, unidadEjecutora);
if (listaExcepcionPresupuestaria != null && !listaExcepcionPresupuestaria.isEmpty()) {
List<ExcepcionCodigo> listaCodigosPresupuestariosExcepcionUnidad = excepcionCodigoService.findAllExcepcionCodigoByExcepcionPresupuestaria(listaExcepcionPresupuestaria.get(0));
for (ExcepcionCodigo excepcionCodigo : listaCodigosPresupuestariosExcepcionUnidad) {
if (listaCodigosPresupuestariosConPresupuesto.contains(excepcionCodigo.getCodigoPresupuestario())) {
listaCodigosPresupuestariosConPresupuesto.remove(excepcionCodigo.getCodigoPresupuestario());
}
}
}
//*************************************************************
// Crear lista de listaCodigosFormuladosSinPresupuesto
//*************************************************************
for (CodigoPresupuestario codigoFormulado : listaCodigosEnPlanOperativo) {
if (!listaCodigosPresupuestariosConPresupuesto.contains(codigoFormulado) && !listaCodigosFormuladosSinPresupuesto.contains(codigoFormulado)) {
listaCodigosFormuladosSinPresupuesto.add(codigoFormulado);
}
}
// Si la lista no esta vacia
if (!listaCodigosFormuladosSinPresupuesto.isEmpty()) {
for (CodigoPresupuestario codigoPresupuestario : listaCodigosFormuladosSinPresupuesto) {
String mensajeMeta = "";
for (MetaPoa meta : listaMetasEnPlanOperativoAcademico) {
for (MetaPoaPresupuesto presupuesto : meta.getListaMetaPoaPresupuestos()) {
if (presupuesto.getCodigoPresupuestario().getId().equals(codigoPresupuestario.getId()) && !listaCodigosPresupuestariosAC.contains(presupuesto.getCodigoPresupuestario())) {
listaCodigosPresupuestariosAC.add(presupuesto.getCodigoPresupuestario());
}
}
}
for (MetaPoa meta : listaMetasEnPlanOperativoVidaUniversitaria) {
for (MetaPoaPresupuesto presupuesto : meta.getListaMetaPoaPresupuestos()) {
if (presupuesto.getCodigoPresupuestario().getId().equals(codigoPresupuestario.getId()) && !listaCodigosPresupuestariosVU.contains(presupuesto.getCodigoPresupuestario())) {
listaCodigosPresupuestariosVU.add(presupuesto.getCodigoPresupuestario());
}
}
}
for (MetaPoa meta : listaMetasEnPlanOperativoAdministrativo) {
for (MetaPoaPresupuesto presupuesto : meta.getListaMetaPoaPresupuestos()) {
if (presupuesto.getCodigoPresupuestario().getId().equals(codigoPresupuestario.getId()) && !listaCodigosPresupuestariosAD.contains(presupuesto.getCodigoPresupuestario())) {
listaCodigosPresupuestariosAD.add(presupuesto.getCodigoPresupuestario());
}
}
}
}
}
// Contatenar las listas
if(!listaCodigosPresupuestariosAC.isEmpty()){
listaCodigosPresupuestarios.addAll(listaCodigosPresupuestariosAC);
}else if(!listaCodigosPresupuestariosVU.isEmpty()){
listaCodigosPresupuestarios.addAll(listaCodigosPresupuestariosVU);
}else if(!listaCodigosPresupuestariosAD.isEmpty()){
listaCodigosPresupuestarios.addAll(listaCodigosPresupuestariosAD);
}
return listaCodigosPresupuestarios;
}
/**
* Definición de método que obtiene los códigos presupuestarios con presupuesto sin asignar a metas de un plan operativo
*
* @param planOperativo
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
@Override
public List<CodigoPresupuestario> obtenerCodigosPresupuestariosConPresupuestoSinAsignarAMetas(PlanOperativo planOperativo) {
//*************************************************************
// Declaración de Variables
//*************************************************************
List<CodigoPresupuestario> listaCodigosFormuladosSinPresupuesto = new ArrayList();
List<CodigoPresupuestario> listaCodigosEnPlanOperativo = new ArrayList();
List<CodigoPresupuestario> listaCodigosConPresupuestoFaltantes = new ArrayList();
List<MetaPoa> listaMetasEnPlanOperativoAcademico = new ArrayList();
List<MetaPoa> listaMetasEnPlanOperativoAdministrativo = new ArrayList();
List<MetaPoa> listaMetasEnPlanOperativoVidaUniversitaria = new ArrayList();
List<ObjetivoPOA> listaObjetivosPoa = planOperativo.getListaObjetivosPOA();
TipoPlanOperativo tipoPlanUnidad = tipoPlanOperativoService.findTipoPlanUnidad();
VinculacionPoa vinculacionPoaActual = vinculacionPoaService.findByUnidadEjecutoraAndPeriodoAnualAndTipoPlanOperativo(planOperativo.getUnidadEjecutora(), planOperativo.getPeriodoAnual(), tipoPlanUnidad);
List<VinPoaUnidadEjecutora> listaVinPoaUnidadEjecutora = new ArrayList();
List<CodigoPresupuestario> listaCodigosPresupuestariosConPresupuesto = new ArrayList();
//*************************************************************
// Si Existe vinculación POA: Obtenemos Los códigos Presupuestarios Con Presupuesto
//*************************************************************
if (vinculacionPoaActual != null) {
if (vinculacionPoaActual.getId() != null) {
listaVinPoaUnidadEjecutora.addAll(vinculacionPoaActual.getListaVinPoaUnidadEjecutora());
} else {
listaVinPoaUnidadEjecutora.clear();
}
for (ObjetivoPOA objetivoPoa : planOperativo.getListaObjetivosPOA()) {
listaCodigosPresupuestariosConPresupuesto.addAll(codigoPresupuestarioService.findByUnidadEjecutoraAndProgramaPresupuestarioAndPeriodoAnual(planOperativo.getUnidadEjecutora(), objetivoPoa.getProgramaPresupuestario(), planOperativo.getPeriodoAnual()));
if (!listaVinPoaUnidadEjecutora.isEmpty()) {
for (VinPoaUnidadEjecutora uniVin : listaVinPoaUnidadEjecutora) {
listaCodigosPresupuestariosConPresupuesto.addAll(codigoPresupuestarioService.findByUnidadEjecutoraAndProgramaPresupuestarioAndPeriodoAnual(uniVin.getUnidadEjecutora(), objetivoPoa.getProgramaPresupuestario(), planOperativo.getPeriodoAnual()));
}
}
}
}
//*************************************************************
// Se eliminan Repetidos
//*************************************************************
Set setConPresupuesto = new HashSet<>(listaCodigosPresupuestariosConPresupuesto);
listaCodigosPresupuestariosConPresupuesto.clear();
listaCodigosPresupuestariosConPresupuesto.addAll(setConPresupuesto);
//*************************************************************
// Obtener las Metas por Programa Presupuestario Y Códigos Presupuestarios por Metas
//*************************************************************
for (ObjetivoPOA objetivo : listaObjetivosPoa) {
for (MetaPoa meta : objetivo.getListaMetasPoa()) {
for (MetaPoaPresupuesto presupuesto : meta.getListaMetaPoaPresupuestos()) {
listaCodigosEnPlanOperativo.add(presupuesto.getCodigoPresupuestario());
}
if (objetivo.getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioAcademico())) {
listaMetasEnPlanOperativoAcademico.add(meta);
} else if (objetivo.getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioAdministrativo())) {
listaMetasEnPlanOperativoAdministrativo.add(meta);
} else if (objetivo.getProgramaPresupuestario().equals(programaPresupuestarioService.getProgramaPresupuestarioVidaEstudiantil())) {
listaMetasEnPlanOperativoVidaUniversitaria.add(meta);
}
}
}
//*************************************************************
// Obtener las Excepciones Presupuestarias y removerlas
//*************************************************************
EtapaPlan etapaPlan = planOperativo.getEtapaPlan();
UnidadEjecutora unidadEjecutora = planOperativo.getUnidadEjecutora();
List<ExcepcionPresupuestaria> listaExcepcionPresupuestaria = excepcionPresupuestariaService.findAllExcepcionPresupuestariaByEtapaPlanAndUnidadEjecutora(etapaPlan, unidadEjecutora);
if (listaExcepcionPresupuestaria != null && !listaExcepcionPresupuestaria.isEmpty()) {
List<ExcepcionCodigo> listaCodigosPresupuestariosExcepcionUnidad = excepcionCodigoService.findAllExcepcionCodigoByExcepcionPresupuestaria(listaExcepcionPresupuestaria.get(0));
for (ExcepcionCodigo excepcionCodigo : listaCodigosPresupuestariosExcepcionUnidad) {
if (listaCodigosPresupuestariosConPresupuesto.contains(excepcionCodigo.getCodigoPresupuestario())) {
listaCodigosPresupuestariosConPresupuesto.remove(excepcionCodigo.getCodigoPresupuestario());
}
}
}
//*************************************************************
// Crear lista de listaCodigosConPresupuestoFaltantes
//*************************************************************
for (CodigoPresupuestario codigoConPresupuesto : listaCodigosPresupuestariosConPresupuesto) {
if (!listaCodigosEnPlanOperativo.contains(codigoConPresupuesto) && !listaCodigosConPresupuestoFaltantes.contains(codigoConPresupuesto)) {
listaCodigosConPresupuestoFaltantes.add(codigoConPresupuesto);
}
}
if (!listaCodigosConPresupuestoFaltantes.isEmpty()) {
Set setCodigos = new HashSet<>(listaCodigosConPresupuestoFaltantes);
listaCodigosConPresupuestoFaltantes.clear();
listaCodigosConPresupuestoFaltantes.addAll(setCodigos);
}
return listaCodigosConPresupuestoFaltantes;
}
/**
* Método que obtiene los planes operativos por PeriodoAnual y Unidad Ejecutora:
*
* @param periodoAnual
* @param unidadEjecutora
* @author Gustavo Matamoros González
* @fechaCreacion: 10/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
@Override
public List<PlanOperativo> findByPeriodoAnualAndUnidadEjecutora(PeriodoAnual periodoAnual, UnidadEjecutora unidadEjecutora) {
return repository.findByPeriodoAnualAndUnidadEjecutora(periodoAnual, unidadEjecutora);
}
/**
* Método que obtiene el plan operativo duplicado
*
* @param planOperativo
* @author Gustavo Matamoros González
* @fechaCreacion: 22/03/2023
* @Version: 1.0.0
* @modulo: PPI-PPO
* @issue: PPI-275
*/
@Override
public PlanOperativo obtenerPlanOperativoDuplicadoPorPlanOperativo( PlanOperativo planOperativo) {
// Obtenemos el estado de borrador
EstadoFormulacionOpe estadoAnulado = estadoFormulacionOpeService.obtenerEstadoAnulado();
// Obtenemos el tipo de Etapa Modificación
TipoEtapa tipoEtapaModificacion = tipoEtapaService.findTipoEtapaByParametro("param_ppi_ppo_tipoEtapa_modificacion");
// Creamos una lista de planes operativos por Unidad Ejecutora
List<PlanOperativo> planesOperativosPorUnidadEjecutora = new ArrayList();
// Obtenemos los planes operativos por PeriodoAnual y Unidad Ejecutora
planesOperativosPorUnidadEjecutora = this.findByPeriodoAnualAndUnidadEjecutora(planOperativo.getPeriodoAnual(),planOperativo.getUnidadEjecutora());
// Crear variable de plan Operativo Duplicado
PlanOperativo planOperativoDuplicado = null;
// Si la lista de Planes Operativos x Unidad Ejecutora no esta vacia
if (!planesOperativosPorUnidadEjecutora.isEmpty()) {
// Recorremos la lista de planes operativos por Unidad ejecutora
for (PlanOperativo planOperativoPorUnidad : planesOperativosPorUnidadEjecutora) {
// Obtenemos el tipo de Etapa Modificación
EtapaPlan etapaPlan = etapaPlanService.findByTipoEtapaAndTipoPlanAndTipoPlanOperativoAndPeriodoAnualAndFechaInicialLessThanEqualAndFechaFinalGreaterThanEqual(tipoEtapaModificacion, planOperativo.getTipoPlan(), planOperativo.getTipoPlanOperativo(), planOperativo.getPeriodoAnual());
// Si la etapa de Plan de Modificación existe
if (etapaPlan != null) {
// Si existe un duplicado para la etapaPlan modificacion
if( (planOperativoPorUnidad.getEstadoFormulacionOpe() != estadoAnulado) && (planOperativoPorUnidad.getEtapaPlan()==etapaPlan)){
planOperativoDuplicado = planOperativoPorUnidad;
}
}
}
}
return planOperativoDuplicado;
}
Paso5: funciones adicionales en EtapaPlan.java
import java.text.SimpleDateFormat;
public String getFechaInicialStr() {
if (fechaInicial != null) {
SimpleDateFormat dt = new SimpleDateFormat("dd-MM-yyyy");
return dt.format(fechaInicial);
} else {
return "";
}
}
public String getFechaFinalStr() {
if (fechaFinal != null) {
SimpleDateFormat dt = new SimpleDateFormat("dd-MM-yyyy");
return dt.format(fechaFinal);
} else {
return "";
}
}