package net.gepafin.tendermanagement.dao; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.response.AmendmentFormFieldResponse; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component public class ApplicationAmendmentRequestDao { @Autowired private ApplicationService applicationService; @Autowired private FormRepository formRepository; @Autowired private UserService userService; @Autowired private ApplicationFormRepository applicationFormRepository; @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; @Autowired private ApplicationFormFieldRepository applicationFormFieldRepository; @Autowired private DocumentRepository documentRepository; public List getApplicationDataForAmendment(HttpServletRequest request,Long applicationId){ log.info("Fetching the application data for the Amendment process {}", applicationId); ApplicationEntity application = applicationService.validateApplication(applicationId); String callName = application.getCall().getName(); Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null; UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : ""; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : ""; String beneficiaryName = (!firstName.isBlank() ? firstName : "") + (!lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; List forms = applicationFormRepository.findByApplicationId(applicationId); List responses = new ArrayList<>(); for (ApplicationFormEntity form : forms) { String content = form.getForm().getContent(); List> result = filterByName(content, "fileupload"); List formFields = getIdAndLabelFromResult(result); ApplicationAmendmentRequestResponse response = convertEntityToResponse( protocolNumber, callName, formFields, beneficiaryName); responses.add(response); } return responses; } public List getIdAndLabelFromResult(List> result) { List formFieldResponses = new ArrayList<>(); for (Map item : result) { AmendmentFormFieldResponse formFieldResponse = new AmendmentFormFieldResponse(); formFieldResponse.setFieldId((String) item.get("id")); // Extract "label" value from the "settings" array List> settings = (List>) item.get("settings"); String label = settings.stream() .filter(setting -> "label".equals(setting.get("name"))) .map(setting -> (String) setting.get("value")) .findFirst() .orElse(""); // Default to empty string if not found if (label == null || label.trim().isEmpty()) { continue; } formFieldResponse.setLabel(label); // Set the label as fieldValue formFieldResponses.add(formFieldResponse); } return formFieldResponses; } private ApplicationAmendmentRequestResponse convertEntityToResponse( Long protocolNumber, String callName, List formFields,String beneficiaryName) { ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse(); response.setProtocolNumber(protocolNumber); response.setCallName(callName); response.setBeneficiaryName(beneficiaryName); response.setFormFields(formFields); response.setResponseDays(null); response.setSendEmail(false); response.setSendNotification(false); response.setNote(null); response.setStartDate(null); return response; } public static List> filterByName(String content, String target) { ObjectMapper objectMapper = new ObjectMapper(); List> filteredList = new ArrayList<>(); try { List> dataList = objectMapper.readValue( content, new TypeReference>>() {}); for (Map data : dataList) { if (target.equals(data.get("name"))) { filteredList.add(data); } } } catch (Exception e) { e.printStackTrace(); } return filteredList; } public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationId, ApplicationAmendmentRequest applicationAmendmentRequest){ log.info("Submiting application data for amendment Process with details: {}", applicationId); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest); ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity); log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); return applicationAmendmentRequestResponse; } public ApplicationAmendmentRequestEntity createApplicationAmendmentRequestEntity(ApplicationAmendmentRequest applicationAmendmentRequest){ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); if (applicationAmendmentRequest.getFormFields() != null) { String fieldIdsString = applicationAmendmentRequest.getFormFields().stream() .filter(AmendmentFormFieldResponse::isSelected) .map(AmendmentFormFieldResponse::getFieldId) .collect(Collectors.joining(",")); applicationAmendmentRequestEntity.setFormFields(fieldIdsString); } applicationAmendmentRequestEntity.setIsEmail(false); applicationAmendmentRequestEntity.setIsNotification(false); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); return applicationAmendment; } public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ ApplicationAmendmentRequestEntity applicationAmendmentRequest= applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity); return applicationAmendmentRequest; } public ApplicationAmendmentRequestResponse convertEntityToResponse(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = new ApplicationAmendmentRequestResponse(); applicationAmendmentRequestResponse.setId(applicationAmendmentRequestEntity.getId()); Long applicationId = 1L; ApplicationEntity application = applicationService.validateApplication(applicationId); applicationAmendmentRequestResponse.setNote(applicationAmendmentRequestEntity.getNote()); applicationAmendmentRequestResponse.setResponseDays(applicationAmendmentRequestEntity.getResponseDays()); applicationAmendmentRequestResponse.setStartDate(applicationAmendmentRequestEntity.getCreatedDate()); applicationAmendmentRequestResponse.setSendEmail(applicationAmendmentRequestEntity.getIsEmail()); applicationAmendmentRequestResponse.setSendNotification(applicationAmendmentRequestEntity.getIsNotification()); String callName = application.getCall().getName(); Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null; UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : ""; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : ""; String beneficiaryName = (!firstName.isBlank() ? firstName : "") + (!lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; applicationAmendmentRequestResponse.setCallName(callName); applicationAmendmentRequestResponse.setProtocolNumber(protocolNumber); applicationAmendmentRequestResponse.setBeneficiaryName(beneficiaryName); String formFieldsString = applicationAmendmentRequestEntity.getFormFields(); List storedFieldIds = (formFieldsString != null) ? Arrays.asList(formFieldsString.split(",")) : Collections.emptyList(); List applicationForms = applicationFormRepository.findByApplicationId(application.getId()); List formFields = new ArrayList<>(); for (ApplicationFormEntity formEntity : applicationForms) { String content = formEntity.getForm().getContent(); List> result = filterByName(content, "fileupload"); List matchingFields = getIdAndLabelFromResult(result).stream() .filter(field -> storedFieldIds.contains(field.getFieldId())) .collect(Collectors.toList()); formFields.addAll(matchingFields); } applicationAmendmentRequestResponse.setFormFields(formFields); List formField = formFields.stream() .map(field -> { AmendmentFormFieldResponse responseField = new AmendmentFormFieldResponse(); responseField.setFieldId(field.getFieldId()); responseField.setLabel(field.getLabel()); responseField.setSelected(true); return responseField; }) .collect(Collectors.toList()); applicationAmendmentRequestResponse.setFormFields(formFields); return applicationAmendmentRequestResponse; } public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long id){ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id).orElseThrow(()-> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); return applicationAmendmentRequestEntity; } public void deleteById(Long id) { log.info("Deleting assigned application with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity= validateApplicationAmendmentRequest(id); applicationAmendmentRequestEntity.setIsDeleted(true); applicationAmendmentRequestEntity= saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); log.info(" Application amendment deleted with ID: {}", id); } public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(Long id) { log.info("Fetching application amendment with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity); log.info("Application Amendment fetched successfully by ID: {}", response); return response; } public List getAllApplicationAmendmentRequest() { List applicationAmendmentRequestEntities = applicationAmendmentRequestRepository.findAll(); return applicationAmendmentRequestEntities.stream() .map(this::convertEntityToResponse) .collect(Collectors.toList()); } public ApplicationAmendmentRequestResponse updateApplicationAmendment( Long id, ApplicationAmendmentRequestBean updateRequest) { log.info("Updating application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); setIfUpdated(existingApplicationAmendment::getNote, existingApplicationAmendment::setNote, updateRequest.getNote()); if (updateRequest.getUpdatedFormFields() != null) { updateApplicationFormFields(existingApplicationAmendment, updateRequest.getUpdatedFormFields()); } existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); log.info("Application Amendment updated successfully: {}", response); return response; } private boolean documentExists(String documentId) { Long documentIdLong = Long.parseLong(documentId); // Convert to Long return documentRepository.existsById(documentIdLong); } private void updateApplicationFormFields(ApplicationAmendmentRequestEntity applicationAmendment, ApplicationFormFieldRequestBean updatedFormField) { List documentIds = Arrays.asList(updatedFormField.getFieldValue().toString().split(",")); for (String documentId : documentIds) { if (!documentExists(documentId)) { log.warn("Document with ID {} does not exist. Skipping update.", documentId); continue; } ApplicationFormFieldEntity formEntity = applicationFormFieldRepository.findByFieldId(updatedFormField.getFieldId()); if (formEntity != null) { formEntity.setFieldValue(updatedFormField.getFieldValue().toString()); applicationFormFieldRepository.save(formEntity); log.info("Updated field value for field ID {} with document IDs {}", updatedFormField.getFieldId(), updatedFormField.getFieldValue()); } else { log.warn("No ApplicationFormEntity found with field ID {}. Skipping update.", updatedFormField.getFieldId()); } } } }