Resolved conflict

This commit is contained in:
rajesh
2026-03-17 15:48:47 +05:30
5 changed files with 152 additions and 5 deletions

View File

@@ -1266,6 +1266,7 @@ public class ApplicationAmendmentRequestDao {
log.info("Updating application amendment with status: {}", id);
ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id);
ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment);
if (Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) && Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))) {
if (existingApplicationAmendment.getStartDate() == null) {
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.AMENDMENT_MUST_BE_APPROVED_FIRST_MSG));
@@ -1274,11 +1275,10 @@ public class ApplicationAmendmentRequestDao {
existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue());
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
applicationAmendmentRequestRepository.save(existingApplicationAmendment);
/** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(existingApplicationAmendment).build());
}
ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment,false);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment, false);
log.info("Amendment status updated successfully: {}", response);
return response;
}

View File

@@ -427,7 +427,9 @@ public class EmailNotificationDao {
if(Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED.getValue()))
|| Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_ADMISSIBLE.getValue()))
|| Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_REJECTED.getValue()))
|| Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REQUESTED.getValue()))) {
|| Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REQUESTED.getValue()))
|| Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.getValue()))
|| Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED_BLUE_TONGUE.getValue()))) {
isSendEmail = Boolean.FALSE;
}
}

View File

@@ -6,6 +6,9 @@ import lombok.extern.log4j.Log4j2;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import net.gepafin.tendermanagement.enums.AssignedApplicationEnum;
import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum;
import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum;
import net.gepafin.tendermanagement.enums.StatusTypeEnum;
@@ -13,6 +16,14 @@ import net.gepafin.tendermanagement.model.response.EmailLogResponse;
import net.gepafin.tendermanagement.model.response.PecEmailLogResponse;
import net.gepafin.tendermanagement.model.response.PecMailResponse;
import net.gepafin.tendermanagement.repositories.*;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository;
import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository;
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository;
import net.gepafin.tendermanagement.repositories.EmailLogRepository;
import net.gepafin.tendermanagement.repositories.UserActionsRepository;
import net.gepafin.tendermanagement.repositories.VersionHistoryRepository;
import net.gepafin.tendermanagement.service.ApplicationService;
import net.gepafin.tendermanagement.service.CallService;
import net.gepafin.tendermanagement.util.DateTimeUtil;
@@ -28,6 +39,8 @@ import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
@Log4j2
@@ -112,11 +125,139 @@ public class PecMailDao {
}
emailLogRepository.saveAll(emailLogs);
EmailLogEntity firstLog = emailLogs.get(0);
rollbackDomainChangesForRejectedEmail(firstLog, userActionId);
ApplicationEntity applicationEntity = applicationService.validateApplication(firstLog.getApplicationId());
String callName = applicationEntity.getCall().getName();
return createPecMailResponse(firstLog.getUserAction().getId(), firstLog, callName);
}
/**
* Rolls back domain changes using version history (audit) for the user action that triggered the email.
* Restores application, application_evaluation, and assigned_applications from oldData in version history.
*/
private void rollbackDomainChangesForRejectedEmail(EmailLogEntity firstLog, Long userActionId) {
if (firstLog == null || firstLog.getApplicationId() == null || firstLog.getEmailType() == null || userActionId == null) {
return;
}
String scenario = firstLog.getEmailType();
Long applicationId = firstLog.getApplicationId();
// Amendment email rejected (normal or special): revert application, then mark amendment REJECTED and soft-deleted
boolean isNormalAmendment = EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REQUESTED.getValue().equals(scenario);
boolean isSpecialAmendment = EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.getValue().equals(scenario)
|| EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED_BLUE_TONGUE.getValue().equals(scenario);
if (isNormalAmendment || isSpecialAmendment) {
ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId);
if (isNormalAmendment) {
List<VersionHistoryEntity> appHistory = versionHistoryRepository.findVersionHistoryByUserActionIdAndTableName(userActionId, TABLE_APPLICATION);
Optional<VersionHistoryEntity> applicationVersion = appHistory.stream()
.filter(v -> applicationId.equals(v.getRecordId()) && v.getOldData() != null && !v.getOldData().isEmpty())
.findFirst();
if (applicationVersion.isPresent()) {
Map<String, Object> oldDataMap = Utils.convertJsonStringToMap(applicationVersion.get().getOldData());
if (oldDataMap != null) {
String previousStatus = Utils.extractString(oldDataMap, "status");
if (previousStatus != null) {
applicationEntity.setStatus(previousStatus);
}
applicationRepository.save(applicationEntity);
log.info("Rolled back application id={} from version history after amendment email rejected (userActionId={})", applicationId, userActionId);
}
} else {
log.warn("No APPLICATION version history with oldData found for userActionId={}, applicationId={}; skipping application rollback", userActionId, applicationId);
}
} else {
applicationEntity.setStatus(ApplicationStatusTypeEnum.ADMISSIBLE.getValue());
applicationEntity.setDateRejected(null);
applicationRepository.save(applicationEntity);
log.info("Set application id={} to ADMISSIBLE after special amendment email rejected (userActionId={})", applicationId, userActionId);
}
markAmendmentRejectedAndDeleted(firstLog.getAmendmentId(), userActionId);
return;
}
// Only rollback for the three evaluation-outcome email scenarios
if (!EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED.getValue().equals(scenario)
&& !EmailScenarioTypeEnum.APPLICATION_REJECTED.getValue().equals(scenario)
&& !EmailScenarioTypeEnum.APPLICATION_ADMISSIBLE.getValue().equals(scenario)) {
return;
}
List<VersionHistoryEntity> appHistory = versionHistoryRepository.findVersionHistoryByUserActionIdAndTableName(userActionId, TABLE_APPLICATION);
Optional<VersionHistoryEntity> applicationVersion = appHistory.stream()
.filter(v -> applicationId.equals(v.getRecordId()) && v.getOldData() != null && !v.getOldData().isEmpty())
.findFirst();
ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId);
if (applicationVersion.isPresent()) {
Map<String, Object> oldDataMap = Utils.convertJsonStringToMap(applicationVersion.get().getOldData());
if (oldDataMap != null) {
String previousStatus = Utils.extractString(oldDataMap, "status");
if (previousStatus != null) {
applicationEntity.setStatus(previousStatus);
}
Object dateRejectedObj = oldDataMap.get("dateRejected");
applicationEntity.setDateRejected(parseLocalDateTimeFromAudit(dateRejectedObj));
applicationRepository.save(applicationEntity);
log.info("Rolled back application id={} from version history (userActionId={})", applicationId, userActionId);
}
} else {
log.warn("No APPLICATION version history with oldData found for userActionId={}, applicationId={}; skipping application rollback", userActionId, applicationId);
}
// Only set application_evaluation and assigned_applications to OPEN for REJECTED and TECHNICAL_EVALUATION_REJECTED (not for ADMISSIBLE)
boolean reopenEvaluationAndAssigned = EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED.getValue().equals(scenario)
|| EmailScenarioTypeEnum.APPLICATION_REJECTED.getValue().equals(scenario);
if (!reopenEvaluationAndAssigned) {
return;
}
applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId).ifPresent(evaluation -> {
evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue());
evaluation.setClosingDate(null);
evaluation.setActiveDays(null);
applicationEvaluationRepository.save(evaluation);
log.info("Set application_evaluation id={} to OPEN (userActionId={})", evaluation.getId(), userActionId);
});
assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).ifPresent(assigned -> {
assigned.setStatus(AssignedApplicationEnum.OPEN.getValue());
assignedApplicationsRepository.save(assigned);
log.info("Set assigned_applications id={} to OPEN (userActionId={})", assigned.getId(), userActionId);
});
}
private void markAmendmentRejectedAndDeleted(Long amendmentId, Long userActionId) {
if (amendmentId == null) {
return;
}
applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId).ifPresent(amendment -> {
amendment.setStatus(ApplicationAmendmentRequestEnum.REJECTED.getValue());
amendment.setIsDeleted(true);
applicationAmendmentRequestRepository.save(amendment);
log.info("Set amendment id={} to REJECTED and is_deleted=true after amendment email rejected (userActionId={})", amendmentId, userActionId);
});
}
private static LocalDateTime parseLocalDateTimeFromAudit(Object value) {
if (value == null) {
return null;
}
if (value instanceof String str && !str.isEmpty()) {
try {
return DateTimeUtil.parseStringToLocalDateTime(str);
} catch (Exception e) {
return null;
}
}
return null;
}
private List<EmailLogEntity> getEmailLogEntities(HttpServletRequest request, Long userActionId) {
UserActionEntity userActionEntity = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId);
if (userActionEntity == null) {

View File

@@ -9,7 +9,9 @@ public enum ApplicationAmendmentRequestEnum {
AWAITING("AWAITING"),
RESPONSE_RECEIVED("RESPONSE_RECEIVED"),
CLOSE("CLOSE"),
EXPIRED("EXPIRED");
EXPIRED("EXPIRED"),
/** Special amendment PEC email was rejected; amendment status set to REJECTED. */
REJECTED("REJECTED");
private String value;

View File

@@ -13,4 +13,6 @@ public interface VersionHistoryRepository extends JpaRepository<VersionHistoryEn
List<VersionHistoryEntity> findVersionHistoryByUserActionIdAndUserIdNull(Long id);
List<VersionHistoryEntity> findVersionHistoryByUserActionId(Long id);
List<VersionHistoryEntity> findVersionHistoryByUserActionIdAndTableName(Long userActionId, String tableName);
}