Merge pull request #160 from Kitzanos/develop

Updated Dashboard, ....
This commit is contained in:
Rinaldo
2025-01-14 10:00:40 +01:00
committed by GitHub
45 changed files with 898 additions and 95 deletions

View File

@@ -12,6 +12,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
@@ -97,7 +98,9 @@ public class SecurityConfig {
} }
@Bean @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth http.csrf(AbstractHttpConfigurer::disable).headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
.contentSecurityPolicy(csp -> csp.policyDirectives("frame-ancestors 'self' https://bandi-staging.memento.credit https://bandi.gepafin.it")))
.authorizeHttpRequests(auth -> auth
// Allow public access to the login endpoints // Allow public access to the login endpoints
.requestMatchers("/v1/user/login").permitAll() // JWT-based login .requestMatchers("/v1/user/login").permitAll() // JWT-based login
.requestMatchers("/v1/user").permitAll() // User registration .requestMatchers("/v1/user").permitAll() // User registration

View File

@@ -355,5 +355,19 @@ public class GepafinConstant {
public static final String NOTIFICATION_DELETED_SUCCESSFULLY="notification.deleted.successfully"; public static final String NOTIFICATION_DELETED_SUCCESSFULLY="notification.deleted.successfully";
public static final String NOTIFICATION_UPDATED_SUCCESSFULLY="notification.updated.successfully"; public static final String NOTIFICATION_UPDATED_SUCCESSFULLY="notification.updated.successfully";
public static final String USER_WITH_COMPANY_NOT_FOUND = "user.with.company.not.found"; public static final String USER_WITH_COMPANY_NOT_FOUND = "user.with.company.not.found";
//action log response
public static final String STATUS_CODE_STRING = "statusCode";
public static final String GET_STATUS_CODE_STRING = "status";
public static final String MESSAGE_STRING = "message";
public static final String AMOUNT_ACCEPTED_REQUIRED_WHILE_APPROVING_APPLICATION="amount.accepted.required";
public static final String CALL_NAME="callName";
public static final String NUMBER_OF_APPLICATIONS="numberOfApplications";
public static final String STATUS="status";
public static final String COUNT="count";
public static final String APPLICATION_PER_CALL="applicationPerCall";
public static final String APPLICATION_PER_STATUS="applicationPerStatus";
} }

View File

@@ -306,7 +306,7 @@ public class ApplicationAmendmentRequestDao {
ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT);
String evaluationStatusType = applicationEvaluationEntity.getStatus(); String evaluationStatusType = applicationEvaluationEntity.getStatus();
if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){ if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){
applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); // applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
//Set Status //Set Status
applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());

View File

@@ -47,6 +47,7 @@ import jakarta.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
@@ -423,6 +424,10 @@ public class ApplicationDao {
if(applicationEntity.getProtocol() != null) { if(applicationEntity.getProtocol() != null) {
responseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); responseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber());
} }
responseBean.setAmountAccepted(applicationEntity.getAmountAccepted());
responseBean.setAmountRequested(applicationEntity.getAmountRequested());
responseBean.setDateAccepted(applicationEntity.getDateAccepted());
responseBean.setDateRejected(applicationEntity.getDateRejected());
return responseBean; return responseBean;
} }
@@ -442,6 +447,10 @@ public class ApplicationDao {
response.setCallId(entity.getCall().getId()); response.setCallId(entity.getCall().getId());
response.setCreatedDate(entity.getCreatedDate()); response.setCreatedDate(entity.getCreatedDate());
response.setUpdatedDate(entity.getUpdatedDate()); response.setUpdatedDate(entity.getUpdatedDate());
response.setAmountAccepted(entity.getAmountAccepted());
response.setAmountRequested(entity.getAmountRequested());
response.setDateAccepted(entity.getDateAccepted());
response.setDateRejected(entity.getDateRejected());
if(entity.getProtocol() != null) { if(entity.getProtocol() != null) {
response.setProtocolNumber(entity.getProtocol().getProtocolNumber()); response.setProtocolNumber(entity.getProtocol().getProtocolNumber());
} }
@@ -480,6 +489,30 @@ public class ApplicationDao {
List<Long> newDocumentIds = validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity); List<Long> newDocumentIds = validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity);
validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity); validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity);
VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT;
List<ContentResponseBean> contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent();
contentResponseBeans.stream()
.filter(content -> "numberinput".equals(content.getName()))
.map(ContentResponseBean::getSettings)
.flatMap(List::stream)
.filter(setting -> "isRequestedAmount".equals(setting.getName()) && Boolean.TRUE.equals(setting.getValue()))
.findFirst()
.ifPresent(setting -> {
Object fieldValue = applicationFormFieldRequestBean.getFieldValue();
if(fieldValue!=null) {
if (fieldValue instanceof String) {
try {
BigDecimal amountRequested = new BigDecimal((String) fieldValue);
applicationFormEntity.getApplication().setAmountRequested(amountRequested);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e);
}
} else {
throw new IllegalArgumentException("Field value is not a String: " + fieldValue);
}
}
});
ApplicationFormFieldEntity oldApplicationFormFieldData = null; ApplicationFormFieldEntity oldApplicationFormFieldData = null;
@@ -811,6 +844,10 @@ public class ApplicationDao {
applicationGetResponseBean.setCallId(applicationEntity.getCall().getId()); applicationGetResponseBean.setCallId(applicationEntity.getCall().getId());
applicationGetResponseBean.setCallTitle(applicationEntity.getCall().getName()); applicationGetResponseBean.setCallTitle(applicationEntity.getCall().getName());
applicationGetResponseBean.setCompanyId(applicationEntity.getCompanyId()); applicationGetResponseBean.setCompanyId(applicationEntity.getCompanyId());
applicationGetResponseBean.setAmountAccepted(applicationEntity.getAmountAccepted());
applicationGetResponseBean.setAmountRequested(applicationEntity.getAmountRequested());
applicationGetResponseBean.setDateAccepted(applicationEntity.getDateAccepted());
applicationGetResponseBean.setDateRejected(applicationEntity.getDateRejected());
if(applicationEntity.getProtocol() != null) { if(applicationEntity.getProtocol() != null) {
applicationGetResponseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); applicationGetResponseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber());
} }
@@ -870,7 +907,7 @@ public class ApplicationDao {
ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity, protocolNumber, userEntity.getHub().getId(),true); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity, protocolNumber, userEntity.getHub().getId(),true);
applicationEntity.setProtocol(protocolEntity); applicationEntity.setProtocol(protocolEntity);
applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue());
applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationEntity.setSubmissionDate(protocolEntity.getCreatedDate());
applicationEntity = applicationRepository.save(applicationEntity); applicationEntity = applicationRepository.save(applicationEntity);
Map<String ,String> placeHolders=notificationDao.sendNotificationToBeneficiary(applicationEntity,NotificationTypeEnum.APPLICATION_SUBMISSION); Map<String ,String> placeHolders=notificationDao.sendNotificationToBeneficiary(applicationEntity,NotificationTypeEnum.APPLICATION_SUBMISSION);
notificationDao.sendNotificationToSuperUser(applicationEntity,placeHolders,NotificationTypeEnum.APPLICATION_SUBMISSION); notificationDao.sendNotificationToSuperUser(applicationEntity,placeHolders,NotificationTypeEnum.APPLICATION_SUBMISSION);

View File

