/** * Copyright © 2011 Instituto Superior Técnico * * This file is part of FenixEdu GIAF Contracts. * * FenixEdu GIAF Contracts is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu GIAF Contracts is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu GIAF Contracts. If not, see <http://www.gnu.org/licenses/>. */ package pt.ist.fenixedu.contracts.tasks.giafsync; import java.io.PrintWriter; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.fenixedu.academic.domain.organizationalStructure.AccountabilityTypeEnum; import org.fenixedu.academic.domain.organizationalStructure.Unit; import org.joda.time.LocalDate; import org.joda.time.YearMonthDay; import org.slf4j.Logger; import pt.ist.fenixedu.contracts.domain.Employee; import pt.ist.fenixedu.contracts.domain.organizationalStructure.Contract; import pt.ist.fenixedu.contracts.domain.organizationalStructure.EmployeeContract; import pt.ist.fenixedu.contracts.domain.personnelSection.contracts.ContractSituation; import pt.ist.fenixedu.contracts.domain.personnelSection.contracts.GiafProfessionalData; import pt.ist.fenixedu.contracts.domain.personnelSection.contracts.PersonContractSituation; import pt.ist.fenixedu.contracts.persistenceTierOracle.Oracle.PersistentSuportGiaf; import pt.ist.fenixedu.contracts.tasks.giafsync.GiafSync.ImportProcessor; import pt.ist.fenixedu.contracts.tasks.giafsync.GiafSync.Modification; class ImportEmployeeUnitsFromGiaf extends ImportProcessor { @Override public List<Modification> processChanges(GiafMetadata metadata, PrintWriter log, Logger logger) throws Exception { List<Modification> modifications = new ArrayList<>(); PersistentSuportGiaf oracleConnection = PersistentSuportGiaf.getInstance(); LocalDate today = new LocalDate(); modifications.addAll(importIt(oracleConnection, metadata, today, getEmployeeWorkingUnitsQuery(), AccountabilityTypeEnum.WORKING_CONTRACT, log, logger)); modifications.addAll(importIt(oracleConnection, metadata, today, getEmployeeMailingUnitsQuery(), AccountabilityTypeEnum.MAILING_CONTRACT, log, logger)); oracleConnection.closeConnection(); return modifications; } private List<Modification> importIt(PersistentSuportGiaf oracleConnection, GiafMetadata metadata, LocalDate today, String query, AccountabilityTypeEnum accountabilityTypeEnum, PrintWriter log, Logger logger) throws SQLException { List<Modification> modifications = new ArrayList<>(); PreparedStatement preparedStatement = oracleConnection.prepareStatement(query); ResultSet result = preparedStatement.executeQuery(); while (result.next()) { String employeeNumber = result.getString("emp_num"); Employee employee = metadata.getEmployee(employeeNumber, logger); if (employee == null) { log.println(accountabilityTypeEnum.getName() + ". Não existe funcionário. Número: " + employeeNumber); continue; } Integer costCenterCode = 0; try { costCenterCode = result.getInt("cc"); } catch (SQLException e) { log.println(accountabilityTypeEnum.getName() + ". CC inválido. Número: " + employeeNumber); continue; } Unit unit = costCenterCode.intValue() == 0 ? null : Unit.readByCostCenterCode(costCenterCode); String ccDateString = result.getString("cc_date"); LocalDate beginDate = today; if (!StringUtils.isEmpty(ccDateString)) { beginDate = new LocalDate(Timestamp.valueOf(ccDateString)); } if (unit != null || costCenterCode.intValue() == 0) { if (employee.getPerson().getPersonProfessionalData() != null) { GiafProfessionalData giafProfessionalDataByGiafPersonIdentification = employee.getPerson().getPersonProfessionalData() .getGiafProfessionalDataByGiafPersonIdentification(employeeNumber); ContractSituation contractSituation = giafProfessionalDataByGiafPersonIdentification.getContractSituation(); if (contractSituation != null) { LocalDate endDate = null; if (contractSituation.getEndSituation()) { PersonContractSituation personContractSituation = getOtherValidPersonContractSituation(giafProfessionalDataByGiafPersonIdentification); if (personContractSituation != null) { contractSituation = personContractSituation.getContractSituation(); endDate = personContractSituation.getEndDate(); } else { endDate = giafProfessionalDataByGiafPersonIdentification.getContractSituationDate(); } } Contract workingContractOnDate = getLastContractByContractType(employee, accountabilityTypeEnum, new YearMonthDay(beginDate), endDate == null ? null : new YearMonthDay(endDate)); if (workingContractOnDate != null) { if (unit != null && endDate == null) { if (!workingContractOnDate.getUnit().equals(unit)) { modifications.addAll(createEmployeeContract(employee, new YearMonthDay(beginDate), null, unit, accountabilityTypeEnum, workingContractOnDate, log, logger)); } else if (!workingContractOnDate.getBeginDate().equals(beginDate) && !StringUtils.isEmpty(ccDateString)) { modifications.add(changeEmployeeContractDates(accountabilityTypeEnum, new YearMonthDay( beginDate), workingContractOnDate, log, logger)); } else if (workingContractOnDate.getEndDate() != null && contractSituation != null && giafProfessionalDataByGiafPersonIdentification.getContractSituationDate() != null) { log.println(accountabilityTypeEnum.getName() + ". Contrato do Funcionário:" + employeeNumber + " Voltou a abrir na mesma unidade :" + giafProfessionalDataByGiafPersonIdentification.getContractSituationDate()); modifications.addAll(createEmployeeContract(employee, new YearMonthDay( giafProfessionalDataByGiafPersonIdentification.getContractSituationDate()), null, unit, accountabilityTypeEnum, null, log, logger)); } else { log.println(accountabilityTypeEnum.getName() + ". Não há alterações para o funcionário:" + employeeNumber); } } else if (endDate != null) { // terminou o contrato corrente modifications.add(closeCurrentContract(accountabilityTypeEnum, workingContractOnDate, new YearMonthDay(endDate.minusDays(1)), log, logger)); } } else { if (unit != null && endDate == null) { // contrato novo modifications.addAll(createEmployeeContract(employee, new YearMonthDay(beginDate), null, unit, accountabilityTypeEnum, null, log, logger)); } else { // já tinha terminado o contrato e já // terminou // tb do nosso lado // log.println(accountabilityTypeEnum.getName() // + ". Contrato terminado na unidade " // + unit.getName() + " para o funcionário:" // + employeeNumber + " (não fez nada)"); } } } else { log.println("ERRO... não tem situação no GIAF " + employeeNumber); Contract currentWorkingContract = employee.getCurrentContractByContractType(accountabilityTypeEnum); if (currentWorkingContract != null) { LocalDate endDate = today.minusDays(1); closeCurrentContract(accountabilityTypeEnum, currentWorkingContract, new YearMonthDay(endDate), log, logger); log.println(accountabilityTypeEnum.getName() + ". Não não tem contrato no GIAF, e terminamos no Fénix: " + employeeNumber); } else { log.println(accountabilityTypeEnum.getName() + ". Não não tem contrato no GIAF, nem no fénix: " + employeeNumber); } } } else { log.println("Não tem employeeProfessionalData. Funcionario: " + employeeNumber); } } else { log.println(accountabilityTypeEnum.getName() + ". Não existe unidade: " + costCenterCode + " para o funcionario: " + employeeNumber); } } result.close(); preparedStatement.close(); return modifications; } private PersonContractSituation getOtherValidPersonContractSituation( GiafProfessionalData giafProfessionalDataByGiafPersonIdentification) { for (PersonContractSituation personContractSituation : giafProfessionalDataByGiafPersonIdentification .getValidPersonContractSituations()) { if (personContractSituation.getBeginDate().equals( giafProfessionalDataByGiafPersonIdentification.getContractSituationDate())) { return personContractSituation; } } return null; } private Contract getLastContractByContractType(Employee employee, AccountabilityTypeEnum contractType, YearMonthDay begin, YearMonthDay end) { if (end != null && end.isBefore(begin)) { end = begin; } YearMonthDay date = null; Contract contractToReturn = null; for (Contract contract : employee.getContractsByContractType(contractType, begin, end)) { if (date == null || contract.getBeginDate().isAfter(date)) { date = contract.getBeginDate(); contractToReturn = contract; } } return contractToReturn; } private Modification changeEmployeeContractDates(final AccountabilityTypeEnum accountabilityTypeEnum, final YearMonthDay yearMonthDay, final Contract currentWorkingContract, PrintWriter log, final Logger logger) { return new Modification() { @Override public void execute() { YearMonthDay yearMonthDayMinusOne = yearMonthDay.minusDays(1); for (Contract contract : currentWorkingContract.getEmployee().getContractsByContractType(accountabilityTypeEnum, yearMonthDay, null)) { if (!currentWorkingContract.equals(contract)) { if (contract.getBeginDate().isBefore(yearMonthDay)) { contract.setEndDate(yearMonthDayMinusOne); log.println(accountabilityTypeEnum.getName() + ". Contrato terminado na unidade " + currentWorkingContract.getUnit().getCostCenterCode() + " para o funcionário:" + currentWorkingContract.getEmployee().getEmployeeNumber() + " . Mudou data de fim para :" + yearMonthDayMinusOne); } else { contract.delete(); log.println(accountabilityTypeEnum.getName() + ". APAGOU para a unidade " + currentWorkingContract.getUnit().getCostCenterCode() + " para o funcionário:" + currentWorkingContract.getEmployee().getEmployeeNumber()); } } } currentWorkingContract.setBeginDate(yearMonthDay); log.println(accountabilityTypeEnum.getName() + " Mudou data de inicio: " + currentWorkingContract.getUnit().getCostCenterCode() + " para o funcionário:" + currentWorkingContract.getEmployee().getEmployeeNumber() + " . Mudou data de inicio para :" + yearMonthDay); } }; } private Modification closeCurrentContract(final AccountabilityTypeEnum accountabilityTypeEnum, final Contract currentWorkingContract, final YearMonthDay endDate, PrintWriter log, final Logger logger) { return new Modification() { @Override public void execute() { if (currentWorkingContract.getEndDate() != null && currentWorkingContract.getEndDate().isEqual(endDate)) { log.println(accountabilityTypeEnum.getName() + ". Já está fechado. Não há alterações para o funcionário:" + currentWorkingContract.getEmployee().getEmployeeNumber()); } else if (currentWorkingContract.getBeginDate().isAfter(endDate)) { log.println(accountabilityTypeEnum.getName() + ". APAGOU para a unidade " + currentWorkingContract.getUnit().getCostCenterCode() + " para o funcionário:" + currentWorkingContract.getEmployee().getEmployeeNumber()); currentWorkingContract.delete(); } else { currentWorkingContract.setEndDate(endDate); log.println(accountabilityTypeEnum.getName() + ". Contrato terminado na unidade " + currentWorkingContract.getUnit().getCostCenterCode() + " para o funcionário:" + currentWorkingContract.getEmployee().getEmployeeNumber() + " . Mudou data de fim para :" + endDate); } } }; } private List<Modification> createEmployeeContract(final Employee employee, final YearMonthDay begin, final YearMonthDay end, final Unit unit, final AccountabilityTypeEnum accountabilityTypeEnum, final Contract currentWorkingContract, PrintWriter log, final Logger logger) { List<Modification> modifications = new ArrayList<>(); if (currentWorkingContract != null) { modifications.add(closeCurrentContract(accountabilityTypeEnum, currentWorkingContract, begin.minusDays(1), log, logger)); } modifications.add(new Modification() { @Override public void execute() { log.println(accountabilityTypeEnum.getName() + ". Novo contrato na unidade " + unit.getName() + " para o funcionário:" + employee.getEmployeeNumber() + " " + begin + " " + end); new EmployeeContract(employee.getPerson(), begin, end, unit, accountabilityTypeEnum, false); } }); return modifications; } private String getEmployeeWorkingUnitsQuery() { return "SELECT emp.EMP_NUM ,emp.emp_sec_serv as cc, emp.emp_sec_serv_dt as cc_date FROM SLDEMP01 emp"; } private String getEmployeeMailingUnitsQuery() { return "SELECT emp.EMP_NUM, emp.emp_sec_serv_ci as cc, null as cc_date FROM SLDEMP03 emp"; } }