diff --git a/CHANGELOG.md b/CHANGELOG.md
index c088e411e..5def72ccb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,12 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.14.0] - UNRELEASED
### Added
- Aggiunto piano ferie 15+2
-
+ - Aggiunto servizio REST per esportazione lista delle sedi
+ - Aggiunto campo externalId ai tipi di assenza
+
### Changed
- Corretta lista persone in Straordinario mensili gruppo, filtrando le persone non più affiliate
- Cambiata la gestione dei codici 71D e seguenti con la stessa logica del 7M
- Corretta possibilità di inserire più richieste di cambio reperibilità non ancora confermate nello stesso mese
-
+ - Nell'esportazione via REST del riepilogo mensile dei dipendenti aggiunto nuovo campo externalId del tipo di assenza
## [2.13.0] - 2024-02-13
### Added
diff --git a/app/cnr/sync/dto/v3/AbsenceShowTerseDto.java b/app/cnr/sync/dto/v3/AbsenceShowTerseDto.java
index 6b452e993..112688080 100644
--- a/app/cnr/sync/dto/v3/AbsenceShowTerseDto.java
+++ b/app/cnr/sync/dto/v3/AbsenceShowTerseDto.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 Consiglio Nazionale delle Ricerche
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -14,7 +14,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
package cnr.sync.dto.v3;
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -49,8 +48,9 @@ public class AbsenceShowTerseDto {
private String justifiedType;
private String note;
private String externalId;
+ private String externalTypeId;
private LocalDateTime updatedAt;
-
+
@JsonIgnore
@Inject
static ModelMapper modelMapper;
@@ -69,6 +69,7 @@ public static AbsenceShowTerseDto build(Absence absence) {
absenceDto.setDate(JodaConverters.jodaToJavaLocalDate(absence.getAbsenceDate()));
if (absence.getAbsenceType() != null) {
absenceDto.setAbsenceTypeId(absence.getAbsenceType().getId());
+ absenceDto.setExternalTypeId(absence.getAbsenceType().getExternalId());
}
return absenceDto;
}
diff --git a/app/cnr/sync/dto/v3/OfficeShowTerseDto.java b/app/cnr/sync/dto/v3/OfficeShowTerseDto.java
new file mode 100644
index 000000000..53fa2650b
--- /dev/null
+++ b/app/cnr/sync/dto/v3/OfficeShowTerseDto.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package cnr.sync.dto.v3;
+
+import cnr.sync.dto.v2.GroupShowDto;
+import cnr.sync.dto.v2.PersonShowTerseDto;
+import helpers.validators.PeriodEndDateCheck;
+import java.time.LocalDateTime;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.val;
+import models.Institute;
+import models.Office;
+import models.Person;
+import org.joda.time.LocalDate;
+import org.modelmapper.ModelMapper;
+import play.data.validation.CheckWith;
+import play.data.validation.Required;
+import play.data.validation.Unique;
+
+/**
+ * Dati esportati in Json per l'Ufficio.
+ *
+ * @author Cristian Lucchesi
+ *
+ */
+@ToString
+@Data
+public class OfficeShowTerseDto {
+
+ private Long id;
+ private Long perseoId;
+ private String name;
+
+ //Codice della sede, per esempio per la sede di Pisa è "044000"
+ private String code;
+
+ //sedeId, serve per l'invio degli attestati, per esempio per la sede di Pisa è "223400"
+ private String codeId;
+ private String address;
+ private LocalDate joiningDate;
+ private LocalDate beginDate;
+ private LocalDate endDate;
+
+ private Long instituteId;
+ private boolean headQuarter = false;
+ private LocalDateTime updatedAt;
+
+ /**
+ * Nuova instanza di un OfficeShowTerseDto contenente i valori
+ * dell'oggetto Office passato.
+ */
+ public static OfficeShowTerseDto build(Office office) {
+ ModelMapper modelMapper = new ModelMapper();
+ modelMapper.getConfiguration().setAmbiguityIgnored(true);
+ val officeDto = modelMapper.map(office, OfficeShowTerseDto.class);
+ if (office.getInstitute() != null) {
+ officeDto.setInstituteId(office.getInstitute().getId());
+ }
+ return officeDto;
+ }
+}
\ No newline at end of file
diff --git a/app/cnr/sync/dto/v3/PersonDayShowDto.java b/app/cnr/sync/dto/v3/PersonDayShowDto.java
index 5c1c17629..e4009e9b8 100644
--- a/app/cnr/sync/dto/v3/PersonDayShowDto.java
+++ b/app/cnr/sync/dto/v3/PersonDayShowDto.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 Consiglio Nazionale delle Ricerche
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -14,7 +14,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
package cnr.sync.dto.v3;
import cnr.sync.dto.v2.PersonShowTerseDto;
diff --git a/app/controllers/rest/v2/Groups.java b/app/controllers/rest/v2/Groups.java
index 4a2f4a647..49d1f489f 100644
--- a/app/controllers/rest/v2/Groups.java
+++ b/app/controllers/rest/v2/Groups.java
@@ -26,6 +26,7 @@
import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
+import controllers.rest.v3.Offices;
import dao.GroupDao;
import helpers.JsonResponse;
import helpers.rest.RestUtils;
diff --git a/app/controllers/rest/v2/Leaves.java b/app/controllers/rest/v2/Leaves.java
index be550d438..b2388e431 100644
--- a/app/controllers/rest/v2/Leaves.java
+++ b/app/controllers/rest/v2/Leaves.java
@@ -25,6 +25,7 @@
import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
+import controllers.rest.v3.Offices;
import dao.AbsenceDao;
import dao.PersonDao;
import helpers.JodaConverters;
diff --git a/app/controllers/rest/v2/Persons.java b/app/controllers/rest/v2/Persons.java
index 57ec2e986..73f03f539 100644
--- a/app/controllers/rest/v2/Persons.java
+++ b/app/controllers/rest/v2/Persons.java
@@ -29,6 +29,7 @@
import common.security.SecurityRules;
import controllers.Resecure;
import controllers.Resecure.BasicAuth;
+import controllers.rest.v3.Offices;
import dao.PersonDao;
import helpers.JodaConverters;
import helpers.JsonResponse;
diff --git a/app/controllers/rest/v2/WorkingTimeTypes.java b/app/controllers/rest/v2/WorkingTimeTypes.java
index 0255c46dc..d70795d10 100644
--- a/app/controllers/rest/v2/WorkingTimeTypes.java
+++ b/app/controllers/rest/v2/WorkingTimeTypes.java
@@ -22,6 +22,7 @@
import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
+import controllers.rest.v3.Offices;
import dao.WorkingTimeTypeDao;
import helpers.JsonResponse;
import helpers.rest.RestUtils;
diff --git a/app/controllers/rest/v3/BadgeReaders.java b/app/controllers/rest/v3/BadgeReaders.java
index 009b5c67b..403850ca0 100644
--- a/app/controllers/rest/v3/BadgeReaders.java
+++ b/app/controllers/rest/v3/BadgeReaders.java
@@ -22,7 +22,6 @@
import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
-import controllers.rest.v2.Offices;
import dao.BadgeReaderDao;
import helpers.JsonResponse;
import helpers.rest.RestUtils;
diff --git a/app/controllers/rest/v3/BadgeSystems.java b/app/controllers/rest/v3/BadgeSystems.java
index d4442bb50..e73c3460b 100644
--- a/app/controllers/rest/v3/BadgeSystems.java
+++ b/app/controllers/rest/v3/BadgeSystems.java
@@ -22,7 +22,6 @@
import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
-import controllers.rest.v2.Offices;
import dao.BadgeSystemDao;
import helpers.JsonResponse;
import helpers.rest.RestUtils;
diff --git a/app/controllers/rest/v3/Badges.java b/app/controllers/rest/v3/Badges.java
index cf3bdac4c..263de6b1a 100644
--- a/app/controllers/rest/v3/Badges.java
+++ b/app/controllers/rest/v3/Badges.java
@@ -26,7 +26,6 @@
import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
-import controllers.rest.v2.Offices;
import controllers.rest.v2.Persons;
import dao.BadgeDao;
import dao.BadgeSystemDao;
diff --git a/app/controllers/rest/v2/Offices.java b/app/controllers/rest/v3/Offices.java
similarity index 59%
rename from app/controllers/rest/v2/Offices.java
rename to app/controllers/rest/v3/Offices.java
index 5dc6bf0b3..c7f56fd27 100644
--- a/app/controllers/rest/v2/Offices.java
+++ b/app/controllers/rest/v3/Offices.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 Consiglio Nazionale delle Ricerche
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -14,15 +14,26 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+package controllers.rest.v3;
-package controllers.rest.v2;
-
+import cnr.sync.dto.v3.OfficeShowTerseDto;
+import com.beust.jcommander.internal.Lists;
import com.google.common.base.Optional;
+import com.google.gson.GsonBuilder;
import common.security.SecurityRules;
import controllers.Resecure;
+import controllers.Resecure.BasicAuth;
import dao.OfficeDao;
+import helpers.JodaConverters;
import helpers.JsonResponse;
+import helpers.rest.RestUtils;
+import helpers.rest.RestUtils.HttpMethod;
+import it.cnr.iit.epas.DateUtility;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.stream.Collectors;
import javax.inject.Inject;
+import lombok.val;
import lombok.extern.slf4j.Slf4j;
import models.Office;
import play.mvc.Controller;
@@ -40,6 +51,38 @@ public class Offices extends Controller {
static OfficeDao officeDao;
@Inject
static SecurityRules rules;
+ @Inject
+ static GsonBuilder gsonBuilder;
+
+ /**
+ * Lista JSON delle persone che appartengono alla sede
+ * individuata con i parametri passati.
+ */
+ @BasicAuth
+ public static void all(LocalDate atDate) {
+ RestUtils.checkMethod(request, HttpMethod.GET);
+ log.debug("rest.Offices::all atDate = {}", atDate);
+ List offices = Lists.newArrayList();
+ if (atDate != null) {
+ offices = officeDao.allOffices(JodaConverters.javaToJodaLocalDate(atDate));
+ } else {
+ offices = officeDao.allEnabledOffices();
+ }
+ val list =
+ offices.stream().map(o -> OfficeShowTerseDto.build(o)).collect(Collectors.toList());
+ renderJSON(gsonBuilder.create().toJson(list));
+ }
+
+ /**
+ * Restituisce il JSON con i dati dell'ufficio individuato con i parametri
+ * passati.
+ */
+ public static void show(Long id, String code, String codeId) {
+ RestUtils.checkMethod(request, HttpMethod.GET);
+ val office = getOfficeFromRequest(id, code, codeId);
+ rules.checkIfPermitted(office);
+ renderJSON(gsonBuilder.create().toJson(OfficeShowTerseDto.build(office)));
+ }
/**
* Cerca l'ufficio in funzione dei parametri passati.
diff --git a/app/controllers/rest/v3/PersonDays.java b/app/controllers/rest/v3/PersonDays.java
index 7503ebd44..0c569a0f3 100755
--- a/app/controllers/rest/v3/PersonDays.java
+++ b/app/controllers/rest/v3/PersonDays.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 Consiglio Nazionale delle Ricerche
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -14,7 +14,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
package controllers.rest.v3;
import cnr.sync.dto.v2.PersonShowTerseDto;
@@ -29,7 +28,6 @@
import common.security.SecurityRules;
import controllers.PersonDays.MealTicketDecision;
import controllers.Resecure;
-import controllers.rest.v2.Offices;
import controllers.rest.v2.Persons;
import dao.PersonDao;
import dao.PersonDayDao;
@@ -43,8 +41,8 @@
import java.util.Set;
import java.util.stream.Collectors;
import javax.inject.Inject;
-import lombok.extern.slf4j.Slf4j;
import lombok.val;
+import lombok.extern.slf4j.Slf4j;
import manager.ConsistencyManager;
import manager.PersonManager;
import models.Office;
@@ -120,7 +118,7 @@ public static void getMonthSituationByOffice(Long id, String code, String codeId
}
val office =
Offices.getOfficeFromRequest(id, code, Strings.isNullOrEmpty(codeId) ? sedeId : codeId);
- rules.checkIfPermitted(office);
+ rules.checkIfPermitted(office);
org.joda.time.LocalDate date = new org.joda.time.LocalDate(year, month, 1);
@@ -132,15 +130,15 @@ public static void getMonthSituationByOffice(Long id, String code, String codeId
personDays.stream().collect(Collectors.groupingBy(PersonDay::getPerson));
List monthRecaps = Lists.newArrayList();
- personDayMap.forEach((p, pds) -> {
- monthRecaps.add(PersonMonthRecapDto.builder()
- .person(PersonShowTerseDto.build(p))
- .year(year).month(month)
- .personDays(
- pds.stream().map(pd -> PersonDayShowTerseDto.build(pd))
- .collect(Collectors.toList()))
- .build());
- });
+ personDayMap.forEach((p, pds) -> {
+ monthRecaps.add(PersonMonthRecapDto.builder()
+ .person(PersonShowTerseDto.build(p))
+ .year(year).month(month)
+ .personDays(
+ pds.stream().map(pd -> PersonDayShowTerseDto.build(pd))
+ .collect(Collectors.toList()))
+ .build());
+ });
val gson = gsonBuilder.create();
renderJSON(gson.toJson(monthRecaps));
@@ -205,7 +203,7 @@ public static void getMonthSituationByPerson(Long id, String email, String eppn,
.collect(Collectors.toList()))
.build();
val gson = gsonBuilder.create();
- renderJSON(gson.toJson(monthRecap));
+ renderJSON(gson.toJson(monthRecap));
}
/**
diff --git a/app/dao/OfficeDao.java b/app/dao/OfficeDao.java
index 0199b4c38..45b1967dc 100755
--- a/app/dao/OfficeDao.java
+++ b/app/dao/OfficeDao.java
@@ -316,4 +316,11 @@ public List allEnabledOffices() {
.or(office.endDate.after(LocalDate.now()))).fetch();
}
+ public List allOffices(LocalDate atDate) {
+ final QOffice office = QOffice.office;
+ BooleanBuilder conditions = new BooleanBuilder(office.beginDate.before(atDate));
+ conditions.and(office.endDate.isNull().or(office.endDate.after(atDate)));
+ return queryFactory.selectFrom(office).where(conditions).fetch();
+ }
+
}
diff --git a/app/helpers/LocalDateJavaBinder.java b/app/helpers/LocalDateJavaBinder.java
index f618439ca..78ac35297 100644
--- a/app/helpers/LocalDateJavaBinder.java
+++ b/app/helpers/LocalDateJavaBinder.java
@@ -33,7 +33,8 @@
public class LocalDateJavaBinder implements TypeBinder {
//Questo formato è utilizzato nelle form HTML
- static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy");
+ static final String ITALIAN_DATE_PATTERN = "dd/MM/yyyy";
+ static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern(ITALIAN_DATE_PATTERN);
@SuppressWarnings("rawtypes")
@Override
@@ -45,7 +46,7 @@ public Object bind(String name, Annotation[] annotations, String value,
try {
return LocalDate.parse(value, dtf);
} catch (Exception ignored) {
- log.debug("Exception during java LocalDate binding, value={}", value);
+ log.debug("Enable to bind java LocalDate using pattern {}, value={}", ITALIAN_DATE_PATTERN, value);
}
//Nei metodi REST le date vengono passate nel formato ISO
return LocalDate.from(DateTimeFormatter.ISO_LOCAL_DATE.parse(value));
diff --git a/app/models/absences/AbsenceType.java b/app/models/absences/AbsenceType.java
index b80ad5db6..757b30e2a 100755
--- a/app/models/absences/AbsenceType.java
+++ b/app/models/absences/AbsenceType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 Consiglio Nazionale delle Ricerche
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -14,7 +14,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
package models.absences;
import com.google.common.base.Joiner;
@@ -158,6 +157,9 @@ public class AbsenceType extends BaseModel {
private boolean shiftCompatible;
private boolean isRealAbsence = true;
+
+ private String externalId;
+
// Metodi
/**
diff --git a/app/views/AbsenceGroups/editAbsenceType.html b/app/views/AbsenceGroups/editAbsenceType.html
index 1db843d24..3e915c0fb 100755
--- a/app/views/AbsenceGroups/editAbsenceType.html
+++ b/app/views/AbsenceGroups/editAbsenceType.html
@@ -57,8 +57,10 @@
#{f.booleanRadio 'absenceType.reperibilityCompatible', custom_popover:'true' /}
#{f.booleanRadio 'absenceType.shiftCompatible', custom_popover:'true' /}
+ #{f.input 'absenceType.externalId',custom_popover:'true' /}
#{f.booleanRadio 'absenceType.toUpdate', custom_popover:'true' /}
+
#{secure.check 'AbsenceGroups.saveAbsenceType' }
diff --git a/conf/messages.it b/conf/messages.it
index 9b2a22d45..564bb2a54 100755
--- a/conf/messages.it
+++ b/conf/messages.it
@@ -1536,6 +1536,8 @@ absenceType.timeForMealTicket=Considerato per buono pasto
absenceType.justifiedTime=Minuti specificati nel tipo assenza
absenceType.toUpdate=Aggiornamento stato assenza
absenceType.mealTicketBehaviour =Comportamento per buono pasto
+absenceType.externalId =External id
+absenceType.externalId.popover =External id utilizzabile anche per il raggruppamento delle assenze per i timesheet
absenceType.replacingTime=Minuti per completamento
absenceType.used=Usato
diff --git a/conf/permissions.drl b/conf/permissions.drl
index 57446629b..b2919f451 100755
--- a/conf/permissions.drl
+++ b/conf/permissions.drl
@@ -4128,7 +4128,10 @@ when
"rest.Absences.attachment",
"rest.v3.AbsenceTypes.list",
- "rest.v3.AbsenceTypes.show"
+ "rest.v3.AbsenceTypes.show",
+
+ "rest.v3.Offices.all",
+ "rest.v3.Offices.show"
), granted == false)
then
diff --git a/db/evolutions/213.sql b/db/evolutions/213.sql
new file mode 100644
index 000000000..e5f8c4407
--- /dev/null
+++ b/db/evolutions/213.sql
@@ -0,0 +1,9 @@
+# --- !Ups
+
+ALTER TABLE absence_types ADD COLUMN external_id TEXT;
+ALTER TABLE absence_types_history ADD COLUMN external_id TEXT;
+
+# --- !Downs
+
+ALTER TABLE absence_types DROP COLUMN external_id;
+ALTER TABLE absence_types_history DROP COLUMN external_id;
\ No newline at end of file