Update attendances module
Add services files directory configuration to application.properties
This commit is contained in:
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
<string name="name" title="Name"/>
|
<string name="name" title="Name"/>
|
||||||
<string name="code" title="Code"/>
|
<string name="code" title="Code"/>
|
||||||
|
<integer name="departmentLevel" title="Level"/>
|
||||||
<many-to-one name="company" ref="com.axelor.apps.base.db.Company"/>
|
<many-to-one name="company" ref="com.axelor.apps.base.db.Company"/>
|
||||||
<integer name="departmentLevel" title="Level" />
|
|
||||||
<many-to-one name="parentDepartment" ref="com.axelor.apps.base.db.CompanyDepartment"/>
|
<many-to-one name="parentDepartment" ref="com.axelor.apps.base.db.CompanyDepartment"/>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ import org.quartz.JobExecutionException;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
|
import com.axelor.app.AppSettings;
|
||||||
|
|
||||||
public class FetchAttendanceJob implements Job {
|
public class FetchAttendanceJob implements Job {
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(FetchCheckInOutJob.class);
|
private final Logger log = LoggerFactory.getLogger(FetchCheckInOutJob.class);
|
||||||
|
private final String pythonScriptDir = AppSettings.get().get("services.dir");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException{
|
public void execute(JobExecutionContext context) throws JobExecutionException{
|
||||||
@@ -22,9 +24,14 @@ public class FetchAttendanceJob implements Job {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pythonScriptDir == null || pythonScriptDir.isEmpty()) {
|
||||||
|
log.error("Python script path is not configured in AppSettings.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Define the command to run the Python script with the correct path (V3)
|
// 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
|
// Execute the command
|
||||||
Process p = Runtime.getRuntime().exec(args);
|
Process p = Runtime.getRuntime().exec(args);
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import org.slf4j.LoggerFactory;
|
|||||||
import com.axelor.inject.Beans;
|
import com.axelor.inject.Beans;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
|
import com.axelor.app.AppSettings;
|
||||||
|
|
||||||
public class FetchCheckInOutJob implements Job {
|
public class FetchCheckInOutJob implements Job {
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(FetchCheckInOutJob.class);
|
private final Logger log = LoggerFactory.getLogger(FetchCheckInOutJob.class);
|
||||||
|
private final String pythonScriptDir = AppSettings.get().get("services.dir");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||||
@@ -26,6 +28,11 @@ public class FetchCheckInOutJob implements Job {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pythonScriptDir == null || pythonScriptDir.isEmpty()) {
|
||||||
|
log.error("Python script path is not configured in AppSettings.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
LocalDate today = LocalDate.now();
|
LocalDate today = LocalDate.now();
|
||||||
@@ -35,11 +42,10 @@ public class FetchCheckInOutJob implements Job {
|
|||||||
.all()
|
.all()
|
||||||
.filter("self.date_attendance = :today")
|
.filter("self.date_attendance = :today")
|
||||||
.bind("today", today)
|
.bind("today", today)
|
||||||
.fetch()
|
.fetch().size();
|
||||||
.size();
|
|
||||||
|
|
||||||
// Define the command to run the Python script with the correct path (V3)
|
// 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
|
// Execute the command
|
||||||
Process p = Runtime.getRuntime().exec(args);
|
Process p = Runtime.getRuntime().exec(args);
|
||||||
|
|||||||
@@ -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
|
// Leave requests fetch task
|
||||||
executorService.submit(
|
executorService.submit(
|
||||||
() -> {
|
() -> {
|
||||||
|
|||||||
@@ -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.extra.hours.ExtraHoursServiceImpl;
|
||||||
import com.axelor.apps.hr.service.leave.LeaveService;
|
import com.axelor.apps.hr.service.leave.LeaveService;
|
||||||
import com.axelor.apps.hr.service.leave.LeaveServiceImpl;
|
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.LunchVoucherAdvanceService;
|
||||||
import com.axelor.apps.hr.service.lunch.voucher.LunchVoucherAdvanceServiceImpl;
|
import com.axelor.apps.hr.service.lunch.voucher.LunchVoucherAdvanceServiceImpl;
|
||||||
import com.axelor.apps.hr.service.lunch.voucher.LunchVoucherMgtLineService;
|
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(PartnerAccountRepository.class).to(PartnerHRRepository.class);
|
||||||
bind(BankOrderMergeServiceImpl.class).to(BankOrderMergeHRServiceImpl.class);
|
bind(BankOrderMergeServiceImpl.class).to(BankOrderMergeHRServiceImpl.class);
|
||||||
bind(TimesheetReportService.class).to(TimesheetReportServiceImpl.class);
|
bind(TimesheetReportService.class).to(TimesheetReportServiceImpl.class);
|
||||||
|
bind(DailyReportService.class).to(DailyReportServiceImpl.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,13 @@ public interface AbsenceService {
|
|||||||
void attachTheAbsenceWithDailyReport(Absence absence, List<DailyReport> dailyreports);
|
void attachTheAbsenceWithDailyReport(Absence absence, List<DailyReport> dailyreports);
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
void deAttachTheAbsenceWithDailyReport(Absence absence, List<DailyReport> dailyreports);
|
void deAttachTheAbsenceWithDailyReport(Absence absence, List<DailyReport> dailyreports, Boolean archive);
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
void chooseAbsenceType(Absence absence, String selectedType);
|
void chooseAbsenceType(Absence absence, Integer selectedType);
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
BigDecimal calculateTotalAbsenceHours(LocalDateTime absenceStartDate, LocalDateTime absenceEndDate);
|
BigDecimal calculateTotalAbsenceHours(LocalDateTime absenceStartDate, LocalDateTime absenceEndDate);
|
||||||
|
|
||||||
|
BigDecimal calculateTotalAbsenceMinutes(LocalDateTime absenceStartDate, LocalDateTime absenceEndDate);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import java.math.BigDecimal;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
public class AbsenceServiceImpl implements AbsenceService {
|
public class AbsenceServiceImpl implements AbsenceService {
|
||||||
|
|
||||||
@@ -41,27 +43,29 @@ public class AbsenceServiceImpl implements AbsenceService {
|
|||||||
Absence absence, List<DailyReport> dailyreports) {
|
Absence absence, List<DailyReport> dailyreports) {
|
||||||
// Iterate over each DailyReport in the list
|
// Iterate over each DailyReport in the list
|
||||||
for (DailyReport dailyreport : dailyreports) {
|
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);
|
dailyReportRepository.save(dailyreport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void deAttachTheAbsenceWithDailyReport(Absence absence, List<DailyReport> dailyreports) {
|
public void deAttachTheAbsenceWithDailyReport(Absence absence, List<DailyReport> dailyreports, Boolean archive) {
|
||||||
if(dailyreports != null){
|
if(dailyreports != null){
|
||||||
// Iterate over each DailyReport in the list
|
// Iterate over each DailyReport in the list
|
||||||
for (DailyReport dailyreport : dailyreports) {
|
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);
|
dailyReportRepository.save(dailyreport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
absence.setArchived(true);
|
if (archive) {
|
||||||
absenceRepository.save(absence);
|
absence.setArchived(true);
|
||||||
|
absenceRepository.save(absence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void chooseAbsenceType(Absence absence, String selectedType) {
|
public void chooseAbsenceType(Absence absence, Integer selectedType) {
|
||||||
// Set the selected absence type to the absence entity
|
// Set the selected absence type to the absence entity
|
||||||
// Assuming you have a field named 'typeAbsence' in the Absence entity
|
// Assuming you have a field named 'typeAbsence' in the Absence entity
|
||||||
absence.setAbsenceType(selectedType);
|
absence.setAbsenceType(selectedType);
|
||||||
@@ -101,6 +105,17 @@ public class AbsenceServiceImpl implements AbsenceService {
|
|||||||
return totalAbsenceHours;
|
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) {
|
private boolean isSpecialOvertimeDay(LocalDate date) {
|
||||||
for (EventsPlanningLine line : eventsPlanningLines) {
|
for (EventsPlanningLine line : eventsPlanningLines) {
|
||||||
if (line.getDate().equals(date)) {
|
if (line.getDate().equals(date)) {
|
||||||
@@ -109,4 +124,28 @@ public class AbsenceServiceImpl implements AbsenceService {
|
|||||||
}
|
}
|
||||||
return false;
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,4 +14,7 @@ public interface AuthorizationService {
|
|||||||
|
|
||||||
@Transactional(rollbackOn = {Exception.class})
|
@Transactional(rollbackOn = {Exception.class})
|
||||||
public void saveBS(JSONObject jsonObject) throws AxelorException;
|
public void saveBS(JSONObject jsonObject) throws AxelorException;
|
||||||
|
|
||||||
|
@Transactional(rollbackOn = {Exception.class})
|
||||||
|
public void saveAP(JSONObject jsonObject) throws AxelorException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
|
|||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
if (dailyReport != null) {
|
if (dailyReport != null) {
|
||||||
dailyReport.setIsAuthorizedAbsence(true);
|
dailyReport.setIsAuthorizedLateArrival(true);
|
||||||
}
|
}
|
||||||
} else if (previousStatus == 2 && newStatus == 4) {
|
} else if (previousStatus == 2 && newStatus == 4) {
|
||||||
System.out.println("Tickets :" + idInt + " Status changed from " + previousStatus + " to " + newStatus);
|
System.out.println("Tickets :" + idInt + " Status changed from " + previousStatus + " to " + newStatus);
|
||||||
@@ -321,7 +321,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
|
|||||||
if (dailyReport != null) {
|
if (dailyReport != null) {
|
||||||
authorization.setDailyReport(dailyReport);
|
authorization.setDailyReport(dailyReport);
|
||||||
if(validation_status == 3)
|
if(validation_status == 3)
|
||||||
dailyReport.setIsAuthorizedAbsence(true);
|
dailyReport.setIsAuthorizedLateArrival(true);
|
||||||
}
|
}
|
||||||
// Save the new Authorization
|
// Save the new Authorization
|
||||||
authorizationRepository.save(authorization);
|
authorizationRepository.save(authorization);
|
||||||
@@ -338,6 +338,156 @@ public class AuthorizationServiceImpl implements AuthorizationService {
|
|||||||
@Transactional(rollbackOn = {Exception.class})
|
@Transactional(rollbackOn = {Exception.class})
|
||||||
public void saveBS(JSONObject jsonObject) throws AxelorException {
|
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 {
|
try {
|
||||||
// Extract fields
|
// Extract fields
|
||||||
int idInt = jsonObject.getInt("id");
|
int idInt = jsonObject.getInt("id");
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package com.axelor.apps.hr.service;
|
|||||||
|
|
||||||
import com.axelor.apps.hr.db.DailyReport;
|
import com.axelor.apps.hr.db.DailyReport;
|
||||||
import com.google.inject.persist.Transactional;
|
import com.google.inject.persist.Transactional;
|
||||||
|
import com.axelor.exception.AxelorException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface DailyReportService {
|
public interface DailyReportService {
|
||||||
|
|
||||||
@@ -10,4 +13,10 @@ public interface DailyReportService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
void determineShift(DailyReport DailyReport);
|
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<DailyReport> DailyReportList, Integer primeSelection, BigDecimal valueToDeduce) throws AxelorException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.OffDayWorkRepository;
|
||||||
import com.axelor.apps.hr.db.repo.DailyReportRepository;
|
import com.axelor.apps.hr.db.repo.DailyReportRepository;
|
||||||
import com.axelor.apps.hr.db.repo.ShiftRepository;
|
import com.axelor.apps.hr.db.repo.ShiftRepository;
|
||||||
|
import com.axelor.apps.hr.service.AbsenceServiceImpl;
|
||||||
import com.axelor.inject.Beans;
|
import com.axelor.inject.Beans;
|
||||||
import com.google.inject.persist.Transactional;
|
import com.google.inject.persist.Transactional;
|
||||||
|
import com.axelor.exception.AxelorException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.time.DayOfWeek;
|
import java.time.DayOfWeek;
|
||||||
@@ -26,6 +28,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.Year;
|
import java.time.Year;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
public class DailyReportServiceImpl implements DailyReportService {
|
public class DailyReportServiceImpl implements DailyReportService {
|
||||||
@@ -85,14 +88,14 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
LocalDate reportDate = dailyReport.getReportDate();
|
LocalDate reportDate = dailyReport.getReportDate();
|
||||||
Integer shift = dailyReport.getShift().getShift();
|
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){
|
if(shift != null){
|
||||||
System.out.println("rapporurnalier: ????????????????"+ dailyReport.getId());
|
|
||||||
shiftStartHour = dailyReport.getShift().getStartHour();
|
shiftStartHour = dailyReport.getShift().getStartHour();
|
||||||
shiftEndHour = dailyReport.getShift().getEndHour();
|
shiftEndHour = dailyReport.getShift().getEndHour();
|
||||||
System.out.println("Shift: "+ shift);
|
shiftStartPauseHour = dailyReport.getShift().getStartPause();
|
||||||
System.out.println("shiftStartHour: "+ shiftStartHour);
|
shiftEndPauseHour = dailyReport.getShift().getEndPause();
|
||||||
System.out.println("shiftENDHour: "+ shiftEndHour);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enters[0] != null && quits[0] != null) {
|
if (enters[0] != null && quits[0] != null) {
|
||||||
@@ -100,9 +103,9 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
Duration totalDuration = Duration.ZERO;
|
Duration totalDuration = Duration.ZERO;
|
||||||
Duration totalSupDuration = Duration.ZERO;
|
Duration totalSupDuration = Duration.ZERO;
|
||||||
Duration nightDuration = Duration.ZERO;
|
Duration nightDuration = Duration.ZERO;
|
||||||
Duration pauseDuration = Duration.ZERO;
|
Duration breakDuration = Duration.ZERO;
|
||||||
LocalDateTime firstEnter = enters[0];
|
firstEnter = enters[0];
|
||||||
LocalDateTime lastQuit = quits[0];
|
lastQuit = quits[0];
|
||||||
|
|
||||||
for (int i = 0; i < enters.length; i++) {
|
for (int i = 0; i < enters.length; i++) {
|
||||||
if (enters[i] != null && quits[i] != null) {
|
if (enters[i] != null && quits[i] != null) {
|
||||||
@@ -114,6 +117,7 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
dailyReport.setLastQuit(lastQuit);
|
dailyReport.setLastQuit(lastQuit);
|
||||||
LocalTime firstEnterTime = firstEnter.toLocalTime();
|
LocalTime firstEnterTime = firstEnter.toLocalTime();
|
||||||
LocalTime lastQuitTime = lastQuit.toLocalTime();
|
LocalTime lastQuitTime = lastQuit.toLocalTime();
|
||||||
|
|
||||||
// Calculate late arrival if firstEnter is later than shift start
|
// Calculate late arrival if firstEnter is later than shift start
|
||||||
if(shiftStartHour != null){
|
if(shiftStartHour != null){
|
||||||
if (firstEnterTime.isAfter(shiftStartHour)) {
|
if (firstEnterTime.isAfter(shiftStartHour)) {
|
||||||
@@ -136,19 +140,24 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
totalDuration = totalDuration.plus(Duration.between(firstEnter, lastQuit));
|
totalDuration = totalDuration.plus(Duration.between(firstEnter, lastQuit));
|
||||||
long totalMinutes = totalDuration.toMinutes();
|
long totalMinutes = totalDuration.toMinutes();
|
||||||
BigDecimal totalHours = BigDecimal.valueOf(totalMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
BigDecimal totalHours = BigDecimal.valueOf(totalMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
||||||
dailyReport.setWorkHours(customRound(totalHours));
|
dailyReport.setWorkHours(totalHours);
|
||||||
|
|
||||||
// Calculate night hours
|
// Calculate night hours
|
||||||
nightDuration = calculateNightDuration(firstEnter, lastQuit);
|
nightDuration = calculateNightDuration(firstEnter, lastQuit);
|
||||||
long totalNightMinutes = nightDuration.toMinutes();
|
long totalNightMinutes = nightDuration.toMinutes();
|
||||||
BigDecimal totalNightHours = BigDecimal.valueOf(totalNightMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
BigDecimal totalNightHours = BigDecimal.valueOf(totalNightMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
||||||
dailyReport.setNightHours(customRound(totalNightHours));
|
dailyReport.setNightHours(totalNightHours);
|
||||||
|
|
||||||
// Pause Hours
|
// Break Hours
|
||||||
pauseDuration = calculatePauseDuration(enters, quits, employee);
|
breakDuration = calculateBreakDuration(enters, quits);
|
||||||
long pauseMinutes = pauseDuration.toMinutes();
|
long breakMinutes = breakDuration.toMinutes();
|
||||||
BigDecimal pauseHours = BigDecimal.valueOf(pauseMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
BigDecimal breakHours = BigDecimal.valueOf(breakMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
||||||
dailyReport.setBreakHours(customRound(pauseHours));
|
dailyReport.setBreakHours(breakHours);
|
||||||
|
|
||||||
|
if(shiftStartPauseHour != null && shiftEndPauseHour != null){
|
||||||
|
boolean allInAllowedRange = areBreaksInAllowedRange(enters, quits, shiftStartPauseHour, shiftEndPauseHour);
|
||||||
|
dailyReport.setBreakNotInTheAllowedRange(allInAllowedRange);
|
||||||
|
}
|
||||||
|
|
||||||
// shift 2
|
// shift 2
|
||||||
if (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.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dailyReport.setExtraHours100(customRound(extraHours100));
|
dailyReport.setExtraHours100(extraHours100);
|
||||||
dailyReport.setExtraHours50(customRound(extraHours50));
|
dailyReport.setExtraHours50(extraHours50);
|
||||||
|
|
||||||
// other shifts
|
// other shifts
|
||||||
} else {
|
} else {
|
||||||
@@ -216,11 +225,11 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
if (firstEnter.getDayOfWeek() == DayOfWeek.SATURDAY) {
|
if (firstEnter.getDayOfWeek() == DayOfWeek.SATURDAY) {
|
||||||
|
|
||||||
if(shift == 0 || shift == 3){
|
if(shift == 0 || shift == 3){
|
||||||
dailyReport.setExtraHours50(customRound(totalHours).subtract(customRound(totalNightHours)));
|
dailyReport.setExtraHours50(totalHours.subtract(totalNightHours));
|
||||||
dailyReport.setExtraHours100(customRound(totalNightHours));
|
dailyReport.setExtraHours100(totalNightHours);
|
||||||
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
} else {
|
} else {
|
||||||
dailyReport.setExtraHours50(customRound(totalHours));
|
dailyReport.setExtraHours50(totalHours);
|
||||||
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,18 +238,18 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
// Add recup
|
// Add recup
|
||||||
if (totalHours.compareTo(BigDecimal.valueOf(6)) >= 0)
|
if (totalHours.compareTo(BigDecimal.valueOf(6)) >= 0)
|
||||||
createOffDayWork(reportDate, employee);
|
createOffDayWork(reportDate, employee);
|
||||||
dailyReport.setExtraHours100(customRound(totalHours));
|
dailyReport.setExtraHours100(totalHours);
|
||||||
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
dailyReport.setAllowanceRecall(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if(shift == 0 || shift == 3){
|
if(shift == 0 || shift == 3){
|
||||||
dailyReport.setExtraHours50(customRound(totalSupHours).subtract(customRound(totalNightHours)));
|
dailyReport.setExtraHours50(totalSupHours.subtract(totalNightHours));
|
||||||
dailyReport.setExtraHours100(customRound(totalNightHours));
|
dailyReport.setExtraHours100(totalNightHours);
|
||||||
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
dailyReport.setAllowanceRecall(totalSupHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
dailyReport.setAllowanceRecall(totalSupHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
} else {
|
} else {
|
||||||
dailyReport.setExtraHours50(customRound(totalSupHours));
|
dailyReport.setExtraHours50(totalSupHours);
|
||||||
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
dailyReport.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
dailyReport.setAllowanceRecall(totalSupHours.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
|
// Calculate ITP
|
||||||
dailyReport.setItp(customRound(calculateItp(totalHours, shift,dailyReport.getHasItp())));
|
dailyReport.setItp(calculateItp(totalHours, shift,dailyReport.getHasItp()));
|
||||||
dailyReport.setIsCalculated(true);
|
dailyReport.setIsCalculated(true);
|
||||||
|
|
||||||
} else if (enters[0] != null && quits[0] == null) {
|
} else if (enters[0] != null && quits[0] == null) {
|
||||||
// When the employee registers attendance only once
|
// When the employee registers attendance only once
|
||||||
dailyReport.setWorkHours(BigDecimal.valueOf(8));
|
if(shift!=2){
|
||||||
dailyReport.setAbsenceHours(BigDecimal.valueOf(0));
|
dailyReport.setWorkHours(BigDecimal.valueOf(8));
|
||||||
dailyReport.setIsCalculated(true);
|
dailyReport.setAbsenceHours(BigDecimal.valueOf(0));
|
||||||
|
dailyReport.setIsCalculated(true);
|
||||||
|
}
|
||||||
} else if (enters.length != quits.length) {
|
} else if (enters.length != quits.length) {
|
||||||
|
|
||||||
Duration totalDuration = Duration.ZERO;
|
Duration totalDuration = Duration.ZERO;
|
||||||
LocalDateTime firstEnter = enters[0];
|
firstEnter = enters[0];
|
||||||
LocalDateTime lastQuit = quits[quits.length - 1];
|
lastQuit = quits[quits.length - 1];
|
||||||
totalDuration = totalDuration.plus(Duration.between(firstEnter, lastQuit));
|
totalDuration = totalDuration.plus(Duration.between(firstEnter, lastQuit));
|
||||||
long totalMinutes = totalDuration.toMinutes();
|
long totalMinutes = totalDuration.toMinutes();
|
||||||
BigDecimal totalHours = BigDecimal.valueOf(totalMinutes).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
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.setAllowance(totalHours.compareTo(BigDecimal.valueOf(5)) >= 0 ? 1 : 0);
|
||||||
|
|
||||||
dailyReport.setLastQuit(lastQuit);
|
dailyReport.setLastQuit(lastQuit);
|
||||||
@@ -288,6 +299,18 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
System.err.println("Warning: Employee doesn't exist.");
|
System.err.println("Warning: Employee doesn't exist.");
|
||||||
dailyReport.setIsCalculated(true);
|
dailyReport.setIsCalculated(true);
|
||||||
} else {
|
} 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.");
|
System.err.println("Warning: no attendances for this day.");
|
||||||
dailyReport.setIsCalculated(true);
|
dailyReport.setIsCalculated(true);
|
||||||
}
|
}
|
||||||
@@ -296,7 +319,7 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
if (dailyReport.getAbsence() == null) {
|
if (dailyReport.getAbsence() == null) {
|
||||||
Absence absence = Beans.get(AbsenceRepository.class)
|
Absence absence = Beans.get(AbsenceRepository.class)
|
||||||
.all()
|
.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("employee", employee)
|
||||||
.bind("reportDate",reportDate) // Changed from absenceStartDate and absenceEndDate to reportDate
|
.bind("reportDate",reportDate) // Changed from absenceStartDate and absenceEndDate to reportDate
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
@@ -307,17 +330,34 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Authorization
|
// Authorization
|
||||||
if(dailyReport.getAuthorizationList() == null){
|
if (dailyReport.getAuthorizationList() == null) {
|
||||||
Authorization authorization = Beans.get(AuthorizationRepository.class)
|
List<Authorization> authorizations = Beans.get(AuthorizationRepository.class)
|
||||||
.all()
|
.all()
|
||||||
.filter("self.employee = :employee and self.requisitionDate = :reportDate")
|
.filter("self.employee = :employee and self.requisitionDate = :reportDate")
|
||||||
.bind("employee",employee)
|
.bind("employee", employee)
|
||||||
.bind("reportDate",reportDate)
|
.bind("reportDate", reportDate)
|
||||||
.fetchOne();
|
.fetch();
|
||||||
if (authorization != null) {
|
|
||||||
authorization.setDailyReport(dailyReport);
|
if (authorizations != null) {
|
||||||
if(authorization.getStatusSelect() == 3)
|
List<Authorization> authorizationList = new ArrayList<>(); // Create a new list for authorizations
|
||||||
dailyReport.setIsAuthorizedAbsence(true);
|
|
||||||
|
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
|
// Absence Hours
|
||||||
if (!(dailyReport.getIsWeekend() || dailyReport.getIsFerieDay()) && dailyReport.getWorkHours().compareTo(BigDecimal.valueOf(8)) < 0) {
|
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 {
|
} else {
|
||||||
dailyReport.setAbsenceHours(BigDecimal.ZERO);
|
dailyReport.setAbsenceHours(BigDecimal.ZERO);
|
||||||
}
|
}
|
||||||
@@ -449,24 +538,40 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
return supDuration;
|
return supDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Duration calculatePauseDuration(
|
private Duration calculateBreakDuration(LocalDateTime[] enters, LocalDateTime[] quits) {
|
||||||
LocalDateTime[] enters, LocalDateTime[] quits, Employee employee) {
|
|
||||||
|
|
||||||
Duration pauseDuration = Duration.ZERO;
|
Duration breakDuration = Duration.ZERO;
|
||||||
for (int i = 1; i < quits.length; i++) {
|
for (int i = 1; i < quits.length; i++) {
|
||||||
if (enters[i] != null && quits[i - 1] != null) {
|
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) {
|
private BigDecimal calculateItp(BigDecimal totalHours, Integer shift, Boolean hasItp) {
|
||||||
// Shift 0 (no itp)
|
// Shift 0 (no itp)
|
||||||
if (hasItp == false)
|
if (hasItp == true && shift != 0)
|
||||||
return BigDecimal.ZERO;
|
|
||||||
else
|
|
||||||
return totalHours.min(BigDecimal.valueOf(8));
|
return totalHours.min(BigDecimal.valueOf(8));
|
||||||
|
else
|
||||||
|
return BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOffDayWork(LocalDate reportDate, Employee employee) {
|
private void createOffDayWork(LocalDate reportDate, Employee employee) {
|
||||||
@@ -545,4 +650,36 @@ public class DailyReportServiceImpl implements DailyReportService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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<DailyReport> dailyReportList, Integer primeSelection, BigDecimal valueToDeduce) throws AxelorException {
|
||||||
|
for (DailyReport dailyReport : dailyReportList) {
|
||||||
|
this.deducePrimes(dailyReport, primeSelection, valueToDeduce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.axelor.apps.base.db.Period;
|
|||||||
import com.axelor.apps.hr.db.Absence;
|
import com.axelor.apps.hr.db.Absence;
|
||||||
import com.axelor.apps.hr.db.Employee;
|
import com.axelor.apps.hr.db.Employee;
|
||||||
import com.axelor.apps.hr.db.DailyReport;
|
import com.axelor.apps.hr.db.DailyReport;
|
||||||
|
import com.axelor.apps.hr.db.MonthlyReport;
|
||||||
import com.google.inject.persist.Transactional;
|
import com.google.inject.persist.Transactional;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -11,13 +12,9 @@ import java.util.List;
|
|||||||
public interface MonthlyReportService {
|
public interface MonthlyReportService {
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
void createMensuelReport(
|
void createMensuelReport(Employee employee, Period period, LocalDate startDate, LocalDate endDate, List<DailyReport> employeeDailyReports, List<Absence> employeeAbsences);
|
||||||
Employee employee,
|
|
||||||
Period period,
|
void updateMensuelReport(MonthlyReport monthlyReport, Employee employee, Period period, LocalDate startDate, LocalDate endDate, List<DailyReport> employeeDailyReports, List<Absence> employeeAbsences);
|
||||||
LocalDate startDate,
|
|
||||||
LocalDate endDate,
|
|
||||||
List<DailyReport> employeeDailyReports,
|
|
||||||
List<Absence> employeeAbsences);
|
|
||||||
|
|
||||||
/*void calculePrimeAssiduite(Mensuels mensuels);*/
|
/*void calculePrimeAssiduite(Mensuels mensuels);*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.math.BigDecimal;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.TemporalAdjusters;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import com.axelor.inject.Beans;
|
import com.axelor.inject.Beans;
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public void createMensuelReport(Employee employee, Period period, LocalDate startDate, LocalDate endDate, List<DailyReport> employeeDailyReports, List<Absence> employeeAbsences) {
|
public void createMensuelReport(Employee employee, Period period, LocalDate startDate, LocalDate endDate, List<DailyReport> employeeDailyReports, List<Absence> employeeAbsences) {
|
||||||
|
|
||||||
Boolean hasNuissance = employee.getHasNuissance();
|
Boolean hasNuissance = employee.getHasNuissance();
|
||||||
@@ -97,19 +99,31 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
|
|||||||
monthlyNightHours = monthlyNightHours.add(dailyReport.getNightHours());
|
monthlyNightHours = monthlyNightHours.add(dailyReport.getNightHours());
|
||||||
totalWorkHours = totalWorkHours.add(dailyReport.getWorkHours());
|
totalWorkHours = totalWorkHours.add(dailyReport.getWorkHours());
|
||||||
|
|
||||||
BigDecimal heureSup50 = dailyReport.getExtraHours50();
|
BigDecimal heureSup50 = dailyReport.getExtraHours50() != null ? dailyReport.getExtraHours50() : BigDecimal.ZERO;
|
||||||
BigDecimal heureSup100 = dailyReport.getExtraHours100();
|
BigDecimal heureSup100 = dailyReport.getExtraHours100() != null ? dailyReport.getExtraHours100() : BigDecimal.ZERO;
|
||||||
BigDecimal itp = dailyReport.getItp();
|
BigDecimal itp = dailyReport.getItp() != null ? dailyReport.getItp() : BigDecimal.ZERO;
|
||||||
BigDecimal nuissance = dailyReport.getNuissance();
|
BigDecimal nuissance = dailyReport.getNuissance() != null ? dailyReport.getNuissance() : BigDecimal.ZERO;
|
||||||
|
|
||||||
if(dailyReport.getDeduceSupHours50())
|
BigDecimal supHours50ToDeduce = dailyReport.getSupHours50ToDeduce() != null ? dailyReport.getSupHours50ToDeduce() : BigDecimal.ZERO;
|
||||||
heureSup50 = heureSup50.subtract(dailyReport.getSupHours50ToDeduce());
|
BigDecimal supHours100ToDeduce = dailyReport.getSupHours100ToDeduce() != null ? dailyReport.getSupHours100ToDeduce() : BigDecimal.ZERO;
|
||||||
if(dailyReport.getDeduceSupHours100())
|
BigDecimal itpToDeduce = dailyReport.getItpToDeduce() != null ? dailyReport.getItpToDeduce() : BigDecimal.ZERO;
|
||||||
heureSup100 = heureSup100.subtract(dailyReport.getSupHours100ToDeduce());
|
BigDecimal nuissanceToDeduce = dailyReport.getNuissanceToDeduce() != null ? dailyReport.getNuissanceToDeduce() : BigDecimal.ZERO;
|
||||||
if(dailyReport.getDeduceItp())
|
|
||||||
itp = itp.subtract(dailyReport.getItpToDeduce());
|
if (dailyReport.getDeduceSupHours50() && heureSup50.compareTo(supHours50ToDeduce) > 0) {
|
||||||
if(dailyReport.getDeduceNuissance())
|
heureSup50 = heureSup50.subtract(supHours50ToDeduce);
|
||||||
nuissance = nuissance.subtract(dailyReport.getNuissanceToDeduce());
|
}
|
||||||
|
|
||||||
|
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);
|
monthlyITP = monthlyITP.add(itp);
|
||||||
totalNuissance = totalNuissance.add(nuissance);
|
totalNuissance = totalNuissance.add(nuissance);
|
||||||
@@ -158,81 +172,109 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Boolean isAuthorizedAbsence = dailyReport.getIsAuthorizedAbsence();
|
Boolean isAuthorizedAbsence = dailyReport.getIsAuthorizedAbsence();
|
||||||
|
Boolean isAuthorizedLateArrival = dailyReport.getIsAuthorizedLateArrival();
|
||||||
|
Boolean isAuthorizedEarlyDeparture = dailyReport.getIsAuthorizedEarlyDeparture();
|
||||||
LeaveRequest leaveRequest = dailyReport.getLeaveRequest();
|
LeaveRequest leaveRequest = dailyReport.getLeaveRequest();
|
||||||
Absence absence = dailyReport.getAbsence();
|
Set<Absence> absences = dailyReport.getAbsenceSet();
|
||||||
|
|
||||||
if (isAuthorizedAbsence == false && leaveRequest == null && absence == null) {
|
if (dailyReport.getAbsenceHours() != null && dailyReport.getAbsenceHours().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getAbsenceHours());
|
if (isAuthorizedAbsence == false && isAuthorizedLateArrival == false && isAuthorizedEarlyDeparture == false && leaveRequest == null && absences == null) {
|
||||||
} else if(isAuthorizedAbsence){
|
irregularAbsenceMonth = irregularAbsenceMonth.add(dailyReport.getAbsenceHours());
|
||||||
justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getAbsenceHours());
|
} else if(isAuthorizedAbsence){
|
||||||
} else if(leaveRequest != null){
|
justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getAbsenceHours());
|
||||||
recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(dailyReport.getAbsenceHours());
|
} else if(isAuthorizedLateArrival){
|
||||||
} else if(absence != null){
|
justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getLateArrival());
|
||||||
totalAbsence = dailyReport.getAbsenceHours();
|
} else if(isAuthorizedEarlyDeparture){
|
||||||
switch (absence.getAbsenceType()) {
|
justifiedAbsenceMonth = justifiedAbsenceMonth.add(dailyReport.getEarlyDeparture());
|
||||||
case "Absence autorisé de payée":
|
} else if(leaveRequest != null){
|
||||||
breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
|
recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(dailyReport.getAbsenceHours());
|
||||||
break;
|
} else if(absences != null){
|
||||||
case "Absence allaitement":
|
for(Absence absence:absences){
|
||||||
breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
|
totalAbsence = dailyReport.getAbsenceHours();
|
||||||
break;
|
switch (absence.getAbsenceType()) {
|
||||||
case "Absence congé récupération":
|
case 0:
|
||||||
recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(totalAbsence);
|
breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence formation":
|
case 1:
|
||||||
trainingAbsenceMonth = trainingAbsenceMonth.add(totalAbsence);
|
recuperationLeaveAbsenceMonth = recuperationLeaveAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence mission":
|
case 2:
|
||||||
missionAbsenceMonth = missionAbsenceMonth.add(totalAbsence);
|
breastfeedingAbsenceMonth = breastfeedingAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence hospitalisation":
|
case 3:
|
||||||
hospitalizationAbsenceMonth = hospitalizationAbsenceMonth.add(totalAbsence);
|
trainingAbsenceMonth = trainingAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence maladie":
|
case 4:
|
||||||
sicknessAbsenceMonth = sicknessAbsenceMonth.add(totalAbsence);
|
missionAbsenceMonth = missionAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Accident de travail":
|
case 5:
|
||||||
workAccidentMonth = workAccidentMonth.add(totalAbsence);
|
hospitalizationAbsenceMonth = hospitalizationAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Maternité":
|
case 6:
|
||||||
maternityMonth = maternityMonth.add(totalAbsence);
|
sicknessAbsenceMonth = sicknessAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence autorisée non payée":
|
case 7:
|
||||||
authorizedUnpaidAbsenceMonth = authorizedUnpaidAbsenceMonth.add(totalAbsence);
|
workAccidentMonth = workAccidentMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence conge annuel":
|
case 8:
|
||||||
annualLeaveAbsenceMonth = annualLeaveAbsenceMonth.add(totalAbsence);
|
maternityMonth = maternityMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence conge sans solde":
|
case 9:
|
||||||
unpaidLeaveAbsenceMonth = unpaidLeaveAbsenceMonth.add(totalAbsence);
|
authorizedUnpaidAbsenceMonth = authorizedUnpaidAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence conge statutaire":
|
case 10:
|
||||||
statutoryLeaveAbsenceMonth = statutoryLeaveAbsenceMonth.add(totalAbsence);
|
annualLeaveAbsenceMonth = annualLeaveAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence démission":
|
case 11:
|
||||||
resignationAbsenceMonth = resignationAbsenceMonth.add(totalAbsence);
|
unpaidLeaveAbsenceMonth = unpaidLeaveAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence fin de contrat":
|
case 12:
|
||||||
contractEndAbsenceMonth = contractEndAbsenceMonth.add(totalAbsence);
|
statutoryLeaveAbsenceMonth = statutoryLeaveAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence justifieé":
|
case 13:
|
||||||
justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
|
resignationAbsenceMonth = resignationAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence recrutement":
|
case 14:
|
||||||
recruitmentAbsenceMonth = recruitmentAbsenceMonth.add(totalAbsence);
|
contractEndAbsenceMonth = contractEndAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Suspension":
|
case 15:
|
||||||
suspensionAbsenceMonth = suspensionAbsenceMonth.add(totalAbsence);
|
justifiedAbsenceMonth = justifiedAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence irrégulière":
|
case 16:
|
||||||
irregularAbsenceMonth = irregularAbsenceMonth.add(totalAbsence);
|
recruitmentAbsenceMonth = recruitmentAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
case "Absence service militaire":
|
case 17:
|
||||||
militaryServiceAbsence = militaryServiceAbsence.add(totalAbsence);
|
suspensionAbsenceMonth = suspensionAbsenceMonth.add(totalAbsence);
|
||||||
break;
|
break;
|
||||||
default:
|
case 18:
|
||||||
// Handle default case
|
militaryServiceAbsence = militaryServiceAbsence.add(totalAbsence);
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,6 +320,284 @@ public class MonthlyReportServiceImpl implements MonthlyReportService {
|
|||||||
// Save the MonthlyReport instance
|
// Save the MonthlyReport instance
|
||||||
monthlyReportRepository.save(monthlyReport);
|
monthlyReportRepository.save(monthlyReport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateMensuelReport(MonthlyReport monthlyReport, Employee employee, Period period, LocalDate startDate, LocalDate endDate, List<DailyReport> employeeDailyReports, List<Absence> 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<Absence> 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
|
@Transactional
|
||||||
public void calculePrimeAssiduite(MonthlyReport monthlyReport) {
|
public void calculePrimeAssiduite(MonthlyReport monthlyReport) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.google.inject.persist.Transactional;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface EmployeeService extends UserService {
|
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. */
|
/** Generates a new {@link DPAE} for given {@link Employee} and returns its id. */
|
||||||
@Transactional(rollbackOn = {Exception.class})
|
@Transactional(rollbackOn = {Exception.class})
|
||||||
Long generateNewDPAE(Employee employee) throws AxelorException;
|
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<Long> employeesIds, Integer configSelect, Boolean status) throws AxelorException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,4 +250,47 @@ public class EmployeeServiceImpl extends UserServiceImpl implements EmployeeServ
|
|||||||
Beans.get(EmployeeRepository.class).save(employee);
|
Beans.get(EmployeeRepository.class).save(employee);
|
||||||
return newDPAE.getId();
|
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<Long> employeesIds, Integer configSelect, Boolean status) throws AxelorException{
|
||||||
|
List<Employee> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.List;
|
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 {
|
public class AbsenceController {
|
||||||
|
|
||||||
@@ -27,22 +31,43 @@ public class AbsenceController {
|
|||||||
LocalDate absenceEndDate = absence.getEndDate().toLocalDate();
|
LocalDate absenceEndDate = absence.getEndDate().toLocalDate();
|
||||||
Employee employee = absence.getEmployee();
|
Employee employee = absence.getEmployee();
|
||||||
|
|
||||||
List<DailyReport> dailyreports =
|
// Fetch all existing daily reports associated with this absence
|
||||||
Beans.get(DailyReportRepository.class)
|
List<DailyReport> existingReports =
|
||||||
.all()
|
Beans.get(DailyReportRepository.class)
|
||||||
.filter(
|
.all()
|
||||||
"self.employee = :employee and self.reportDate between :absenceStartDate and :absenceEndDate")
|
.filter("self.absenceSet = :absence")
|
||||||
.bind("employee", employee)
|
.bind("absence", absence)
|
||||||
.bind("absenceStartDate", absenceStartDate)
|
.fetch();
|
||||||
.bind("absenceEndDate", absenceEndDate)
|
|
||||||
.fetch();
|
if (existingReports != null && !existingReports.isEmpty()) {
|
||||||
|
// Detach absence only from reports that are outside the new date range
|
||||||
|
List<DailyReport> 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<DailyReport> 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
|
// Check if there are any reports
|
||||||
if (dailyreports.isEmpty()) {
|
if (newReports.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Beans.get(AbsenceServiceImpl.class).attachTheAbsenceWithDailyReport(absence, dailyreports);
|
Beans.get(AbsenceServiceImpl.class).attachTheAbsenceWithDailyReport(absence, newReports);
|
||||||
response.setReload(true);
|
response.setReload(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -52,7 +77,7 @@ public class AbsenceController {
|
|||||||
public void chooseAbsenceType(ActionRequest request, ActionResponse response) {
|
public void chooseAbsenceType(ActionRequest request, ActionResponse response) {
|
||||||
try {
|
try {
|
||||||
// Get the selected absence type from the request parameters
|
// 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
|
// Get the list of selected absence IDs
|
||||||
List<Long> absenceIds = (List<Long>) request.getContext().get("_ids");
|
List<Long> absenceIds = (List<Long>) request.getContext().get("_ids");
|
||||||
@@ -89,7 +114,14 @@ public class AbsenceController {
|
|||||||
.bind("absence", absenceId)
|
.bind("absence", absenceId)
|
||||||
.fetch();
|
.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) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
public String fetchAA(String accessToken) {
|
||||||
String endpoint = BASE_URL + "tickets/aa/";
|
String endpoint = BASE_URL + "tickets/aa/";
|
||||||
HttpURLConnection conn = null;
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,28 @@
|
|||||||
package com.axelor.apps.hr.web;
|
package com.axelor.apps.hr.web;
|
||||||
|
|
||||||
import com.axelor.apps.hr.db.Shift;
|
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.DailyReport;
|
||||||
import com.axelor.apps.hr.db.repo.DailyReportRepository;
|
import com.axelor.apps.hr.db.repo.DailyReportRepository;
|
||||||
import com.axelor.apps.hr.db.repo.ShiftRepository;
|
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.apps.hr.service.DailyReportServiceImpl;
|
||||||
import com.axelor.inject.Beans;
|
import com.axelor.inject.Beans;
|
||||||
import com.axelor.rpc.ActionRequest;
|
import com.axelor.rpc.ActionRequest;
|
||||||
import com.axelor.rpc.ActionResponse;
|
import com.axelor.rpc.ActionResponse;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.axelor.exception.service.TraceBackService;
|
||||||
|
|
||||||
public class DailyReportController {
|
public class DailyReportController {
|
||||||
|
|
||||||
@@ -115,4 +124,112 @@ public class DailyReportController {
|
|||||||
response.setReload(true);
|
response.setReload(true);
|
||||||
response.setFlash("Working hours calculated successfully.");
|
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<Employee> employees = new ArrayList<>();
|
||||||
|
|
||||||
|
if (employeesObject instanceof List) {
|
||||||
|
List<LinkedHashMap<String, Object>> employeesList = (List<LinkedHashMap<String, Object>>) employeesObject;
|
||||||
|
|
||||||
|
for (LinkedHashMap<String, Object> 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<Integer> employeeIds = new ArrayList<>();
|
||||||
|
for (Employee employee : employees) {
|
||||||
|
employeeIds.add(employee.getId().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch all rapport journaliers within the date range for all employees
|
||||||
|
List<DailyReport> 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import com.axelor.rpc.ActionResponse;
|
|||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import wslite.json.JSONException;
|
import wslite.json.JSONException;
|
||||||
@@ -47,11 +48,13 @@ import wslite.json.JSONObject;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import com.axelor.app.AppSettings;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class EmployeeController {
|
public class EmployeeController {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
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)
|
public void showAnnualReport(ActionRequest request, ActionResponse response)
|
||||||
throws JSONException, NumberFormatException, AxelorException {
|
throws JSONException, NumberFormatException, AxelorException {
|
||||||
@@ -165,11 +168,17 @@ public class EmployeeController {
|
|||||||
String employeeRegistrationNumber = employee.getRegistrationNumber();
|
String employeeRegistrationNumber = employee.getRegistrationNumber();
|
||||||
String employeeName = employee.getContactPartner().getName();
|
String employeeName = employee.getContactPartner().getName();
|
||||||
|
|
||||||
|
if (pythonScriptDir == null || pythonScriptDir.isEmpty()) {
|
||||||
|
LOG.error("Pythons script path is not configured in AppSettings.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
||||||
String[] args = {
|
String[] args = {
|
||||||
"python",
|
"python",
|
||||||
"C:\\Users\\administrator\\Desktop\\attendance\\main.py",
|
pythonScriptDir + "\\Attendance\\main.py",
|
||||||
"--commande", "create",
|
"--commande", "create",
|
||||||
"--ip_address", ipAdress,
|
"--ip_address", ipAdress,
|
||||||
"--code", code,
|
"--code", code,
|
||||||
@@ -198,6 +207,7 @@ public class EmployeeController {
|
|||||||
// Check if the process ran successfully
|
// Check if the process ran successfully
|
||||||
if (exitCode == 0) {
|
if (exitCode == 0) {
|
||||||
LOG.info("Python script executed successfully (Employee Enrolling).");
|
LOG.info("Python script executed successfully (Employee Enrolling).");
|
||||||
|
Beans.get(EmployeeService.class).setEmployeeEnrolled(employee);
|
||||||
response.setFlash("Employee enrolled successfully.");
|
response.setFlash("Employee enrolled successfully.");
|
||||||
} else {
|
} else {
|
||||||
LOG.error("Python script execution (Employee Enrolling) failed with exit code: " + exitCode);
|
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<Long> employeeIds = (List<Long>) 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<Long> employeeIds = (List<Long>) 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,17 @@ import java.time.LocalDate;
|
|||||||
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.TemporalAdjusters;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class MonthlyReportController {
|
public class MonthlyReportController {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||||
|
|
||||||
public void createMensuelReport(ActionRequest request, ActionResponse response) {
|
public void createMensuelReport(ActionRequest request, ActionResponse response) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -68,32 +72,29 @@ public class MonthlyReportController {
|
|||||||
// Iterate over employees and calculate/update MonthlyReport instances
|
// Iterate over employees and calculate/update MonthlyReport instances
|
||||||
for (Employee employee : employees) {
|
for (Employee employee : employees) {
|
||||||
// Filter rapport journaliers for the current employee
|
// Filter rapport journaliers for the current employee
|
||||||
List<DailyReport> employeeDailyReports =
|
List<DailyReport> employeeDailyReports = allDailyReports
|
||||||
allDailyReports
|
.stream()
|
||||||
.stream()
|
.filter(r -> r.getEmployee().equals(employee))
|
||||||
.filter(r -> r.getEmployee().equals(employee))
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
// Filter absences for the current employee
|
// Filter absences for the current employee
|
||||||
List<Absence> employeeAbsences =
|
List<Absence> employeeAbsences = allAbsences
|
||||||
allAbsences
|
.stream()
|
||||||
.stream()
|
.filter(a -> a.getEmployee().equals(employee))
|
||||||
.filter(a -> a.getEmployee().equals(employee))
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
System.out.println("Employee: "+ employee.getRegistrationNumber());
|
|
||||||
|
|
||||||
if (!employeeDailyReports.isEmpty() || !employeeAbsences.isEmpty()) {
|
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
|
// Process the employee's monthly report using filtered rapport and absences
|
||||||
Beans.get(MonthlyReportServiceImpl.class)
|
Beans.get(MonthlyReportServiceImpl.class).createMensuelReport(
|
||||||
.createMensuelReport(
|
|
||||||
employee,
|
employee,
|
||||||
period,
|
period,
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
employeeDailyReports,
|
employeeDailyReports,
|
||||||
employeeAbsences);
|
employeeAbsences);
|
||||||
|
} else {
|
||||||
|
log.error("No Daily Reports exist for employee: "+ employee.getRegistrationNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Indicate that the action was successful and a reload is needed
|
// Indicate that the action was successful and a reload is needed
|
||||||
@@ -177,6 +178,44 @@ public class MonthlyReportController {
|
|||||||
.bind("employeesIds", employeesIds)
|
.bind("employeesIds", employeesIds)
|
||||||
.fetch();
|
.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<MonthlyReport> monthlyReportOpt = Optional.ofNullable(monthlyReport);
|
||||||
|
|
||||||
|
// Filter daily reports for the current employee
|
||||||
|
List<DailyReport> employeeDailyReports = allDailyReports.stream()
|
||||||
|
.filter(r -> r.getEmployee().equals(employee))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Filter absences for the current employee
|
||||||
|
List<Absence> 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
|
// Indicate that the action was successful and a reload is needed
|
||||||
response.setReload(true);
|
response.setReload(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -8,13 +8,15 @@
|
|||||||
|
|
||||||
<entity name="Absence">
|
<entity name="Absence">
|
||||||
<many-to-one name="employee" ref="com.axelor.apps.hr.db.Employee"/>
|
<many-to-one name="employee" ref="com.axelor.apps.hr.db.Employee"/>
|
||||||
<string name="absenceType" title="Type Absence" selection="hr.type.absence.selection"/>
|
<integer name="absenceType" title="Type Absence" selection="hr.type.absence.selection"/>
|
||||||
|
|
||||||
<datetime name="startDate" title="Date Début"/>
|
<datetime name="startDate" title="Date Début"/>
|
||||||
<datetime name="endDate" title="Date Fin"/>
|
<datetime name="endDate" title="Date Fin"/>
|
||||||
<decimal name="totalAbsenceHours" precision="20" scale="2"/>
|
<decimal name="totalAbsenceHours" precision="20" scale="2"/>
|
||||||
<one-to-many name="dailyReport" ref="com.axelor.apps.hr.db.DailyReport"/>
|
<one-to-many name="dailyReport" ref="com.axelor.apps.hr.db.DailyReport"/>
|
||||||
|
|
||||||
|
<many-to-many name="dailyReportSet" ref="com.axelor.apps.hr.db.DailyReport"/>
|
||||||
|
|
||||||
<string name="fullName" namecolumn="true">
|
<string name="fullName" namecolumn="true">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
String fullName = "";
|
String fullName = "";
|
||||||
@@ -30,14 +32,61 @@
|
|||||||
}
|
}
|
||||||
return fullName;
|
return fullName;
|
||||||
]]>
|
]]>
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
|
<extra-code><![CDATA[
|
||||||
|
|
||||||
|
// PERIOD ABSENCE TYPE
|
||||||
|
public static final int PERIOD_ABSENCE_TYPE_PARTIAL_DAY = 0;
|
||||||
|
public static final int PERIOD_ABSENCE_TYPE_FULL_DAY = 1;
|
||||||
|
public static final int PERIOD_ABSENCE_TYPE_MULTIPLE_DAYS = 2;
|
||||||
|
|
||||||
|
]]></extra-code>
|
||||||
|
|
||||||
|
<track>
|
||||||
|
<field name="employee"/>
|
||||||
|
<field name="absenceType"/>
|
||||||
|
<field name="startDate"/>
|
||||||
|
<field name="endDate"/>
|
||||||
|
</track>
|
||||||
|
|
||||||
|
<!--<string name="fullName" namecolumn="true">
|
||||||
|
<![CDATA[
|
||||||
|
String fullName = "";
|
||||||
|
if (employee != null && employee.getContactPartner() != null && employee.getContactPartner().getFullName() != null) {
|
||||||
|
fullName += employee.getContactPartner().getFullName();
|
||||||
|
}
|
||||||
|
if (absenceType != null) {
|
||||||
|
fullName += " - " + absenceType;
|
||||||
|
}
|
||||||
|
if (periodAbsenceType != null){
|
||||||
|
if(periodAbsenceType == 0){
|
||||||
|
if (startDate != null && endDate != null){
|
||||||
|
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("HH:mm");
|
||||||
|
fullName += " (from " + startDate.format(formatter) + " to " + endDate.format(formatter) + ")";
|
||||||
|
}
|
||||||
|
} else if(periodAbsenceType == 1){
|
||||||
|
if(startDate != null){
|
||||||
|
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy");
|
||||||
|
fullName += " - " + startDate.format(formatter);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (startDate != null && endDate != null){
|
||||||
|
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy");
|
||||||
|
fullName += " (from " + startDate.format(formatter) + " to " + endDate.format(formatter) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (startDate != null && endDate != null) {
|
||||||
|
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
|
||||||
|
fullName += " (from " + startDate.format(formatter) + " to " + endDate.format(formatter) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fullName;
|
||||||
|
]]>
|
||||||
|
</string> -->
|
||||||
|
|
||||||
</entity>
|
</entity>
|
||||||
|
|
||||||
<track>
|
|
||||||
<field name="employee"/>
|
|
||||||
<field name="absenceType"/>
|
|
||||||
<field name="startDate"/>
|
|
||||||
<field name="endDate"/>
|
|
||||||
</track>
|
|
||||||
|
|
||||||
</domain-models>
|
</domain-models>
|
||||||
@@ -38,6 +38,11 @@
|
|||||||
<decimal name="lateArrival" title ="Late arrival" precision="20" scale="2" />
|
<decimal name="lateArrival" title ="Late arrival" precision="20" scale="2" />
|
||||||
<decimal name="earlyDeparture" title ="Early departure" precision="20" scale="2" />
|
<decimal name="earlyDeparture" title ="Early departure" precision="20" scale="2" />
|
||||||
|
|
||||||
|
<boolean name="isAuthorizedAbsence" default="False"/>
|
||||||
|
<boolean name="isAuthorizedLateArrival" default="False"/>
|
||||||
|
<boolean name="isAuthorizedEarlyDeparture" default="False"/>
|
||||||
|
|
||||||
|
|
||||||
<decimal name="itp" precision="20" scale="2" />
|
<decimal name="itp" precision="20" scale="2" />
|
||||||
<decimal name="nuissance" precision="20" scale="2" />
|
<decimal name="nuissance" precision="20" scale="2" />
|
||||||
<integer name="allowance" precision="20" scale="2" /> <!-- Panier -->
|
<integer name="allowance" precision="20" scale="2" /> <!-- Panier -->
|
||||||
@@ -45,7 +50,6 @@
|
|||||||
|
|
||||||
<boolean name="isFerieDay" default="False"/>
|
<boolean name="isFerieDay" default="False"/>
|
||||||
<boolean name="isValidSupHours" default="False"/>
|
<boolean name="isValidSupHours" default="False"/>
|
||||||
<boolean name="isAuthorizedAbsence" default="False"/>
|
|
||||||
<boolean name="isCalculated" default="False"/>
|
<boolean name="isCalculated" default="False"/>
|
||||||
<boolean name="isTransfaire" title="Transfaire"/>
|
<boolean name="isTransfaire" title="Transfaire"/>
|
||||||
<boolean name="hasItp" title="Transfaire"/>
|
<boolean name="hasItp" title="Transfaire"/>
|
||||||
@@ -54,6 +58,8 @@
|
|||||||
<boolean name="isWeekend" default="False"/>
|
<boolean name="isWeekend" default="False"/>
|
||||||
<boolean name="isChanged" default="False"/>
|
<boolean name="isChanged" default="False"/>
|
||||||
<boolean name="isClosed" default="False"/>
|
<boolean name="isClosed" default="False"/>
|
||||||
|
<boolean name="breakNotInTheAllowedRange" default="False"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<boolean name="deduceSupHours50" default="False"/>
|
<boolean name="deduceSupHours50" default="False"/>
|
||||||
@@ -74,6 +80,8 @@
|
|||||||
<many-to-one name="absence" title="Absence" ref="com.axelor.apps.hr.db.Absence" mappedBy="dailyReport"/>
|
<many-to-one name="absence" title="Absence" ref="com.axelor.apps.hr.db.Absence" mappedBy="dailyReport"/>
|
||||||
<many-to-one name="monthlyReport" title="Monthly Report" ref="com.axelor.apps.hr.db.MonthlyReport" mappedBy="dailyReports"/>
|
<many-to-one name="monthlyReport" title="Monthly Report" ref="com.axelor.apps.hr.db.MonthlyReport" mappedBy="dailyReports"/>
|
||||||
|
|
||||||
|
<many-to-many name="absenceSet" title="Absences" ref="com.axelor.apps.hr.db.Absence"/>
|
||||||
|
|
||||||
<unique-constraint columns="employee,reportDate"/>
|
<unique-constraint columns="employee,reportDate"/>
|
||||||
<track>
|
<track>
|
||||||
<field name="enter1"/>
|
<field name="enter1"/>
|
||||||
@@ -88,6 +96,7 @@
|
|||||||
<field name="quit4"/>
|
<field name="quit4"/>
|
||||||
<field name="quit5"/>
|
<field name="quit5"/>
|
||||||
<field name="quit6"/>
|
<field name="quit6"/>
|
||||||
|
<field name="shift"/>
|
||||||
<field name="isValidSupHours"/>
|
<field name="isValidSupHours"/>
|
||||||
<field name="isAuthorizedAbsence"/>
|
<field name="isAuthorizedAbsence"/>
|
||||||
<field name="deduceSupHours50"/>
|
<field name="deduceSupHours50"/>
|
||||||
|
|||||||
@@ -89,11 +89,15 @@
|
|||||||
<boolean name="isEnrolled" title="Enrolled" readonly="true"/>
|
<boolean name="isEnrolled" title="Enrolled" readonly="true"/>
|
||||||
<date name="quitDate" title="Quit date"/>
|
<date name="quitDate" title="Quit date"/>
|
||||||
<string name="registrationNumber" title="Registration Number"/>
|
<string name="registrationNumber" title="Registration Number"/>
|
||||||
|
<string name="jobTitleStr"/>
|
||||||
<many-to-one name="managerEmployee" ref="com.axelor.apps.hr.db.Employee" title="Manager" massUpdate="true"/>
|
<many-to-one name="managerEmployee" ref="com.axelor.apps.hr.db.Employee" title="Manager" massUpdate="true"/>
|
||||||
<many-to-one name="initialShift" ref="com.axelor.apps.hr.db.Shift" title="Shift Initial" mappedBy="employee"/>
|
<many-to-one name="initialShift" ref="com.axelor.apps.hr.db.Shift" title="Shift Initial" mappedBy="employee"/>
|
||||||
<one-to-many name="dailyReport" title="Daily Report" ref="com.axelor.apps.hr.db.DailyReport" mappedBy="employee"/>
|
<one-to-many name="dailyReport" title="Daily Report" ref="com.axelor.apps.hr.db.DailyReport" mappedBy="employee"/>
|
||||||
<one-to-many name="offDaysWork" ref="com.axelor.apps.hr.db.OffDayWork" mappedBy="employee"/>
|
<one-to-many name="offDaysWork" ref="com.axelor.apps.hr.db.OffDayWork" mappedBy="employee"/>
|
||||||
|
|
||||||
|
<many-to-one name="companyDepartment" ref="com.axelor.apps.base.db.CompanyDepartment" title="Company department" />
|
||||||
|
<many-to-one name="companySubDepartment" ref="com.axelor.apps.base.db.CompanyDepartment" title="Company Sup department" />
|
||||||
|
|
||||||
</entity>
|
</entity>
|
||||||
|
|
||||||
</domain-models>
|
</domain-models>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models
|
||||||
|
https://axelor.com/xml/ns/domain-models/domain-models_6.0.xsd">
|
||||||
|
|
||||||
|
<module name="human-resource" package="com.axelor.apps.hr.db"/>
|
||||||
|
|
||||||
|
<entity name="EmployeeFingerPrint">
|
||||||
|
<many-to-many name="employee" ref="com.axelor.apps.hr.db.Employee"/>
|
||||||
|
<integer name="fingerId" min="0" max="9"/>
|
||||||
|
<string name="fingerPrint" title="Finger Print"/>
|
||||||
|
</entity>
|
||||||
|
|
||||||
|
</domain-models>
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
public static final Integer STATUS_CANCELED = 5;
|
public static final Integer STATUS_CANCELED = 5;
|
||||||
]]>
|
]]>
|
||||||
</extra-code>
|
</extra-code>
|
||||||
|
<unique-constraint columns="ticketId"/>
|
||||||
|
|
||||||
</entity>
|
</entity>
|
||||||
|
|
||||||
|
|||||||
@@ -12,14 +12,20 @@
|
|||||||
<time name="endHour" title="End Hour"/>
|
<time name="endHour" title="End Hour"/>
|
||||||
<time name="enterMin" title="Minimum Entry Time"/>
|
<time name="enterMin" title="Minimum Entry Time"/>
|
||||||
<time name="enterMax" title="Maximum Entry Time"/>
|
<time name="enterMax" title="Maximum Entry Time"/>
|
||||||
|
<time name="maxTimeLateArrival" title="Max Time for Late Arrival"/>
|
||||||
|
<time name="maxTimeEarlyDeparture" title="Max Time for Early Departure"/>
|
||||||
|
<time name="startPause" title="Start Time for Break"/>
|
||||||
|
<time name="endPause" title="End Time for Break"/>
|
||||||
|
|
||||||
<one-to-many name="rapportJournalierList" ref="com.axelor.apps.hr.db.DailyReport " title="Rapports Journalier" mappedBy="shift"/>
|
<one-to-many name="dailyReportList" ref="com.axelor.apps.hr.db.DailyReport " title="Rapports Journalier" mappedBy="shift"/>
|
||||||
<one-to-many name="employee" ref="com.axelor.apps.hr.db.Employee" title="Employees" mappedBy="initialShift"/>
|
<one-to-many name="employee" ref="com.axelor.apps.hr.db.Employee" title="Employees" mappedBy="initialShift"/>
|
||||||
<track>
|
<track>
|
||||||
<field name="startHour"/>
|
<field name="startHour"/>
|
||||||
<field name="endHour"/>
|
<field name="endHour"/>
|
||||||
<field name="enterMin"/>
|
<field name="enterMin"/>
|
||||||
<field name="enterMax"/>
|
<field name="enterMax"/>
|
||||||
|
<field name="maxTimeLateArrival"/>
|
||||||
|
<field name="maxTimeEarlyDeparture"/>
|
||||||
</track>
|
</track>
|
||||||
</entity>
|
</entity>
|
||||||
</domain-models>
|
</domain-models>
|
||||||
|
|||||||
@@ -949,3 +949,4 @@
|
|||||||
"value:Leave Management","Gestion des congés",,
|
"value:Leave Management","Gestion des congés",,
|
||||||
"value:Timesheet Management","Feuilles de temps",,
|
"value:Timesheet Management","Feuilles de temps",,
|
||||||
"{{ ""HR manager"" }}",,,
|
"{{ ""HR manager"" }}",,,
|
||||||
|
"Absences","Absences",,
|
||||||
|
|||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<object-views xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd" xmlns="http://axelor.com/xml/ns/object-views" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<grid name="employee-finger-print-grid" title="Employee finger prints" model="com.axelor.apps.hr.db.EmployeeFingerPrint" edit-icon="true">
|
||||||
|
<field name="fingerId"/>
|
||||||
|
<field name="fingerPrint"/>
|
||||||
|
<field name="attrs"/>
|
||||||
|
<field name="importId"/>
|
||||||
|
<field name="importOrigin"/>
|
||||||
|
<field name="archived"/>
|
||||||
|
</grid>
|
||||||
|
<form name="employee-finger-print-form" title="Employee finger print" model="com.axelor.apps.hr.db.EmployeeFingerPrint">
|
||||||
|
<panel title="Overview">
|
||||||
|
<field name="fingerId"/>
|
||||||
|
<field name="fingerPrint"/>
|
||||||
|
<field name="attrs"/>
|
||||||
|
<field name="importId"/>
|
||||||
|
<field name="importOrigin"/>
|
||||||
|
<field name="archived"/>
|
||||||
|
</panel>
|
||||||
|
<panel-related field="employee" target="com.axelor.apps.hr.db.Employee">
|
||||||
|
<field name="name"/>
|
||||||
|
</panel-related>
|
||||||
|
</form>
|
||||||
|
</object-views>
|
||||||
@@ -197,4 +197,50 @@
|
|||||||
<option value="2">Only missing</option>
|
<option value="2">Only missing</option>
|
||||||
</selection>
|
</selection>
|
||||||
|
|
||||||
|
<selection name="hr.type.absence.selection">
|
||||||
|
<option value="0">Absence autorisé payée</option>
|
||||||
|
<option value="1">Absence congé récupération</option>
|
||||||
|
<option value="2">Absence allaitement</option>
|
||||||
|
<option value="3">Absence formation</option>
|
||||||
|
<option value="4">Absence mission</option>
|
||||||
|
<option value="5">Absence hospitalisation</option>
|
||||||
|
<option value="6">Absence maladie</option>
|
||||||
|
<option value="7">Accident de travail</option>
|
||||||
|
<option value="8">Maternité</option>
|
||||||
|
<option value="9">Absence autorisée non payée</option>
|
||||||
|
<option value="10">Absence conge annuel</option>
|
||||||
|
<option value="11">Absence conge sans solde</option>
|
||||||
|
<option value="12">Absence conge statutaire</option>
|
||||||
|
<option value="13">Absence démission</option>
|
||||||
|
<option value="14">Absence fin de contrat</option>
|
||||||
|
<option value="15">Absence justifieé</option>
|
||||||
|
<option value="16">Absence recrutement</option>
|
||||||
|
<option value="17">Suspension</option>
|
||||||
|
<option value="18">Absence Service militaire</option>
|
||||||
|
<option value="19">Absence irrégulière</option>
|
||||||
|
<option value="20">Retard irrégulier</option>
|
||||||
|
<option value="21">Départ irrégulier</option>
|
||||||
|
</selection>
|
||||||
|
|
||||||
|
<selection name="hr.period.absence.selection">
|
||||||
|
<option value="0">Partial Day</option>
|
||||||
|
<option value="1">Full Day</option>
|
||||||
|
<option value="2">Multiple Days</option>
|
||||||
|
</selection>
|
||||||
|
|
||||||
|
<selection name="hr.type.absence.authorization.selection">
|
||||||
|
<option value="0">Exit Authorization</option>
|
||||||
|
<option value="1">Entry Authorization</option>
|
||||||
|
<option value="2">Absence Authorization</option>
|
||||||
|
<option value="3">Salary Absence Authorization</option>
|
||||||
|
</selection>
|
||||||
|
|
||||||
|
|
||||||
|
<selection name="hr.type.shift.selection">
|
||||||
|
<option value="0">Shift 0</option>
|
||||||
|
<option value="1">Shift 1</option>
|
||||||
|
<option value="2">Shift 2</option>
|
||||||
|
<option value="3">Shift 3</option>
|
||||||
|
</selection>
|
||||||
|
|
||||||
</object-views>
|
</object-views>
|
||||||
|
|||||||
@@ -8,16 +8,20 @@
|
|||||||
# ~~~~~
|
# ~~~~~
|
||||||
db.default.driver = org.postgresql.Driver
|
db.default.driver = org.postgresql.Driver
|
||||||
db.default.ddl = update
|
db.default.ddl = update
|
||||||
db.default.url = jdbc:postgresql://localhost:5432/postgres5
|
db.default.url = jdbc:postgresql://localhost:5432/bdd_test2
|
||||||
db.default.user = postgres
|
db.default.user = postgres
|
||||||
db.default.password = Mal@Ben$$23
|
db.default.password = Mal@Ben$$23
|
||||||
|
|
||||||
# API
|
# Api
|
||||||
# ~~~~~
|
# ~~~~~
|
||||||
portail.api.baseurl = http://127.0.0.1:8000/api/
|
portail.api.baseurl = http://127.0.0.1:8000/api/
|
||||||
portail.api.user = admin
|
portail.api.user = admin
|
||||||
portail.api.password = 0000
|
portail.api.password = 0000
|
||||||
|
|
||||||
|
# Services file directory
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
services.dir = {user.home}/axelor/services
|
||||||
|
|
||||||
# Application Information
|
# Application Information
|
||||||
# ~~~~~
|
# ~~~~~
|
||||||
application.name = SOPHAL SPA
|
application.name = SOPHAL SPA
|
||||||
@@ -193,8 +197,8 @@ logging.level.com.axelor = DEBUG
|
|||||||
|
|
||||||
# Quartz scheduler
|
# Quartz scheduler
|
||||||
# ~~~~~
|
# ~~~~~
|
||||||
quartz.enable = false
|
quartz.enable = true
|
||||||
# quartz.threadCount = 5
|
quartz.threadCount = 1
|
||||||
|
|
||||||
# Allows to open maximum 10 Tabs
|
# Allows to open maximum 10 Tabs
|
||||||
view.tabs.max = 10
|
view.tabs.max = 10
|
||||||
|
|||||||
Reference in New Issue
Block a user