Merge branch 'develop' of https://github.com/Kitzanos/GEPAFIN-BE into develop
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -245,6 +245,12 @@
|
|||||||
<artifactId>reactor-netty</artifactId>
|
<artifactId>reactor-netty</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.15.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package net.gepafin.tendermanagement.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class JacksonConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ObjectMapper objectMapper() {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.registerModule(new JavaTimeModule());
|
||||||
|
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -355,5 +355,10 @@ 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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ 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.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;
|
||||||
@@ -1800,6 +1802,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);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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;
|
||||||
@@ -13,6 +14,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
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,6 +42,9 @@ public class DashboardDao {
|
|||||||
private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository;
|
private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEvaluationRepository applicationEvaluationRepository;
|
||||||
|
|
||||||
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));
|
||||||
@@ -133,4 +141,70 @@ public class DashboardDao {
|
|||||||
}
|
}
|
||||||
return beneficiaryWidgetResponseBean;
|
return beneficiaryWidgetResponseBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ 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 +33,27 @@ 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 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
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,4 +44,20 @@ 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 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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ import org.springframework.stereotype.Repository;
|
|||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface UserActionsRepository extends JpaRepository<UserActionEntity, Long> {
|
public interface UserActionsRepository extends JpaRepository<UserActionEntity, Long> {
|
||||||
UserActionEntity findUserActionById(Long id);
|
UserActionEntity findUserActionByIdAndIsDeletedFalse(Long id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user