@@ -24,7 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -580,6 +583,10 @@ public class ApplicationEvaluationDao {
CompanyEntity company = companyService.validateCompany(application.getCompanyId()); CompanyEntity company = companyService.validateCompany(application.getCompanyId());
response.setCompanyName(company.getCompanyName()); response.setCompanyName(company.getCompanyName());
} }
response.setAmountAccepted(application.getAmountAccepted());
response.setAmountRequested(application.getAmountRequested());
response.setDateAccepted(application.getDateAccepted());
response.setDateRejected(application.getDateRejected());
} }
@@ -594,7 +601,8 @@ public class ApplicationEvaluationDao {
Optional<AssignedApplicationsEntity> assignedApplications = Optional<AssignedApplicationsEntity> assignedApplications =
assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationId); assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationId);
ApplicationEvaluationEntity oldApplicationEvaluation = null; ApplicationEvaluationEntity oldApplicationEvaluation = null;
VersionActionTypeEnum actionType; ApplicationEntity application = applicationService.validateApplication(assignedApplications.get().getApplication().getId());
VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT;
if (existingEntityOptional.isPresent()) { if (existingEntityOptional.isPresent()) {
entity = existingEntityOptional.get(); entity = existingEntityOptional.get();
oldApplicationEvaluation = Utils.getClonedEntityForData(entity); oldApplicationEvaluation = Utils.getClonedEntityForData(entity);
@@ -610,10 +618,15 @@ public class ApplicationEvaluationDao {
entity.setIsDeleted(false); entity.setIsDeleted(false);
setIfUpdated(entity::getNote, entity::setNote, req.getNote()); setIfUpdated(entity::getNote, entity::setNote, req.getNote());
setIfUpdated(entity::getMotivation, entity::setMotivation, req.getMotivation()); setIfUpdated(entity::getMotivation, entity::setMotivation, req.getMotivation());
if(Boolean.TRUE.equals(req.getApplicationStatus().equals(ApplicationStatusForEvaluation.APPROVED)) && (req.getAmountAccepted()==null || req.getAmountAccepted().compareTo(BigDecimal.ZERO) < 0)){
throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.AMOUNT_ACCEPTED_REQUIRED_WHILE_APPROVING_APPLICATION));
}
if (req.getAmountAccepted() != null && req.getAmountAccepted().compareTo(BigDecimal.ZERO) > 0) {
application.setAmountAccepted(req.getAmountAccepted());
}
actionType = VersionActionTypeEnum.UPDATE; actionType = VersionActionTypeEnum.UPDATE;
} else { } else {
AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId);
ApplicationEntity application = applicationService.validateApplication(assignedApplicationsEntity.getApplication().getId());
entity = convertToEntity(user, req, assignedApplicationId); entity = convertToEntity(user, req, assignedApplicationId);
actionType = VersionActionTypeEnum.INSERT; actionType = VersionActionTypeEnum.INSERT;
@@ -642,7 +655,6 @@ public class ApplicationEvaluationDao {
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldApplicationEvaluation).newData(entity).build()); loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldApplicationEvaluation).newData(entity).build());
if (status != null) { if (status != null) {
ApplicationEntity application = applicationService.validateApplication(assignedApplications.get().getApplication().getId());
AssignedApplicationsEntity assignedApplicationsEntity = assignedApplications.get(); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplications.get();
return updateApplicationEvaluationStatus(application, assignedApplicationsEntity, status); return updateApplicationEvaluationStatus(application, assignedApplicationsEntity, status);
} else { } else {
@@ -1800,6 +1812,11 @@ public class ApplicationEvaluationDao {
existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue());
} }
if (existingEntity.getStartDate() != null && existingEntity.getClosingDate() != null) {
long activeDays = ChronoUnit.DAYS.between(existingEntity.getStartDate(), existingEntity.getClosingDate());
activeDays -= existingEntity.getSuspendedDays() != null ? existingEntity.getSuspendedDays() : 0;
existingEntity.setActiveDays(activeDays);
}
entity = applicationEvaluationRepository.save(existingEntity); entity = applicationEvaluationRepository.save(existingEntity);
assignedApplicationsRepository.save(assignedApplicationsEntity); assignedApplicationsRepository.save(assignedApplicationsEntity);
@@ -1814,9 +1831,15 @@ public class ApplicationEvaluationDao {
if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.APPROVED.getValue())))) { if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.APPROVED.getValue())))) {
application.setDateAccepted(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
application.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
application = applicationRepository.save(application);
emailNotificationDao.sendAdmissibilityNotificationEmailForApprovedApplication(application); emailNotificationDao.sendAdmissibilityNotificationEmailForApprovedApplication(application);
} }
if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.REJECTED.getValue())))) { if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.REJECTED.getValue())))) {
application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
application.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
application = applicationRepository.save(application);
emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity); emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity);
} }

View File

