diff --git a/modules/axelor-open-suite/axelor-base/src/main/resources/domains/CompanyDepartment.xml b/modules/axelor-open-suite/axelor-base/src/main/resources/domains/CompanyDepartment.xml
index 8de0bd9..7a9e51d 100644
--- a/modules/axelor-open-suite/axelor-base/src/main/resources/domains/CompanyDepartment.xml
+++ b/modules/axelor-open-suite/axelor-base/src/main/resources/domains/CompanyDepartment.xml
@@ -9,8 +9,8 @@
+
-
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchAttendanceJob.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchAttendanceJob.java
index 1f4b1e0..98e0dcf 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchAttendanceJob.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchAttendanceJob.java
@@ -10,10 +10,12 @@ import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.SchedulerException;
+import com.axelor.app.AppSettings;
public class FetchAttendanceJob implements Job {
private final Logger log = LoggerFactory.getLogger(FetchCheckInOutJob.class);
+ private final String pythonScriptDir = AppSettings.get().get("services.dir");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException{
@@ -22,9 +24,14 @@ public class FetchAttendanceJob implements Job {
return;
}
+ if (pythonScriptDir == null || pythonScriptDir.isEmpty()) {
+ log.error("Python script path is not configured in AppSettings.");
+ return;
+ }
+
try {
// Define the command to run the Python script with the correct path (V3)
- String[] args = {"python", "C:\\Users\\administrator\\Desktop\\Scrape\\main.py"};
+ String[] args = {"python", pythonScriptDir + "\\Scrape\\main.py"};
// Execute the command
Process p = Runtime.getRuntime().exec(args);
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchCheckInOutJob.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchCheckInOutJob.java
index 4f05438..d340235 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchCheckInOutJob.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchCheckInOutJob.java
@@ -14,10 +14,12 @@ import org.slf4j.LoggerFactory;
import com.axelor.inject.Beans;
import java.time.LocalDate;
import org.quartz.SchedulerException;
+import com.axelor.app.AppSettings;
public class FetchCheckInOutJob implements Job {
private final Logger log = LoggerFactory.getLogger(FetchCheckInOutJob.class);
+ private final String pythonScriptDir = AppSettings.get().get("services.dir");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
@@ -26,6 +28,11 @@ public class FetchCheckInOutJob implements Job {
return;
}
+ if (pythonScriptDir == null || pythonScriptDir.isEmpty()) {
+ log.error("Python script path is not configured in AppSettings.");
+ return;
+ }
+
try {
LocalDate today = LocalDate.now();
@@ -35,11 +42,10 @@ public class FetchCheckInOutJob implements Job {
.all()
.filter("self.date_attendance = :today")
.bind("today", today)
- .fetch()
- .size();
+ .fetch().size();
// Define the command to run the Python script with the correct path (V3)
- String[] args = {"python", "C:\\Users\\administrator\\Desktop\\Scrape\\main2.py", String.valueOf(lenCheckInOutList)};
+ String[] args = {"python", pythonScriptDir + "\\Scrape\\main2.py", String.valueOf(lenCheckInOutList)};
// Execute the command
Process p = Runtime.getRuntime().exec(args);
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchHrTicketsJob.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchHrTicketsJob.java
index 023bd3c..0ebe68a 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchHrTicketsJob.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/job/FetchHrTicketsJob.java
@@ -155,6 +155,30 @@ public class FetchHrTicketsJob implements Job {
}
});
+ executorService.submit(
+ () -> {
+ try {
+ log.info("Fetching authorization AP...");
+ String jsonResponse = Beans.get(AuthorizationController.class).fetchAP(token);
+ log.info("Fetched authorization AP successfully.");
+ if (jsonResponse != null) {
+ try {
+ JSONArray jsonArray = new JSONArray(jsonResponse);
+ for (int i = 0; i < jsonArray.length(); i++) {
+ JSONObject jsonObject = jsonArray.getJSONObject(i);
+ Beans.get(AuthorizationService.class).saveAP(jsonObject);
+ }
+ } catch (JSONException e) {
+ log.error("Failed to parse JSON: " + jsonResponse, e);
+ }
+ } else {
+ log.warn("No response received from fetchAP.");
+ }
+ } catch (Exception e) {
+ log.error("Failed to fetch Salary authorization: ", e);
+ }
+ });
+
// Leave requests fetch task
executorService.submit(
() -> {
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/module/HumanResourceModule.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/module/HumanResourceModule.java
index ec9da5e..db12c44 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/module/HumanResourceModule.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/module/HumanResourceModule.java
@@ -59,6 +59,8 @@ import com.axelor.apps.hr.service.extra.hours.ExtraHoursService;
import com.axelor.apps.hr.service.extra.hours.ExtraHoursServiceImpl;
import com.axelor.apps.hr.service.leave.LeaveService;
import com.axelor.apps.hr.service.leave.LeaveServiceImpl;
+import com.axelor.apps.hr.service.DailyReportService;
+import com.axelor.apps.hr.service.DailyReportServiceImpl;
import com.axelor.apps.hr.service.lunch.voucher.LunchVoucherAdvanceService;
import com.axelor.apps.hr.service.lunch.voucher.LunchVoucherAdvanceServiceImpl;
import com.axelor.apps.hr.service.lunch.voucher.LunchVoucherMgtLineService;
@@ -117,5 +119,6 @@ public class HumanResourceModule extends AxelorModule {
bind(PartnerAccountRepository.class).to(PartnerHRRepository.class);
bind(BankOrderMergeServiceImpl.class).to(BankOrderMergeHRServiceImpl.class);
bind(TimesheetReportService.class).to(TimesheetReportServiceImpl.class);
+ bind(DailyReportService.class).to(DailyReportServiceImpl.class);
}
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceService.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceService.java
index dfc6056..c3bb5a1 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceService.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceService.java
@@ -13,12 +13,13 @@ public interface AbsenceService {
void attachTheAbsenceWithDailyReport(Absence absence, List dailyreports);
@Transactional
- void deAttachTheAbsenceWithDailyReport(Absence absence, List dailyreports);
+ void deAttachTheAbsenceWithDailyReport(Absence absence, List dailyreports, Boolean archive);
@Transactional
- void chooseAbsenceType(Absence absence, String selectedType);
+ void chooseAbsenceType(Absence absence, Integer selectedType);
@Transactional
BigDecimal calculateTotalAbsenceHours(LocalDateTime absenceStartDate, LocalDateTime absenceEndDate);
+ BigDecimal calculateTotalAbsenceMinutes(LocalDateTime absenceStartDate, LocalDateTime absenceEndDate);
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceServiceImpl.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceServiceImpl.java
index 442125d..1f4f542 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceServiceImpl.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AbsenceServiceImpl.java
@@ -18,6 +18,8 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
+import java.time.Duration;
+import java.math.RoundingMode;
public class AbsenceServiceImpl implements AbsenceService {
@@ -41,27 +43,29 @@ public class AbsenceServiceImpl implements AbsenceService {
Absence absence, List dailyreports) {
// Iterate over each DailyReport in the list
for (DailyReport dailyreport : dailyreports) {
- dailyreport.setAbsence(absence); // Set the absence for each report
+ dailyreport.addAbsenceSetItem(absence); // Set the absence for each report
dailyReportRepository.save(dailyreport);
}
}
@Transactional
- public void deAttachTheAbsenceWithDailyReport(Absence absence, List dailyreports) {
+ public void deAttachTheAbsenceWithDailyReport(Absence absence, List dailyreports, Boolean archive) {
if(dailyreports != null){
// Iterate over each DailyReport in the list
for (DailyReport dailyreport : dailyreports) {
- dailyreport.setAbsence(null); // Set the absence for each report
+ dailyreport.removeAbsenceSetItem(null); // Set the absence for each report
dailyReportRepository.save(dailyreport);
}
}
-
- absence.setArchived(true);
- absenceRepository.save(absence);
+
+ if (archive) {
+ absence.setArchived(true);
+ absenceRepository.save(absence);
+ }
}
@Transactional
- public void chooseAbsenceType(Absence absence, String selectedType) {
+ public void chooseAbsenceType(Absence absence, Integer selectedType) {
// Set the selected absence type to the absence entity
// Assuming you have a field named 'typeAbsence' in the Absence entity
absence.setAbsenceType(selectedType);
@@ -101,6 +105,17 @@ public class AbsenceServiceImpl implements AbsenceService {
return totalAbsenceHours;
}
+ public BigDecimal calculateTotalAbsenceMinutes(LocalDateTime absenceStartDate, LocalDateTime absenceEndDate) {
+ // Calculate the duration between the two LocalDateTime objects
+ Duration duration = Duration.between(absenceStartDate, absenceEndDate);
+
+ // Convert the duration to minutes and then divide by 60 to get hours
+ long minutes = duration.toMinutes();
+ BigDecimal hours = BigDecimal.valueOf(minutes).divide(BigDecimal.valueOf(60), 2, BigDecimal.ROUND_HALF_UP);
+
+ return customRound(hours);
+ }
+
private boolean isSpecialOvertimeDay(LocalDate date) {
for (EventsPlanningLine line : eventsPlanningLines) {
if (line.getDate().equals(date)) {
@@ -109,4 +124,28 @@ public class AbsenceServiceImpl implements AbsenceService {
}
return false;
}
+
+ public static BigDecimal customRound(BigDecimal value) {
+ // Get the fractional part of the number
+ BigDecimal fractionalPart = value.remainder(BigDecimal.ONE);
+
+ // Define the intervals and their corresponding rounded values
+ if (fractionalPart.compareTo(new BigDecimal("0.125")) < 0) {
+ return value.setScale(0, RoundingMode.DOWN);
+ } else if (fractionalPart.compareTo(new BigDecimal("0.125")) >= 0
+ && fractionalPart.compareTo(new BigDecimal("0.375")) < 0) {
+ return value.setScale(0, RoundingMode.DOWN).add(new BigDecimal("0.25"));
+ } else if (fractionalPart.compareTo(new BigDecimal("0.375")) >= 0
+ && fractionalPart.compareTo(new BigDecimal("0.625")) < 0) {
+ return value.setScale(0, RoundingMode.DOWN).add(new BigDecimal("0.50"));
+ } else if (fractionalPart.compareTo(new BigDecimal("0.625")) >= 0
+ && fractionalPart.compareTo(new BigDecimal("0.875")) < 0) {
+ return value.setScale(0, RoundingMode.DOWN).add(new BigDecimal("0.75"));
+ } else if (fractionalPart.compareTo(new BigDecimal("0.875")) >= 0) {
+ return value.setScale(0, RoundingMode.UP);
+ } else {
+ return value; // In case no rounding is needed
+ }
+ }
+
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationService.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationService.java
index 2c58355..836f50d 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationService.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationService.java
@@ -14,4 +14,7 @@ public interface AuthorizationService {
@Transactional(rollbackOn = {Exception.class})
public void saveBS(JSONObject jsonObject) throws AxelorException;
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void saveAP(JSONObject jsonObject) throws AxelorException;
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationServiceImpl.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationServiceImpl.java
index 8aa7dd0..3acdc42 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationServiceImpl.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/AuthorizationServiceImpl.java
@@ -281,7 +281,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
.fetchOne();
if (dailyReport != null) {
- dailyReport.setIsAuthorizedAbsence(true);
+ dailyReport.setIsAuthorizedLateArrival(true);
}
} else if (previousStatus == 2 && newStatus == 4) {
System.out.println("Tickets :" + idInt + " Status changed from " + previousStatus + " to " + newStatus);
@@ -321,7 +321,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
if (dailyReport != null) {
authorization.setDailyReport(dailyReport);
if(validation_status == 3)
- dailyReport.setIsAuthorizedAbsence(true);
+ dailyReport.setIsAuthorizedLateArrival(true);
}
// Save the new Authorization
authorizationRepository.save(authorization);
@@ -338,6 +338,156 @@ public class AuthorizationServiceImpl implements AuthorizationService {
@Transactional(rollbackOn = {Exception.class})
public void saveBS(JSONObject jsonObject) throws AxelorException {
+ try {
+ // Extract fields
+ int idInt = jsonObject.getInt("id");
+ String id = Integer.toString(idInt);
+ String ticketLink = "https://dsi.sophal.dz/front/ticket.form.php?id=" + id;
+ String matricule = jsonObject.getString("matricule");
+ String date_absence = jsonObject.getString("date_sortie");
+ String commentaire = jsonObject.getString("motif");
+ String heure_sortie = jsonObject.getString("heure_sortie");
+ int validation_status = jsonObject.optInt("validation_status",2);
+ String validateByUser = jsonObject.optString("validate_by_user",null);
+ String dateValidation = jsonObject.optString("validation_date",null);
+
+ // GET EMPLOYEES
+ Employee employee = employeeRepo
+ .all()
+ .filter("self.registrationNumber = :matricule")
+ .bind("matricule", matricule)
+ .fetchOne();
+
+ if (employee == null) {
+ System.err.println("Employee with matricule " + matricule + " not found.");
+ return;
+ }
+
+ Employee validatedByEmployee = null;
+
+ if(validateByUser != null){
+ validatedByEmployee = employeeRepo
+ .all()
+ .filter("self.registrationNumber = :matricule")
+ .bind("matricule", validateByUser)
+ .fetchOne();
+
+ if (validatedByEmployee == null) {
+ System.err.println("Validator employee with matricule " + validateByUser + " not found.");
+ return;
+ }
+ }
+
+ // Parse validation date (handle null case)
+ LocalDate validationDate = null;
+ if (dateValidation != null && !dateValidation.isEmpty()) {
+ try {
+ OffsetDateTime offsetDateTime = OffsetDateTime.parse(dateValidation, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+ validationDate = offsetDateTime.toLocalDate(); // Extract only the date part
+ } catch (DateTimeParseException e) {
+ System.out.println("Error parsing dateValidation: " + dateValidation);
+ validationDate = null;
+ }
+ }
+
+ // Parse Requisition Date
+ LocalDate absenceDate;
+ try {
+ absenceDate = LocalDate.parse(date_absence);
+ } catch (DateTimeParseException e) {
+ System.out.println("Error parsing date_absence: " + date_absence);
+ absenceDate = null;
+ }
+
+ // Check if Authorization exists by ticketId
+ Authorization authorization = authorizationRepository
+ .all()
+ .filter("self.ticketId = :ticketId")
+ .bind("ticketId", idInt)
+ .fetchOne();
+
+ if (authorization != null) {
+ // Authorization exists, compare previous and new status
+ int previousStatus = authorization.getStatusSelect(); // Previous status
+ int newStatus = validation_status; // New status
+
+ if (previousStatus == 2 && newStatus == 3) {
+ System.out.println("Tickets :" + idInt + " Status changed from " + previousStatus + " to " + newStatus);
+ // Update the fields of the existing Authorization
+ authorization.setValidatedByEmployee(validatedByEmployee);
+ authorization.setValidationDate(validationDate);
+ authorization.setStatusSelect(newStatus);
+ // Save the updated Authorization
+ authorizationRepository.save(authorization);
+
+ // Get Daily report
+ DailyReport dailyReport =
+ dailyReportRepo
+ .all()
+ .filter("self.employee = :employee and self.reportDate = :reportDate")
+ .bind("employee", employee)
+ .bind("reportDate", absenceDate)
+ .fetchOne();
+
+ if (dailyReport != null) {
+ dailyReport.setIsAuthorizedEarlyDeparture(true);
+ }
+
+ } else if (previousStatus == 2 && newStatus == 4) {
+ System.out.println("Tickets :" + idInt + " Status changed from " + previousStatus + " to " + newStatus);
+ authorization.setRefusedByEmployee(validatedByEmployee);
+ authorization.setRefusalDate(validationDate);
+ authorization.setStatusSelect(newStatus);
+ // Save the updated Authorization
+ authorizationRepository.save(authorization);
+ }
+ } else {
+ String updatedDescription = commentaire + " - " + heure_sortie;
+ // Create an instance of Authorization
+ authorization = new Authorization();
+ authorization.setEmployee(employee);
+ authorization.setTicketId(idInt);
+ authorization.setTicket(ticketLink);
+ authorization.setRequisitionDate(absenceDate);
+ authorization.setDescription(updatedDescription);
+ authorization.setStatusSelect(validation_status);
+ authorization.setAuthorizationType(0);
+
+ if (validation_status == 3) {
+ authorization.setValidatedByEmployee(validatedByEmployee);
+ authorization.setValidationDate(validationDate);
+ } else if (validation_status == 4) {
+ authorization.setRefusedByEmployee(validatedByEmployee);
+ authorization.setRefusalDate(validationDate);
+ }
+
+ // Get Daily report
+ DailyReport dailyReport = dailyReportRepo
+ .all()
+ .filter("self.employee = :employee and self.reportDate = :reportDate")
+ .bind("employee", employee)
+ .bind("reportDate", absenceDate)
+ .fetchOne();
+
+ if (dailyReport != null) {
+ authorization.setDailyReport(dailyReport);
+ if(validation_status == 3)
+ dailyReport.setIsAuthorizedEarlyDeparture(true);
+ }
+ // Save the new Authorization
+ authorizationRepository.save(authorization);
+ }
+ } catch (JSONException e) {
+ System.err.println("Failed to parse JSON: " + jsonObject.toString());
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void saveAP(JSONObject jsonObject) throws AxelorException {
+
try {
// Extract fields
int idInt = jsonObject.getInt("id");
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportService.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportService.java
index db65660..2c879ca 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportService.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportService.java
@@ -2,6 +2,9 @@ package com.axelor.apps.hr.service;
import com.axelor.apps.hr.db.DailyReport;
import com.google.inject.persist.Transactional;
+import com.axelor.exception.AxelorException;
+import java.math.BigDecimal;
+import java.util.List;
public interface DailyReportService {
@@ -10,4 +13,10 @@ public interface DailyReportService {
@Transactional
void determineShift(DailyReport DailyReport);
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void deducePrimes(DailyReport DailyReport, Integer primeSelection, BigDecimal valueToDeduce) throws AxelorException ;
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void massDeducePrimes(List DailyReportList, Integer primeSelection, BigDecimal valueToDeduce) throws AxelorException;
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportServiceImpl.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportServiceImpl.java
index 30a4599..a5f7725 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportServiceImpl.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/DailyReportServiceImpl.java
@@ -15,8 +15,10 @@ import com.axelor.apps.hr.db.repo.AuthorizationRepository;
import com.axelor.apps.hr.db.repo.OffDayWorkRepository;
import com.axelor.apps.hr.db.repo.DailyReportRepository;
import com.axelor.apps.hr.db.repo.ShiftRepository;
+import com.axelor.apps.hr.service.AbsenceServiceImpl;
import com.axelor.inject.Beans;
import com.google.inject.persist.Transactional;
+import com.axelor.exception.AxelorException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
@@ -26,6 +28,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Year;
import java.util.List;
+import java.util.ArrayList;
import com.google.inject.Inject;
public class DailyReportServiceImpl implements DailyReportService {
@@ -85,14 +88,14 @@ public class DailyReportServiceImpl implements DailyReportService {
LocalDate reportDate = dailyReport.getReportDate();
Integer shift = dailyReport.getShift().getShift();
- LocalTime shiftStartHour = null, shiftEndHour = null;
+ LocalDateTime firstEnter, lastQuit;
+
+ LocalTime shiftStartHour = null, shiftEndHour = null, shiftStartPauseHour = null, shiftEndPauseHour = null;
if(shift != null){
- System.out.println("rapporurnalier: ????????????????"+ dailyReport.getId());
shiftStartHour = dailyReport.getShift().getStartHour();
shiftEndHour = dailyReport.getShift().getEndHour();
- System.out.println("Shift: "+ shift);
- System.out.println("shiftStartHour: "+ shiftStartHour);
- System.out.println("shiftENDHour: "+ shiftEndHour);
+ shiftStartPauseHour = dailyReport.getShift().getStartPause();
+ shiftEndPauseHour = dailyReport.getShift().getEndPause();
}
if (enters[0] != null && quits[0] != null) {
@@ -100,9 +103,9 @@ public class DailyReportServiceImpl implements DailyReportService {
Duration totalDuration = Duration.ZERO;
Duration totalSupDuration = Duration.ZERO;
Duration nightDuration = Duration.ZERO;
- Duration pauseDuration = Duration.ZERO;
- LocalDateTime firstEnter = enters[0];
- LocalDateTime lastQuit = quits[0];
+ Duration breakDuration = Duration.ZERO;
+ firstEnter = enters[0];
+ lastQuit = quits[0];
for (int i = 0; i < enters.length; i++) {
if (enters[i] != null && quits[i] != null) {
@@ -114,6 +117,7 @@ public class DailyReportServiceImpl implements DailyReportService {
dailyReport.setLastQuit(lastQuit);
LocalTime firstEnterTime = firstEnter.toLocalTime();
LocalTime lastQuitTime = lastQuit.toLocalTime();
+
// Calculate late arrival if firstEnter is later than shift start
if(shiftStartHour != null){
if (firstEnterTime.isAfter(shiftStartHour)) {
@@ -136,19 +140,24 @@ public class DailyReportServiceImpl implements DailyReportService {
totalDuration = totalDuration.plus(Duration.between(firstEnter, lastQuit));
long totalMinutes = totalDuration.toMinutes();
BigDecimal totalHours = BigDecimal.valueOf(totalMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
- dailyReport.setWorkHours(customRound(totalHours));
+ dailyReport.setWorkHours(totalHours);
// Calculate night hours
nightDuration = calculateNightDuration(firstEnter, lastQuit);
long totalNightMinutes = nightDuration.toMinutes();
BigDecimal totalNightHours = BigDecimal.valueOf(totalNightMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
- dailyReport.setNightHours(customRound(totalNightHours));
+ dailyReport.setNightHours(totalNightHours);
- // Pause Hours
- pauseDuration = calculatePauseDuration(enters, quits, employee);
- long pauseMinutes = pauseDuration.toMinutes();
- BigDecimal pauseHours = BigDecimal.valueOf(pauseMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
- dailyReport.setBreakHours(customRound(pauseHours));
+ // Break Hours
+ breakDuration = calculateBreakDuration(enters, quits);
+ long breakMinutes = breakDuration.toMinutes();
+ BigDecimal breakHours = BigDecimal.valueOf(breakMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
+ dailyReport.setBreakHours(breakHours);
+
+ if(shiftStartPauseHour != null && shiftEndPauseHour != null){
+ boolean allInAllowedRange = areBreaksInAllowedRange(enters, quits, shiftStartPauseHour, shiftEndPauseHour);
+ dailyReport.setBreakNotInTheAllowedRange(allInAllowedRange);
+ }
// shift 2
if (shift == 2) {
@@ -202,8 +211,8 @@ public class DailyReportServiceImpl implements DailyReportService {
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
}
- dailyReport.setExtraHours100(customRound(extraHours100));
- dailyReport.setExtraHours50(customRound(extraHours50));
+ dailyReport.setExtraHours100(extraHours100);
+ dailyReport.setExtraHours50(extraHours50);
// other shifts
} else {
@@ -216,11 +225,11 @@ public class DailyReportServiceImpl implements DailyReportService {
if (firstEnter.getDayOfWeek() == DayOfWeek.SATURDAY) {
if(shift == 0 || shift == 3){
- dailyReport.setExtraHours50(customRound(totalHours).subtract(customRound(totalNightHours)));
- dailyReport.setExtraHours100(customRound(totalNightHours));
+ dailyReport.setExtraHours50(totalHours.subtract(totalNightHours));
+ dailyReport.setExtraHours100(totalNightHours);
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
} else {
- dailyReport.setExtraHours50(customRound(totalHours));
+ dailyReport.setExtraHours50(totalHours);
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
}
@@ -229,18 +238,18 @@ public class DailyReportServiceImpl implements DailyReportService {
// Add recup
if (totalHours.compareTo(BigDecimal.valueOf(6)) >= 0)
createOffDayWork(reportDate, employee);
- dailyReport.setExtraHours100(customRound(totalHours));
+ dailyReport.setExtraHours100(totalHours);
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
} else {
if(shift == 0 || shift == 3){
- dailyReport.setExtraHours50(customRound(totalSupHours).subtract(customRound(totalNightHours)));
- dailyReport.setExtraHours100(customRound(totalNightHours));
+ dailyReport.setExtraHours50(totalSupHours.subtract(totalNightHours));
+ dailyReport.setExtraHours100(totalNightHours);
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
dailyReport.setAllowanceRecall(totalSupHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
} else {
- dailyReport.setExtraHours50(customRound(totalSupHours));
+ dailyReport.setExtraHours50(totalSupHours);
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
dailyReport.setAllowanceRecall(totalSupHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
}
@@ -248,23 +257,25 @@ public class DailyReportServiceImpl implements DailyReportService {
}
// Calculate ITP
- dailyReport.setItp(customRound(calculateItp(totalHours, shift,dailyReport.getHasItp())));
+ dailyReport.setItp(calculateItp(totalHours, shift,dailyReport.getHasItp()));
dailyReport.setIsCalculated(true);
} else if (enters[0] != null && quits[0] == null) {
// When the employee registers attendance only once
- dailyReport.setWorkHours(BigDecimal.valueOf(8));
- dailyReport.setAbsenceHours(BigDecimal.valueOf(0));
- dailyReport.setIsCalculated(true);
+ if(shift!=2){
+ dailyReport.setWorkHours(BigDecimal.valueOf(8));
+ dailyReport.setAbsenceHours(BigDecimal.valueOf(0));
+ dailyReport.setIsCalculated(true);
+ }
} else if (enters.length != quits.length) {
Duration totalDuration = Duration.ZERO;
- LocalDateTime firstEnter = enters[0];
- LocalDateTime lastQuit = quits[quits.length - 1];
+ firstEnter = enters[0];
+ lastQuit = quits[quits.length - 1];
totalDuration = totalDuration.plus(Duration.between(firstEnter, lastQuit));
long totalMinutes = totalDuration.toMinutes();
BigDecimal totalHours = BigDecimal.valueOf(totalMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
- dailyReport.setWorkHours(customRound(totalHours));
+ dailyReport.setWorkHours(totalHours);
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
dailyReport.setLastQuit(lastQuit);
@@ -288,6 +299,18 @@ public class DailyReportServiceImpl implements DailyReportService {
System.err.println("Warning: Employee doesn't exist.");
dailyReport.setIsCalculated(true);
} else {
+ dailyReport.setWorkHours(BigDecimal.valueOf(0));
+ dailyReport.setNightHours(BigDecimal.valueOf(0));
+ dailyReport.setBreakHours(BigDecimal.valueOf(0));
+ dailyReport.setExtraHours50(BigDecimal.valueOf(0));
+ dailyReport.setExtraHours100(BigDecimal.valueOf(0));
+ dailyReport.setItp(BigDecimal.valueOf(0));
+ dailyReport.setLateArrival(BigDecimal.valueOf(0));
+ dailyReport.setEarlyDeparture(BigDecimal.valueOf(0));
+ dailyReport.setAllowance(0);
+ dailyReport.setAllowanceRecall(0);
+ dailyReport.setBreakNotInTheAllowedRange(false);
+ dailyReport.setShift(Beans.get(ShiftRepository.class).find(50L));
System.err.println("Warning: no attendances for this day.");
dailyReport.setIsCalculated(true);
}
@@ -296,7 +319,7 @@ public class DailyReportServiceImpl implements DailyReportService {
if (dailyReport.getAbsence() == null) {
Absence absence = Beans.get(AbsenceRepository.class)
.all()
- .filter("self.employee = :employee and self.startDate <= :reportDate and self.endDate >= :reportDate")
+ .filter("self.employee = :employee and self.startDate <= :reportDate and self.endDate >= :reportDate and (archived = false or archived is null)")
.bind("employee", employee)
.bind("reportDate",reportDate) // Changed from absenceStartDate and absenceEndDate to reportDate
.fetchOne();
@@ -307,17 +330,34 @@ public class DailyReportServiceImpl implements DailyReportService {
}
// Authorization
- if(dailyReport.getAuthorizationList() == null){
- Authorization authorization = Beans.get(AuthorizationRepository.class)
- .all()
- .filter("self.employee = :employee and self.requisitionDate = :reportDate")
- .bind("employee",employee)
- .bind("reportDate",reportDate)
- .fetchOne();
- if (authorization != null) {
- authorization.setDailyReport(dailyReport);
- if(authorization.getStatusSelect() == 3)
- dailyReport.setIsAuthorizedAbsence(true);
+ if (dailyReport.getAuthorizationList() == null) {
+ List authorizations = Beans.get(AuthorizationRepository.class)
+ .all()
+ .filter("self.employee = :employee and self.requisitionDate = :reportDate")
+ .bind("employee", employee)
+ .bind("reportDate", reportDate)
+ .fetch();
+
+ if (authorizations != null) {
+ List authorizationList = new ArrayList<>(); // Create a new list for authorizations
+
+ for (Authorization authorization : authorizations) {
+ authorization.setDailyReport(dailyReport);
+ authorizationList.add(authorization); // Add each authorization to the list
+
+ // Check authorization type and set corresponding flags in dailyReport
+ if (authorization.getAuthorizationType() == 0 && authorization.getStatusSelect() == 3) {
+ dailyReport.setIsAuthorizedEarlyDeparture(true);
+ }
+ if (authorization.getAuthorizationType() == 1 && authorization.getStatusSelect() == 3) {
+ dailyReport.setIsAuthorizedLateArrival(true);
+ }
+ if (authorization.getAuthorizationType() == 2 && authorization.getStatusSelect() == 3) {
+ dailyReport.setIsAuthorizedAbsence(true);
+ }
+ }
+ // Set the authorization list to dailyReport
+ dailyReport.setAuthorizationList(authorizationList);
}
}
@@ -333,7 +373,56 @@ public class DailyReportServiceImpl implements DailyReportService {
// Absence Hours
if (!(dailyReport.getIsWeekend() || dailyReport.getIsFerieDay()) && dailyReport.getWorkHours().compareTo(BigDecimal.valueOf(8)) < 0) {
- dailyReport.setAbsenceHours(customRound(BigDecimal.valueOf(8).subtract(dailyReport.getWorkHours())));
+ dailyReport.setAbsenceHours(BigDecimal.valueOf(8).subtract(dailyReport.getWorkHours()));
+ // Create Absence AI
+ if(dailyReport.getAbsenceSet().isEmpty()){
+ Boolean isAuthorizedAbsence = dailyReport.getIsAuthorizedAbsence();
+ Boolean isAuthorizedLateArrival = dailyReport.getIsAuthorizedLateArrival();
+ Boolean isAuthorizedEarlyDeparture = dailyReport.getIsAuthorizedEarlyDeparture();
+ // AI all day
+ if(dailyReport.getAbsenceHours().compareTo(new BigDecimal("8")) == 0){
+ if(!isAuthorizedAbsence){
+ Absence absence = new Absence();
+ absence.setEmployee(employee);
+ absence.setAbsenceType(19); // Absence irrégulière
+ absence.setStartDate(reportDate.atStartOfDay());
+ absence.setEndDate(reportDate.atStartOfDay());
+ BigDecimal totalAbsenceHours = Beans.get(AbsenceServiceImpl.class).calculateTotalAbsenceHours(reportDate.atStartOfDay(),reportDate.atStartOfDay());
+ absence.setTotalAbsenceHours(totalAbsenceHours);
+ absenceRepository.save(absence);
+ dailyReport.addAbsenceSetItem(absence);
+ }
+ }else{
+ if(dailyReport.getShift().getMaxTimeLateArrival() != null){ // to check that is different to shift N/A
+ LocalTime firstEnterTime = dailyReport.getEnter1().toLocalTime();
+ if(firstEnterTime.isAfter(dailyReport.getShift().getMaxTimeLateArrival()) && !isAuthorizedLateArrival){
+ Absence absence = new Absence();
+ absence.setEmployee(employee);
+ absence.setAbsenceType(20); // Retard irrégulier
+ absence.setStartDate(reportDate.atTime(shiftStartHour));
+ absence.setEndDate(dailyReport.getEnter1());
+ BigDecimal totalAbsenceHours = Beans.get(AbsenceServiceImpl.class).calculateTotalAbsenceMinutes(reportDate.atTime(shiftStartHour),dailyReport.getEnter1());
+ absence.setTotalAbsenceHours(totalAbsenceHours);
+ absenceRepository.save(absence);
+ dailyReport.addAbsenceSetItem(absence);
+ }
+ if(dailyReport.getLastQuit() != null){
+ LocalTime lastQuitTime = dailyReport.getLastQuit().toLocalTime();
+ if(lastQuitTime.isBefore(dailyReport.getShift().getMaxTimeEarlyDeparture()) && !isAuthorizedEarlyDeparture){
+ Absence absence = new Absence();
+ absence.setEmployee(employee);
+ absence.setAbsenceType(21); // Départ irrégulier
+ absence.setStartDate(dailyReport.getLastQuit());
+ absence.setEndDate(reportDate.atTime(shiftEndHour));
+ BigDecimal totalAbsenceHours = Beans.get(AbsenceServiceImpl.class).calculateTotalAbsenceMinutes(dailyReport.getLastQuit(),reportDate.atTime(shiftEndHour));
+ absence.setTotalAbsenceHours(totalAbsenceHours);
+ absenceRepository.save(absence);
+ dailyReport.addAbsenceSetItem(absence);
+ }
+ }
+ }
+ }
+ }
} else {
dailyReport.setAbsenceHours(BigDecimal.ZERO);
}
@@ -449,24 +538,40 @@ public class DailyReportServiceImpl implements DailyReportService {
return supDuration;
}
- private Duration calculatePauseDuration(
- LocalDateTime[] enters, LocalDateTime[] quits, Employee employee) {
+ private Duration calculateBreakDuration(LocalDateTime[] enters, LocalDateTime[] quits) {
- Duration pauseDuration = Duration.ZERO;
+ Duration breakDuration = Duration.ZERO;
for (int i = 1; i < quits.length; i++) {
if (enters[i] != null && quits[i - 1] != null) {
- pauseDuration = pauseDuration.plus(Duration.between(quits[i - 1], enters[i]));
+ breakDuration = breakDuration.plus(Duration.between(quits[i - 1], enters[i]));
}
}
- return pauseDuration;
+ return breakDuration;
+ }
+
+ private boolean areBreaksInAllowedRange(LocalDateTime[] enters, LocalDateTime[] quits, LocalTime allowedStartTime, LocalTime allowedEndTime) {
+
+ for (int i = 1; i < quits.length; i++) {
+ if (enters[i] != null && quits[i - 1] != null) {
+ LocalTime breakStartTime = quits[i - 1].toLocalTime();
+ LocalTime breakEndTime = enters[i].toLocalTime();
+
+ // Check if the break falls outside the allowed range
+ if (breakStartTime.isBefore(allowedStartTime) || breakEndTime.isAfter(allowedEndTime)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
private BigDecimal calculateItp(BigDecimal totalHours, Integer shift, Boolean hasItp) {
// Shift 0 (no itp)
- if (hasItp == false)
- return BigDecimal.ZERO;
- else
+ if (hasItp == true && shift != 0)
return totalHours.min(BigDecimal.valueOf(8));
+ else
+ return BigDecimal.ZERO;
}
private void createOffDayWork(LocalDate reportDate, Employee employee) {
@@ -544,5 +649,37 @@ public class DailyReportServiceImpl implements DailyReportService {
return value; // In case no rounding is needed
}
}
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void deducePrimes(DailyReport dailyReport, Integer primeSelection, BigDecimal valueToDeduce) throws AxelorException {
+ switch (primeSelection) {
+ case 1: // ITP
+ dailyReport.setDeduceItp(true);
+ dailyReport.setItpToDeduce(valueToDeduce);
+ break;
+ case 2: // Nuissance
+ dailyReport.setDeduceNuissance(true);
+ dailyReport.setItpToDeduce(valueToDeduce);
+ break;
+ case 3: // HS 50
+ dailyReport.setDeduceSupHours50(true);
+ dailyReport.setSupHours50ToDeduce(valueToDeduce);
+ break;
+ case 4: // HS 100
+ dailyReport.setDeduceSupHours100(true);
+ dailyReport.setSupHours100ToDeduce(valueToDeduce);
+ break;
+ default:
+ return; // Invalid configSelect, stop processing
+ }
+ Beans.get(DailyReportRepository.class).save(dailyReport);
+ }
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void massDeducePrimes(List dailyReportList, Integer primeSelection, BigDecimal valueToDeduce) throws AxelorException {
+ for (DailyReport dailyReport : dailyReportList) {
+ this.deducePrimes(dailyReport, primeSelection, valueToDeduce);
+ }
+ }
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportService.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportService.java
index b347b09..4781da2 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportService.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportService.java
@@ -4,6 +4,7 @@ import com.axelor.apps.base.db.Period;
import com.axelor.apps.hr.db.Absence;
import com.axelor.apps.hr.db.Employee;
import com.axelor.apps.hr.db.DailyReport;
+import com.axelor.apps.hr.db.MonthlyReport;
import com.google.inject.persist.Transactional;
import java.time.LocalDate;
import java.util.List;
@@ -11,13 +12,9 @@ import java.util.List;
public interface MonthlyReportService {
@Transactional
- void createMensuelReport(
- Employee employee,
- Period period,
- LocalDate startDate,
- LocalDate endDate,
- List employeeDailyReports,
- List employeeAbsences);
+ void createMensuelReport(Employee employee, Period period, LocalDate startDate, LocalDate endDate, List employeeDailyReports, List employeeAbsences);
+
+ void updateMensuelReport(MonthlyReport monthlyReport, Employee employee, Period period, LocalDate startDate, LocalDate endDate, List employeeDailyReports, List employeeAbsences);
/*void calculePrimeAssiduite(Mensuels mensuels);*/
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportServiceImpl.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportServiceImpl.java
index 8b2fdcc..a3ea988 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportServiceImpl.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/MonthlyReportServiceImpl.java
@@ -16,6 +16,7 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
+import java.util.Set;
import javax.inject.Inject;
import com.axelor.inject.Beans;
@@ -41,6 +42,7 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
@Transactional
@Override
+
public void createMensuelReport(Employee employee, Period period, LocalDate startDate, LocalDate endDate, List employeeDailyReports, List employeeAbsences) {
Boolean hasNuissance = employee.getHasNuissance();
@@ -97,19 +99,31 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
monthlyNightHours = monthlyNightHours.add(dailyReport.getNightHours());
totalWorkHours = totalWorkHours.add(dailyReport.getWorkHours());
- BigDecimal heureSup50 = dailyReport.getExtraHours50();
- BigDecimal heureSup100 = dailyReport.getExtraHours100();
- BigDecimal itp = dailyReport.getItp();
- BigDecimal nuissance = dailyReport.getNuissance();
+ BigDecimal heureSup50 = dailyReport.getExtraHours50() != null ? dailyReport.getExtraHours50() : BigDecimal.ZERO;
+ BigDecimal heureSup100 = dailyReport.getExtraHours100() != null ? dailyReport.getExtraHours100() : BigDecimal.ZERO;
+ BigDecimal itp = dailyReport.getItp() != null ? dailyReport.getItp() : BigDecimal.ZERO;
+ BigDecimal nuissance = dailyReport.getNuissance() != null ? dailyReport.getNuissance() : BigDecimal.ZERO;
- if(dailyReport.getDeduceSupHours50())
- heureSup50 = heureSup50.subtract(dailyReport.getSupHours50ToDeduce());
- if(dailyReport.getDeduceSupHours100())
- heureSup100 = heureSup100.subtract(dailyReport.getSupHours100ToDeduce());
- if(dailyReport.getDeduceItp())
- itp = itp.subtract(dailyReport.getItpToDeduce());
- if(dailyReport.getDeduceNuissance())
- nuissance = nuissance.subtract(dailyReport.getNuissanceToDeduce());
+ BigDecimal supHours50ToDeduce = dailyReport.getSupHours50ToDeduce() != null ? dailyReport.getSupHours50ToDeduce() : BigDecimal.ZERO;
+ BigDecimal supHours100ToDeduce = dailyReport.getSupHours100ToDeduce() != null ? dailyReport.getSupHours100ToDeduce() : BigDecimal.ZERO;
+ BigDecimal itpToDeduce = dailyReport.getItpToDeduce() != null ? dailyReport.getItpToDeduce() : BigDecimal.ZERO;
+ BigDecimal nuissanceToDeduce = dailyReport.getNuissanceToDeduce() != null ? dailyReport.getNuissanceToDeduce() : BigDecimal.ZERO;
+
+ if (dailyReport.getDeduceSupHours50() && heureSup50.compareTo(supHours50ToDeduce) > 0) {
+ heureSup50 = heureSup50.subtract(supHours50ToDeduce);
+ }
+
+ if (dailyReport.getDeduceSupHours100() && heureSup100.compareTo(supHours100ToDeduce) > 0) {
+ heureSup100 = heureSup100.subtract(supHours100ToDeduce);
+ }
+
+ if (dailyReport.getDeduceItp() && itp.compareTo(itpToDeduce) > 0) {
+ itp = itp.subtract(itpToDeduce);
+ }
+
+ if (dailyReport.getDeduceNuissance() && nuissance.compareTo(nuissanceToDeduce) > 0) {
+ nuissance = nuissance.subtract(nuissanceToDeduce);
+ }
monthlyITP = monthlyITP.add(itp);
totalNuissance = totalNuissance.add(nuissance);
@@ -158,83 +172,111 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
}
Boolean isAuthorizedAbsence = dailyReport.getIsAuthorizedAbsence();
+ Boolean isAuthorizedLateArrival = dailyReport.getIsAuthorizedLateArrival();
+ Boolean isAuthorizedEarlyDeparture = dailyReport.getIsAuthorizedEarlyDeparture();
LeaveRequest leaveRequest = dailyReport.getLeaveRequest();
- Absence absence = dailyReport.getAbsence();
+ Set absences = dailyReport.getAbsenceSet();
- if (isAuthorizedAbsence == false && leaveRequest == null && absence == null) {
- irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getAbsenceHours());
- } else if(isAuthorizedAbsence){
- justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getAbsenceHours());
- } else if(leaveRequest != null){
- recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(dailyReport.getAbsenceHours());
- } else if(absence != null){
- totalAbsence = dailyReport.getAbsenceHours();
- switch (absence.getAbsenceType()) {
- case "Absence autorisé de payée":
- breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
- break;
- case "Absence allaitement":
- breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
- break;
- case "Absence congé récupération":
- recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(totalAbsence);
- break;
- case "Absence formation":
- trainingAbsenceMonth = trainingAbsenceMonth.add(totalAbsence);
- break;
- case "Absence mission":
- missionAbsenceMonth = missionAbsenceMonth.add(totalAbsence);
- break;
- case "Absence hospitalisation":
- hospitalizationAbsenceMonth = hospitalizationAbsenceMonth.add(totalAbsence);
- break;
- case "Absence maladie":
- sicknessAbsenceMonth = sicknessAbsenceMonth.add(totalAbsence);
- break;
- case "Accident de travail":
- workAccidentMonth = workAccidentMonth.add(totalAbsence);
- break;
- case "Maternité":
- maternityMonth = maternityMonth.add(totalAbsence);
- break;
- case "Absence autorisée non payée":
- authorizedUnpaidAbsenceMonth = authorizedUnpaidAbsenceMonth.add(totalAbsence);
- break;
- case "Absence conge annuel":
- annualLeaveAbsenceMonth = annualLeaveAbsenceMonth.add(totalAbsence);
- break;
- case "Absence conge sans solde":
- unpaidLeaveAbsenceMonth = unpaidLeaveAbsenceMonth.add(totalAbsence);
- break;
- case "Absence conge statutaire":
- statutoryLeaveAbsenceMonth = statutoryLeaveAbsenceMonth.add(totalAbsence);
- break;
- case "Absence démission":
- resignationAbsenceMonth = resignationAbsenceMonth.add(totalAbsence);
- break;
- case "Absence fin de contrat":
- contractEndAbsenceMonth = contractEndAbsenceMonth.add(totalAbsence);
- break;
- case "Absence justifieé":
- justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
- break;
- case "Absence recrutement":
- recruitmentAbsenceMonth = recruitmentAbsenceMonth.add(totalAbsence);
- break;
- case "Suspension":
- suspensionAbsenceMonth = suspensionAbsenceMonth.add(totalAbsence);
- break;
- case "Absence irrégulière":
- irregularAbsenceMonth = irregularAbsenceMonth.add(totalAbsence);
- break;
- case "Absence service militaire":
- militaryServiceAbsence = militaryServiceAbsence.add(totalAbsence);
- break;
- default:
- // Handle default case
- break;
+ if (dailyReport.getAbsenceHours() != null && dailyReport.getAbsenceHours().compareTo(BigDecimal.ZERO) > 0) {
+ if (isAuthorizedAbsence == false && isAuthorizedLateArrival == false && isAuthorizedEarlyDeparture == false && leaveRequest == null && absences == null) {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getAbsenceHours());
+ } else if(isAuthorizedAbsence){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getAbsenceHours());
+ } else if(isAuthorizedLateArrival){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getLateArrival());
+ } else if(isAuthorizedEarlyDeparture){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getEarlyDeparture());
+ } else if(leaveRequest != null){
+ recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(dailyReport.getAbsenceHours());
+ } else if(absences != null){
+ for(Absence absence:absences){
+ totalAbsence = dailyReport.getAbsenceHours();
+ switch (absence.getAbsenceType()) {
+ case 0:
+ breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
+ break;
+ case 1:
+ recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 2:
+ breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
+ break;
+ case 3:
+ trainingAbsenceMonth = trainingAbsenceMonth.add(totalAbsence);
+ break;
+ case 4:
+ missionAbsenceMonth = missionAbsenceMonth.add(totalAbsence);
+ break;
+ case 5:
+ hospitalizationAbsenceMonth = hospitalizationAbsenceMonth.add(totalAbsence);
+ break;
+ case 6:
+ sicknessAbsenceMonth = sicknessAbsenceMonth.add(totalAbsence);
+ break;
+ case 7:
+ workAccidentMonth = workAccidentMonth.add(totalAbsence);
+ break;
+ case 8:
+ maternityMonth = maternityMonth.add(totalAbsence);
+ break;
+ case 9:
+ authorizedUnpaidAbsenceMonth = authorizedUnpaidAbsenceMonth.add(totalAbsence);
+ break;
+ case 10:
+ annualLeaveAbsenceMonth = annualLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 11:
+ unpaidLeaveAbsenceMonth = unpaidLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 12:
+ statutoryLeaveAbsenceMonth = statutoryLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 13:
+ resignationAbsenceMonth = resignationAbsenceMonth.add(totalAbsence);
+ break;
+ case 14:
+ contractEndAbsenceMonth = contractEndAbsenceMonth.add(totalAbsence);
+ break;
+ case 15:
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
+ break;
+ case 16:
+ recruitmentAbsenceMonth = recruitmentAbsenceMonth.add(totalAbsence);
+ break;
+ case 17:
+ suspensionAbsenceMonth = suspensionAbsenceMonth.add(totalAbsence);
+ break;
+ case 18:
+ militaryServiceAbsence = militaryServiceAbsence.add(totalAbsence);
+ break;
+ case 19:
+ if(dailyReport.getIsAuthorizedAbsence()){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
+ } else {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(totalAbsence);
+ }
+ break;
+ case 20:
+ if(dailyReport.getIsAuthorizedLateArrival()){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getLateArrival());
+ } else {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getLateArrival());
+ }
+ break;
+ case 21:
+ if(dailyReport.getIsAuthorizedEarlyDeparture()){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getEarlyDeparture());
+ } else {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getEarlyDeparture());
+ }
+ break;
+ default:
+ // Handle default case
+ break;
+ }
+ }
}
- }
+ }
}
// Update or create MonthlyReport instance with calculated values
@@ -278,6 +320,284 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
// Save the MonthlyReport instance
monthlyReportRepository.save(monthlyReport);
}
+
+ public void updateMensuelReport(MonthlyReport monthlyReport, Employee employee, Period period, LocalDate startDate, LocalDate endDate, List employeeDailyReports, List employeeAbsences) {
+
+ Boolean hasNuissance = employee.getHasNuissance();
+ LocalDate firstDayOfMonth = endDate.with(TemporalAdjusters.firstDayOfMonth());
+ // Perform calculations
+ Integer monthlyAllowance = 0;
+ Integer monthlyAllowanceRecall = 0;
+ BigDecimal monthlyNightHours = BigDecimal.ZERO;
+ BigDecimal monthlyExtraHours50 = BigDecimal.ZERO;
+ BigDecimal monthlyExtraHours100 = BigDecimal.ZERO;
+ BigDecimal excessHours50 = BigDecimal.ZERO;
+ BigDecimal excessHours100 = BigDecimal.ZERO;
+ BigDecimal totalSupHours = BigDecimal.ZERO;
+
+ BigDecimal monthlyITP = BigDecimal.ZERO;
+ BigDecimal totalNuissance = BigDecimal.ZERO;
+ BigDecimal totalAbsence = BigDecimal.ZERO;
+ BigDecimal totalWorkHours = BigDecimal.ZERO;
+
+ BigDecimal breastfeedingAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal authorizedPaidAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal recuperationLeaveAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal trainingAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal missionAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal hospitalizationAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal sicknessAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal workAccidentMonth = BigDecimal.ZERO;
+ BigDecimal maternityMonth = BigDecimal.ZERO;
+ BigDecimal authorizedUnpaidAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal annualLeaveAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal unpaidLeaveAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal statutoryLeaveAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal resignationAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal contractEndAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal justifiedAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal recruitmentAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal suspensionAbsenceMonth = BigDecimal.ZERO;
+ BigDecimal militaryServiceAbsence = BigDecimal.ZERO;
+ BigDecimal irregularAbsenceMonth = BigDecimal.ZERO;
+
+ //monthlyAllowance = monthlyAllowance + remainingDateToLastOfMonth;
+
+ // Calculate totals for DailyReport
+ for (DailyReport dailyReport : employeeDailyReports) {
+ // Panier
+ /*LocalDate reportDate = dailyReport.getReportDate();
+ Integer panier = dailyReport.getPanier();
+ if (reportDate.isAfter(firstDayOfMonth) && panier == 1) {
+ monthlyAllowance = monthlyAllowance + 1;
+ }*/
+
+ monthlyAllowance = monthlyAllowance + dailyReport.getAllowance();;
+ monthlyAllowanceRecall = monthlyAllowanceRecall + dailyReport.getAllowanceRecall();
+ monthlyNightHours = monthlyNightHours.add(dailyReport.getNightHours());
+ totalWorkHours = totalWorkHours.add(dailyReport.getWorkHours());
+
+ BigDecimal heureSup50 = dailyReport.getExtraHours50() != null ? dailyReport.getExtraHours50() : BigDecimal.ZERO;
+ BigDecimal heureSup100 = dailyReport.getExtraHours100() != null ? dailyReport.getExtraHours100() : BigDecimal.ZERO;
+ BigDecimal itp = dailyReport.getItp() != null ? dailyReport.getItp() : BigDecimal.ZERO;
+ BigDecimal nuissance = dailyReport.getNuissance() != null ? dailyReport.getNuissance() : BigDecimal.ZERO;
+
+ BigDecimal supHours50ToDeduce = dailyReport.getSupHours50ToDeduce() != null ? dailyReport.getSupHours50ToDeduce() : BigDecimal.ZERO;
+ BigDecimal supHours100ToDeduce = dailyReport.getSupHours100ToDeduce() != null ? dailyReport.getSupHours100ToDeduce() : BigDecimal.ZERO;
+ BigDecimal itpToDeduce = dailyReport.getItpToDeduce() != null ? dailyReport.getItpToDeduce() : BigDecimal.ZERO;
+ BigDecimal nuissanceToDeduce = dailyReport.getNuissanceToDeduce() != null ? dailyReport.getNuissanceToDeduce() : BigDecimal.ZERO;
+
+ if (dailyReport.getDeduceSupHours50() && heureSup50.compareTo(supHours50ToDeduce) > 0) {
+ heureSup50 = heureSup50.subtract(supHours50ToDeduce);
+ }
+
+ if (dailyReport.getDeduceSupHours100() && heureSup100.compareTo(supHours100ToDeduce) > 0) {
+ heureSup100 = heureSup100.subtract(supHours100ToDeduce);
+ }
+
+ if (dailyReport.getDeduceItp() && itp.compareTo(itpToDeduce) > 0) {
+ itp = itp.subtract(itpToDeduce);
+ }
+
+ if (dailyReport.getDeduceNuissance() && nuissance.compareTo(nuissanceToDeduce) > 0) {
+ nuissance = nuissance.subtract(nuissanceToDeduce);
+ }
+
+ monthlyITP = monthlyITP.add(itp);
+ totalNuissance = totalNuissance.add(nuissance);
+
+ // Sup Hours
+ if (dailyReport.getIsValidSupHours()) {
+
+ // Handle HeureSup50
+ if (heureSup50 != null) {
+ if (totalSupHours.add(heureSup50).compareTo(new BigDecimal(32)) <= 0) {
+ // If the total hours are still less than or equal to 32 after adding new hours
+ monthlyExtraHours50 = monthlyExtraHours50.add(heureSup50);
+ totalSupHours = totalSupHours.add(heureSup50);
+ } else if (totalSupHours.compareTo(new BigDecimal(32)) < 0) {
+ // If totalSupHours is less than 32, but adding heureSup50 exceeds 32
+ BigDecimal remainingHours = new BigDecimal(32).subtract(totalSupHours);
+ monthlyExtraHours50 = monthlyExtraHours50.add(remainingHours);
+ totalSupHours = totalSupHours.add(remainingHours);
+
+ // Add the excess to excessHours50
+ excessHours50 = excessHours50.add(heureSup50.subtract(remainingHours));
+ } else {
+ // If totalSupHours already exceeds 32, all new hours go to excess
+ excessHours50 = excessHours50.add(heureSup50);
+ }
+ }
+ // Handle HeureSup100
+ if (heureSup100 != null) {
+ if (totalSupHours.add(heureSup100).compareTo(new BigDecimal(32)) <= 0) {
+ // If the total hours are still less than or equal to 32 after adding new hours
+ monthlyExtraHours100 = monthlyExtraHours100.add(heureSup100);
+ totalSupHours = totalSupHours.add(heureSup100);
+ } else if (totalSupHours.compareTo(new BigDecimal(32)) < 0) {
+ // If totalSupHours is less than 32, but adding heureSup100 exceeds 32
+ BigDecimal remainingHours = new BigDecimal(32).subtract(totalSupHours);
+ monthlyExtraHours100 = monthlyExtraHours100.add(remainingHours);
+ totalSupHours = totalSupHours.add(remainingHours);
+
+ // Add the excess to excessHours100
+ excessHours100 = excessHours100.add(heureSup100.subtract(remainingHours));
+ } else {
+ // If totalSupHours already exceeds 32, all new hours go to excess
+ excessHours100 = excessHours100.add(heureSup100);
+ }
+ }
+ }
+
+ Boolean isAuthorizedAbsence = dailyReport.getIsAuthorizedAbsence();
+ Boolean isAuthorizedLateArrival = dailyReport.getIsAuthorizedLateArrival();
+ Boolean isAuthorizedEarlyDeparture = dailyReport.getIsAuthorizedEarlyDeparture();
+ LeaveRequest leaveRequest = dailyReport.getLeaveRequest();
+ Set absences = dailyReport.getAbsenceSet();
+
+ if (dailyReport.getAbsenceHours() != null && dailyReport.getAbsenceHours().compareTo(BigDecimal.ZERO) > 0) {
+ if (isAuthorizedAbsence == false && isAuthorizedLateArrival == false && isAuthorizedEarlyDeparture == false && leaveRequest == null && absences == null) {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getAbsenceHours());
+ } else if(isAuthorizedAbsence){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getAbsenceHours());
+ } else if(isAuthorizedLateArrival){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getLateArrival());
+ } else if(isAuthorizedEarlyDeparture){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getEarlyDeparture());
+ } else if(leaveRequest != null){
+ recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(dailyReport.getAbsenceHours());
+ } else if(absences != null){
+ for(Absence absence:absences){
+ totalAbsence = dailyReport.getAbsenceHours();
+ switch (absence.getAbsenceType()) {
+ case 0:
+ breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
+ break;
+ case 1:
+ recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 2:
+ breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
+ break;
+ case 3:
+ trainingAbsenceMonth = trainingAbsenceMonth.add(totalAbsence);
+ break;
+ case 4:
+ missionAbsenceMonth = missionAbsenceMonth.add(totalAbsence);
+ break;
+ case 5:
+ hospitalizationAbsenceMonth = hospitalizationAbsenceMonth.add(totalAbsence);
+ break;
+ case 6:
+ sicknessAbsenceMonth = sicknessAbsenceMonth.add(totalAbsence);
+ break;
+ case 7:
+ workAccidentMonth = workAccidentMonth.add(totalAbsence);
+ break;
+ case 8:
+ maternityMonth = maternityMonth.add(totalAbsence);
+ break;
+ case 9:
+ authorizedUnpaidAbsenceMonth = authorizedUnpaidAbsenceMonth.add(totalAbsence);
+ break;
+ case 10:
+ annualLeaveAbsenceMonth = annualLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 11:
+ unpaidLeaveAbsenceMonth = unpaidLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 12:
+ statutoryLeaveAbsenceMonth = statutoryLeaveAbsenceMonth.add(totalAbsence);
+ break;
+ case 13:
+ resignationAbsenceMonth = resignationAbsenceMonth.add(totalAbsence);
+ break;
+ case 14:
+ contractEndAbsenceMonth = contractEndAbsenceMonth.add(totalAbsence);
+ break;
+ case 15:
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
+ break;
+ case 16:
+ recruitmentAbsenceMonth = recruitmentAbsenceMonth.add(totalAbsence);
+ break;
+ case 17:
+ suspensionAbsenceMonth = suspensionAbsenceMonth.add(totalAbsence);
+ break;
+ case 18:
+ militaryServiceAbsence = militaryServiceAbsence.add(totalAbsence);
+ break;
+ case 19:
+ if(dailyReport.getIsAuthorizedAbsence()){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
+ } else {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(totalAbsence);
+ }
+ break;
+ case 20:
+ if(dailyReport.getIsAuthorizedLateArrival()){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getLateArrival());
+ } else {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getLateArrival());
+ }
+ break;
+ case 21:
+ if(dailyReport.getIsAuthorizedEarlyDeparture()){
+ justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getEarlyDeparture());
+ } else {
+ irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getEarlyDeparture());
+ }
+ break;
+ default:
+ // Handle default case
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Update or create MonthlyReport instance with calculated values
+ monthlyReport.setPeriod(period);
+ monthlyReport.setEmployee(employee);
+ monthlyReport.setMonthlyAllowance(monthlyAllowance);
+ monthlyReport.setMonthlyAllowanceRecall(monthlyAllowanceRecall);
+ monthlyReport.setMonthlyNightHours(monthlyNightHours);
+ monthlyReport.setMonthlyExtraHours50(monthlyExtraHours50);
+ monthlyReport.setMonthlyExtraHours100(monthlyExtraHours100);
+ monthlyReport.setExcessHours50(excessHours50);
+ monthlyReport.setExcessHours100(excessHours100);
+
+ monthlyReport.setMonthlyITP(monthlyITP);
+ monthlyReport.setTotalNuissance(totalNuissance);
+ monthlyReport.setTotalWorkHours(totalWorkHours);
+
+ // Set total absence values for each specific type
+ monthlyReport.setBreastfeedingAbsenceMonth(breastfeedingAbsenceMonth);
+ monthlyReport.setAuthorizedPaidAbsenceMonth(authorizedPaidAbsenceMonth);
+ monthlyReport.setAuthorizedUnpaidAbsenceMonth(authorizedUnpaidAbsenceMonth);
+ monthlyReport.setAnnualLeaveAbsenceMonth(annualLeaveAbsenceMonth);
+ monthlyReport.setRecuperationLeaveAbsenceMonth(recuperationLeaveAbsenceMonth);
+ monthlyReport.setUnpaidLeaveAbsenceMonth(unpaidLeaveAbsenceMonth);
+ monthlyReport.setStatutoryLeaveAbsenceMonth(statutoryLeaveAbsenceMonth);
+ monthlyReport.setResignationAbsenceMonth(resignationAbsenceMonth);
+ monthlyReport.setContractEndAbsenceMonth(contractEndAbsenceMonth);
+ monthlyReport.setTrainingAbsenceMonth(trainingAbsenceMonth);
+ monthlyReport.setHospitalizationAbsenceMonth(hospitalizationAbsenceMonth);
+ monthlyReport.setMissionAbsenceMonth(missionAbsenceMonth);
+ monthlyReport.setSicknessAbsenceMonth(sicknessAbsenceMonth);
+ monthlyReport.setWorkAccidentMonth(workAccidentMonth);
+ monthlyReport.setMaternityMonth(maternityMonth);
+ monthlyReport.setJustifiedAbsenceMonth(justifiedAbsenceMonth);
+ monthlyReport.setRecruitmentAbsenceMonth(recruitmentAbsenceMonth);
+ monthlyReport.setSuspensionAbsenceMonth(suspensionAbsenceMonth);
+ monthlyReport.setMilitaryServiceAbsence(militaryServiceAbsence);
+ monthlyReport.setIrregularAbsenceMonth(irregularAbsenceMonth);
+
+ // Save the MonthlyReport instance
+ monthlyReportRepository.save(monthlyReport);
+ }
+
/*
@Transactional
public void calculePrimeAssiduite(MonthlyReport monthlyReport) {
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeService.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeService.java
index db5e560..a25d196 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeService.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeService.java
@@ -25,6 +25,7 @@ import com.google.inject.persist.Transactional;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Map;
+import java.util.List;
public interface EmployeeService extends UserService {
@@ -43,4 +44,14 @@ public interface EmployeeService extends UserService {
/** Generates a new {@link DPAE} for given {@link Employee} and returns its id. */
@Transactional(rollbackOn = {Exception.class})
Long generateNewDPAE(Employee employee) throws AxelorException;
+
+ @Transactional
+ public void setEmployeeEnrolled(Employee employee);
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void updateEmployeeConfig(Employee employee, Integer configSelect, Boolean status) throws AxelorException ;
+
+ @Transactional(rollbackOn = {Exception.class})
+ public void massUpdateEmployeeConfig(List employeesIds, Integer configSelect, Boolean status) throws AxelorException;
+
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeServiceImpl.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeServiceImpl.java
index 9b897a2..8ba166b 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeServiceImpl.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/service/employee/EmployeeServiceImpl.java
@@ -250,4 +250,47 @@ public class EmployeeServiceImpl extends UserServiceImpl implements EmployeeServ
Beans.get(EmployeeRepository.class).save(employee);
return newDPAE.getId();
}
+
+ @Override
+ @Transactional
+ public void setEmployeeEnrolled(Employee employee){
+ employee.setIsEnrolled(true);
+ Beans.get(EmployeeRepository.class).save(employee);
+ }
+
+ @Override
+ @Transactional(rollbackOn = {Exception.class})
+ public void updateEmployeeConfig(Employee employee, Integer configSelect, Boolean status)
+ throws AxelorException {
+ switch (configSelect) {
+ case 1: // ITP
+ employee.setHasItp(status);
+ break;
+ case 2: // Nuissance
+ employee.setHasNuissance(status);
+ break;
+ case 3: // Transfaire
+ employee.setIsTransfaire(status);
+ break;
+ default:
+ return; // Invalid configSelect, stop processing
+ }
+ Beans.get(EmployeeRepository.class).save(employee);
+ }
+
+ @Override
+ @Transactional(rollbackOn = {Exception.class})
+ public void massUpdateEmployeeConfig(List employeesIds, Integer configSelect, Boolean status) throws AxelorException{
+ List employees =
+ Beans.get(EmployeeRepository.class)
+ .all()
+ .filter("self.id in (?1)", employeesIds)
+ .fetch();
+
+ if (employeesIds != null || !employeesIds.isEmpty()) {
+ for (Employee employee : employees) {
+ this.updateEmployeeConfig(employee, configSelect, status);
+ }
+ }
+ }
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AbsenceController.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AbsenceController.java
index e45f96e..011b75f 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AbsenceController.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AbsenceController.java
@@ -15,6 +15,10 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
+import com.axelor.i18n.I18n;
+import com.axelor.meta.schema.actions.ActionView;
+import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
+import java.util.stream.Collectors;
public class AbsenceController {
@@ -27,22 +31,43 @@ public class AbsenceController {
LocalDate absenceEndDate = absence.getEndDate().toLocalDate();
Employee employee = absence.getEmployee();
- List dailyreports =
- Beans.get(DailyReportRepository.class)
- .all()
- .filter(
- "self.employee = :employee and self.reportDate between :absenceStartDate and :absenceEndDate")
- .bind("employee", employee)
- .bind("absenceStartDate", absenceStartDate)
- .bind("absenceEndDate", absenceEndDate)
- .fetch();
+ // Fetch all existing daily reports associated with this absence
+ List existingReports =
+ Beans.get(DailyReportRepository.class)
+ .all()
+ .filter("self.absenceSet = :absence")
+ .bind("absence", absence)
+ .fetch();
+
+ if (existingReports != null && !existingReports.isEmpty()) {
+ // Detach absence only from reports that are outside the new date range
+ List reportsToDetach = existingReports.stream()
+ .filter(report -> report.getReportDate().isBefore(absenceStartDate) || report.getReportDate().isAfter(absenceEndDate))
+ .collect(Collectors.toList());
+
+ // Detach absence from these specific reports
+ if (!reportsToDetach.isEmpty()) {
+ Beans.get(AbsenceServiceImpl.class).deAttachTheAbsenceWithDailyReport(absence, reportsToDetach, false);
+ }
+ }
+
+ List newReports =
+ Beans.get(DailyReportRepository.class)
+ .all()
+ .filter(
+ "self.employee = :employee and self.reportDate between :absenceStartDate and :absenceEndDate")
+ .bind("employee", employee)
+ .bind("absenceStartDate", absenceStartDate)
+ .bind("absenceEndDate", absenceEndDate)
+ .fetch();
+
// Check if there are any reports
- if (dailyreports.isEmpty()) {
+ if (newReports.isEmpty()) {
return;
}
- Beans.get(AbsenceServiceImpl.class).attachTheAbsenceWithDailyReport(absence, dailyreports);
+ Beans.get(AbsenceServiceImpl.class).attachTheAbsenceWithDailyReport(absence, newReports);
response.setReload(true);
} catch (Exception e) {
e.printStackTrace();
@@ -52,7 +77,7 @@ public class AbsenceController {
public void chooseAbsenceType(ActionRequest request, ActionResponse response) {
try {
// Get the selected absence type from the request parameters
- String selectedType = (String) request.getContext().get("selectedType");
+ Integer selectedType = (Integer) request.getContext().get("selectedType");
// Get the list of selected absence IDs
List absenceIds = (List) request.getContext().get("_ids");
@@ -89,7 +114,14 @@ public class AbsenceController {
.bind("absence", absenceId)
.fetch();
- Beans.get(AbsenceServiceImpl.class).deAttachTheAbsenceWithDailyReport(absence, dailyreports);
+ Beans.get(AbsenceServiceImpl.class).deAttachTheAbsenceWithDailyReport(absence, dailyreports, true);
+ ActionViewBuilder actionView =
+ ActionView.define(I18n.get("Absences"))
+ .model(Absence.class.getName())
+ .add("grid", "absence-grid")
+ .add("form", "absence-form");
+
+ response.setView(actionView.map());
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AuthorizationController.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AuthorizationController.java
index e4688a1..eb734bd 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AuthorizationController.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/AuthorizationController.java
@@ -137,6 +137,42 @@ public class AuthorizationController {
}
}
+ public void fetchSalaryAuthorization(ActionRequest request, ActionResponse response) {
+ try {
+ String accessToken = AppBaseController.getAccessToken();
+ if (accessToken == null) {
+ logger.error("Access token is null, unable to proceed.");
+ return;
+ }
+ String jsonResponse = fetchAP(accessToken);
+
+ if (jsonResponse != null) {
+ try {
+ JSONArray jsonArray = new JSONArray(jsonResponse);
+
+ for (int i = 0; i < jsonArray.length(); i++) {
+ JSONObject jsonObject = jsonArray.getJSONObject(i);
+ Beans.get(AuthorizationService.class).saveAP(jsonObject);
+ }
+
+ // Reload the response after successfully saving extra hours
+ response.setReload(true);
+
+ } catch (JSONException e) {
+ // Log the specific JSON parsing error
+ System.err.println("Failed to parse JSON: " + jsonResponse);
+ e.printStackTrace();
+ }
+ } else {
+ System.err.println("No response received from fetchAP.");
+ }
+ } catch (Exception e) {
+ // General catch for unexpected exceptions
+ System.err.println("An error occurred while fetching Salary Authorization: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
public String fetchAA(String accessToken) {
String endpoint = BASE_URL + "tickets/aa/";
HttpURLConnection conn = null;
@@ -283,4 +319,55 @@ public class AuthorizationController {
}
}
}
+
+ // Authorisation de paye
+ public String fetchAP(String accessToken) {
+ String endpoint = BASE_URL + "tickets/ap/";
+ HttpURLConnection conn = null;
+
+ try {
+ URL url = new URL(endpoint);
+ conn = (HttpURLConnection) url.openConnection();
+
+ conn.setRequestMethod("GET");
+ conn.setRequestProperty("Content-Type", "application/json");
+ conn.setRequestProperty("Accept", "application/json");
+ // Include the access token in the Authorization header
+ conn.setRequestProperty("Authorization", "Bearer " + accessToken);
+
+ int responseCode = conn.getResponseCode();
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ try (BufferedReader br =
+ new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
+ StringBuilder response = new StringBuilder();
+ String responseLine;
+ while ((responseLine = br.readLine()) != null) {
+ response.append(responseLine.trim());
+ }
+ // Process the response as needed
+ return response.toString();
+ }
+ } else {
+ // Read the error stream for more details
+ StringBuilder errorResponse = new StringBuilder();
+ try (BufferedReader br =
+ new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8"))) {
+ String errorLine;
+ while ((errorLine = br.readLine()) != null) {
+ errorResponse.append(errorLine.trim());
+ }
+ }
+ throw new RuntimeException(
+ "Failed: HTTP error code: " + responseCode + ", Error: " + errorResponse.toString());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null; // Return null in case of failure
+ } finally {
+ if (conn != null) {
+ conn.disconnect(); // Ensure connection is closed
+ }
+ }
+ }
+
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/DailyReportController.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/DailyReportController.java
index 4ed42cb..5908ca4 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/DailyReportController.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/DailyReportController.java
@@ -1,19 +1,28 @@
package com.axelor.apps.hr.web;
import com.axelor.apps.hr.db.Shift;
+import com.axelor.apps.hr.db.Employee;
import com.axelor.apps.hr.db.DailyReport;
import com.axelor.apps.hr.db.repo.DailyReportRepository;
import com.axelor.apps.hr.db.repo.ShiftRepository;
+import com.axelor.apps.hr.db.repo.EmployeeRepository;
+import com.axelor.apps.hr.service.DailyReportService;
import com.axelor.apps.hr.service.DailyReportServiceImpl;
import com.axelor.inject.Beans;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import java.lang.invoke.MethodHandles;
+import java.util.LinkedHashMap;
+import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
+import java.time.format.DateTimeParseException;
import java.time.LocalTime;
+import java.time.LocalDate;
+import java.math.BigDecimal;
+import com.axelor.exception.service.TraceBackService;
public class DailyReportController {
@@ -115,4 +124,112 @@ public class DailyReportController {
response.setReload(true);
response.setFlash("Working hours calculated successfully.");
}
+
+ public void massDeducePrime(ActionRequest request, ActionResponse response) {
+
+ Integer primeSelection = (Integer) request.getContext().get("primesSelect");
+ String startDateStr = (String) request.getContext().get("startDate");
+ String endDateStr = (String) request.getContext().get("endDate");
+
+ LocalDate startDate = null;
+ LocalDate endDate = null;
+
+ try {
+ if (startDateStr != null) {
+ startDate = LocalDate.parse(startDateStr);
+ }
+ if (endDateStr != null) {
+ endDate = LocalDate.parse(endDateStr);
+ }
+
+ // Validate the dates
+ if (startDate == null || endDate == null) {
+ response.setFlash("Start date or end date is missing or invalid.");
+ return;
+ }
+
+ if (startDate.isAfter(endDate)) {
+ response.setFlash("Start date cannot be after end date.");
+ return;
+ }
+
+ } catch (DateTimeParseException e) {
+ response.setFlash("Invalid date format for startDate or endDate. Expected format: yyyy-MM-dd.");
+ return;
+ }
+
+ Object valueToDeduceObj = request.getContext().get("valueToDeduce");
+
+ BigDecimal valueToDeduce = null;
+ if (valueToDeduceObj instanceof Integer) {
+ valueToDeduce = BigDecimal.valueOf((Integer) valueToDeduceObj);
+ } else if (valueToDeduceObj instanceof BigDecimal) {
+ valueToDeduce = (BigDecimal) valueToDeduceObj;
+ } else if (valueToDeduceObj instanceof String) {
+ try {
+ valueToDeduce = new BigDecimal((String) valueToDeduceObj);
+ } catch (NumberFormatException e) {
+ response.setFlash("Value to deduce must be a valid number.");
+ return;
+ }
+ } else {
+ response.setFlash("Invalid value to deduce: unsupported type " + (valueToDeduceObj != null ? valueToDeduceObj.getClass().getName() : "null"));
+ return;
+ }
+
+ Object employeesObject = request.getContext().get("employees");
+
+ // Initialize the employees list
+ List employees = new ArrayList<>();
+
+ if (employeesObject instanceof List) {
+ List> employeesList = (List>) employeesObject;
+
+ for (LinkedHashMap employeeMap : employeesList) {
+ Integer employeeIdInt = (Integer) employeeMap.get("id");
+
+ if (employeeIdInt != null) {
+ Long employeeId = employeeIdInt.longValue();
+ Employee employee = Beans.get(EmployeeRepository.class).find(employeeId);
+
+ if (employee != null) {
+ employees.add(employee);
+ }
+ }
+ }
+ }
+
+ if (employees.isEmpty()) {
+ response.setFlash("No employees selected.");
+ return;
+ }
+
+ List employeeIds = new ArrayList<>();
+ for (Employee employee : employees) {
+ employeeIds.add(employee.getId().intValue());
+ }
+
+ // Fetch all rapport journaliers within the date range for all employees
+ List dailyReportList = Beans.get(DailyReportRepository.class)
+ .all()
+ .filter("self.employee.id in :employeeIds and self.reportDate >= :startDate and self.reportDate <= :endDate")
+ .bind("startDate", startDate)
+ .bind("endDate", endDate)
+ .bind("employeeIds", employeeIds)
+ .fetch();
+
+ try {
+ if (!dailyReportList.isEmpty()) {
+ Beans.get(DailyReportService.class).massDeducePrimes(dailyReportList, primeSelection, valueToDeduce);
+ response.setReload(true);
+ response.setFlash("Prime deductions processed successfully.");
+ } else {
+ response.setFlash("No reports found for the selected date range.");
+ }
+ } catch (Exception e) {
+ TraceBackService.trace(response, e);
+ response.setFlash("An error occurred while processing the request.");
+ }
+ }
+
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/EmployeeController.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/EmployeeController.java
index 3346388..ec21728 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/EmployeeController.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/EmployeeController.java
@@ -40,6 +40,7 @@ import com.axelor.rpc.ActionResponse;
import com.google.inject.Singleton;
import java.lang.invoke.MethodHandles;
import java.util.Map;
+import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wslite.json.JSONException;
@@ -47,11 +48,13 @@ import wslite.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import com.axelor.app.AppSettings;
@Singleton
public class EmployeeController {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private final String pythonScriptDir = AppSettings.get().get("services.dir");
public void showAnnualReport(ActionRequest request, ActionResponse response)
throws JSONException, NumberFormatException, AxelorException {
@@ -164,12 +167,18 @@ public class EmployeeController {
if (employee.getContactPartner() != null){
String employeeRegistrationNumber = employee.getRegistrationNumber();
String employeeName = employee.getContactPartner().getName();
+
+ if (pythonScriptDir == null || pythonScriptDir.isEmpty()) {
+ LOG.error("Pythons script path is not configured in AppSettings.");
+ return;
+ }
try {
+
String[] args = {
"python",
- "C:\\Users\\administrator\\Desktop\\attendance\\main.py",
+ pythonScriptDir + "\\Attendance\\main.py",
"--commande", "create",
"--ip_address", ipAdress,
"--code", code,
@@ -198,6 +207,7 @@ public class EmployeeController {
// Check if the process ran successfully
if (exitCode == 0) {
LOG.info("Python script executed successfully (Employee Enrolling).");
+ Beans.get(EmployeeService.class).setEmployeeEnrolled(employee);
response.setFlash("Employee enrolled successfully.");
} else {
LOG.error("Python script execution (Employee Enrolling) failed with exit code: " + exitCode);
@@ -223,4 +233,47 @@ public class EmployeeController {
}
}
+ public void setEmployeeConfig(ActionRequest request, ActionResponse response) {
+
+ List employeeIds = (List) request.getContext().get("_ids");
+ System.out.println("****************");
+ System.out.println(employeeIds);
+ System.out.println("****************");
+ Integer configSelect = (Integer) request.getContext().get("configSelect");
+
+ if (employeeIds == null || employeeIds.isEmpty()) {
+ response.setFlash("You haven't selected any Employee.");
+ }
+ try {
+ if (!employeeIds.isEmpty()) {
+ Beans.get(EmployeeService.class).massUpdateEmployeeConfig(employeeIds, configSelect,true);
+ response.setReload(true);
+ }
+ } catch (Exception e) {
+ TraceBackService.trace(response, e);
+ }
+ }
+
+ public void unSetEmployeeConfig(ActionRequest request, ActionResponse response) {
+
+ List employeeIds = (List) request.getContext().get("_ids");
+ System.out.println("****************");
+ System.out.println(employeeIds);
+ System.out.println("****************");
+ Integer configSelect = (Integer) request.getContext().get("configSelect");
+
+ if (employeeIds == null || employeeIds.isEmpty()) {
+ response.setFlash("You haven't selected any Employee.");
+ }
+ try {
+ if (!employeeIds.isEmpty()) {
+ Beans.get(EmployeeService.class).massUpdateEmployeeConfig(employeeIds, configSelect,false);
+ response.setReload(true);
+ }
+
+ } catch (Exception e) {
+ TraceBackService.trace(response, e);
+ }
+ }
+
}
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/MonthlyReportController.java b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/MonthlyReportController.java
index 4c336d1..e378b52 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/MonthlyReportController.java
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/java/com/axelor/apps/hr/web/MonthlyReportController.java
@@ -19,13 +19,17 @@ import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
+import java.lang.invoke.MethodHandles;
import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class MonthlyReportController {
+ private final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
public void createMensuelReport(ActionRequest request, ActionResponse response) {
try {
@@ -68,32 +72,29 @@ public class MonthlyReportController {
// Iterate over employees and calculate/update MonthlyReport instances
for (Employee employee : employees) {
// Filter rapport journaliers for the current employee
- List employeeDailyReports =
- allDailyReports
- .stream()
- .filter(r -> r.getEmployee().equals(employee))
- .collect(Collectors.toList());
+ List employeeDailyReports = allDailyReports
+ .stream()
+ .filter(r -> r.getEmployee().equals(employee))
+ .collect(Collectors.toList());
// Filter absences for the current employee
- List employeeAbsences =
- allAbsences
- .stream()
- .filter(a -> a.getEmployee().equals(employee))
- .collect(Collectors.toList());
-
- System.out.println("Employee: "+ employee.getRegistrationNumber());
+ List employeeAbsences = allAbsences
+ .stream()
+ .filter(a -> a.getEmployee().equals(employee))
+ .collect(Collectors.toList());
if (!employeeDailyReports.isEmpty() || !employeeAbsences.isEmpty()) {
- System.out.println("Calculé pour: "+ employee.getRegistrationNumber());
+ System.out.println("Create monthly report for employee: "+ employee.getRegistrationNumber());
// Process the employee's monthly report using filtered rapport and absences
- Beans.get(MonthlyReportServiceImpl.class)
- .createMensuelReport(
+ Beans.get(MonthlyReportServiceImpl.class).createMensuelReport(
employee,
period,
startDate,
endDate,
employeeDailyReports,
employeeAbsences);
+ } else {
+ log.error("No Daily Reports exist for employee: "+ employee.getRegistrationNumber());
}
}
// Indicate that the action was successful and a reload is needed
@@ -176,7 +177,45 @@ public class MonthlyReportController {
.bind("endDate", endDate)
.bind("employeesIds", employeesIds)
.fetch();
-
+
+ for (Employee employee : employees) {
+ // Check if a MonthlyReport exists for this employee in the specified period
+ MonthlyReport monthlyReport = Beans.get(MonthlyReportRepository.class)
+ .all()
+ .filter("self.employee = :employee and self.period = :period")
+ .bind("employee", employee)
+ .bind("period", period)
+ .fetchOne();
+
+ Optional monthlyReportOpt = Optional.ofNullable(monthlyReport);
+
+ // Filter daily reports for the current employee
+ List employeeDailyReports = allDailyReports.stream()
+ .filter(r -> r.getEmployee().equals(employee))
+ .collect(Collectors.toList());
+
+ // Filter absences for the current employee
+ List employeeAbsences = allAbsences.stream()
+ .filter(a -> a.getEmployee().equals(employee))
+ .collect(Collectors.toList());
+
+ if (!employeeDailyReports.isEmpty() || !employeeAbsences.isEmpty()) {
+ if (monthlyReportOpt.isPresent()) {
+ MonthlyReport existingReport = monthlyReportOpt.get();
+ System.out.println("Update monthly report for employee: " + employee.getRegistrationNumber());
+ // Update the existing monthly report
+ Beans.get(MonthlyReportServiceImpl.class).updateMensuelReport(existingReport, employee, period, startDate, endDate, employeeDailyReports, employeeAbsences);
+ } else {
+ System.out.println("Create monthly report for employee: " + employee.getRegistrationNumber());
+ // Create a new monthly report
+ Beans.get(MonthlyReportServiceImpl.class).createMensuelReport(employee, period, startDate, endDate, employeeDailyReports, employeeAbsences);
+ }
+ } else {
+ System.err.println("No Daily Reports exist for employee: " + employee.getRegistrationNumber());
+ }
+ }
+
+
// Indicate that the action was successful and a reload is needed
response.setReload(true);
} catch (Exception e) {
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/Absence.xml b/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/Absence.xml
index 7d27ada..90c4332 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/Absence.xml
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/Absence.xml
@@ -8,12 +8,14 @@
-
+
+
+
-
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
diff --git a/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/DailyReport.xml b/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/DailyReport.xml
index 1dbb4fe..7b8d365 100644
--- a/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/DailyReport.xml
+++ b/modules/axelor-open-suite/axelor-human-resource/src/main/resources/domains/DailyReport.xml
@@ -38,6 +38,11 @@
+
+
+
+
+
@@ -45,7 +50,6 @@
-
@@ -54,6 +58,8 @@
+
+
@@ -74,6 +80,8 @@
+
+