diff --git a/app/controllers/Administration.java b/app/controllers/Administration.java index f92a90947..6cbfa9ce1 100755 --- a/app/controllers/Administration.java +++ b/app/controllers/Administration.java @@ -49,8 +49,10 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; import java.lang.management.ManagementFactory; import java.net.MalformedURLException; import java.util.AbstractMap.SimpleEntry; @@ -68,6 +70,7 @@ import javax.validation.Valid; import lombok.extern.slf4j.Slf4j; import lombok.val; +import manager.AbsenceManager; import manager.CompetenceManager; import manager.ConsistencyManager; import manager.ContractManager; @@ -96,9 +99,13 @@ import models.User; import models.UsersRolesOffices; import models.absences.Absence; +import models.absences.AbsenceType; +import models.absences.CategoryTab; import models.absences.JustifiedType; import models.absences.JustifiedType.JustifiedTypeName; import models.enumerate.LimitType; + +import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.lang.WordUtils; import org.joda.time.LocalDate; import org.joda.time.YearMonth; @@ -176,6 +183,8 @@ public class Administration extends Controller { static HelpdeskServiceManager helpdeskServiceManager; @Inject static CertificationsComunication certificationComunication; + @Inject + static AbsenceManager absenceManager; /** * Utilizzabile solo da developer e admin permette di prelevare un token del client @@ -248,7 +257,7 @@ public static void fixPersonSituation(Person person, Office office, Validation.addError("person", "Obbligatorio specificare un utente o un ufficio"); Validation.addError("office", "Obbligatorio specificare un utente o un ufficio"); } - + if (Validation.hasErrors()) { flash.error("Correggere gli errori evidenziati"); log.debug("Errori di validazione in fixPersonSituation, person={}, " @@ -273,7 +282,7 @@ public static void fixPersonSituation(Person person, Office office, personList = personDao.getActivePersonInMonth( Sets.newHashSet(office), new YearMonth(date.getYear(), date.getMonthOfYear())); } - + consistencyManager.fixPersonSituation(personList, date, onlyRecap); flash.success("Esecuzione avviata in background"); @@ -457,7 +466,7 @@ public static void saveGeneralSetting(@Required @Valid GeneralSetting generalSet generalSetting(); } } - + /** * Mostra tutti i parametri di configurazione del play. */ @@ -500,7 +509,7 @@ public static void runtimeData() { "Free Memory", String.format("%s Mb", runtime.freeMemory() / mb), "Max Memory", String.format("%s Mb", runtime.maxMemory() / mb), "Total Memory", String.format("%s Mb", runtime.totalMemory() / mb)).entrySet(); - + final Set> entries = Sets.newHashSet(entrySet); entries.add(new SimpleEntry("Load", String.format("%s", load))); render("@data", entries); @@ -514,7 +523,7 @@ public static void threadsData() { val threadsData = threads.dumpAllThreads(true, true); render("@threadsData", threadsData); } - + /** * Render del modale per l'aggiunta di un nuovo parametro di configurazione. */ @@ -638,8 +647,8 @@ public static void administratorsEmails() { List uros = UsersRolesOffices.findAll(); List emails = uros.stream().filter(uro -> - uro.getRole().getName().equals(Role.PERSONNEL_ADMIN) - && uro.getUser().getPerson() != null) + uro.getRole().getName().equals(Role.PERSONNEL_ADMIN) + && uro.getUser().getPerson() != null) .map(uro -> uro.getUser().getPerson().getEmail()) .distinct().collect(Collectors.toList()); @@ -747,7 +756,7 @@ public static void applyBonusAllOffices(int year, int month) { competenceManager.applyBonus(Optional.absent(), item, yearMonth); }); } - + /** * Metodo che applica le competenze a presenza mensile/giornaliera. * @@ -995,7 +1004,7 @@ public static void updateAllOfficeConfigurations() { configurationManager.updateAllOfficesConfigurations(); renderText("Aggiornati i parametri di configuratione di tutti gli uffici."); } - + public static void updatePeopleConfigurations() { configurationManager.updatePeopleConfigurations(); renderText("Aggiornati i parametri di configurazione di tutte le persone."); @@ -1053,11 +1062,11 @@ private static void changeSeatLocation(Office office, Institute institute, institute.save(); } - + public static void emergency(Boolean confirm) { render(confirm); } - + /** * Il peggior hack di sempre per uccidere il play. * È da utilizzare in casi disperati come quando sta finendo la @@ -1149,4 +1158,29 @@ public void deleteExpiredJwtTokens() { log.debug("Cancellati {} expired tokens", expiredTokens.size()); renderText(String.format("Cancellati %s expired tokens", expiredTokens.size())); } + + /** + * Genero l'alberatura dei gruppi dei codici d'assenza con limiti di fruizione e completamento + * @throws ArchiveException + */ + public void generateAbsencesFile() throws ArchiveException { + List categoryTabs = absenceComponentDao.tabsByPriority(); + InputStream file = absenceManager.buildFile(categoryTabs); + + renderBinary(file, "export.zip", false); + } + + public void generateAbsenceCodeList() { + List list = absenceTypeDao + .list(java.util.Optional.empty(), java.util.Optional.of(LocalDate.now()), java.util.Optional.empty()); + list = list.stream().filter(abt -> !abt.isInternalUse()).collect(Collectors.toList()); + InputStream file = null; + try { + file = absenceManager.buildAbsenceTypeListFile(list); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + renderBinary(file, "codici.zip", false); + } } \ No newline at end of file diff --git a/app/manager/AbsenceManager.java b/app/manager/AbsenceManager.java index aebf63c92..dbb21249d 100755 --- a/app/manager/AbsenceManager.java +++ b/app/manager/AbsenceManager.java @@ -18,6 +18,7 @@ package manager; import com.google.common.base.Function; +import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; @@ -37,6 +38,16 @@ import dao.absences.AbsenceComponentDao; import dao.wrapper.IWrapperFactory; import dao.wrapper.IWrapperPerson; +import it.cnr.iit.epas.DateUtility; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -44,11 +55,16 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import lombok.val; +import manager.charts.ChartsManager.PersonStampingDayRecapHeader; import manager.configurations.ConfigurationManager; import manager.configurations.EpasParam; +import manager.recaps.personstamping.PersonStampingDayRecap; import manager.response.AbsenceInsertReport; import manager.response.AbsencesResponse; import manager.services.absences.AbsenceService.InsertReport; @@ -65,6 +81,7 @@ import models.absences.Absence; import models.absences.AbsenceType; import models.absences.CategoryGroupAbsenceType; +import models.absences.CategoryTab; import models.absences.GroupAbsenceType; import models.absences.JustifiedType; import models.absences.JustifiedType.JustifiedTypeName; @@ -81,11 +98,18 @@ import net.fortuna.ical4j.model.property.Version; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.MultiPartEmail; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; import org.joda.time.DateTimeZone; import org.joda.time.LocalDate; import org.joda.time.YearMonth; import play.db.jpa.Blob; import play.db.jpa.JPA; +import play.i18n.Messages; import play.libs.Mail; @@ -886,7 +910,7 @@ public Integer getJustifiedMinutes(Absence absence) { if (absence.getJustifiedType().getName() .equals(JustifiedTypeName.complete_day_and_add_overtime)) { timeToJustify = - workingTimeTypeDay.get().getWorkingTime() - absence.getPersonDay().getStampingsTime(); + workingTimeTypeDay.get().getWorkingTime() - absence.getPersonDay().getStampingsTime(); } if (absence.getJustifiedType().getName().equals(JustifiedTypeName.absence_type_minutes)) { timeToJustify = absence.getAbsenceType().getJustifiedTime(); @@ -932,4 +956,295 @@ public Calendar createIcsAbsencesCalendar( return icsCalendar; } + /** + * Metodo di utilità da chiamare dal controller Administration per generare il file che contiene + * la lista dei codici raggruppati con le loro caratteristiche. + * @param categoryTabs la lista dell categorie dei codici + * @return il file generato contenente i codici raggruppati con le loro caratteristiche. + */ + public InputStream buildFile(List categoryTabs) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ZipOutputStream zos = new ZipOutputStream(out); + byte[] buffer = new byte[1024]; + File file = null; + try { + try { + file = File.createTempFile( + "statoAssenzeEpas", ".xls"); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Workbook wb = new HSSFWorkbook(); + FileOutputStream outStream = new FileOutputStream(file); + Sheet sheet = wb.createSheet("codiciAssenza"); + + Row row = null; + Cell cell = null; + + row = sheet.createRow(0); + row.setHeightInPoints(30); + for (int i = 0; i < 5; i++) { + sheet.setColumnWidth((short) i, (short) ((50 * 8) / ((double) 1 / 20))); + cell = row.createCell(i); + switch (i) { + case 0: + cell.setCellValue("Gruppo"); + break; + case 1: + cell.setCellValue("Periodo"); + break; + case 2: + cell.setCellValue("Limite"); + break; + case 3: + cell.setCellValue("Codici"); + break; + case 4: + cell.setCellValue("Completamenti e Codici"); + break; + default: + break; + } + } + int rownum = 1; + for (CategoryTab category : categoryTabs) { + for (CategoryGroupAbsenceType categoryGroup : category.getCategoryGroupAbsenceTypes()) { + for (GroupAbsenceType group : categoryGroup.getGroupAbsenceTypes()) { + row = sheet.createRow(rownum); + + for (int cellnum = 0; cellnum < 5; cellnum++) { + cell = row.createCell(cellnum); + switch (cellnum) { + case 0: + cell.setCellValue(group.getDescription()); + break; + case 1: + cell.setCellValue(Messages.get(group.getPeriodType().toString())); + break; + case 2: + if (group.getTakableAbsenceBehaviour().getFixedLimit() > 0) { + cell.setCellValue(group.getTakableAbsenceBehaviour().getFixedLimit().toString() +" " + + Messages.get(group.getTakableAbsenceBehaviour().getAmountType())); + } else { + cell.setCellValue("Nessun limite"); + } + break; + case 3: + for (AbsenceType abt : group.getTakableAbsenceBehaviour().getTakableCodes()) { + String temp = cell.getStringCellValue(); + cell.setCellValue(temp + " " + abt.getCode() +" "); + } + break; + case 4: + if (group.getComplationAbsenceBehaviour() != null) { + cell.setCellValue("Completamento in " + Messages.get(group.getComplationAbsenceBehaviour().getAmountType())); + for (AbsenceType abt : group.getComplationAbsenceBehaviour().getComplationCodes()) { + if (!abt.isExpired()) { + String temp = cell.getStringCellValue(); + cell.setCellValue(temp + " " + abt.getCode() +" "); + } + } + } + break; + default: + break; + } + } + rownum++; + } + } + } + + try { + wb.write(outStream); + wb.close(); + out.close(); + } catch (IOException ex) { + log.error("problema in chiusura stream"); + ex.printStackTrace(); + } + } catch (IllegalArgumentException | FileNotFoundException ex) { + log.error("Problema in riconoscimento file"); + ex.printStackTrace(); + } + + // faccio lo stream da inviare al chiamante... + FileInputStream in = null; + try { + in = new FileInputStream(file); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + zos.putNextEntry(new ZipEntry(file.getName())); + int length; + while ((length = in.read(buffer)) > 0) { + zos.write(buffer, 0, length); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + file.delete(); + try { + zos.closeEntry(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + zos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return new ByteArrayInputStream(out.toByteArray()); + } + + + + public InputStream buildAbsenceTypeListFile(List absenceTypeList) throws FileNotFoundException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ZipOutputStream zos = new ZipOutputStream(out); + byte[] buffer = new byte[1024]; + File file = null; + try { + file = File.createTempFile( + "codiciAssenzaEpas", ".xls"); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Workbook wb = new HSSFWorkbook(); + + FileOutputStream outStream = new FileOutputStream(file); + + Sheet sheet = wb.createSheet("codiciAssenza"); + Row row = null; + Cell cell = null; + + row = sheet.createRow(0); + row.setHeightInPoints(30); + for (int i = 0; i < 5; i++) { + sheet.setColumnWidth((short) i, (short) ((50 * 8) / ((double) 1 / 20))); + cell = row.createCell(i); + switch (i) { + case 0: + cell.setCellValue("Codice assenza"); + break; + case 1: + cell.setCellValue("Descrizione"); + break; + case 2: + cell.setCellValue("Compatibile coi turni"); + break; + case 3: + cell.setCellValue("Compatibile con la reperibilità"); + break; + case 4: + cell.setCellValue("Usabile nel week end"); + break; + default: + break; + } + } + int rownum = 1; + for (AbsenceType abt : absenceTypeList) { + row = sheet.createRow(rownum); + + for (int cellnum = 0; cellnum < 5; cellnum++) { + cell = row.createCell(cellnum); + switch (cellnum) { + case 0: + cell.setCellValue(abt.getCode()); + break; + case 1: + cell.setCellValue(abt.getDescription()); + break; + case 2: + if (abt.isShiftCompatible()) { + cell.setCellValue("Sì"); + } else { + cell.setCellValue("No"); + } + break; + case 3: + if (abt.isReperibilityCompatible()) { + cell.setCellValue("Sì"); + } else { + cell.setCellValue("No"); + } + break; + case 4: + if (abt.isConsideredWeekEnd()) { + cell.setCellValue("Sì"); + } else { + cell.setCellValue("No"); + } + break; + default: + break; + } + } + rownum++; + } + try { + wb.write(outStream); + wb.close(); + out.close(); + } catch (IOException ex) { + log.error("problema in chiusura stream"); + ex.printStackTrace(); + } + + + // faccio lo stream da inviare al chiamante... + FileInputStream in = null; + try { + in = new FileInputStream(file); + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + zos.putNextEntry(new ZipEntry(file.getName())); + int length; + while ((length = in.read(buffer)) > 0) { + zos.write(buffer, 0, length); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + file.delete(); + try { + zos.closeEntry(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + zos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return new ByteArrayInputStream(out.toByteArray()); + } + + }