@@ -124,7 +124,6 @@ public class CompanyDao {
userWithCompanyEntity.setContactEmail(companyRequest.getContactEmail()); userWithCompanyEntity.setContactEmail(companyRequest.getContactEmail());
userWithCompanyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) ); userWithCompanyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) );
UserWithCompanyEntity userWithCompany = userWithCompanyRepository.save(userWithCompanyEntity); UserWithCompanyEntity userWithCompany = userWithCompanyRepository.save(userWithCompanyEntity);
/** This code is responsible for adding a version history log for the "adding user with company" operation. **/ /** This code is responsible for adding a version history log for the "adding user with company" operation. **/
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompany).build()); loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompany).build());
return userWithCompany; return userWithCompany;
@@ -144,6 +143,22 @@ public class CompanyDao {
entity.setNumberOfEmployees(request.getNumberOfEmployees()); entity.setNumberOfEmployees(request.getNumberOfEmployees());
entity.setAnnualRevenue(request.getAnnualRevenue()); entity.setAnnualRevenue(request.getAnnualRevenue());
entity.setHub(userEntity.getHub()); entity.setHub(userEntity.getHub());
Map<String, Object> vatCheckResponse = request.getVatCheckResponse();
if (request.getVatCheckResponse() != null) {
if (vatCheckResponse.containsKey("dettaglio")) {
Map<String, Object> dettaglio = (Map<String, Object>) vatCheckResponse.get("dettaglio");
if (dettaglio != null) {
if (dettaglio.containsKey("codice_ateco")) {
Object codiceAtecoObj = dettaglio.get("codice_ateco");
String codiceAteco = (codiceAtecoObj != null) ? codiceAtecoObj.toString() : null;
if (codiceAteco != null) {
entity.setCodiceAteco(codiceAteco);
}
}
}
}
}
return entity; return entity;
} }
@@ -165,6 +180,7 @@ public class CompanyDao {
response.setAnnualRevenue(entity.getAnnualRevenue()); response.setAnnualRevenue(entity.getAnnualRevenue());
if(userWithCompanyEntity!=null) { if(userWithCompanyEntity!=null) {
response.setIsLegalRepresentant(userWithCompanyEntity.getIsLegalRepresentant()); response.setIsLegalRepresentant(userWithCompanyEntity.getIsLegalRepresentant());
response.setCodiceAteco(entity.getCodiceAteco());
} }
response.setCreatedDate(entity.getCreatedDate()); response.setCreatedDate(entity.getCreatedDate());
response.setUpdatedDate(entity.getUpdatedDate()); response.setUpdatedDate(entity.getUpdatedDate());

View File

@@ -1,18 +1,34 @@
package net.gepafin.tendermanagement.dao; package net.gepafin.tendermanagement.dao;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.CompanyEntity;
import net.gepafin.tendermanagement.entities.UserActionEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.entities.UserWithCompanyEntity;
import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.enums.CallStatusEnum;
import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.Widget1; import net.gepafin.tendermanagement.model.response.Widget1;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.repositories.*;
import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.CompanyService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -37,11 +53,17 @@ public class DashboardDao {
private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository; private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository;
@Autowired
private ApplicationEvaluationRepository applicationEvaluationRepository;
@Autowired
private UserActionsRepository userActionsRepository;
public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) { public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) {
SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean(); SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean();
widgetResponseBean.setWidget1(createWidget1(requestedUserEntity)); widgetResponseBean.setWidget1(createWidget1(requestedUserEntity));
// List<Object[]> widgetBars = callRepository.findApplicationsPerCall(); Map<String, Object> widgetBars =getStatistics(requestedUserEntity);
// widgetResponseBean.setWidgetBars(widgetBars); widgetResponseBean.setWidgetBars(widgetBars);
return widgetResponseBean; return widgetResponseBean;
} }
@@ -54,7 +76,8 @@ public class DashboardDao {
setSubmittedApplications(widget1, requestedUserEntity); setSubmittedApplications(widget1, requestedUserEntity);
setDraftApplications(widget1, requestedUserEntity); setDraftApplications(widget1, requestedUserEntity);
setNumberOfCompanies(widget1, requestedUserEntity); setNumberOfCompanies(widget1, requestedUserEntity);
setAmountRequested(widget1,requestedUserEntity);
setAmountAccepted(widget1,requestedUserEntity);
return widget1; return widget1;
} }
@@ -71,6 +94,20 @@ public class DashboardDao {
} }
} }
private void setAmountRequested(Widget1 widget1, UserEntity requestedUserEntity) {
BigDecimal amountRequested = applicationRepository.findTotalAmountRequestedOfApplication(requestedUserEntity.getHub().getId());
if (amountRequested != null) {
widget1.setTotalAmountRequested(amountRequested);
}
}
private void setAmountAccepted(Widget1 widget1, UserEntity requestedUserEntity) {
BigDecimal amountAccepted = applicationRepository.findTotalAmountAcceptedOfApplication(requestedUserEntity.getHub().getId());
if (amountAccepted != null) {
widget1.setTotalAmountAccepted(amountAccepted);
}
}
private void setRegisteredUsers(Widget1 widget1, UserEntity requestedUserEntity) { private void setRegisteredUsers(Widget1 widget1, UserEntity requestedUserEntity) {
Long activeUsers = userRepository.countByStatusAndRoleEntityRoleTypeAndHubId(UserStatusEnum.ACTIVE.getValue(), Long activeUsers = userRepository.countByStatusAndRoleEntityRoleTypeAndHubId(UserStatusEnum.ACTIVE.getValue(),
RoleStatusEnum.ROLE_BENEFICIARY.getValue(), requestedUserEntity.getHub().getId()); RoleStatusEnum.ROLE_BENEFICIARY.getValue(), requestedUserEntity.getHub().getId());
@@ -133,4 +170,99 @@ public class DashboardDao {
} }
return beneficiaryWidgetResponseBean; return beneficiaryWidgetResponseBean;
} }
public Map<String, Object> getStatistics(UserEntity requestedUser) {
Map<String, Object> stats = new HashMap<>();
// Get applications per call
List<Object[]> applicationsPerCall = applicationRepository.findApplicationsPerCallWithName(requestedUser.getHub().getId());
stats.put(GepafinConstant.APPLICATION_PER_CALL, applicationsPerCall.stream().map(result -> {
Map<String, Object> callData = new HashMap<>();
callData.put(GepafinConstant.CALL_NAME, result[0]); // Call name
callData.put(GepafinConstant.NUMBER_OF_APPLICATIONS, result[1]); // Application count
return callData;
}).toList());
// Get applications grouped by status
List<Object[]> applicationsByStatus = applicationRepository.findApplicationsByStatus(requestedUser.getHub().getId());
stats.put(GepafinConstant.APPLICATION_PER_STATUS, applicationsByStatus.stream().map(result -> {
Map<String, Object> statusData = new HashMap<>();
statusData.put(GepafinConstant.STATUS, result[0]); // Application status
statusData.put(GepafinConstant.NUMBER_OF_APPLICATIONS, result[1]); // Count of applications
return statusData;
}).toList());
return stats;
}
// public Page<UserActionEntity> getUserAction(UserEntity requestedUserEntity){
// Pageable pageable = PageRequest.of(0, 20); // Get the first 20 records
// List<String> roles=List.of(RoleStatusEnum.ROLE_PRE_INSTRUCTOR.getValue(),RoleStatusEnum.ROLE_GEPAFIN_OPERATOR.getValue(),RoleStatusEnum.ROLE_INSTRUCTOR_MANAGER.getValue());
// Page<UserActionEntity> userActionEntities=userActionsRepository.findActionsByRoleNamesAndHubId(roles,requestedUserEntity.getHub().getId(),pageable);
// return userActionEntities;
// }
public ApplicationWidgetResponseBean getApplicationDetails(UserEntity userEntity) {
ApplicationWidgetResponseBean applicationWidgetResponseBean = initializeResponseBean();
Long hubId = userEntity.getHub().getId();
setApplicationCounts(applicationWidgetResponseBean, hubId);
calculateEvaluationAverageTime(applicationWidgetResponseBean, hubId);
return applicationWidgetResponseBean;
}
private ApplicationWidgetResponseBean initializeResponseBean() {
return ApplicationWidgetResponseBean.builder()
.numberOfApplication(0L)
.numberOfAssignedApplication(0L)
.numberOfAcceptedApplication(0L)
.numberOfApplicationInAmendmentState(0L)
.numberOfDueApplication(0L)
.evaluationAverageTime(BigDecimal.ZERO)
.build();
}
private void setApplicationCounts(ApplicationWidgetResponseBean responseBean, Long hubId) {
Long activeApplications = applicationRepository.countApplicationsByHubId(hubId);
if (activeApplications != null) {
responseBean.setNumberOfApplication(activeApplications);
}
Long assignedApplications = applicationRepository.countAssignedApplicationsByHubId(hubId);
if (assignedApplications != null) {
responseBean.setNumberOfAssignedApplication(assignedApplications);
}
Long approvedApplications = applicationRepository.countApprovedApplicationsByHubId(hubId);
if (approvedApplications != null) {
responseBean.setNumberOfAcceptedApplication(approvedApplications);
}
Long soccorsoApplications = applicationRepository.countSoccorsoApplicationsByHubId(hubId);
if (soccorsoApplications != null) {
responseBean.setNumberOfApplicationInAmendmentState(soccorsoApplications);
}
}
private void calculateEvaluationAverageTime(ApplicationWidgetResponseBean responseBean, Long hubId) {
List<Long> applicationIds = applicationRepository.findApplicationIdsByHubId(hubId);
if (Boolean.FALSE.equals(applicationIds.isEmpty())) {
BigDecimal averageTime = applicationEvaluationRepository.findAverageEvaluationTimeByApplicationIds(applicationIds);
responseBean.setEvaluationAverageTime(averageTime != null ? averageTime : BigDecimal.ZERO);
}
LocalDate twoDaysLater = LocalDate.now().plusDays(2);
Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween(
applicationIds,
LocalDate.now(),
twoDaysLater
);
if (dueApplications != null) {
responseBean.setNumberOfDueApplication(dueApplications);
}
}
} }

View File

@@ -309,6 +309,10 @@ public class FlowFormDao {
if(applicationEntity.getProtocol() != null) { if(applicationEntity.getProtocol() != null) {
nextOrPreviousFormResponse.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); nextOrPreviousFormResponse.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber());
} }
nextOrPreviousFormResponse.setAmountAccepted(applicationEntity.getAmountAccepted());
nextOrPreviousFormResponse.setAmountRequested(applicationEntity.getAmountRequested());
nextOrPreviousFormResponse.setDateAccepted(applicationEntity.getDateAccepted());
nextOrPreviousFormResponse.setDateRejected(applicationEntity.getDateRejected());
return nextOrPreviousFormResponse; return nextOrPreviousFormResponse;
} }

View File

