Created new endpoint for application and fixed amendment issue

This commit is contained in:
rajesh
2026-03-30 19:56:45 +05:30
parent 4a46cf68af
commit 3f25753515
13 changed files with 186 additions and 8 deletions

View File

@@ -205,6 +205,8 @@ public class GepafinConstant {
public static final String CALL_ALREADY_ENDED = "call.already.ended";
public static final String APPLICATION_STATUS_UPDATED_SUCCESSFULLY = "application.status.updated.successfully";
public static final String APPLICATION_ALREADY_IN_PREVIOUS_STATUS = "application.already.in.provided.status";
public static final String APPLICATION_STATUS_TRANSITION_RESTRICTED = "application.status.transition.restricted";
public static final String APPLICATION_REGISTRY_SEGMENT_INVALID = "application.registry.segment.invalid";
public static final String DELEGATION_NOT_FOUND = "delegation.not.found";
public static final String USER_COMPANY_RELATION_NOT_FOUND = "user.company.relation.not.found";
public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success";

View File

@@ -1164,8 +1164,12 @@ public class ApplicationAmendmentRequestDao {
applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity());
log.info("Updated ApplicationEvaluation status to OPEN for ID: {}", existingApplicationEvaluationEntity.getId());
if(Boolean.FALSE.equals(existingApplicationAmendment.getType().equals(ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue()))){
application.setStatus(application.getPreviousStatus());
String previousApplicationStatus = application.getPreviousStatus();
if (previousApplicationStatus != null) {
application.setStatus(previousApplicationStatus);
} else if (ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue().equals(existingApplicationAmendment.getType())) {
application.setStatus(ApplicationStatusTypeEnum.ADMISSIBLE.getValue());
log.warn("Special amendment close: previousStatus was null for applicationId={}, defaulting to ADMISSIBLE", application.getId());
}
applicationRepository.save(application);
log.info("Updated Application status to previous state for Application ID: {}", application.getId());
@@ -1222,8 +1226,22 @@ public class ApplicationAmendmentRequestDao {
applicationAmendmentRequestEntity.setExtensionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(newResponseDays)));
applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue());
applicationAmendmentRequestEntity.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue());
ApplicationEvaluationEntity evaluationEntity = applicationAmendmentRequestEntity.getApplicationEvaluationEntity();
ApplicationEvaluationEntity oldEvaluationEntity = Utils.getClonedEntityForData(evaluationEntity);
evaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequestEntity.getApplicationId());
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
if (ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue().equals(applicationAmendmentRequestEntity.getType())) {
applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING_TECHNICAL_EVALUATION.getValue());
} else {
applicationEntity.setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue());
}
applicationEvaluationRepository.save(evaluationEntity);
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldEvaluationEntity).newData(evaluationEntity).build());
applicationRepository.save(applicationEntity);
/** Version history for application when extending a special amendment (aligned with create special amendment). **/
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build());
applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
/** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/
@@ -1910,6 +1928,15 @@ public class ApplicationAmendmentRequestDao {
if(Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.ADMISSIBLE.getValue()))) {
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS));
}
List<ApplicationAmendmentRequestEntity> existingAmendmentsForEval = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId());
boolean noneClosedOrExpiredForSpecial = existingAmendmentsForEval.stream()
.noneMatch(amendment ->
amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()) ||
amendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue())
);
if (Boolean.TRUE.equals(noneClosedOrExpiredForSpecial)) {
applicationEntity.setPreviousStatus(oldApplicationEntity.getStatus());
}
ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity();
if(Boolean.TRUE.equals(applicationAmendmentRequest.getAmendmentDocumentType().equals(AmendmentDocumentTypeEnum.ALTRE_GARANZIE))) {
applicationAmendmentRequestEntity.setResponseDays(20l);

View File

@@ -69,6 +69,7 @@ import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
@@ -1047,6 +1048,10 @@ public class ApplicationDao {
log.info("Updating status for Application id : " + applicationId);
ApplicationEntity applicationEntity = validateApplication(applicationId);
if (ApplicationStatusTypeEnum.DELETED.equals(status) || ApplicationStatusTypeEnum.DELETED_CONFIRMED.equals(status)) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_TRANSITION_RESTRICTED));
}
log.info("Call end date verified successfully | callId: {}", applicationEntity.getCall().getId());
//cloned entity for old application data
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
@@ -1120,6 +1125,83 @@ public class ApplicationDao {
return getApplicationResponse(applicationEntity);
}
/**
* Opaque registry segment update (restricted operators only). {@code segment} 1 → {@link ApplicationStatusTypeEnum#DELETED},
* 2 → {@link ApplicationStatusTypeEnum#DELETED_CONFIRMED}.
*/
public ApplicationResponse recordApplicationRegistrySegment(HttpServletRequest request, Long applicationId,ApplicationStatusTypeEnum status) {
validator.validateSuperAdminOrDirector();
validator.validateUser(request);
if (Boolean.FALSE.equals(status.equals(ApplicationStatusTypeEnum.DELETED)) && Boolean.FALSE.equals(status.equals(ApplicationStatusTypeEnum.DELETED_CONFIRMED))) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_REGISTRY_SEGMENT_INVALID));
}
ApplicationEntity applicationEntity = validateApplication(applicationId);
if (Boolean.FALSE.equals(validator.checkIsSuperAdmin())) {
validator.validateHubId(request, applicationEntity.getHubId());
}
if (status.getValue().equals(applicationEntity.getStatus())) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS));
}
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
applicationEntity.setStatus(status.getValue());
applicationEntity = applicationRepository.save(applicationEntity);
closeAmendmentsEvaluationAndAssignedApplicationForRegistry(request, applicationId);
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build());
log.info("Registry segment persisted | applicationId={}, status={}", applicationId, status);
return getApplicationResponse(applicationEntity);
}
/**
* Sets all non-terminal amendments, the application evaluation (if any), and the assigned application row to CLOSE.
*/
private void closeAmendmentsEvaluationAndAssignedApplicationForRegistry(HttpServletRequest httpRequest, Long applicationId) {
LocalDateTime nowUtc = DateTimeUtil.DateServerToUTC(LocalDateTime.now());
List<ApplicationAmendmentRequestEntity> amendments = applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId);
for (ApplicationAmendmentRequestEntity amendment : amendments) {
if (ApplicationAmendmentRequestEnum.CLOSE.getValue().equals(amendment.getStatus())
|| ApplicationAmendmentRequestEnum.EXPIRED.getValue().equals(amendment.getStatus())
|| ApplicationAmendmentRequestEnum.REJECTED.getValue().equals(amendment.getStatus())) {
continue;
}
ApplicationAmendmentRequestEntity oldAmendment = Utils.getClonedEntityForData(amendment);
amendment.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue());
amendment.setClosingDate(nowUtc);
applicationAmendmentRequestRepository.save(amendment);
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(httpRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendment).newData(amendment).build());
}
applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId).ifPresent(evaluation -> {
if (ApplicationEvaluationStatusTypeEnum.CLOSE.getValue().equals(evaluation.getStatus())) {
return;
}
ApplicationEvaluationEntity oldEvaluation = Utils.getClonedEntityForData(evaluation);
evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue());
evaluation.setClosingDate(nowUtc);
if (evaluation.getStartDate() != null && evaluation.getClosingDate() != null) {
long activeDays = ChronoUnit.DAYS.between(evaluation.getStartDate(), evaluation.getClosingDate());
activeDays -= evaluation.getSuspendedDays() != null ? evaluation.getSuspendedDays() : 0;
evaluation.setActiveDays(activeDays);
}
applicationEvaluationRepository.save(evaluation);
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(httpRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldEvaluation).newData(evaluation).build());
});
assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).ifPresent(assigned -> {
if (AssignedApplicationEnum.CLOSE.getValue().equals(assigned.getStatus())) {
return;
}
AssignedApplicationsEntity oldAssigned = Utils.getClonedEntityForData(assigned);
assigned.setStatus(AssignedApplicationEnum.CLOSE.getValue());
assignedApplicationsRepository.save(assigned);
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(httpRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssigned).newData(assigned).build());
});
}
public Integer calculateProgress(Long totalSteps, Long completedSteps) {
if (FieldValidator.isNullOrZero(totalSteps)) {
throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.TOTAL_STEPS_NOT_BE_ZERO));