@@ -109,76 +109,7 @@ public class PdfDao {
document.add(new Paragraph(" ")); // Add line break document.add(new Paragraph(" ")); // Add line break
} }
document.add(new Paragraph("\n")); // Add line break document.add(new Paragraph("\n")); // Add line break
Font boldSmallFont = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD,new BaseColor(105, 105, 105));
// Adding the "Documenti Allegati" section title
// document.add(new Paragraph(" "));
//
//// pageEvent.setTotalPages(writer.getPageNumber());
// document.newPage();
//// pageEvent.setTotalPages(writer.getPageNumber());
// document.add(new Paragraph("Documenti Allegati", sectionFont));
// document.add(new Paragraph(" "));
//
//
//// 1. Autocertificazione possesso Requisiti
// Paragraph p1 = new Paragraph();
// p1.add(new Chunk("1. ", boldSmallFont));
// p1.add(new Chunk("Autocertificazione possesso Requisiti ", boldSmallFont));
// p1.add(new Chunk("ai sensi degli artt. 46 e 47 del DPR 445/2000", smallFont));
// document.add(p1);
// document.add(new Paragraph(" "));
//
//
//
//// 2. Informativa Privacy relativa al trattamento dei dati personali
// Paragraph p2 = new Paragraph();
// p2.add(new Chunk("2. ", boldSmallFont));
// p2.add(new Chunk("Informativa Privacy relativa al trattamento dei dati personali", boldSmallFont));
// document.add(p2);
// document.add(new Paragraph(" "));
//
//
//// 3. Dati richiesti per la valutazione delladeguatezza dei flussi finanziari
// Paragraph p3 = new Paragraph();
// p3.add(new Chunk("3. ", boldSmallFont));
// p3.add(new Chunk("Dati richiesti per la valutazione delladeguatezza dei flussi finanziari prospettici come da tabella di cui allAppendice 9", boldSmallFont));
// document.add(p3);
// document.add(new Paragraph(" "));
//
//
//// 4. Rilevazione Centrale dei Rischi
// Paragraph p4 = new Paragraph();
// p4.add(new Chunk("4. ", boldSmallFont));
// p4.add(new Chunk("Rilevazione Centrale dei Rischi riferita agli ultimi 36 mesi disponibili alla data di presentazione della Domanda", boldSmallFont));
// document.add(p4);
// document.add(new Paragraph(" "));
//
//
//// 5. Schema di presentazione dei dati di bilancio
// Paragraph p5 = new Paragraph();
// p5.add(new Chunk("5. ", boldSmallFont));
// p5.add(new Chunk("Schema di presentazione dei dati di bilancio", boldSmallFont));
// document.add(p5);
// document.add(new Paragraph(" "));
//
//
//// 6. Dettagli bilanci in forma abbreviata
// Paragraph p6 = new Paragraph();
// p6.add(new Chunk("6. ", boldSmallFont));
// p6.add(new Chunk("Dettagli bilanci in forma abbreviata", boldSmallFont));
// document.add(p6);
// document.add(new Paragraph(" "));
//
//
//// 7. Relazione aziendale illustrativa
// Paragraph p7 = new Paragraph();
// p7.add(new Chunk("7. ", boldSmallFont));
// p7.add(new Chunk("Relazione aziendale illustrativa", boldSmallFont));
// document.add(p7);
// document.add(new Paragraph(" "));
//
// addColoredLines(writer,document,greenColor);
document.close(); document.close();
@@ -488,12 +419,19 @@ public class PdfDao {
.orElse(null); // If no match is found, set label to null .orElse(null); // If no match is found, set label to null
// Find the form field in the response that matches the contentId // Find the form field in the response that matches the contentId
if (name.equals("paragraph")){ if (name.equals("paragraph")){
// String paragraph = content.getSettings().stream()
// .filter(setting -> "text".equals(setting.getName())) // Filter settings by name
// .map(SettingResponseBean::getValue) // Extract the value from the matching setting
// .map(Object::toString) // Convert the value to a string
// .findFirst() // Get the first matching value
// .orElse(null);
String paragraph = content.getSettings().stream() String paragraph = content.getSettings().stream()
.filter(setting -> "text".equals(setting.getName())) // Filter settings by name .filter(setting -> "text".equals(setting.getName())) // Filter settings by name
.map(SettingResponseBean::getValue) // Extract the value from the matching setting .map(SettingResponseBean::getValue) // Extract the value from the matching setting
.map(Object::toString) // Convert the value to a string .map(value -> value != null ? value.toString() : " ") // Replace null with an empty string
.findFirst() // Get the first matching value .findFirst() // Get the first matching value
.orElse(null); .orElse(null); // Return null if no value is found
Paragraph labelParagraph = new Paragraph(); Paragraph labelParagraph = new Paragraph();
PdfPCell labelCell = new PdfPCell(PdfUtils.htmlToPdfPCell(paragraph,labelFont)); PdfPCell labelCell = new PdfPCell(PdfUtils.htmlToPdfPCell(paragraph,labelFont));
labelCell.setBorder(Rectangle.NO_BORDER); labelCell.setBorder(Rectangle.NO_BORDER);

View File

@@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.entities;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.*; import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Entity @Entity
@@ -55,4 +56,16 @@ public class ApplicationEntity extends BaseEntity {
@Column(name = "APPOINTMENT_ID") @Column(name = "APPOINTMENT_ID")
private String appointmentId; private String appointmentId;
@Column(name="AMOUNT_REQUESTED")
private BigDecimal amountRequested;
@Column(name="AMOUNT_ACCEPTED")
private BigDecimal amountAccepted;
@Column(name="DATE_ACCEPTED")
private LocalDateTime dateAccepted;
@Column(name="DATE_REJECTED")
private LocalDateTime dateRejected;
} }

View File

@@ -65,4 +65,7 @@ public class ApplicationEvaluationEntity extends BaseEntity{
@Column(name = "CLOSING_DATE") @Column(name = "CLOSING_DATE")
private LocalDateTime closingDate; private LocalDateTime closingDate;
@Column(name = "ACTIVE_DAYS")
private Long activeDays;
} }

View File

@@ -56,4 +56,7 @@ public class CompanyEntity extends BaseEntity{
@Column(name = "NDG") @Column(name = "NDG")
private String ndg; private String ndg;
@Column(name = "CODICE_ATECO")
private String codiceAteco;
} }

View File

@@ -0,0 +1,21 @@
package net.gepafin.tendermanagement.entities;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import lombok.Data;
@Entity
@Table(name = "expiration_config")
@Data
public class ExpirationConfigEntity extends BaseEntity {
@Column(name="INTERVAL_DAYS")
private Long intervalDays;
@Column(name="TYPE")
private String type;
@Column(name="IS_DELETED")
private Boolean isDeleted;
}

View File

@@ -0,0 +1,20 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ExpirationTypeEnum {
AMENDMENT("AMENDMENT"),
EVALUATION("EVALUATION");
private String value;
ExpirationTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -11,7 +11,9 @@ public enum NotificationTypeEnum {
AMENDMENT_CLOSED("AMENDMENT_CLOSED"), AMENDMENT_CLOSED("AMENDMENT_CLOSED"),
NDG_GENERATION("NDG_GENERATION"), NDG_GENERATION("NDG_GENERATION"),
EVALUATION_CREATION("EVALUATION_CREATION"), EVALUATION_CREATION("EVALUATION_CREATION"),
EVALUATION_EXPIRED("EVALUATION_EXPIRED"); EVALUATION_EXPIRED("EVALUATION_EXPIRED"),
AMENDMENT_EXPIRATION_REMINDER("AMENDMENT_EXPIRATION_REMINDER"),
EVALUATION_EXPIRATION_REMINDER("EVALUATION_EXPIRATION_REMINDER");
private final String value; private final String value;

View File

@@ -136,6 +136,7 @@ public enum UserActionContextEnum {
/** Dashboard action context **/ /** Dashboard action context **/
GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN("GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN"), GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN("GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN"),
GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"), GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"),
GET_APPLICATION_DETAILS("GET_APPLICATION_DETAILS"),
/** Evaluation criteria action context **/ /** Evaluation criteria action context **/
GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"), GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"),

View File

@@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.model.request;
import lombok.Data; import lombok.Data;
import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation; import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@Data @Data
public class ApplicationEvaluationRequest { public class ApplicationEvaluationRequest {
@@ -15,4 +16,5 @@ public class ApplicationEvaluationRequest {
private String note; private String note;
private ApplicationStatusForEvaluation applicationStatus; private ApplicationStatusForEvaluation applicationStatus;
private String motivation; private String motivation;
private BigDecimal amountAccepted;
} }

View File

@@ -4,6 +4,7 @@ import lombok.Data;
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@@ -38,4 +39,8 @@ public class ApplicationEvaluationResponse {
private LocalDateTime assignedAt; private LocalDateTime assignedAt;
private String ndg; private String ndg;
private String appointmentId; private String appointmentId;
private BigDecimal amountRequested;
private BigDecimal amountAccepted;
private LocalDateTime dateAccepted;
private LocalDateTime dateRejected;
} }

View File

@@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.model.response;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@@ -26,6 +27,15 @@ public class ApplicationGetResponseBean {
private Long protocolNumber; private Long protocolNumber;
private BigDecimal amountRequested;
private BigDecimal amountAccepted;
private LocalDateTime dateAccepted;
private LocalDateTime dateRejected;
private List<FormApplicationResponse> form; private List<FormApplicationResponse> form;
} }

View File

@@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.model.response;
import lombok.Data; import lombok.Data;
import net.gepafin.tendermanagement.model.response.ApplicationFormFieldResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationFormFieldResponseBean;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@@ -37,4 +38,12 @@ public class ApplicationResponse{
private String assignedUserName; private String assignedUserName;
private BigDecimal amountRequested;
private BigDecimal amountAccepted;
private LocalDateTime dateAccepted;
private LocalDateTime dateRejected;
} }

View File

@@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.model.response;
import lombok.Data; import lombok.Data;
import net.gepafin.tendermanagement.model.BaseBean; import net.gepafin.tendermanagement.model.BaseBean;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@@ -19,6 +20,14 @@ public class ApplicationResponseBean extends BaseBean {
private Long protocolNumber; private Long protocolNumber;
private BigDecimal amountRequested;
private BigDecimal amountAccepted;
private LocalDateTime dateAccepted;
private LocalDateTime dateRejected;
private List<ApplicationFormFieldResponseBean> formFields; private List<ApplicationFormFieldResponseBean> formFields;
} }

View File

@@ -0,0 +1,23 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
@Builder
@Data
public class ApplicationWidgetResponseBean {
private Long numberOfApplication;
private Long numberOfAssignedApplication;
private Long numberOfAcceptedApplication;
private Long numberOfApplicationInAmendmentState;
private Long numberOfDueApplication;
private BigDecimal evaluationAverageTime;
}

View File

@@ -24,4 +24,5 @@ public class CompanyResponse extends BaseBean{
private Boolean isLegalRepresentant; private Boolean isLegalRepresentant;
private String contactName; private String contactName;
private String contactEmail; private String contactEmail;
private String codiceAteco;
} }

View File

@@ -3,6 +3,9 @@ package net.gepafin.tendermanagement.model.response;
import lombok.Data; import lombok.Data;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data @Data
public class NextOrPreviousFormResponse { public class NextOrPreviousFormResponse {
@@ -26,6 +29,14 @@ public class NextOrPreviousFormResponse {
private ApplicationStatusTypeEnum applicationStatus; private ApplicationStatusTypeEnum applicationStatus;
private BigDecimal amountRequested;
private BigDecimal amountAccepted;
private LocalDateTime dateAccepted;
private LocalDateTime dateRejected;
private FormApplicationResponse applicationFormResponse; private FormApplicationResponse applicationFormResponse;
} }

View File

@@ -1,14 +1,17 @@
package net.gepafin.tendermanagement.model.response; package net.gepafin.tendermanagement.model.response;
import lombok.Data; import lombok.Data;
import net.gepafin.tendermanagement.entities.UserActionEntity;
import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
public class SuperAdminWidgetResponseBean { public class SuperAdminWidgetResponseBean {
private Widget1 widget1; private Widget1 widget1;
// private List<Object[]> widgetBars; private Map<String, Object> widgetBars;
} }

View File

@@ -23,4 +23,8 @@ public class Widget1 {
private BigDecimal totalActiveFinancing; private BigDecimal totalActiveFinancing;
private BigDecimal totalAmountRequested;
private BigDecimal totalAmountAccepted;
} }

View File

@@ -74,4 +74,10 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository<App
" AND activeAmendment.isDeleted = false) ") " AND activeAmendment.isDeleted = false) ")
Set<ApplicationEvaluationEntity> findEvaluationsWithoutActiveAmendmentsByIds(@Param("applicationEvaluationIds") Set<Long> applicationEvaluationIds); Set<ApplicationEvaluationEntity> findEvaluationsWithoutActiveAmendmentsByIds(@Param("applicationEvaluationIds") Set<Long> applicationEvaluationIds);
@Query("SELECT a FROM ApplicationAmendmentRequestEntity a " +
"WHERE a.isDeleted = false " +
"AND a.status NOT IN ('CLOSE', 'EXPIRED') " +
"AND a.endDate BETWEEN :startTime AND :endTime")
List<ApplicationAmendmentRequestEntity> findExpiringBetween(LocalDateTime startTime, LocalDateTime endTime);
} }

View File

@@ -1,12 +1,15 @@
package net.gepafin.tendermanagement.repositories; package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEntity;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -31,4 +34,33 @@ public interface ApplicationEvaluationRepository extends JpaRepository<Applicati
@Query("SELECT a FROM ApplicationEvaluationEntity a WHERE a.isDeleted = false AND a.endDate < :currentDate") @Query("SELECT a FROM ApplicationEvaluationEntity a WHERE a.isDeleted = false AND a.endDate < :currentDate")
List<ApplicationEvaluationEntity> findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate); List<ApplicationEvaluationEntity> findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate);
@Query("SELECT a FROM ApplicationEvaluationEntity a " +
"WHERE a.isDeleted = false " +
"AND a.status NOT IN ('CLOSE', 'EXPIRED') " +
"AND a.endDate BETWEEN :startTime AND :endTime")
List<ApplicationEvaluationEntity> findExpiringBetween(LocalDateTime startTime, LocalDateTime endTime);
// @Query("SELECT AVG(DATEDIFF(DAY, e.startDate, e.endDate)) FROM ApplicationEvaluationEntity e WHERE e.applicationId IN :applicationIds AND e.startDate IS NOT NULL AND e.endDate IS NOT NULL AND e.isDeleted = false ")
@Query("""
SELECT AVG(e.activeDays)
FROM ApplicationEvaluationEntity e
WHERE e.applicationId IN :applicationIds
AND e.activeDays IS NOT NULL
AND e.isDeleted = false
""")
BigDecimal findAverageEvaluationTimeByApplicationIds(@Param("applicationIds") List<Long> applicationIds);
@Query("""
SELECT COUNT(e)
FROM ApplicationEvaluationEntity e
WHERE e.applicationId IN :applicationIds
AND FUNCTION('DATE', e.endDate) BETWEEN :startDate AND :endDate
AND e.isDeleted = false
""")
Long countDueApplicationsBetween(
@Param("applicationIds") List<Long> applicationIds,
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate
);
} }

View File