View File

@@ -8,7 +8,9 @@ public enum ApplicationStatusForEvaluation {
ADMISSIBLE("ADMISSIBLE"),
TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"),
AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION"),
TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED");
TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"),
DELETED("DELETED"),
DELETED_CONFIRMED("DELETED_CONFIRMED");;
private String value;

View File

@@ -20,7 +20,9 @@ public enum ApplicationStatusTypeEnum {
TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"),
AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION"),
AWAITING_CONTRACT("AWAITING_CONTRACT"),
CONTRACT_SIGNED("CONTRACT_SIGNED");
CONTRACT_SIGNED("CONTRACT_SIGNED"),
DELETED("DELETED"),
DELETED_CONFIRMED("DELETED_CONFIRMED");
private String value;

View File

@@ -9,7 +9,8 @@ public enum RoleStatusEnum {
ROLE_PRE_INSTRUCTOR("ROLE_PRE_INSTRUCTOR"),
ROLE_GEPAFIN_OPERATOR("ROLE_GEPAFIN_OPERATOR"),
ROLE_INSTRUCTOR_MANAGER("ROLE_INSTRUCTOR_MANAGER"),
ROLE_CONFIDI("ROLE_CONFIDI");
ROLE_CONFIDI("ROLE_CONFIDI"),
ROLE_DIRECTOR("ROLE_DIRECTOR");
private String value;

View File

@@ -34,6 +34,8 @@ public interface ApplicationService {
public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status);
ApplicationResponse recordApplicationRegistrySegment(HttpServletRequest request, Long applicationId,ApplicationStatusTypeEnum status);
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file);
public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId);

View File

@@ -107,6 +107,13 @@ public class ApplicationServiceImpl implements ApplicationService {
return applicationDao.updateApplicationStatus(request, applicationId, status);
}
@Override
@Transactional(rollbackFor = Exception.class)
public ApplicationResponse recordApplicationRegistrySegment(HttpServletRequest request, Long applicationId,ApplicationStatusTypeEnum status) {
UserEntity userEntity = validator.validateUser(request);
return applicationDao.recordApplicationRegistrySegment(request, applicationId, status);
}
@Override
@Transactional(readOnly = true)
public List<ApplicationResponse> getAllApplications(HttpServletRequest request, Long callId, Long companyId ,List<ApplicationStatusTypeEnum> statusList) {

View File

@@ -197,6 +197,26 @@ public class Validator {
}
return false;
}
public Boolean checkIsDirector() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
for (GrantedAuthority authority : authentication.getAuthorities()) {
if (RoleStatusEnum.ROLE_DIRECTOR.getValue().equals(authority.getAuthority())) {
return true;
}
}
}
return false;
}
/** Super admin (any hub) or director (hub must match application — enforced separately). */
public void validateSuperAdminOrDirector() {
if (Boolean.TRUE.equals(checkIsSuperAdmin()) || Boolean.TRUE.equals(checkIsDirector())) {
return;
}
throw new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
}
public Boolean checkIsConfidi() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {

View File

@@ -132,6 +132,21 @@ public interface ApplicationApi {
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId,
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationStatusTypeEnum status);
@Operation(summary = "Api to update application segment",
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) })) })
@PatchMapping(value = "/{applicationId}/segment", produces = { "application/json" })
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_DIRECTOR')")
ResponseEntity<Response<ApplicationResponse>> updateApplicationSegment(HttpServletRequest request,
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId,
@Parameter(description = "Application status", required = true) @RequestParam ApplicationStatusTypeEnum status);
@Operation(summary = "API to generate PDF for an application",
responses = {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/pdf")),

View File

@@ -22,6 +22,8 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@@ -141,6 +143,18 @@ public class ApplicationApiController implements ApplicationApi {
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY)));
}
@Override
public ResponseEntity<Response<ApplicationResponse>> updateApplicationSegment(HttpServletRequest request, Long applicationId,
ApplicationStatusTypeEnum status) {
loggingUtil.logUserAction(
UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_APPLICATION_STATUS).build());
ApplicationResponse applicationResponse = applicationService.recordApplicationRegistrySegment(request, applicationId, status);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY)));
}
@Override
public ResponseEntity<byte[]> generateApplicationPdf(HttpServletRequest request, Long applicationId) {

View File

@@ -230,6 +230,8 @@ call.not.started.yet = The call has not started yet. Please wait until the speci
call.already.ended = The call has already ended. You cannot submit the application after the deadline.
status.updated.successfully=Status updated successfully.
application.status.updated.successfully = Application status updated successfully.
application.status.transition.restricted=This status change is not available through this operation.
application.registry.segment.invalid=Invalid segment value.
application.already.in.provided.status=Application is already in provided status.
delegation.not.found=Delegation not found.
user.company.relation.not.found=User with the specified company relation not found.

View File

@@ -425,4 +425,6 @@ upload.company.document.to.application=Documento aziendale caricato correttament
company.document.not.found.with.ids=Documento aziendale non trovato. ID mancanti: {0}
amount.field.not.provided= Si prega di fornire i campi obbligatori per l'importo.
vat.or.tax.code.required=È obbligatorio il numero di partita IVA o il codice fiscale.
provide.valid.vat.number=Inserisci un numero di partita IVA valido per procedere con NDG.
provide.valid.vat.number=Inserisci un numero di partita IVA valido per procedere con NDG.
application.status.transition.restricted=Questa modifica di stato non è disponibile tramite questa operazione.
application.registry.segment.invalid=Valore del segmento non valido.