@@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -24,7 +25,6 @@ public interface ApplicationRepository extends JpaRepository<ApplicationEntity,
public Optional<ApplicationEntity> findByIdAndUserIdAndIsDeletedFalse(Long id,Long userId); public Optional<ApplicationEntity> findByIdAndUserIdAndIsDeletedFalse(Long id,Long userId);
Optional<ApplicationEntity> findByUserIdAndUserWithCompanyIdAndCallIdAndIsDeletedFalse(Long userId, Long userWithCompanyId, Long callId);
public Optional<ApplicationEntity> findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId, public Optional<ApplicationEntity> findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId,
Long callId); Long callId);
@@ -44,4 +44,37 @@ public interface ApplicationRepository extends JpaRepository<ApplicationEntity,
@Query("SELECT a.call.id FROM ApplicationEntity a WHERE a.id = :id AND a.isDeleted = false") @Query("SELECT a.call.id FROM ApplicationEntity a WHERE a.id = :id AND a.isDeleted = false")
Long findCallIdById(@Param("id") Long id); Long findCallIdById(@Param("id") Long id);
@Query("SELECT a.call.name, COUNT(a.id) FROM ApplicationEntity a WHERE a.isDeleted = false AND a.call.hub.id = :hubId GROUP BY a.call.name")
List<Object[]> findApplicationsPerCallWithName(@Param("hubId") Long hubId);
// Count Applications by Status by Hub ID
@Query("SELECT a.status, COUNT(a.id) FROM ApplicationEntity a WHERE a.isDeleted = false AND a.call.hub.id = :hubId GROUP BY a.status")
List<Object[]> findApplicationsByStatus(@Param("hubId") Long hubId);
@Query("SELECT SUM(a.amountRequested) " +
"FROM ApplicationEntity a " +
"WHERE a.hubId = :hubId AND a.status IN ('SUBMIT', 'SOCCORSO', 'APPROVED', 'EVALUATION', 'APPOINTMENT', 'NDG', 'ADMISSIBLE','REJECTED')")
BigDecimal findTotalAmountRequestedOfApplication(@Param("hubId") Long hubId);
@Query("SELECT SUM(a.amountAccepted) " +
"FROM ApplicationEntity a " +
"WHERE a.hubId = :hubId AND a.status = 'APPROVED'")
BigDecimal findTotalAmountAcceptedOfApplication(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'SUBMIT' AND a.isDeleted = false")
public Long countApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'EVALUATION' AND a.isDeleted = false")
Long countAssignedApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'APPROVED' AND a.isDeleted = false")
Long countApprovedApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'SOCCORSO' AND a.isDeleted = false")
Long countSoccorsoApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT a.id FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.isDeleted = false")
List<Long> findApplicationIdsByHubId(@Param("hubId") Long hubId);
} }

View File

@@ -47,6 +47,10 @@ public interface CallRepository extends JpaRepository<CallEntity, Long> {
BigDecimal findTotalAmountOfPublishedCallsAndHubId(@Param("hubId") Long hubId); BigDecimal findTotalAmountOfPublishedCallsAndHubId(@Param("hubId") Long hubId);
@Query("SELECT c FROM CallEntity c WHERE c.id IN :ids AND c.status IN :status") @Query("SELECT c FROM CallEntity c WHERE c.id IN :ids AND c.status IN :status")
List<CallEntity> findByIdInAndStatusIn(@Param("ids") List<Long> ids, @Param("status") List<String> status); List<CallEntity> findByIdInAndStatusIn(@Param("ids") List<Long> ids, @Param("status") List<String> status);
@Query("SELECT SUM(c.amount) FROM CallEntity c WHERE c.hub.id = :hubId AND c.status = 'PUBLISH'")
BigDecimal findTotalAmountOfPublishedCalls(@Param("hubId") Long hubId);
List<CallEntity> findByIdIn(@Param("ids") List<Long> ids); List<CallEntity> findByIdIn(@Param("ids") List<Long> ids);
} }

View File

@@ -0,0 +1,13 @@
package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.ExpirationConfigEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ExpirationConfigRepository extends JpaRepository<ExpirationConfigEntity, Long> {
List<ExpirationConfigEntity> findByTypeAndIsDeletedFalse(String type);
}

View File

@@ -1,10 +1,18 @@
package net.gepafin.tendermanagement.repositories; package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.UserActionEntity; import net.gepafin.tendermanagement.entities.UserActionEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
@Repository @Repository
public interface UserActionsRepository extends JpaRepository<UserActionEntity, Long> { public interface UserActionsRepository extends JpaRepository<UserActionEntity, Long> {
UserActionEntity findUserActionById(Long id); UserActionEntity findUserActionById(Long id);
UserActionEntity findUserActionByIdAndIsDeletedFalse(Long id);
} }

View File

@@ -0,0 +1,125 @@
package net.gepafin.tendermanagement.scheduler;
import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao;
import net.gepafin.tendermanagement.dao.ApplicationEvaluationDao;
import net.gepafin.tendermanagement.dao.NotificationDao;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.ExpirationTypeEnum;
import net.gepafin.tendermanagement.enums.NotificationTypeEnum;
import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository;
import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository;
import net.gepafin.tendermanagement.repositories.ExpirationConfigRepository;
import net.gepafin.tendermanagement.service.ApplicationService;
import net.gepafin.tendermanagement.service.CompanyService;
import net.gepafin.tendermanagement.service.UserService;
import net.gepafin.tendermanagement.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class ExpirationScheduler {
@Autowired
private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository;
@Autowired
private ApplicationEvaluationRepository applicationEvaluationRepository;
@Autowired
private ExpirationConfigRepository expirationNotificationConfigRepository;
@Autowired
private ApplicationEvaluationDao applicationEvaluationDao;
@Autowired
private ApplicationAmendmentRequestDao applicationAmendmentRequestDao;
@Autowired
private UserService userService;
@Autowired
private ApplicationService applicationService;
@Autowired
private NotificationDao notificationDao;
@Autowired
private CompanyService companyService;
private static final Logger log = LoggerFactory.getLogger(ExpirationScheduler.class);
@Scheduled(cron = "0 0 3 * * ?")
public void processExpiration(){
log.info("Starting the Expiration scheduler...");
try {
Utils.setHttpServletRequestForScheduler();
log.info("Starting processing expiration notifications for Amendment");
processExpiration(ExpirationTypeEnum.AMENDMENT);
log.info("Starting processing expiration notifications for Evaluation");
processExpiration(ExpirationTypeEnum.EVALUATION);
log.info("Expiration scheduler completed successfully.");
}
catch (Exception e){
log.error("An error occurred during the Notification Expiration Scheduler: {}", e.getMessage(), e);
}
}
private void processExpiration(ExpirationTypeEnum type) {
List<ExpirationConfigEntity> configEntities = expirationNotificationConfigRepository.findByTypeAndIsDeletedFalse(type.getValue());
for (ExpirationConfigEntity config : configEntities) {
Long daysBefore = config.getIntervalDays();
LocalDateTime now = LocalDateTime.now();
LocalDateTime startDate = now.plusDays(daysBefore).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime endDate = startDate.plusDays(1).minusNanos(1).withNano(0);
if (ExpirationTypeEnum.AMENDMENT.equals(type)) {
processAmendmentExpiration(startDate, endDate, daysBefore);
} else if (ExpirationTypeEnum.EVALUATION.equals(type)) {
processEvaluationExpiration(startDate, endDate, daysBefore);
}
}
}
private void processAmendmentExpiration(LocalDateTime startDate, LocalDateTime endDate, Long daysBefore) {
List<ApplicationAmendmentRequestEntity> amendmentEntities = applicationAmendmentRequestRepository.findExpiringBetween(startDate, endDate);
for (ApplicationAmendmentRequestEntity entity : amendmentEntities) {
ApplicationEntity application = entity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication();
Map<String, String> placeHolders = replacePlaceholders(application,daysBefore);
notificationDao.sendNotificationToInstructor(placeHolders,entity.getApplicationEvaluationEntity(), NotificationTypeEnum.AMENDMENT_EXPIRATION_REMINDER);
}
}
private Map<String, String> replacePlaceholders (ApplicationEntity application, Long daysBefore){
Long companyId = application.getCompanyId();
CompanyEntity company = companyService.validateCompany(companyId);
Map<String, String> placeHolders = new HashMap<>();
placeHolders.put("{{call_name}}",application.getCall().getName());
placeHolders.put("{{company_name}}", company.getCompanyName());
placeHolders.put("{{days_before}}", daysBefore.toString());
return placeHolders;
}
private void processEvaluationExpiration(LocalDateTime startDate, LocalDateTime endDate, Long daysBefore) {
List<ApplicationEvaluationEntity> evaluationEntities = applicationEvaluationRepository.findExpiringBetween(startDate, endDate);
for (ApplicationEvaluationEntity entity : evaluationEntities) {
ApplicationEntity application = entity.getAssignedApplicationsEntity().getApplication();
Map<String, String> placeHolders = replacePlaceholders(application,daysBefore);
notificationDao.sendNotificationToInstructor(placeHolders,entity,NotificationTypeEnum.EVALUATION_EXPIRATION_REMINDER);
}
}
}

View File

@@ -1,6 +1,7 @@
package net.gepafin.tendermanagement.service; package net.gepafin.tendermanagement.service;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
@@ -9,5 +10,5 @@ public interface DashboardService {
public SuperAdminWidgetResponseBean getDashboardWidgetForSuperAdmin(HttpServletRequest request); public SuperAdminWidgetResponseBean getDashboardWidgetForSuperAdmin(HttpServletRequest request);
public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId); public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId);
public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request);
} }

View File

@@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.dao.DashboardDao; import net.gepafin.tendermanagement.dao.DashboardDao;
import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.CompanyEntity;
import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.service.DashboardService; import net.gepafin.tendermanagement.service.DashboardService;
@@ -32,4 +33,10 @@ public class DashboardServiceImpl implements DashboardService {
CompanyEntity company = validator.validateUserWithCompany(request, companyId); CompanyEntity company = validator.validateUserWithCompany(request, companyId);
return dashboardDao.getDashboardWidgetForBeneficiary(userEntity, company); return dashboardDao.getDashboardWidgetForBeneficiary(userEntity, company);
} }
@Override
public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request) {
UserEntity userEntity=validator.validateUser(request);
return dashboardDao.getApplicationDetails(userEntity);
}
} }

View File

@@ -41,6 +41,8 @@ public class LoggingUtil {
@Autowired @Autowired
private TokenProvider tokenProvider; private TokenProvider tokenProvider;
private static final ThreadLocal<Long> userActionIdHolder = new ThreadLocal<>();
public UserActionEntity logUserAction(UserActionRequest userActionRequest) { public UserActionEntity logUserAction(UserActionRequest userActionRequest) {
UserActionEntity userAction = new UserActionEntity(); UserActionEntity userAction = new UserActionEntity();
try { try {
@@ -83,12 +85,22 @@ public class LoggingUtil {
userAction.setResponse(response); userAction.setResponse(response);
userActionsRepository.save(userAction); userActionsRepository.save(userAction);
userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId());
userActionIdHolder.set(userAction.getId());
} catch (Exception e) { } catch (Exception e) {
log.error("Error logging user action: {}", e.getMessage(), e); log.error("Error logging user action: {}", e.getMessage(), e);
} }
return userAction; return userAction;
} }
public Long getUserActionId() {
return userActionIdHolder.get();
}
public void clearUserActionId() {
userActionIdHolder.remove();
log.info("UserActionId cleared from ThreadLocal");
}
private String normalizeUrl(String url) { private String normalizeUrl(String url) {
url = url.replaceAll("(?<!:)//+", "/"); url = url.replaceAll("(?<!:)//+", "/");
@@ -263,6 +275,7 @@ public class LoggingUtil {
userAction.setResponse(response); userAction.setResponse(response);
userActionsRepository.save(userAction); userActionsRepository.save(userAction);
userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId());
} catch (Exception e) { } catch (Exception e) {
log.error("Error logging user action: {}", e.getMessage(), e); log.error("Error logging user action: {}", e.getMessage(), e);
} }
@@ -323,10 +336,35 @@ public class LoggingUtil {
public UserActionEntity getUserActionLogById(Long id) { public UserActionEntity getUserActionLogById(Long id) {
return userActionsRepository.findUserActionById(id); return userActionsRepository.findUserActionByIdAndIsDeletedFalse(id);
} }
public List<VersionHistoryEntity> getVersionHistoryLogById(Long id) { public List<VersionHistoryEntity> getVersionHistoryLogById(Long id) {
return versionHistoryRepository.findVersionHistoryByUserActionId(id); return versionHistoryRepository.findVersionHistoryByUserActionId(id);
} }
public void updateUserActionWithError(Long userActionId, String errorDetails) {
if (userActionId == null) {
return;
}
UserActionEntity userAction = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId);
if (userAction != null) {
userAction.setResponse(errorDetails);
userActionsRepository.save(userAction);
}
}
public void updateUserActionWithResponse(Long userActionId, String response) {
if (userActionId == null) {
return;
}
UserActionEntity userAction = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId);
if (userAction != null) {
userAction.setResponse(response);
userActionsRepository.save(userAction);
}
}
} }

View File

@@ -0,0 +1,148 @@
package net.gepafin.tendermanagement.util;
import com.amazonaws.services.alexaforbusiness.model.UnauthorizedException;
import jakarta.persistence.EntityNotFoundException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.server.ResponseStatusException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.AccessDeniedException;
import java.util.LinkedHashMap;
import java.util.Map;
@Aspect
@Component
@Slf4j
public class UserActionAspect {
@Autowired
private LoggingUtil loggingUtil;
@Around("execution(public * net.gepafin.tendermanagement.web.rest.api.impl..*(..))")
public Object logApiResponse(ProceedingJoinPoint joinPoint) throws Throwable {
Object result;
HttpServletRequest request = getRequestFromContext();
try {
Long userActionId = getUserActionIdFromRequest(request);
if (userActionId != null) {
request.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId);
log.info("Stored userActionId in RequestContext: {}", userActionId);
} else {
userActionId = loggingUtil.getUserActionId();
if (userActionId != null) {
request.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId);
}
}
result = joinPoint.proceed();
if (result instanceof ResponseEntity<?>) {
Long storedUserActionId = (Long) request.getAttribute(GepafinConstant.USER_ACTION_ID);
handleSuccessResponse((ResponseEntity<?>) result, storedUserActionId == null ? userActionId : storedUserActionId);
}
} catch (Exception ex) {
log.error("Exception occurred: ", ex);
handleError(ex, getUserActionIdFromRequest(request));
throw ex;
} finally {
loggingUtil.clearUserActionId();
}
return result;
}
private void handleSuccessResponse(ResponseEntity<?> responseEntity, Long userActionId) {
if (userActionId != null) {
Map<String, Object> responseWithUserAction = new LinkedHashMap<>();
responseWithUserAction.put(GepafinConstant.STATUS_CODE_STRING, responseEntity.getStatusCode().value());
// Log and update user action
loggingUtil.updateUserActionWithResponse(userActionId, Utils.convertMapIntoJsonString(responseWithUserAction));
log.info("Updated userActionId with response: {}", userActionId);
}
}
private void handleError(Throwable ex, Long userActionId) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
HttpStatus status = getStatusCodeFromException(ex);
log.info("Status Code received from exception : {}", status);
String errorMessage = ex.getMessage();
Map<String, Object> errorResponse = new LinkedHashMap<>();
errorResponse.put(GepafinConstant.STATUS_CODE_STRING, status.value());
errorResponse.put(GepafinConstant.GET_STATUS_CODE_STRING, status);
errorResponse.put(GepafinConstant.MESSAGE_STRING, errorMessage);
if (userActionId != null) {
String errorDetails = Utils.convertMapIntoJsonString(errorResponse);
loggingUtil.updateUserActionWithError(userActionId, errorDetails);
log.info("Updated userActionId with error details: {}", userActionId);
}
}
private HttpServletRequest getRequestFromContext() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return attributes != null ? attributes.getRequest() : null;
}
private Long getUserActionIdFromRequest(HttpServletRequest request) {
if (request != null) {
Object userActionIdAttr = request.getAttribute(GepafinConstant.USER_ACTION_ID);
return userActionIdAttr != null ? Long.valueOf(userActionIdAttr.toString()) : null;
}
return null;
}
private HttpStatus getStatusCodeFromException(Throwable ex) {
if (ex instanceof ResourceNotFoundException) {
return HttpStatus.NOT_FOUND;
}
if (ex instanceof ResponseStatusException responseStatusException) {
return (HttpStatus) responseStatusException.getStatusCode();
}
if (ex instanceof CustomValidationException) {
return HttpStatus.BAD_REQUEST;
}
if (ex instanceof EntityNotFoundException) {
return HttpStatus.NOT_FOUND;
}
if (ex instanceof IllegalArgumentException || ex instanceof MissingServletRequestParameterException || ex instanceof MethodArgumentNotValidException) {
return HttpStatus.BAD_REQUEST;
}
if (ex instanceof AccessDeniedException) {
return HttpStatus.FORBIDDEN;
}
if (ex instanceof UnauthorizedException) {
return HttpStatus.UNAUTHORIZED;
}
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}

View File

@@ -154,6 +154,9 @@ public class Utils {
public static String convertMapIntoJsonString(Map<String, Object> map) { public static String convertMapIntoJsonString(Map<String, Object> map) {
try { try {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
if (MapUtils.isNotEmpty(map)) { if (MapUtils.isNotEmpty(map)) {
return mapper.writeValueAsString(map); return mapper.writeValueAsString(map);
} }

View File

@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.model.util.Response;
@@ -47,6 +48,18 @@ public interface DashboardApi {
ResponseEntity<Response<BeneficiaryWidgetResponseBean>> getDashboardWidgetForBeneficiary(HttpServletRequest request, ResponseEntity<Response<BeneficiaryWidgetResponseBean>> getDashboardWidgetForBeneficiary(HttpServletRequest request,
@Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId); @Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId);
@Operation(summary = "Api to get Application details",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "/application",
produces = { "application/json" })
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')")
ResponseEntity<Response<ApplicationWidgetResponseBean>> getApplicationDetails(HttpServletRequest request);
} }

View File

@@ -6,6 +6,7 @@ import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionContextEnum;
import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum;
import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.UserActionRequest;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.model.util.Response;
@@ -49,5 +50,14 @@ public class DashboardApiController implements DashboardApi {
return ResponseEntity.status(HttpStatus.CREATED) return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY)));
} }
@Override
public ResponseEntity<Response<ApplicationWidgetResponseBean>> getApplicationDetails(HttpServletRequest request) {
/** This code is responsible for creating user action logs for the "Get complete application page" operation. **/
loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_DETAILS).build());
ApplicationWidgetResponseBean widgetResponseBean= dashboardService.getApplicationDetails(request);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY)));
}
} }

View File

@@ -2093,6 +2093,11 @@
<column name="closing_date" type="TIMESTAMP WITHOUT TIME ZONE"></column> <column name="closing_date" type="TIMESTAMP WITHOUT TIME ZONE"></column>
</addColumn> </addColumn>
</changeSet> </changeSet>
<changeSet id="03-01-2025_RK_191100" author="Rajesh Khore">
<addColumn tableName="application_evaluation">
<column name="ACTIVE_DAYS" type="INTEGER"></column>
</addColumn>
</changeSet>
<changeSet id="13-12-2024_1" author="Piyush Kag"> <changeSet id="13-12-2024_1" author="Piyush Kag">
<createTable tableName="notification"> <createTable tableName="notification">
@@ -2159,4 +2164,43 @@
path="db/dump/update_form_field_data_03_01_2025.sql"/> path="db/dump/update_form_field_data_03_01_2025.sql"/>
</changeSet> </changeSet>
<changeSet id="07-01-2025_NK_063910" author="Nisha Kashyap">
<createTable tableName="expiration_config">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="expiration_config_pkey"/>
</column>
<column name="INTERVAL_DAYS" type="INTEGER"></column>
<column name="TYPE" type="VARCHAR(255)"></column>
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE"></column>
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"></column>
</createTable>
</changeSet>
<changeSet id="07-01-2025_NK_064515" author="Nisha kashyap">
<sqlFile dbms="postgresql"
path="db/dump/update_json_template_for_notification_03_01_2025.sql"/>
</changeSet>
<changeSet id="07-01-2025_NK_064516" author="Nisha kashyap">
<sqlFile dbms="postgresql"
path="db/dump/insert_expiration_scheduler_data_07_01_2025.sql"/>
</changeSet>
<changeSet id="13-01-2025_RK_191315" author="Rajesh Khore">
<addColumn tableName="company">
<column name="CODICE_ATECO" type="VARCHAR(286)">
</column>
</addColumn>
</changeSet>
<changeSet id="08-01-2025_NK_075410" author="Nisha kashyap">
<addColumn tableName="application">
<column name="amount_requested" type="numeric"></column>
<column name="amount_accepted" type="numeric"></column>
<column name="date_accepted" type="TIMESTAMP WITHOUT TIME ZONE"></column>
<column name="date_rejected" type="TIMESTAMP WITHOUT TIME ZONE"></column>
</addColumn>
</changeSet>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -0,0 +1,9 @@
INSERT INTO expiration_config (interval_days, type, created_date, updated_date)
VALUES
(5, 'AMENDMENT', '2024-12-03T11:00:51', '2024-12-03T11:00:51'),
(2, 'AMENDMENT', '2024-12-03T11:00:51', '2024-12-03T11:00:51'),
(0, 'AMENDMENT', '2024-12-03T11:00:51', '2024-12-03T11:00:51'),
(5, 'EVALUATION', '2024-12-03T11:00:51', '2024-12-03T11:00:51'),
(2, 'EVALUATION', '2024-12-03T11:00:51', '2024-12-03T11:00:51'),
(0, 'EVALUATION', '2024-12-03T11:00:51', '2024-12-03T11:00:51');

View File

@@ -0,0 +1,3 @@
INSERT INTO notification_type (notification_name,title, json_template,created_date,updated_date,is_deleted) VALUES
('AMENDMENT_EXPIRATION_REMINDER','Lemendamento sta per scadere','Lemendamento per {{call_name}} - {{company_name}} scadrà tra {{days_before}} giorni. Assicurati che tutte le azioni necessarie siano completate prima della scadenza.','2025-01-03T10:16:26.472Z','2025-01-03T10:16:26.472Z','false'),
('EVALUATION_EXPIRATION_REMINDER','La valutazione sta per scadere','Lemendamento per {{call_name}} - {{company_name}} scadrà tra {{days_before}} giorni. Assicurati che tutte le azioni necessarie siano completate prima della scadenza.','2025-01-03T10:16:26.472Z','2025-01-03T10:16:26.472Z','false');

View File

@@ -346,3 +346,4 @@ notification.sent.successfully=Notification sent successfully.
notification.deleted.successfully=Notification deleted successfully. notification.deleted.successfully=Notification deleted successfully.
notification.updated.successfully=Notification updated successfully. notification.updated.successfully=Notification updated successfully.
user.with.company.not.found = User with company not found for user or company. user.with.company.not.found = User with company not found for user or company.
amount.accepted.required=Amount accepted is required while approving the application.

View File

@@ -329,7 +329,6 @@ appointment.created.successfully = Appuntamento creato con successo.
error.try.again = Errore di chiamata di servizio durante l'esecuzione dell'operazione. Riprovare. error.try.again = Errore di chiamata di servizio durante l'esecuzione dell'operazione. Riprovare.
document.uploading.is.in.progress = Il documento ? in fase di caricamento. document.uploading.is.in.progress = Il documento ? in fase di caricamento.
all.document.checked.and.one.checklist.checked=Tutti i documenti devono essere controllati e almeno una checklist deve essere controllata. all.document.checked.and.one.checklist.checked=Tutti i documenti devono essere controllati e almeno una checklist deve essere controllata.
<<<<<<< HEAD
#notification messsages #notification messsages
notification.already.in.state=La notifica � gi� nello stato fornito. notification.already.in.state=La notifica � gi� nello stato fornito.
@@ -339,5 +338,4 @@ notification.sent.successfully=Notifica inviata con successo.
notification.deleted.successfully=Notifica eliminata con successo. notification.deleted.successfully=Notifica eliminata con successo.
notification.updated.successfully=Notifica aggiornata con successo. notification.updated.successfully=Notifica aggiornata con successo.
user.with.company.not.found = Utente con azienda non trovato per utente o azienda. user.with.company.not.found = Utente con azienda non trovato per utente o azienda.
======= amount.accepted.required=L'importo accettato è obbligatorio durante l'approvazione della domanda.
>>>>>>> 832666a4d412c2c81f5c1dfb5b1866aba2c40bdd