diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 02a92762..f6e87839 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -159,7 +159,8 @@ public class ApplicationAmendmentRequestDao { String file=applicationEvaluationEntity.getFile(); String checkList=applicationEvaluationEntity.getChecklist(); if(file != null){ - evaluationFileRequests=Utils.convertJsonStringToList(file,FieldRequest.class); + log.info("Parsing evaluation file data for evaluationId={}", applicationEvaluationId); + evaluationFileRequests=Utils.convertJsonStringToList(file,FieldRequest.class); } if(applicationEvaluationEntity.getEvaluationVersion().equals(EvaluationVersionEnum.V1.getValue())) { checklistValidationForEvaluationV1(evaluationFileRequests, checkList, checklistRequests); @@ -326,6 +327,7 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); if(applicationAmendmentRequest.getResponseDays()==null || applicationAmendmentRequest.getResponseDays() < 0){ + log.warn("Invalid responseDays received: {}", applicationAmendmentRequest.getResponseDays()); throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL)); } applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays())); @@ -378,6 +380,8 @@ public class ApplicationAmendmentRequestDao { userEntity.getHub().getId(),false); applicationAmendmentRequestEntity.setProtocol(protocolEntity); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); + log.info("Amendment request saved with ID={}", applicationAmendment.getId()); + String evaluationStatusType = applicationEvaluationEntity.getStatus(); if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){ // applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); @@ -416,7 +420,7 @@ public class ApplicationAmendmentRequestDao { loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build()); } - + log.info("Amendment creation process completed successfully for applicationId={}, evaluationId={}", applicationId, applicationEvaluationId); return applicationAmendment; } private void setAmendmentDocuments(String amendmentNotes, String amendmentFieldRequest, @@ -507,7 +511,7 @@ public class ApplicationAmendmentRequestDao { } public DocumentResponseBean createDocumentResponseBean(String documentId) { - + log.info("Initiating document response creation for documentId={}", documentId); if (!StringUtils.isEmpty(documentId)) { Optional documentEntity = documentRepository.findByIdAndNotDeleted(Long.valueOf(documentId)); if(documentEntity.isPresent()){ @@ -671,7 +675,9 @@ public class ApplicationAmendmentRequestDao { } public List getAllApplicationAmendmentRequest(HttpServletRequest request, Long userId) { + log.info("Entering getAllApplicationAmendmentRequest with userId={}", userId); if (validator.checkIsPreInstructor() && userId == null) { + log.warn("Access denied: Pre-instructor must provide userId for amendment request retrieval."); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); } if (userId != null) { @@ -714,9 +720,11 @@ public class ApplicationAmendmentRequestDao { isBeneficiary=true; } if(Boolean.TRUE.equals(isBeneficiary) && existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue())){ - throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); + log.warn("Permission denied: Beneficiary tried to update amendment ID {} with status RESPONSE_RECEIVED", id); + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); } if(Boolean.FALSE.equals(isBeneficiary) && existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())){ + log.warn("Permission denied: Non-beneficiary tried to update amendment ID {} with status AWAITING", id); throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); } @@ -739,10 +747,12 @@ public class ApplicationAmendmentRequestDao { } existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); if(updateRequest.getAmendmentDocuments()!=null && Boolean.FALSE.equals(updateRequest.getAmendmentDocuments().isEmpty())) { + log.debug("Setting amendment documents for amendment ID: {}", id); setAmendmentDocuments(updateRequest.getAmendmentNotes(),updateRequest.getAmendmentDocuments(), existingApplicationAmendment); } ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false); + log.info("Successfully updated ApplicationAmendmentRequest with ID: {}", id); log.info("Application Amendment updated successfully: {}", response); return response; } @@ -1038,6 +1048,7 @@ public class ApplicationAmendmentRequestDao { public List getAllAmendmentRequestByBeneficiaryId(Long beneficiaryUserId) { + log.info("Fetching all amendment requests for beneficiaryUserId={}", beneficiaryUserId); UserEntity userEntity = userService.validateUser(beneficiaryUserId); List entities = applicationAmendmentRequestRepository.findByUserId(beneficiaryUserId); @@ -1057,6 +1068,8 @@ public class ApplicationAmendmentRequestDao { existingApplicationAmendment.getApplicationEvaluationEntity().getId() ); + log.debug("Found {} amendment requests for ApplicationEvaluationId={}", amendmentRequestList.size(), existingApplicationAmendment.getApplicationEvaluationEntity().getId()); + // Check if this is the last amendment being closed boolean isLastRemaining = amendmentRequestList.stream() .filter(amendment -> !amendment.getId().equals(id)) // Exclude the current amendment @@ -1074,6 +1087,8 @@ public class ApplicationAmendmentRequestDao { } ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false); + log.info("Updated amendment status to CLOSE for amendment ID: {}", id); + List amendmentRequests = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( existingApplicationAmendment.getApplicationEvaluationEntity().getId()); Boolean allClosed = amendmentRequests.stream().allMatch(amendment -> (amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()) || amendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue()))); @@ -1081,16 +1096,17 @@ public class ApplicationAmendmentRequestDao { ApplicationEntity oldApplicationEntityData = Utils.getClonedEntityForData(application); if (Boolean.TRUE.equals(allClosed)) { existingApplicationAmendment.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); - if (allClosed) { ApplicationEvaluationEntity existingApplicationEvaluationEntity = existingApplicationAmendment.getApplicationEvaluationEntity(); ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(existingApplicationEvaluationEntity); existingApplicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity()); + log.info("Updated ApplicationEvaluation status to OPEN for ID: {}", existingApplicationEvaluationEntity.getId()); application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); + log.info("Updated Application status to EVALUATION for Application ID: {}", application.getId()); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsDao.validateAssignedApplication( existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getId()); @@ -1098,7 +1114,7 @@ public class ApplicationAmendmentRequestDao { existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().setStatus(AssignedApplicationEnum.OPEN.getValue()); assignedApplicationsEntity = assignedApplicationsRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity()); - + log.info("Updated AssignedApplication status to OPEN for ID: {}", assignedApplicationsEntity.getId()); Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.AMENDMENT_CLOSED); @@ -1125,6 +1141,7 @@ public class ApplicationAmendmentRequestDao { public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validatApplicationAmendmentRequestByStatus(id,ApplicationAmendmentRequestEnum.EXPIRED.getValue()); + log.info("Extending response days for Application Amendment ID: {}, Additional Days: {}", id, newResponseDays); if (newResponseDays != null && newResponseDays > 0) { ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); @@ -1177,6 +1194,7 @@ public class ApplicationAmendmentRequestDao { 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))) { + log.info("Updating amendment ID {} status from {} to {}", id, existingApplicationAmendment.getStatus(), statusTypeEnum); existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestRepository.save(existingApplicationAmendment); @@ -1191,8 +1209,12 @@ public class ApplicationAmendmentRequestDao { public EmailReminderResponse sendReminderEmail(Long amendmentId) { + log.info("Initiating reminder email process for Amendment ID: {}", amendmentId); + ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); + .orElseThrow(() -> { log.error("Amendment not found with ID: {}", amendmentId); + return new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)); + }); Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId()); EmailReminderResponse emailReminderResponse = new EmailReminderResponse(); @@ -1205,6 +1227,7 @@ public class ApplicationAmendmentRequestDao { String body = prepareBody(emailTemplate, amendment, beneficiaryUser); String email = beneficiaryUser.getEmail(); if (Boolean.TRUE.equals(amendment.getIsEmail()) && email != null && !email.isEmpty()) { + log.info("Sending reminder email to: {}", email); EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(), RecipientTypeEnum.USER, beneficiaryUser.getId(), email, beneficiaryUser.getId(), applicationEntity.getId(), amendment.getId(), applicationEntity.getCall().getId()); emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email), emailLogRequest); @@ -1217,7 +1240,9 @@ public class ApplicationAmendmentRequestDao { else{ emailReminderResponse.setEmailSendResponse(Collections.emptyList()); } + log.info("Reminder email sent successfully for Amendment ID: {}", amendmentId); } else { + log.warn("Beneficiary email not found or isEmail flag is false for Amendment ID: {}", amendmentId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.BENEFICIARY_EMAIL_NOT_FOUND_MSG)); } } @@ -1303,7 +1328,9 @@ public class ApplicationAmendmentRequestDao { return response; } private void softDeleteDocument(Long documentId) { + log.info("Initiating soft delete for Document ID: {}", documentId); documentService.deleteFile(documentId); + log.info("Document ID: {} soft deleted successfully.", documentId); } // public PageableResponseBean> getApplicationAmendmentByPaginnation(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { @@ -1422,6 +1449,7 @@ public class ApplicationAmendmentRequestDao { // } public PageableResponseBean> getApplicationAmendmentByPaginationByView(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { + log.info("Fetching paginated application amendments for userId: {}", userId); Integer pageNo = null; Integer pageLimit = null; if (applicationAmendmentPaginationRequestBean.getGlobalFilters() != null) { @@ -1453,6 +1481,7 @@ public class ApplicationAmendmentRequestDao { pageableResponseBean.setTotalRecords(entityPage.getTotalElements()); pageableResponseBean.setPageSize(entityPage.getSize()); + log.info("Paginated response prepared successfully for userId: {}", userId); return pageableResponseBean; } public Specification searchPaginationByView(Long userId,ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { @@ -1484,6 +1513,7 @@ public class ApplicationAmendmentRequestDao { private List getPredicatesByView(ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean, CriteriaBuilder criteriaBuilder, Root root,Long userId) { + log.info("Building predicates for userId: {}", userId); Integer year = null; String search = null; Map filters = new HashMap<>(); @@ -1503,6 +1533,7 @@ public class ApplicationAmendmentRequestDao { LocalDateTime startOfYear = LocalDateTime.of(filterYear, 1, 1, 0, 0); LocalDateTime endOfYear = LocalDateTime.of(filterYear, 12, 31, 23, 59, 59); + log.debug("Filtering by year between {} and {}", startOfYear, endOfYear); // Add the range comparison to filter records within the year predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), startOfYear, endOfYear)); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 3a80c27d..b0f09777 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -211,13 +211,16 @@ public class ApplicationDao { public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { + log.info("Starting createApplication: formId={}, applicationId={}", formId, applicationId); FormEntity formEntity = formService.validateForm(formId); // callService.validatePublishedCall(formEntity.getCall().getId()); validateFormFields(applicationRequestBean,formEntity); ApplicationEntity applicationEntity = validateApplication(applicationId); checkCallEndDate(applicationEntity.getCall()); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); + log.info("Validated user-company association for company ID: {}", applicationEntity.getCompanyId()); if(Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { + log.warn("Application ID {} is not in DRAFT status", applicationId); throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } formService.validateFormField(applicationRequestBean.getFormFields(),applicationEntity,formEntity); @@ -244,10 +247,12 @@ public class ApplicationDao { } public ApplicationFormEntity createApplicationFormEntity(ApplicationEntity application, FormEntity formEntity) { + log.info("Creating ApplicationFormEntity for applicationId: {}, formId: {}", application.getId(), formEntity.getId()); ApplicationFormEntity applicationFormEntity = new ApplicationFormEntity(); applicationFormEntity.setApplication(application); applicationFormEntity.setForm(formEntity); applicationFormEntity = saveApplicationFormEntity(applicationFormEntity); + log.info("Created ApplicationFormEntity with id: {}", applicationFormEntity.getId()); return applicationFormEntity; } @@ -299,6 +304,7 @@ public class ApplicationDao { List documentResponseBeans = new ArrayList<>(); if (fileUploadContent.isPresent()) { String documentId = applicationFormFieldEntity.getFieldValue(); + log.debug("Field is file upload/select type. Document IDs: {}", documentId); if (documentId != null && !documentId.isEmpty()) { documentResponseBeans = Arrays.stream(documentId.split(",")) .map(String::trim) @@ -306,6 +312,7 @@ public class ApplicationDao { .map(docId -> { DocumentEntity documentEntity = documentService.validateDocument(docId); if (Boolean.FALSE.equals(DocumentSourceTypeEnum.APPLICATION.getValue().equals(documentEntity.getSource()))) { + log.warn("Document {} source type invalid: {}", docId, documentEntity.getSource()); throw new CustomValidationException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } return documentEntity; @@ -331,6 +338,7 @@ public class ApplicationDao { ApplicationEntity applicationEntity= validateApplication(id); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) { + log.warn("Application with ID: {} is not in DRAFT status, cannot delete. Current status: {}", id, applicationEntity.getStatus()); throw new CustomValidationException( Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS) @@ -341,6 +349,7 @@ public class ApplicationDao { validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); applicationEntity.setIsDeleted(true); applicationEntity = applicationRepository.save(applicationEntity); + log.info("Marked application as deleted and saved for ID: {}", id); /** This code is responsible for adding a version history log for the "Delete application" operation. **/ loggingUtil.addVersionHistory( @@ -428,6 +437,7 @@ public class ApplicationDao { } private ApplicationResponse getApplicationResponse(ApplicationEntity applicationEntity) { + log.info("Generating ApplicationResponse for application ID: {}", applicationEntity.getId()); ApplicationResponse responseBean = new ApplicationResponse(); List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalFormSteps = flowFormDao.calculateTotalSteps(flowEdgesList); @@ -468,9 +478,13 @@ public class ApplicationDao { } public ApplicationEntity validateApplication(Long id) { + log.info("Validating existence of Application with ID: {}", id); ApplicationEntity applicationEntity = applicationRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); + .orElseThrow(() -> { + log.warn("Application not found for ID: {}", id); + return new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG)); + }); return applicationEntity; } @@ -494,10 +508,12 @@ public class ApplicationDao { } private ApplicationFormEntity getApplicationFormOrCreate(FormEntity formEntity, ApplicationEntity applicationEntity) { + log.info("Fetching ApplicationForm for Application ID: {} and Form ID: {}", applicationEntity.getId(), formEntity.getId()); ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); ApplicationFormEntity oldApplicationFormEntity = Utils.getClonedEntityForData(applicationFormEntity); if (applicationFormEntity == null) { + log.info("No existing ApplicationForm found. Creating new ApplicationForm for Application ID: {}, Form ID: {}", applicationEntity.getId(), formEntity.getId()); applicationFormEntity = createApplicationFormEntity(applicationEntity, formEntity); /** This code is responsible for adding a version history log for the "Create application form" operation. **/ @@ -523,6 +539,8 @@ public class ApplicationDao { public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, ApplicationFormEntity applicationFormEntity, List applicationFormFieldEntities, FormEntity formEntity,FieldValidator fieldValidator) { + log.info("Starting createOrUpdateApplicationFormField for ApplicationForm ID: {}", applicationFormEntity.getId()); + ApplicationFormFieldEntity applicationFormFieldEntity = new ApplicationFormFieldEntity(); List newDocumentIds = validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity); @@ -542,7 +560,9 @@ public class ApplicationDao { try { BigDecimal amountRequested = new BigDecimal(fieldValue.toString()); applicationFormEntity.getApplication().setAmountRequested(amountRequested); + log.info("Set amountRequested to {} for Application ID: {}", amountRequested, applicationFormEntity.getApplication().getId()); } catch (NumberFormatException e) { + log.error("Invalid number format for requested amount: {}", fieldValue, e); throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e); } } @@ -683,6 +703,8 @@ public class ApplicationDao { List documentIds=null; // List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); List contentResponseBeans=formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); + log.debug("Validating file upload documents for field ID: {} in form ID: {}", applicationFormFieldRequestBean.getFieldId(), formEntity.getId()); + for (ContentResponseBean contentResponseBean:contentResponseBeans){ if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload")) || Boolean.TRUE.equals(contentResponseBean.getName().equals("fileselect"))) { if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { @@ -692,6 +714,7 @@ public class ApplicationDao { String documentId = (String) fieldValueObject; // Now you can use documentId as needed documentIds = validateDocumentIds(documentId); + log.info("Validated document IDs: {}", documentIds); } } } @@ -701,6 +724,7 @@ public class ApplicationDao { public List validateDocumentIds(String documentId) { if (documentId != null && !documentId.isEmpty()) { + log.info("Validating document IDs: {}", documentId); return Arrays.stream(documentId.split(",")) .map(Long::parseLong) .peek(docId -> documentService.validateDocument(docId)) @@ -753,6 +777,7 @@ public class ApplicationDao { } public ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId, Long formId) { + log.info("Received request to get application by formId. ApplicationId: {}, FormId: {}", applicationId, formId); List formApplicationResponses = new ArrayList<>(); List formEntities = new ArrayList<>(); UserEntity userEntity = validator.validateUser(request); @@ -903,6 +928,7 @@ public class ApplicationDao { public ApplicationResponse createApplicationByCallId(CompanyEntity companyEntity, ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) { + log.info("Start creating application for CallId: {}, UserId: {}, CompanyId: {}", callId, userEntity.getId(), companyEntity.getId()); CallEntity call = callService.validateCall(callId); UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId()); checkCallEndDate(call); @@ -926,11 +952,15 @@ public class ApplicationDao { public void checkIfApplicationExists(CallEntity call, UserWithCompanyEntity userWithCompanyEntity, UserEntity userEntity){ + log.info("Checking existing applications for UserId: {}, UserWithCompanyId: {}, CallId: {}", + userEntity.getId(), userWithCompanyEntity.getId(), call.getId()); List applications = applicationRepository.findByUserIdAndUserWithCompany_IdAndCall_IdAndIsDeletedFalseAndStatusNot( userEntity.getId(), userWithCompanyEntity.getId(), call.getId(), ApplicationStatusTypeEnum.REJECTED.name() ); if (!applications.isEmpty()) { + log.warn("Application already exists for UserId: {}, UserWithCompanyId: {}, CallId: {}. Applications found: {}", + userEntity.getId(), userWithCompanyEntity.getId(), call.getId(), applications.size()); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); } } @@ -952,10 +982,12 @@ public class ApplicationDao { UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { + log.warn("Attempt to change status after submission denied | applicationId: {}", applicationId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); } if (Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))) { + log.warn("Requested status is the same as current status | applicationId: {}, status: {}", applicationId, status); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS)); } @@ -1095,6 +1127,7 @@ public class ApplicationDao { } private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { + log.info("Preparing to send submission email | applicationId: {}, userId: {}", applicationEntity.getId(), userEntity.getId()); CallEntity call =applicationEntity.getCall(); CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); UserWithCompanyEntity userWithCompany=companyService.getUserWithCompany(userEntity.getId(),company.getId()); @@ -1185,6 +1218,7 @@ public class ApplicationDao { } public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { + log.info("Received request to upload signed document | applicationId: {}, fileName: {}", applicationId, file.getOriginalFilename()); ApplicationEntity applicationEntity = validateApplication(applicationId); checkCallEndDate(applicationEntity.getCall()); //cloned entity for old data @@ -1197,9 +1231,11 @@ public class ApplicationDao { ApplicationSignedDocumentEntity oldApplicationSingedDocumentData = Utils.getClonedEntityForData(applicationSignedDocument); if (applicationSignedDocument != null) { + log.info("Existing active signed document found and will be deleted | applicationId: {}, fileName: {}", applicationId, applicationSignedDocument.getFileName()); deleteSignedDocumentFromS3(applicationSignedDocument); } UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = uploadFileOnAmazonS3ForUserSignedDocument(file, applicationEntity.getCall().getId(), applicationId); + log.info("File uploaded to S3 successfully | applicationId: {}", applicationId); applicationSignedDocument = new ApplicationSignedDocumentEntity(); applicationSignedDocument.setApplication(applicationEntity); applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName()); @@ -1213,6 +1249,8 @@ public class ApplicationDao { applicationEntity.setStatus(ApplicationStatusTypeEnum.READY.getValue()); applicationEntity = applicationRepository.save(applicationEntity); + log.info("Application status updated to READY | applicationId: {}", applicationEntity.getId()); + /** This code is responsible for adding a version history log for the "Create Call" operation. **/ loggingUtil.addVersionHistory( @@ -1221,16 +1259,22 @@ public class ApplicationDao { return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } public void deleteSignedDocumentFromS3(ApplicationSignedDocumentEntity applicationSignedDocumentEntity){ + log.info("Starting soft delete of signed document | applicationSignedDocumentId: {}, fileName: {}", + applicationSignedDocumentEntity.getId(), applicationSignedDocumentEntity.getFileName()); ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocumentEntity); String oldS3Path = applicationSignedDocumentEntity.getFilePath(); + log.debug("Old S3 path: {} ", oldS3Path); String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L); + log.debug("Generated new S3 path for deleted document: {}", newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(applicationSignedDocumentEntity.getFileName(), oldS3Path, newS3Path); + log.info("Moved file in S3 from {} to {} | fileName: {}", oldS3Path, newS3Path, response.getFileName()); applicationSignedDocumentEntity.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); applicationSignedDocumentEntity.setFileName(response.getFileName()); applicationSignedDocumentEntity.setFilePath(response.getFilePath()); applicationSignedDocumentRepository.save(applicationSignedDocumentEntity); + log.info("Updated signed document entity status to INACTIVE and saved | applicationSignedDocumentId: {}", applicationSignedDocumentEntity.getId()); loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplicationSignedDocument).newData(applicationSignedDocumentEntity).build()); } @@ -1249,6 +1293,7 @@ public class ApplicationDao { log.info("S3 Path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { + log.error("Failed to upload user signed document | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } @@ -1256,6 +1301,7 @@ public class ApplicationDao { try { return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L); } catch (IllegalArgumentException e) { + log.error("Failed to generate S3 path for delegation | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } } @@ -1280,13 +1326,14 @@ public class ApplicationDao { } String filename = file.getOriginalFilename(); if (filename == null || !filename.endsWith(".p7m")) { + log.warn("Invalid file type detected | filename: {}", filename); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE)); } } public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) { - + log.info("Fetching signed document for applicationId: {}", applicationId); ApplicationEntity applicationEntity = validateApplication(applicationId); // validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); @@ -1300,6 +1347,7 @@ public class ApplicationDao { ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); if(applicationSignedDocument == null) { + log.warn("No active signed document found for applicationId: {}", applicationId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); } @@ -1307,6 +1355,7 @@ public class ApplicationDao { } public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { + log.info("Initiating deletion of signed document for applicationId: {}", applicationId); ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); @@ -1315,6 +1364,7 @@ public class ApplicationDao { //cloned entity for old data ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocument); if(applicationSignedDocument == null) { + log.warn("No active signed document found to delete for applicationId: {}", applicationId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); } @@ -1327,7 +1377,7 @@ public class ApplicationDao { } public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) { - + log.info("Starting application validation process | applicationId: {}", applicationId); ApplicationEntity applicationEntity = validateApplication(applicationId); ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); checkCallEndDate(applicationEntity.getCall()); @@ -1335,15 +1385,18 @@ public class ApplicationDao { UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) { + log.warn("Application not in draft status | applicationId: {}, status: {}", applicationId, applicationEntity.getStatus()); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } if (applicationEntity.getAmountRequested() == null || applicationEntity.getAmountRequested().compareTo(BigDecimal.ZERO) <= 0 ) { + log.warn("Invalid amount requested | amount: {}", applicationEntity.getAmountRequested()); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.AMOUNT_REQUEST_SHOULD_GREATED_THEN_ZERO)); } List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalSteps = flowFormDao.calculateTotalSteps(flowEdgesList); Integer completedSteps = flowFormDao.getCompletedSteps(applicationEntity, true); if (totalSteps.intValue() != completedSteps) { + log.warn("Application incomplete | applicationId: {}", applicationId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); } @@ -1358,7 +1411,7 @@ public class ApplicationDao { } public byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) { - + log.info("Starting ZIP download process for applicationId: {}", applicationId); ApplicationEntity applicationEntity = validateApplication(applicationId); validateAssignedUser(request, applicationId); Set documentIds = extractDocumentIdsFromApplicationForms(applicationId); @@ -1368,13 +1421,14 @@ public class ApplicationDao { List amendmentDocuments = fetchAmendmentDocuments(applicationId); List evaluationDocuments = fetchEvaluationDocuments(applicationId); if (documents.isEmpty() && signedDocument == null && amendmentDocuments.isEmpty() && evaluationDocuments.isEmpty()) { + log.warn("No documents found for applicationId: {}", applicationId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId); } private void validateAssignedUser(HttpServletRequest request, Long applicationId) { - + log.info("Validating assigned user for applicationId: {}", applicationId); AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); if (assignedApplications != null) { validator.validatePreInstructor(request, assignedApplications.getUserId()); @@ -1382,7 +1436,7 @@ public class ApplicationDao { } private Set extractDocumentIdsFromApplicationForms(Long applicationId) { - + log.info("Extracting document IDs from application forms | applicationId: {}", applicationId); Set documentIds = new HashSet<>(); List applicationForms = applicationFormRepository.findByApplicationId(applicationId); applicationForms.forEach(applicationForm -> { @@ -1404,16 +1458,17 @@ public class ApplicationDao { } private List fetchAmendmentDocuments(Long applicationId) { - + log.info("Fetching amendment documents for applicationId: {}", applicationId); List amendmentRequests = applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId); Set amendmentIds = amendmentRequests.stream().map(ApplicationAmendmentRequestEntity::getId).collect(Collectors.toSet()); return documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(amendmentIds, DocumentSourceTypeEnum.AMENDMENT.getValue()); } private List fetchEvaluationDocuments(Long applicationId) { - + log.info("Fetching evaluation documents for applicationId: {}", applicationId); Optional evaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if (evaluationEntity.isPresent()) { Long evaluationId = evaluationEntity.get().getId(); + log.debug("Found evaluation entity with id: {}", evaluationId); return documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(Collections.singleton(evaluationId), DocumentSourceTypeEnum.EVALUATION.getValue()); } return Collections.emptyList(); @@ -1427,12 +1482,14 @@ public class ApplicationDao { return "unknown"; } private void addDocumentToZip(ZipOutputStream zos, String s3Folder, String filePath, String fullPath) { - + log.info("Attempting to add file to ZIP. S3 folder: {}, file path: {}", s3Folder, filePath); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, filePath)) { zos.putNextEntry(new ZipEntry(fullPath)); IOUtils.copy(fileInputStream, zos); zos.closeEntry(); } catch (IOException e) { + log.error("Failed to add file to ZIP. S3 folder: {}, file path: {}, error: {}", + s3Folder, filePath, e.getMessage(), e); throw new RuntimeException("Error downloading or adding document to ZIP: " + fullPath, e); } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index b9782af0..57f54964 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -655,6 +655,7 @@ public class ApplicationEvaluationDao { ApplicationEvaluationRequest req, Long assignedApplicationId) { + log.info("Start createOrUpdateApplicationEvaluation: assignedApplicationId={}, userId={}", assignedApplicationId, user.getId()); Optional existingEntityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(assignedApplicationId); ApplicationEvaluationEntity entity = null; @@ -665,6 +666,7 @@ public class ApplicationEvaluationDao { VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; validateApplicationEvaluationRequest(req, application); if (existingEntityOptional.isPresent()) { + log.info("Updating existing application evaluation for assignedApplicationId={}", assignedApplicationId); entity = existingEntityOptional.get(); oldApplicationEvaluation = Utils.getClonedEntityForData(entity); if(req.getCriteria()!=null) { @@ -690,6 +692,7 @@ public class ApplicationEvaluationDao { entity = applicationEvaluationRepository.save(entity); } else { + log.info("Creating new application evaluation for assignedApplicationId={}", assignedApplicationId); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); entity = convertToEntity(user, req, assignedApplicationId); actionType = VersionActionTypeEnum.INSERT; @@ -722,12 +725,13 @@ public class ApplicationEvaluationDao { List applicationAmendmentRequestEntities = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId()); if(req.getEvaluationDocument()!=null) { + log.info("Updating evaluation document for assignedApplicationId={}", assignedApplicationId); updateApplicationEvaluation(assignedApplicationId, req.getEvaluationDocument()); } // Fetch amendment details from the request if(req.getAmendmentDetails()!=null) { + log.debug("Processing amendment details for evaluationId={}", entity.getId()); List amendmentDetailsRequests = req.getAmendmentDetails(); - updateAmendmentDocumentsAndFormFields(applicationAmendmentRequestEntities, amendmentDetailsRequests); } @@ -740,7 +744,10 @@ public class ApplicationEvaluationDao { } private void validateApplicationEvaluationRequest(ApplicationEvaluationRequest req, ApplicationEntity application) { + log.debug("Validating evaluation request for applicationId={}, evaluationVersion={}", + application.getId(), application.getEvaluationVersion()); if(EvaluationVersionEnum.V2.getValue().equals(application.getEvaluationVersion())) { + log.info("Evaluation version is V2 for applicationId={}; setting checklist and criteria to null", application.getId()); req.setChecklist(null); req.setCriteria(null); } @@ -1065,15 +1072,18 @@ public class ApplicationEvaluationDao { } public ApplicationEvaluationEntity validateApplicationEvaluation(Long id) { - + log.debug("Validating existence of ApplicationEvaluationEntity with ID: {}", id); Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(id); if (entityOptional.isEmpty()) { + log.warn("ApplicationEvaluationEntity not found or marked as deleted for ID: {}", id); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_NOT_FOUND, id)); } + log.info("Successfully validated ApplicationEvaluationEntity with ID: {}", id); return entityOptional.get(); } public void validatePreinstructor(HttpServletRequest request,Long applicationId,Long assignedApplicationId){ + log.debug("Validating preinstructor access: applicationId={}, assignedApplicationId={}", applicationId, assignedApplicationId); if (applicationId == null && assignedApplicationId == null) { throw new CustomValidationException( Status.BAD_REQUEST, @@ -1097,12 +1107,14 @@ public class ApplicationEvaluationDao { validator.validatePreInstructor(request, assignedApplications.getUserId()); } public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(HttpServletRequest request, UserEntity user, Long applicationID, Long assignedApplicationID) { + log.info("Entering getApplicationEvaluationByApplicationId: applicationID={}, assignedApplicationID={}", applicationID, assignedApplicationID); Long applicationId; Long assignedApplicationId; validatePreinstructor(request, applicationID, assignedApplicationID); if (applicationID == null && assignedApplicationID != null) { assignedApplicationId = assignedApplicationID; + log.debug("applicationID is null, fetching from assignedApplicationID={}", assignedApplicationId); Optional assignedApplicationsOptional = assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationId); @@ -1150,6 +1162,7 @@ public class ApplicationEvaluationDao { public ApplicationEvaluationResponse getEvaluationResponseByApplicationid(UserEntity user, Long applicationId, Long assignedApplicationId) { + log.debug("Entering getEvaluationResponseByApplicationid with applicationId={}, assignedApplicationId={}, userId={}", applicationId, assignedApplicationId, user.getId()); ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity(); ApplicationEvaluationResponse response = new ApplicationEvaluationResponse(); CallEntity call = null; @@ -1203,6 +1216,7 @@ public class ApplicationEvaluationDao { ApplicationEvaluationResponse response, List evaluationCriterias) { + log.info("Setting criteria responses for applicationId: {}", applicationId); List criteriaResponses = getInitialCriteriaResponses(entity, applicationId); criteriaResponses.forEach(criteriaResponse -> { @@ -1398,6 +1412,7 @@ public class ApplicationEvaluationDao { private void setChecklistResponses(ApplicationEvaluationEntity entity, Long applicationId, ApplicationEvaluationResponse response, List checklistEntities) { + log.info("Setting checklist responses for applicationId: {}", applicationId); List checklistResponses = entity.getChecklist() != null ? Utils.convertJsonToList(entity.getChecklist(), new TypeReference>() { }) : getChecklistResponse(applicationId); @@ -1516,6 +1531,7 @@ public class ApplicationEvaluationDao { } List getCriteriaResponse(Long applicationId) { + log.info("Getting criteria response for applicationId: {}", applicationId); CallEntity call = getCallEntityByApplicationId(applicationId); List evaluationCriterias = getEvaluationCriterias(call); @@ -1525,10 +1541,12 @@ public class ApplicationEvaluationDao { } private CallEntity getCallEntityByApplicationId(Long applicationId) { + log.info("Fetching CallEntity for applicationId: {}", applicationId); return callRepository.findCallEntityByApplicationId(applicationId); } private List getEvaluationCriterias(CallEntity call) { + log.info("Fetching evaluation criterias for callId: {}", call.getId()); return evaluationCriteriaRepository .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); } @@ -1775,6 +1793,7 @@ public class ApplicationEvaluationDao { List getChecklistResponse(Long applicationId) { + log.info("Fetching checklist responses for applicationId: {}", applicationId); CallEntity call = callRepository.findCallEntityByApplicationId(applicationId); List checklistEntities = callTargetAudienceChecklistRepository .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.CHECKLIST.getValue()); @@ -1860,7 +1879,7 @@ public class ApplicationEvaluationDao { } public void deleteById(Long id) { - + log.info("Starting soft delete for ApplicationEvaluation with id: {}", id); ApplicationEvaluationEntity applicationEvaluationEntity = validateApplicationEvaluation(id); ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationEvaluationEntity.setIsDeleted(true); @@ -1882,6 +1901,8 @@ public class ApplicationEvaluationDao { public ApplicationEvaluationResponse updateApplicationEvaluationStatus(ApplicationEntity application, AssignedApplicationsEntity assignedApplicationsEntity, ApplicationStatusForEvaluation newStatus) { + log.info("Starting updateApplicationEvaluationStatus for applicationId: {}, assignedApplicationId: {}, newStatus: {}", + application.getId(), assignedApplicationsEntity.getId(), newStatus); Optional existingEntityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse( assignedApplicationsEntity.getId()); ApplicationEvaluationEntity entity; @@ -1907,11 +1928,13 @@ public class ApplicationEvaluationDao { } if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION) && Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.ADMISSIBLE.getValue()))){ + log.info("Processing technical evaluation for applicationId: {}", application.getId()); processTechnicalEvaluation(application.getId(), application, newStatus); } if((newStatus.equals(ApplicationStatusForEvaluation.APPROVED) || newStatus.equals(ApplicationStatusForEvaluation.REJECTED)) && application.getStatus().equals(ApplicationStatusTypeEnum.EVALUATION.getValue())) { application.setStatus(newStatus.getValue()); + log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); } application = applicationRepository.save(application); @@ -1923,6 +1946,7 @@ public class ApplicationEvaluationDao { List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(existingEntity.getId(),List.of(ApplicationAmendmentRequestEnum.AWAITING.getValue(),ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue())); if(amendmentRequest !=null && Boolean.FALSE.equals(amendmentRequest.isEmpty())){ + log.warn("Application cannot be approved or rejected due to pending amendment requests. applicationEvaluationId: {}", existingEntity.getId()); throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_CANNOT_APPROVED_OR_REJECTED)); } String statusType = application.getStatus(); @@ -1930,11 +1954,13 @@ public class ApplicationEvaluationDao { existingEntity.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue()); existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); + log.info("Closing ApplicationEvaluation and AssignedApplication for applicationId: {}", application.getId()); } 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); + log.debug("Calculated active days for ApplicationEvaluationEntity id {}: {}", existingEntity.getId(), activeDays); } entity = applicationEvaluationRepository.save(existingEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); @@ -1993,15 +2019,20 @@ public class ApplicationEvaluationDao { } public ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId) { + log.info("Validating ApplicationEvaluation for applicationId: {}", applicationId); return applicationEvaluationRepository .findByApplicationIdAndIsDeletedFalse(applicationId) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_NOT_FOUND))); + .orElseThrow(() -> { + log.error("ApplicationEvaluation not found for applicationId: {}", applicationId); + return new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_NOT_FOUND)); + }); } public ApplicationEvaluationResponse updateApplicationEvaluation( Long assignedApplicationId, List docRequest) { + log.info("Starting updateApplicationEvaluation for assignedApplicationId: {}", assignedApplicationId); Optional entityOptional=applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(assignedApplicationId); ApplicationEvaluationEntity applicationEvaluationEntity =null; ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(entityOptional.get()); @@ -2023,14 +2054,17 @@ public class ApplicationEvaluationDao { applicationEvaluationEntity.setEvaluationDocument(updatedEvaluationDocJson); } ApplicationEvaluationEntity savedEntity = applicationEvaluationRepository.save(applicationEvaluationEntity); + log.info("Saved ApplicationEvaluationEntity with id: {}", savedEntity.getId()); /** This code is responsible for adding a version history log for the "Upload Document in Application Evaluation" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluation).newData(savedEntity).build()); + log.info("Version history logged for update on ApplicationEvaluationEntity id: {}", savedEntity.getId()); return convertToResponse(savedEntity); } public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationFormId, Long assignedApplicationId){ - + + log.info("Start createApplicationEvaluation - assignedApplicationId: {}, evaluationFormId: {}", assignedApplicationId, evaluationFormId); UserEntity user = validator.validateUser(request); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); ApplicationEntity application = applicationService.validateApplication(assignedApplicationsEntity.getApplication().getId()); @@ -2094,6 +2128,7 @@ public class ApplicationEvaluationDao { String fieldId = requestField.getFieldId(); if (!contentMap.containsKey(fieldId)) { + log.warn("Field ID not found in evaluation form: {}", fieldId); validator.addError(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_ID_NOT_FOUND), fieldId)); } @@ -2121,6 +2156,7 @@ public class ApplicationEvaluationDao { ApplicationEvaluationFormEntity applicationEvaluationFormEntity, List applicationEvaluationFormFieldEntities, EvaluationFormEntity evaluationFormEntity,FieldValidator fieldValidator){ + log.debug("Starting createOrUpdateApplicationEvaluationFormField for fieldId: {}", applicationFormFieldRequestBean.getFieldId()); ApplicationEvaluationFormFieldEntity applicationEvaluationFormFieldEntity = new ApplicationEvaluationFormFieldEntity(); validateFileUploadDocuments(applicationFormFieldRequestBean, evaluationFormEntity); VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; @@ -2161,6 +2197,7 @@ public class ApplicationEvaluationDao { } private List validateFileUploadDocuments(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, EvaluationFormEntity evaluationFormEntity) { + log.debug("Validating file upload documents for fieldId: {}", applicationFormFieldRequestBean.getFieldId()); List documentIds=null; List contentResponseBeans=evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(evaluationFormEntity).getContent(); @@ -2185,6 +2222,9 @@ public class ApplicationEvaluationDao { private List createEvaluationFormFieldResponse( List evaluationFormFieldEntities, ApplicationEvaluationFormEntity applicationEvaluationFormEntity){ + log.info("Starting to create evaluation form field response for EvaluationFormEntity ID: {}", + applicationEvaluationFormEntity.getEvaluationForm().getId()); + List evaluationFormFieldResponseBeans = new ArrayList<>(); List contentResponseBeans =evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(applicationEvaluationFormEntity.getEvaluationForm()).getContent(); @@ -2276,6 +2316,7 @@ public class ApplicationEvaluationDao { public ApplicationEvaluationFormResponse getApplicationEvaluationForm(HttpServletRequest request, Long applicationId, Long assignedApplicationId ){ + log.debug("Fetching evaluation form. applicationId: {}, assignedApplicationId: {}", applicationId, assignedApplicationId); if (applicationId == null && assignedApplicationId == null) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.EITHER_APPLICATION_ID_OR_ASSIGNED_APPLICATION_ID_MUST_BE_PROVIDED)); } @@ -2505,6 +2546,7 @@ public class ApplicationEvaluationDao { return false; } private void processTechnicalEvaluation(Long applicationId, ApplicationEntity applicationEntity, ApplicationStatusForEvaluation status){ + log.info("Starting technical evaluation processing for applicationId: {}", applicationId); Optional evaluationEntityOpt = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if (evaluationEntityOpt.isPresent()){ ApplicationEvaluationEntity evaluationEntity = evaluationEntityOpt.get(); @@ -2513,9 +2555,10 @@ public class ApplicationEvaluationDao { BigDecimal totalScore = calculateTotalScore(evaluationEntity.getCriteria()); if (totalScore.compareTo(new BigDecimal("40")) > 0) { applicationEntity.setStatus(status.getValue()); - log.info("Status updated to TECHNICAL_EVALUATION for applicationId: " + applicationId); + log.info("Status updated to TECHNICAL_EVALUATION for applicationId: {}", applicationId); } else{ + log.warn("Insufficient score ({}) for applicationId: {}. Throwing validation exception.", totalScore, applicationId); throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.INSUFFICIENT_SCORE_MESSAGE)); } } @@ -2537,10 +2580,11 @@ public class ApplicationEvaluationDao { }) .reduce(BigDecimal.ZERO, BigDecimal::add); + log.info("Total score calculated successfully: {}", totalScore); return totalScore; } catch (Exception e) { - log.error(" Error parsing criteria JSON: {}", e.getMessage()); + log.error("Error parsing criteria JSON. Input: {}. Exception: {}", criteriaJson, e.getMessage(), e); return BigDecimal.ZERO; } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index b1166689..6b57af23 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -157,10 +157,11 @@ public class AppointmentDao { private static final ThreadLocal threadLocalHubId = new ThreadLocal<>(); public NdgResponse checkNdgForAppointment(Long applicationId) { - + log.info("Starting NDG check for appointment. applicationId: {}", applicationId); ApplicationEntity application = applicationService.validateApplication(applicationId); NdgResponse ndgResponse = new NdgResponse(); if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_IN_PROGRESS)) { + log.warn("NDG generation already in progress. applicationId: {}", applicationId); throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS)); } @@ -170,6 +171,7 @@ public class AppointmentDao { } // Update application status + log.info("Updating NDG status to IN_PROGRESS. applicationId: {}", applicationId); application.setNdgStatus(GepafinConstant.NDG_IN_PROGRESS); applicationRepository.save(application); @@ -177,6 +179,7 @@ public class AppointmentDao { HubEntity hub = hubRepository.findByHubId(application.getHubId()); loginToOdessa(hub, application); startAsyncNdgProcessing(applicationId); + log.info("NDG check initiation completed. applicationId: {}", applicationId); return ndgResponse; } @@ -340,7 +343,7 @@ public class AppointmentDao { // } private void loginToOdessa(HubEntity hub, ApplicationEntity application) { - + log.info("Starting login to Odessa. HubId: {}, ApplicationId: {}", hub.getId(), application.getId()); performOdessaLogin(hub, application); } @@ -363,7 +366,7 @@ public class AppointmentDao { Map body = Collections.emptyMap(); ResponseEntity responseLogin = appointmentApiService.loginWithOdessa(authJwtToken, source, context, user, password, body); if (responseLogin.getStatusCode() == HttpStatus.OK) { - log.info("Login successful to odessa. Parsing response."); + log.info("Login to Odessa successful. Parsing response. HubId: {}", hub.getId()); String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody()); AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson); @@ -374,6 +377,7 @@ public class AppointmentDao { log.info("Saved new authToken and areaCode for Hub."); return hub; } else { + log.error("Login response from Odessa missing tokenId. HubId: {}", hub.getId()); throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again."); } } @@ -424,6 +428,9 @@ public class AppointmentDao { } catch (IOException e) { log.error("Error parsing JSON response: {}", e.getMessage()); } + catch (Exception e) { + throw new RuntimeException("Authentication failed on Odessa. try again", e); + } } private void startAsyncNdgProcessing(Long applicationId) { @@ -460,6 +467,7 @@ public class AppointmentDao { private void processNdgGeneration(Long applicationId) { // Validate application, company, and hub + log.info("Starting NDG generation process for applicationId: {}", applicationId); ApplicationEntity application = applicationService.validateApplication(applicationId); CompanyEntity company = companyService.validateCompany(application.getCompanyId()); HubEntity hub = hubRepository.findByHubId(application.getHubId()); @@ -487,14 +495,15 @@ public class AppointmentDao { handleNdgPolling(application, company, hub, authorizationToken); } } catch (Exception e) { - log.error("Error during NDG generation for applicationId: {}", applicationId, e); + log.error("Exception occurred during NDG generation. ApplicationId: {}, CompanyId: {}, HubId: {}, Error: {}", + applicationId, company.getId(), hub.getId(), e.getMessage(), e); } } private void handleNdgPolling(ApplicationEntity application, CompanyEntity company, HubEntity hub, String authorizationToken) { try { - log.info("Starting NDG polling for applicationId: {}", application.getId()); + log.info("Starting NDG polling for applicationId: {}, CompanyId: {}, HubId: {}", application.getId(),company.getId(), hub.getId()); long startTime = System.currentTimeMillis(); while (true) { @@ -506,12 +515,13 @@ public class AppointmentDao { try { // Fetch Visura list and attempt to parse NDG String visuraListJson = getVisuraList(application.getIdVisura(), authorizationToken, application, hub); + log.debug("Parsing NDG from visura list response | ApplicationId: {}", application.getId()); String ndg = parseNdgFromVisuraListResponse(visuraListJson); - if (isNdgValid(ndg)) { // CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company); // ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application); + log.info("Valid NDG retrieved: {} | ApplicationId: {}", ndg, application.getId()); company.setNdg(ndg); application.setNdg(ndg); application.setNdgStatus(GepafinConstant.NDG_GENERATED); @@ -584,6 +594,7 @@ public class AppointmentDao { private String getVisuraList(String idVisura, String authorizationToken, ApplicationEntity application, HubEntity hub) { + log.info("Initiating Visura list retrieval | ApplicationId: {}, HubId: {}, IdVisura: {}", application.getId(), hub.getId(), idVisura); AppointmentVisuraListRequest visuraListRequest = new AppointmentVisuraListRequest(); AppointmentVisuraListRequest.VisuraFilter filter = new AppointmentVisuraListRequest.VisuraFilter(); filter.setIdVisura(idVisura); @@ -594,12 +605,12 @@ public class AppointmentDao { ResponseEntity response = appointmentApiService.getVisuraList(requestJson, authorizationToken); return Utils.convertObjectToJson(response.getBody()); } catch (FeignException.Forbidden forbiddenException) { - log.error("403 Forbidden received while getting visuraList for Ndg code. Regenerating token..."); + log.warn("403 Forbidden while fetching Visura list. Attempting token regeneration | ApplicationId: {}, HubId: {}", application.getId(), hub.getId()); // Regenerate the token and retry String newAuthorizationToken = regenerateTokenAndSave(hub, application); return getVisuraList(idVisura, newAuthorizationToken, application, hub); } catch (Exception e) { - log.error("Failed to fetch Ndg code: {}", e.getMessage(), e); + log.error("Error while fetching Visura list | ApplicationId: {}, HubId: {}, Error: {}", application.getId(), hub.getId(), e.getMessage(), e); throw new RuntimeException("Error fetching Ndg List", e); } } @@ -607,6 +618,7 @@ public class AppointmentDao { private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application) { try { + log.info("Initiating NDG retrieval by VAT number | ApplicationId: {}, HubId: {}, VAT: {}", application.getId(), hub.getId(), vatNumber); // Prepare the NDG request AppointmentNdgRequest ndgRequest = getAppointmentNdgRequest(vatNumber); // Call the API to retrieve NDG @@ -615,12 +627,13 @@ public class AppointmentDao { // Parse and return the NDG response return parseNdgResponse(responseJson); } catch (FeignException.Forbidden forbiddenException) { + log.error("403 Forbidden during NDG retrieval | ApplicationId: {}, HubId: {}", application.getId(), hub.getId()); logForbiddenError(); // Regenerate the token and retry String newAuthorizationToken = regenerateTokenAndSave(hub, application); return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application); } catch (Exception e) { - log.error("Failed to retrieve NDG by VAT number: {}", e.getMessage(), e); + log.error("Error during NDG retrieval | ApplicationId: {}, HubId: {}, Message: {}", application.getId(), hub.getId(), e.getMessage(), e); throw new RuntimeException("NDG retrieval failed.", e); } } @@ -656,6 +669,7 @@ public class AppointmentDao { private static AppointmentNdgRequest getAppointmentNdgRequest(String vatNumber) { + log.info("Creating Appointment NDG Request | VAT Number: {}", vatNumber); AppointmentNdgRequest request = new AppointmentNdgRequest(); AppointmentNdgRequest.Filter filter = new AppointmentNdgRequest.Filter(); filter.setPartitaIva(vatNumber); @@ -786,6 +800,7 @@ public class AppointmentDao { public AppointmentCreationResponse createAppointment(Long applicationId, CreateAppointmentRequest createAppointmentRequest) { // Validate the application + log.info("Starting appointment creation for applicationId: {}", applicationId); ApplicationEntity application = applicationService.validateApplication(applicationId); AppointmentCreationResponse appointmentCreationResponse = new AppointmentCreationResponse(); @@ -808,6 +823,7 @@ public class AppointmentDao { } if (application.getNdg() == null && Objects.equals(application.getNdgStatus(), GepafinConstant.NDG_IN_PROGRESS)) { + log.warn("NDG in progress but not available for applicationId: {}", applicationId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NDG_NOT_FOUND_FOR_APPLICATION)); } @@ -815,6 +831,7 @@ public class AppointmentDao { String authorizationToken = regenerateTokenAndSave(hub, application); Long appointmentTemplateId = application.getCall().getAppointmentTemplateId(); if (appointmentTemplateId == null) { + log.error("Missing appointment template ID for applicationId: {}", applicationId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_CANNOT_BE_CREATED)); } ResponseEntity response = appointmentApiService.getAppointmentTemplateForTemplateCreation(authorizationToken, appointmentTemplateId); @@ -840,6 +857,7 @@ public class AppointmentDao { String appointmentId = extractAppointmentIdFromResponse(appointmentResponse); if (appointmentId == null) { + log.error("Failed to extract appointment ID from response for applicationId: {}", applicationId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_NOT_CREATED)); } // Update application with the appointment ID @@ -855,7 +873,7 @@ public class AppointmentDao { return appointmentCreationResponse; } catch (FeignException.Forbidden forbiddenException) { - log.error("403 Forbidden received while retrieving template. Regenerating token..."); + log.error("403 Forbidden received while retrieving template. Attempting to regenerate token and retry. Application ID: {}", applicationId); regenerateTokenAndSave(hub, application); return createAppointment(applicationId, createAppointmentRequest); } @@ -990,6 +1008,7 @@ public class AppointmentDao { } public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) { + log.info("Initiating upload to external system for documentId: {}", documentId); // Check if the document is already being processed DocumentEntity systemDoc = documentDao.validateDocument(documentId); @@ -1098,6 +1117,7 @@ public class AppointmentDao { DocumentUploadResponse parsedResponse = parseDocumentUploadResponse(responseData); if (parsedResponse == null) { + log.error("Upload failed: parsed response is null for documentId: {}", documentId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_UPLOADING_DOCUMENT)); } @@ -1107,7 +1127,7 @@ public class AppointmentDao { log.info("Document uploaded successfully to external system: {}", parsedResponse); } catch (FeignException.Forbidden forbiddenException) { - log.error("403 Forbidden received while uploading document. Regenerating token..."); + log.error("403 Forbidden from external system during upload for documentId: {}. Retrying with new token...", documentId); regenerateTokenAndSave(hub, application); uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, application); } catch (Exception e) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 7339a7c5..c05b04c2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -87,8 +87,10 @@ public class AssignedApplicationsDao { AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); if (assignedApplications != null && assignedApplications.getUserId().equals(userId)) { + log.warn("Application ID={} is already assigned to User ID={}", applicationId, userId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); } else if(assignedApplications != null) { + log.info("Reassigning Application ID={} from User ID={} to User ID={}", applicationId, assignedApplications.getUserId(), userId); assignedApplications = reassignApplication(userId, assignedByUser, assignedApplications); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignedApplications); log.info("Application re-assigned succesfully {}", assignApplicationToInstructorResponse); @@ -98,6 +100,7 @@ public class AssignedApplicationsDao { if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.SUBMIT.getValue().equals(application.getStatus()))) { + log.warn("Invalid application status for assignment. Application ID={}, Current Status={}", applicationId, application.getStatus()); throw new CustomValidationException( Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS) @@ -106,6 +109,7 @@ public class AssignedApplicationsDao { ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(application); application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); + log.info("Application status updated to EVALUATION for Application ID={}", applicationId); /** This code is responsible for adding a version history log for the "Update Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); @@ -120,7 +124,10 @@ public class AssignedApplicationsDao { private AssignedApplicationsEntity reassignApplication(Long userId, UserEntity assignedByUser, AssignedApplicationsEntity assignedApplication) { - + + log.info("Starting reassignment for AssignedApplication ID={}, from User ID={} to User ID={}, Assigned By User ID={}", + assignedApplication.getId(), assignedApplication.getUserId(), userId, assignedByUser.getId()); + AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplication); setIfUpdated(assignedApplication::getAssignedBy, assignedApplication::setAssignedBy, assignedByUser.getId()); @@ -135,11 +142,13 @@ public class AssignedApplicationsDao { /** This code is responsible for adding a version history log for the "Create Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(entityOptional.get()).build()); + log.info("Updated ApplicationEvaluationEntity for AssignedApplication ID={}", assignedApplication.getId()); }; assignedApplication = assignedApplicationsRepository.save(assignedApplication); /** This code is responsible for adding a version history log for the "Create Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplication).build()); + log.info("Reassignment completed for AssignedApplication ID={}, new User ID={}", assignedApplication.getId(), userId); return assignedApplication; } @@ -220,8 +229,13 @@ public class AssignedApplicationsDao { } public AssignedApplicationsEntity validateAssignedApplication(Long id) { - AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.findByIdAndIsDeletedFalse(id).orElseThrow(() -> - new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG))); + AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> { + log.warn("AssignedApplication not found or deleted for ID: {}", id); + return new ResourceNotFoundException( + Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG) + ); + }); return assignedApplication; } @@ -232,11 +246,12 @@ public class AssignedApplicationsDao { AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); assignedApplicationsEntity.setIsDeleted(true); assignedApplicationsEntity = saveAssignedApplication(assignedApplicationsEntity, oldAssignedApplicationEntity, VersionActionTypeEnum.SOFT_DELETE); - log.info("Assigned Application deleted with ID: {}", id); + log.info("Soft-delete completed for AssignedApplication ID: {} by User ID: {}", id, assignedApplicationsEntity.getUserId()); } public List getAllAssignedApplications(HttpServletRequest request, Long userId,List statusList) { - UserEntity user = validator.validateUser(request); + log.info("Fetching all assigned applications. Filtered target userId: {}", userId); + UserEntity user = validator.validateUser(request); if(validator.checkIsPreInstructor() && userId == null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); } @@ -303,6 +318,8 @@ public class AssignedApplicationsDao { return response; } public PageableResponseBean> getAllAssignedApplicationsByPagination(UserEntity user, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean,Long userId) { + log.info("Fetching assigned applications. Requestor: {}, Target User: {}", user.getId(), userId); + Integer pageNo = null; Integer pageLimit = null; if (assignedApplicationPageableRequestBean.getGlobalFilters() != null) { @@ -478,13 +495,16 @@ public class AssignedApplicationsDao { } public AssignedApplicationsResponse updateAssignedApplicationStatus(HttpServletRequest request, Long assignedApplicationId, AssignedApplicationEnum status) { - + log.info("Request received to update status of assigned application. AssignedApplicationId: {}, NewStatus: {}", assignedApplicationId, status); AssignedApplicationsEntity assignedApplication = validateAssignedApplication(assignedApplicationId); validator.validatePreInstructor(request, assignedApplication.getUserId()); AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplication); assignedApplication.setStatus(status.getValue()); AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(assignedApplication, oldAssignedApplicationEntity, VersionActionTypeEnum.UPDATE); + log.info("Assigned application status updated successfully. AssignedApplicationId: {}, OldStatus: {}, NewStatus: {}", + assignedApplicationId, oldAssignedApplicationEntity.getStatus(), status.getValue()); + return convertEntityToResponse(updatedAssignment); } private void applyFilters(Root root, CriteriaBuilder criteriaBuilder, List predicates, Map filters) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 7fc9663a..94c6f912 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -50,6 +50,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundExceptio import net.gepafin.tendermanagement.web.rest.api.errors.Status; import static net.gepafin.tendermanagement.enums.RoleStatusEnum.ROLE_SUPER_ADMIN; +import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; import static org.apache.commons.lang3.StringUtils.isEmpty; import static org.hibernate.internal.util.collections.CollectionHelper.listOf; @@ -128,6 +129,7 @@ public class CallDao { private ApplicationRepository applicationRepository; public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { + log.info("Starting Call creation - Step 1 by userId: {}", userEntity.getId()); createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity); @@ -136,12 +138,15 @@ public class CallDao { CallResponse createCallResponseBean = getCallResponseBean(callEntity); createCallResponseBean.setCurrentStep(GepafinConstant.STEP_1); + log.info("Call creation - Step 1 completed successfully for callId: {}", callEntity.getId()); return createCallResponseBean; } public byte[] downloadCallDocumentsAsZip(Long callId) { + log.info("Starting download of call documents as ZIP for callId: {}", callId); List documents = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callId, DocumentSourceTypeEnum.CALL.getValue(),DocumentTypeEnum.DOCUMENT.getValue()); if (documents.isEmpty()) { + log.warn("No documents found for callId: {}", callId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } @@ -149,6 +154,7 @@ public class CallDao { ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { for (DocumentEntity document : documents) { + log.info("Adding document to ZIP: documentId={}, fileName={}", document.getId(), document.getFileName()); String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) { String fileName = Utils.extractFileName(document.getFilePath()); @@ -157,14 +163,17 @@ public class CallDao { IOUtils.copy(fileInputStream, zos); zos.closeEntry(); } catch (IOException e) { + log.error("Error downloading or adding document to ZIP. documentId={}, fileName={}", document.getId(), document.getFileName(), e); throw new RuntimeException("Error downloading or adding document to ZIP: " + document.getFileName(), e); } } zos.finish(); + log.info("Successfully created ZIP file for callId: {}", callId); return zipOutputStream.toByteArray(); } catch (IOException e) { + log.error("Error while creating ZIP file for callId: {}", callId, e); throw new RuntimeException("Error while creating ZIP file", e); } } @@ -175,8 +184,11 @@ public class CallDao { CallEntity callEntity = new CallEntity(); // validateCallEntity(createCallRequest); RegionEntity region = regionRepository.findById(createCallRequest.getRegionId()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.REGION_NOT_FOUND))); + .orElseThrow(() -> { + log.error("Region not found for id: {}", createCallRequest.getRegionId()); + return new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND)); + }); + callEntity.setRegion(region); callEntity.setName(createCallRequest.getName()); callEntity.setDescriptionShort(createCallRequest.getDescriptionShort()); @@ -198,6 +210,7 @@ public class CallDao { } callEntity.setDocumentationRequested(createCallRequest.getDocumentationRequested()); if (createCallRequest.getAmountMin() != null && createCallRequest.getAmountMin().compareTo(BigDecimal.ZERO) < 0) { + log.error("Invalid minimum amount: {}", createCallRequest.getAmountMin()); throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.AMOUNT_GREATER_THAN_ZERO_MSG)); } callEntity.setAmountMin(createCallRequest.getAmountMin()); @@ -212,6 +225,7 @@ public class CallDao { callEntity.setNumberOfCheck(createCallRequest.getNumberOfCheck()); callEntity.setAppointmentTemplateId(createCallRequest.getAppointmentTemplateId()); callEntity = callRepository.save(callEntity); + log.info("CallEntity saved with ID: {} for call name: '{}'", callEntity.getId(), callEntity.getName()); /** This code is responsible for adding a version history log for the "Create Call" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(callEntity).build()); @@ -237,9 +251,11 @@ public class CallDao { } private void softDeleteEvaluationCriteria(EvaluationCriteriaEntity evaluationCriteriaEntity) { + log.info("Starting soft delete for EvaluationCriteriaEntity with ID: {}", evaluationCriteriaEntity.getId()); EvaluationCriteriaEntity oldEvaluationCriteriaEntity = Utils.getClonedEntityForData(evaluationCriteriaEntity); evaluationCriteriaEntity.setIsDeleted(true); evaluationCriteriaRepository.save(evaluationCriteriaEntity); + log.info("Soft deleted EvaluationCriteriaEntity with ID: {}", evaluationCriteriaEntity.getId()); /** This code is responsible for adding a version history log for the "soft delete evaluation criteria" operation **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldEvaluationCriteriaEntity).newData(evaluationCriteriaEntity).build()); @@ -256,8 +272,8 @@ public class CallDao { /** This code is responsible for adding a version history log for the "soft delete criteria form field" operation **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldCriteriaFormFieldEntity).newData(data).build()); }); - criteriaFormFieldRepository.saveAll(list); - + criteriaFormFieldRepository.saveAll(list); + log.info("Soft deleted all linked CriteriaFormFieldEntity records for EvaluationCriteriaEntity ID: {}", evaluationCriteriaEntity.getId()); } } @@ -327,8 +343,11 @@ public class CallDao { private DocumentEntity convertToDocumentEntity(DocumentReq documentReq,Long sourceId) { validateDocumentEntity(documentReq.getId()); DocumentEntity documentEntity = documentRepository.findByIdAndSourceIdAndSourceAndIsDeletedFalse(documentReq.getId(),sourceId, DocumentSourceTypeEnum.CALL.getValue()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND))); + .orElseThrow(() -> { + log.error("Document not found or already deleted. Document ID: {}, Source ID: {}", documentReq.getId(), sourceId); + return new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); + }); return documentEntity; } @@ -353,6 +372,7 @@ public class CallDao { public void validateDocumentEntity(Long documentId) { if (documentId == null || documentId < 1) { + log.warn("Invalid Document ID provided: {}", documentId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.DOCUMENT_ID_NOT_FOUND)); } @@ -491,13 +511,16 @@ public class CallDao { } public CallEntity validateCall(Long callId) { - return callRepository.findById(callId).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.CALL_NOT_FOUND))); + return callRepository.findById(callId).orElseThrow(() -> { log.error("Call not found for ID: {}", callId); + return new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.CALL_NOT_FOUND)); + }); } public CallResponse getCallById(HttpServletRequest request,UserEntity user, CallEntity callEntity, Long companyId) { Long userId = user.getId(); Long callId = callEntity.getId(); + log.info("Fetching Call details for Call ID: {}, User ID: {}, Company ID: {}", callId, userId, companyId); BeneficiaryPreferredCallEntity preferredCall; if (companyId != null) { @@ -523,10 +546,13 @@ public class CallDao { public CallResponse createCallStep2(CallEntity callEntity, CreateCallRequestStep2 createCallRequest, UserEntity user) { // validateUpdate(callEntity); + log.info("Starting Call Step 2 update for Call ID: {}, User ID: {}", callEntity.getId(), user.getId()); if(createCallRequest.getThreshold() != null && Boolean.FALSE.equals(createCallRequest.getThreshold().equals(callEntity.getThreshold()))) { CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); setIfUpdated(callEntity::getThreshold, callEntity::setThreshold, createCallRequest.getThreshold()); callEntity = callRepository.save(callEntity); + + log.info("Updated threshold for Call ID: {}", callEntity.getId()); /** This code is responsible for adding a version history log for the "update call step 2" operation **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); @@ -546,6 +572,7 @@ public class CallDao { public void validateUpdate(CallEntity callEntity) { if(callEntity.getStatus().equals(CallStatusEnum.PUBLISH.getValue())) { + log.warn("Attempted update on published call. Call ID: {}", callEntity.getId()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PUBLISHED_CALL_NOT_UPDATE)); } @@ -574,12 +601,14 @@ public class CallDao { } if (Boolean.FALSE.equals(isValid)) { + log.error("Invalid date range detected for Call ID: {}", callEntity.getId()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_DATE_MSG)); } } public CallResponse updateCallStep1(HttpServletRequest request,CallEntity callEntity, UpdateCallRequestStep1 updateCallRequest, UserEntity userEntity) { + log.info("Updating Call ID: {}, by User ID: {}", callEntity.getId(),userEntity.getId() ); CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); isValidDateRange(updateCallRequest, callEntity); setIfUpdated(callEntity::getName, callEntity::setName, updateCallRequest.getName()); @@ -639,9 +668,11 @@ public class CallDao { updateCallRequest.getDocumentationRequested()); if (updateCallRequest.getAmountMin() != null && updateCallRequest.getAmountMin().compareTo(BigDecimal.ZERO) < 0) { + log.error("Validation failed: Invalid email {} for Call ID: {}", updateCallRequest.getEmail(), callEntity.getId()); throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.AMOUNT_GREATER_THAN_ZERO_MSG)); } if(updateCallRequest.getEmail()!=null && Boolean.FALSE.equals(Utils.isValidEmail(updateCallRequest.getEmail()))){ + log.error("Validation failed: Invalid email {} for Call ID: {}", updateCallRequest.getEmail(), callEntity.getId()); throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.VALIDATION_EMAIL,updateCallRequest.getEmail())); } setIfUpdated(callEntity::getAmountMin, callEntity::setAmountMin, updateCallRequest.getAmountMin()); @@ -661,6 +692,7 @@ public class CallDao { updateFaq(updateCallRequest.getFaq(), callEntity, userEntity, LookUpDataTypeEnum.FAQ); CallResponse createCallResponseBean = getCallResponseBean(callEntity); createCallResponseBean.setCurrentStep(GepafinConstant.STEP_1); + log.info("Call Step 1 update completed for Call ID: {}", callEntity.getId()); return createCallResponseBean; } @@ -764,6 +796,7 @@ public class CallDao { } private CallResponse getCallResponseBean(CallEntity callEntity) { + log.info("Building CallResponse for Call ID: {}", callEntity.getId()); List documentEntities = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callEntity.getId(),DocumentSourceTypeEnum.CALL.getValue() , DocumentTypeEnum.DOCUMENT.getValue()); List imageEntities = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callEntity.getId(), DocumentSourceTypeEnum.CALL.getValue() @@ -790,6 +823,9 @@ public class CallDao { public List getAllCalls(HttpServletRequest request,UserEntity user, Long companyId,Boolean onlyPreferredCall,Boolean onlyConfidiCall) { String type = user.getRoleEntity().getRoleType(); + log.info("Fetching calls for User ID: {}, Role: {}, Company ID: {}, onlyPreferredCall: {}, onlyConfidiCall: {}", + user.getId(), type, companyId, onlyPreferredCall, onlyConfidiCall); + List callStatusList = CallStatusEnum.getStatusValues(); if (Boolean.FALSE.equals(ROLE_SUPER_ADMIN.getValue().equals(type))) { callStatusList = List.of(CallStatusEnum.PUBLISH.getValue()); @@ -811,6 +847,7 @@ public class CallDao { call.getEndDate() != null && call.getEndTime() != null) { LocalDateTime callEndDateTime = LocalDateTime.of(LocalDate.from(call.getEndDate()), call.getEndTime()); if (callEndDateTime.isBefore(now)) { + log.info("Call ID: {} has expired. Updating status from PUBLISH to EXPIRED.", call.getId()); call.setStatus(CallStatusEnum.EXPIRED.getValue()); callRepository.save(call); } @@ -846,14 +883,17 @@ public class CallDao { } public Map getBeneficiaryPreferredCallsForUser(HttpServletRequest request, UserEntity user, List callIds, Long companyId) { + log.info("Fetching preferred calls for User ID: {}, Company ID: {}, Call IDs: {}", user.getId(), companyId, callIds); List beneficiaryPreferredCalls; if (companyId != null && (Boolean.TRUE.equals(validator.checkIsBeneficiary()) || Boolean.TRUE.equals(validator.checkIsConfidi()))) { + log.info("Validating user with company for preferred calls: User ID: {}, Company ID: {}", user.getId(), companyId); validator.validateUserWithCompany(request, companyId); UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId); beneficiaryPreferredCalls = beneficiaryPreferredCallRepository .findByUserIdAndCallIdInAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), callIds, userWithCompanyEntity.getId()); } else { + log.info("Fetching preferred calls without company filtering for User ID: {}", user.getId()); beneficiaryPreferredCalls = beneficiaryPreferredCallRepository .findByUserIdAndCallIdInAndIsDeletedFalse(user.getId(), callIds); beneficiaryPreferredCalls = beneficiaryPreferredCalls.stream() @@ -877,6 +917,7 @@ public class CallDao { public CallResponse validateCallData(CallEntity callEntity) { + log.info("Starting call validation for Call ID: {}, Current Status: {}", callEntity.getId(), callEntity.getStatus()); CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); validateUpdate(callEntity); CallResponse callResponseBean = getCallResponseBean(callEntity); @@ -886,6 +927,7 @@ public class CallDao { CallValidatorServiceImpl.validateResponse(callResponseBean,flowResponseBean,formResponseBean,evaluationFormResponseBean); callEntity.setStatus(CallStatusEnum.READY_TO_PUBLISH.getValue()); callEntity = callRepository.save(callEntity); + log.info("Call status updated to READY_TO_PUBLISH for Call ID: {}", callEntity.getId()); /** This code is responsible for adding a version history log for the "validate call" operation **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); @@ -903,11 +945,13 @@ public class CallDao { // } public CallResponse updateCallStatus(CallEntity callEntity, CallStatusEnum statusReq) { + log.info("Updating call status for Call ID: {} from {} to {}", callEntity.getId(), callEntity.getStatus(), statusReq); CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); CallStatusEnum currentStatus = CallStatusEnum.valueOf(callEntity.getStatus()); validateStatusChange(currentStatus, statusReq, callEntity.getId()); callEntity.setStatus(statusReq.getValue()); callEntity = callRepository.save(callEntity); + log.info("Call status updated in DB for Call ID: {}. New Status: {}", callEntity.getId(), callEntity.getStatus()); //Creating notification. List userIds = beneficiaryRepository.findUserIdsByHubIdAndBeneficiaryId(callEntity.getHub().getId()); @@ -926,27 +970,32 @@ public class CallDao { } private void validateStatusChange(CallStatusEnum currentStatus, CallStatusEnum newStatus, Long callId) { - + log.info("Validating status change for Call ID: {} from '{}' to '{}'", callId, currentStatus, newStatus); if (currentStatus == newStatus) { + log.warn("Validation failed: current status and new status are the same for Call ID: {}", callId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.STATUS_SAME_ERROR)); } switch (currentStatus) { case DRAFT: if (newStatus == CallStatusEnum.READY_TO_PUBLISH || newStatus == CallStatusEnum.PUBLISH) { + log.warn("Invalid status change attempt from DRAFT to {} for Call ID: {}", newStatus, callId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_DRAFT)); } break; case PUBLISH: if (newStatus == CallStatusEnum.READY_TO_PUBLISH) { + log.warn("Invalid status change attempt from PUBLISH to READY_TO_PUBLISH for Call ID: {}", callId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH)); } if (newStatus == CallStatusEnum.DRAFT && Boolean.TRUE.equals(applicationRepository.existsByCallId(callId))) { + log.warn("Invalid status change attempt from PUBLISH to DRAFT for Call ID: {} due to existing applications", callId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH_TO_DRAFT)); } break; case EXPIRED: + log.warn("Attempt to change status from EXPIRED for Call ID: {} which is not allowed", callId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.STATUS_CANNOT_BE_CHANGED)); case READY_TO_PUBLISH: @@ -957,9 +1006,11 @@ public class CallDao { } public CallEntity validatePublishedCall(Long callId, Long hubId) { + log.info("Validating published call for Call ID: {}, Hub ID: {}", callId, hubId); CallEntity callEntity= callRepository .findByIdAndStatusAndHubId(callId, CallStatusEnum.PUBLISH.getValue(), hubId); if(callEntity==null){ + log.warn("No published call found with Call ID: {} and Hub ID: {}", callId, hubId); throw new ResourceNotFoundException( Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CALL_NOT_PUBLISHED)); @@ -969,6 +1020,7 @@ public class CallDao { if (currentDate.isBefore(callEntity.getStartDate().toLocalDate()) || (currentDate.isEqual(callEntity.getStartDate().toLocalDate()) && currentTime.isBefore(callEntity.getStartTime()))) { + log.warn("Call ID: {} has not started yet. Current time is before start time.", callId); throw new CustomValidationException( Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CALL_NOT_STARTED_YET) @@ -977,6 +1029,7 @@ public class CallDao { if (currentDate.isAfter(callEntity.getEndDate().toLocalDate()) || (currentDate.isEqual(callEntity.getEndDate().toLocalDate()) && currentTime.isAfter(callEntity.getEndTime()))) { + log.warn("Call ID: {} has already ended. Current time is after end time.", callId); throw new CustomValidationException( Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CALL_ALREADY_ENDED) @@ -987,6 +1040,7 @@ public class CallDao { } public PageableResponseBean> getAllCallsByPagination(HttpServletRequest request,UserEntity user,Long companyId , Boolean onlyPreferredCall, Boolean onlyConfidiCall, CallPageableRequestBean callPageableRequestBean) { + log.info("Fetching paginated calls for userId={}, companyId={}, onlyPreferredCall={}", user.getId(), companyId, onlyPreferredCall); Integer pageNo = null; Integer pageLimit = null; if (callPageableRequestBean.getGlobalFilters() != null) { @@ -1009,6 +1063,7 @@ public class CallDao { Specification spec = search(request,user, callPageableRequestBean,onlyConfidiCall); Page entityPage; if (Boolean.TRUE.equals(onlyPreferredCall)) { + log.debug("Filtering calls for preferred by userId={} and companyId={}", user.getId(), companyId); validator.validateUserWithCompany(request, companyId); UserWithCompanyEntity userWithCompanyEntity = companyService.getUserWithCompany(user.getId(), companyId); List preferredCalls = beneficiaryPreferredCallRepository @@ -1171,6 +1226,8 @@ public class CallDao { LocalDate currentDate = DateTimeUtil.DateServerToUTC(LocalDateTime.now()).toLocalDate(); LocalTime currentTime = DateTimeUtil.LocalTimeServerToEurope(LocalTime.now()); + + log.info("Checking for expired published calls at date={}, time={}", currentDate, currentTime); List expirdedCallList = callRepository.findExpiredCallsWhichIsPublished(CallStatusEnum.PUBLISH.getValue(), currentDate, currentTime); @@ -1321,7 +1378,7 @@ public class CallDao { public CallResponse createCallStep2EvaluationV2(CallEntity callEntity, CreateCallRequestStep2EvaluationV2 createCallRequest, UserEntity user) { - + log.info("Starting Step 2 Evaluation (V2) for Call ID={}, User ID={}", callEntity.getId(), user.getId()); convertToDocumentEntities(createCallRequest.getDocs(), callEntity.getId(), DocumentTypeEnum.DOCUMENT); convertToDocumentEntities(createCallRequest.getImages(), callEntity.getId(), DocumentTypeEnum.IMAGES); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 91a589e7..9cf2e0e2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -73,6 +73,7 @@ public class CompanyDao { public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { + log.info("Initiating company creation by userId: {}", userEntity.getId()); CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); UserWithCompanyEntity userWithCompanyEntity = null; if (existingCompany != null) { @@ -84,6 +85,7 @@ public class CompanyDao { loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompanyEntity).build()); } else { + log.warn("User already connected to company. userId: {}, companyId: {}", userEntity.getId(), existingCompany.getId()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY)); } return convertCompanyEntityToCompanyResponse(existingCompany, userWithCompanyEntity); @@ -121,6 +123,7 @@ public class CompanyDao { private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant,CompanyRequest companyRequest) { + log.info("Creating user-company relation. userId: {}, companyId: {}, isLegalRep: {}", userEntity.getId(), companyEntity.getId(), isLegalRepresentant); UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); if (userEntity.getBeneficiary() != null) { userWithCompanyEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); @@ -140,6 +143,7 @@ public class CompanyDao { companyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse())); updateCodiceAtecoFieldWithNewJson(companyEntity); companyEntity = companyRepository.save(companyEntity); + log.info("Updated company JSON field and saved. companyId: {}", companyEntity.getId()); /** This code is responsible for adding a version history log for "updating company json field" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder() @@ -202,6 +206,7 @@ public class CompanyDao { public CompanyResponse updateCompany(UserEntity userEntity, Long companyId, CompanyRequest companyRequest) { + log.info("Updating company. companyId: {}, userId: {}", companyId, userEntity.getId()); CompanyEntity companyEntity = validateCompany(companyId); //cloned entity for old data CompanyEntity oldCompanyData = Utils.getClonedEntityForData(companyEntity); @@ -226,11 +231,14 @@ public class CompanyDao { // // } companyRepository.save(companyEntity); + log.info("Company updated and saved. companyId: {}", companyEntity.getId()); /** This code is responsible for adding a version history log for the "Update company" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData).newData(companyEntity).build()); + log.info("Logged version history for company update. companyId: {}", companyEntity.getId()); + UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); //cloned entity for old data UserWithCompanyEntity oldUserWithCompanyData = Utils.getClonedEntityForData(userWithCompanyEntity); @@ -253,17 +261,19 @@ public class CompanyDao { } public CompanyEntity validateCompany(Long companyId) { + log.info("Validating company. companyId: {}", companyId); return companyRepository.findById(companyId).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMPANY_NOT_FOUND_MSG))); } public CompanyResponse getCompany(UserEntity userEntity, Long companyId) { + log.info("Fetching company details. userId: {}, companyId: {}", userEntity.getId(), companyId); UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); return convertCompanyEntityToCompanyResponse(validateCompany(companyId), userWithCompanyEntity); } public void deleteCompany(UserEntity userEntity, Long companyId) { - + log.info("Deleting company. userId: {}, companyId: {}", userEntity.getId(), companyId); CompanyEntity companyEntity = validateCompany(companyId); /** This code is responsible for adding a version history log for the "delete company" operation. **/ @@ -281,6 +291,7 @@ public class CompanyDao { } public List getCompanyByUserId(Long userId) { + log.info("Fetching companies by userId: {}", userId); UserEntity userEntity = userService.validateUser(userId); List activeCompanyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(userEntity.getId()); List companies = companyRepository.findByIdInAndHubId(activeCompanyIds, userEntity.getHub().getId()); @@ -291,15 +302,18 @@ public class CompanyDao { } public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) { + log.info("Validating user-company access. userId: {}, companyId: {}", userId, companyId); return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, companyId).orElseThrow(() -> new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED))); } public UserWithCompanyEntity getUserWithCompany(Long userId, Long compnayId) { + log.info("Fetching user-company relation. userId: {}, companyId: {}", userId, compnayId); return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, compnayId).orElseThrow( () -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_COMPANY_RELATION_NOT_FOUND))); } public void removeCompanyFromList(UserEntity userEntity, Long companyId) { + log.info("Initiating removal of company from user list. userId: {}, companyId: {}", userEntity.getId(), companyId); CompanyEntity companyEntity = validateCompany(companyId); UserWithCompanyEntity existingRelation=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId()); List userApplications = applicationRepository.findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(existingRelation.getId(), userEntity.getId()); @@ -314,6 +328,7 @@ public class CompanyDao { boolean notAllowedStatus = userApplications.stream() .anyMatch(application -> !applicationStatusAllowed.contains(application.getStatus())); if (notAllowedStatus) { + log.warn("Cannot remove company. One or more applications in non-removable status. userId: {}, companyId: {}", userEntity.getId(), companyId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java index 53a1f410..acf12515 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java @@ -92,16 +92,20 @@ public class CompanyDocumentDao { private AmazonS3 amazonS3; public List uploadFileForCompany(HttpServletRequest request, Long userId, List files, Long companyId, Long documentCategoryId, CompanyDocumentTypeEnum companyDocumentSourceTypeEnum, LocalDateTime expirationDate,String name){ + + log.info("Uploading files for company. userId={}, companyId={}, documentCategoryId={}", userId, companyId, documentCategoryId); DocumentCategoryEntity categoryEntity = categoryDao.validateCategory(documentCategoryId); validator.validateUserWithCompany(request,companyId); UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userId,companyId); LocalDateTime currentDate = LocalDateTime.now(); if (expirationDate.isBefore(currentDate)) { + log.warn("Expiration date {} is before current time {}", expirationDate, currentDate); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_EXPIRATION_DATE)); } List companyDocumentEntities = new ArrayList<>(); for (MultipartFile file : files){ + log.info("Uploading file '{}' for companyId={}", file.getOriginalFilename(), companyId); UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, companyDocumentSourceTypeEnum, companyId); if (uploadFileOnAmazonS3Response != null) { CompanyDocumentEntity companyDocumentEntity = new CompanyDocumentEntity(); @@ -114,8 +118,10 @@ public class CompanyDocumentDao { companyDocumentEntity.setName(name); if (expirationDate.isBefore(currentDate.plusDays(7))) { companyDocumentEntity.setStatus(CompanyDocumentStatusEnum.DUE.getValue()); + log.info("Document '{}' marked as DUE (expires within 7 days).", uploadFileOnAmazonS3Response.getFileName()); } else { companyDocumentEntity.setStatus(CompanyDocumentStatusEnum.VALID.getValue()); + log.info("Document '{}' marked as VALID.", uploadFileOnAmazonS3Response.getFileName()); } companyDocumentEntity.setCategoryEntity(categoryEntity); @@ -125,9 +131,9 @@ public class CompanyDocumentDao { } } companyDocumentRepository.saveAll(companyDocumentEntities); + log.info("Saved {} documents for companyId={}", companyDocumentEntities.size(), companyId); /** This code is responsible for adding a version history log for the "Upload company document" operation. **/ - companyDocumentEntities.forEach(entity -> loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build())); @@ -143,6 +149,7 @@ public class CompanyDocumentDao { log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { + log.error("Error occurred while uploading file '{}' for Company ID '{}': {}", file.getOriginalFilename(), companyId, e.getMessage()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } @@ -151,13 +158,17 @@ public class CompanyDocumentDao { try { return s3ConfigBean.generateCompanyDocumentPath(typeOfDocument, companyId); } catch (IllegalArgumentException e) { + log.error("Failed to generate S3 path for Company ID '{}' and Document Type '{}': {}", companyId, typeOfDocument, e.getMessage()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } } public CompanyDocumentEntity validateCompanyDocument(Long id) { - return companyDocumentRepository.findByIdAndNotDeleted(id).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.COMPANY_DOCUMENT_NOT_FOUND))); + return companyDocumentRepository.findByIdAndNotDeleted(id).orElseThrow(() -> { + log.warn("Company Document not found with ID '{}'", id); + return new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.COMPANY_DOCUMENT_NOT_FOUND)); + }); } public CompanyDocumentResponseBean convertToCompanyDocumentResponseBean(CompanyDocumentEntity entity) { @@ -182,20 +193,23 @@ public class CompanyDocumentDao { } public CompanyDocumentResponseBean updateCompanyDocument(HttpServletRequest request,Long companyDocumentId, CompanyDocumentRequest companyDocumentRequest){ - + log.info("Start: Updating company document with ID: {}", companyDocumentId); CompanyDocumentEntity companyDocumentEntity = validateCompanyDocument(companyDocumentId); validator.validateUserWithCompany(request,companyDocumentEntity.getCompanyId()); CompanyDocumentEntity oldCompanyDocumentData = Utils.getClonedEntityForData(companyDocumentEntity); LocalDateTime currentDate = LocalDateTime.now(); if (companyDocumentRequest.getExpirationDate() != null) { if (companyDocumentRequest.getExpirationDate().isBefore(currentDate)) { + log.warn("Invalid expiration date: {}", companyDocumentRequest.getExpirationDate()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_EXPIRATION_DATE)); } companyDocumentEntity.setExpirationDate(companyDocumentRequest.getExpirationDate()); if (companyDocumentRequest.getExpirationDate().isBefore(currentDate.plusDays(7))) { companyDocumentEntity.setStatus(CompanyDocumentStatusEnum.DUE.getValue()); + log.info("Document '{}' marked as DUE.", companyDocumentEntity.getName()); } else { companyDocumentEntity.setStatus(CompanyDocumentStatusEnum.VALID.getValue()); + log.info("Document '{}' marked as VALID (expiration is beyond 7 days).", companyDocumentEntity.getName()); } } if (companyDocumentRequest.getCategoryId() != null && companyDocumentRequest.getCategoryId() >0) { @@ -204,6 +218,7 @@ public class CompanyDocumentDao { } setIfUpdated(companyDocumentEntity::getName, companyDocumentEntity::setName, companyDocumentRequest.getName()); companyDocumentRepository.save(companyDocumentEntity); + log.info("Saved updates for Company Document ID '{}'", companyDocumentId); /** This code is responsible for adding a version history log for the "updating company document" operation. **/ loggingUtil.addVersionHistory( @@ -213,12 +228,14 @@ public class CompanyDocumentDao { } public CompanyDocumentResponseBean getCompanyDocument(UserEntity user ,Long companyDocumentId) { + log.info("Fetching company document with ID '{}' for user '{}'", companyDocumentId, user.getId()); CompanyDocumentEntity companyDocumentEntity = validateCompanyDocument(companyDocumentId); validator.validateUserWithCompany(request,companyDocumentEntity.getCompanyId()); return convertToCompanyDocumentResponseBean(companyDocumentEntity); } public void deleteCompanyFile(Long companyDocumentId){ + log.info("Deleting file for company document ID '{}'", companyDocumentId); CompanyDocumentEntity companyDocumentEntity = validateCompanyDocument(companyDocumentId); deleteCompanyFileFromS3(companyDocumentEntity); } @@ -259,6 +276,7 @@ public class CompanyDocumentDao { } public DocumentResponseBean createDuplicateCompanyDocument(HttpServletRequest request , Long userId ,Long companyDocumentId , Long applicationId , DocumentTypeEnum documentTypeEnum){ + log.info("Creating duplicate of company document ID '{}' for application ID '{}'", companyDocumentId, applicationId); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); CompanyDocumentEntity companyDocumentEntity = validateCompanyDocument(companyDocumentId); validator.validateUserWithCompany(request,companyDocumentEntity.getCompanyId()); @@ -272,7 +290,7 @@ public class CompanyDocumentDao { try { response = amazonS3ServiceImpl.copyFile(companyDocumentEntity.getName(), companyDocumentPath, documentPath); } catch (Exception e) { - log.error("Error occurred while uploading file from Amazon S3: {}", e); + log.error("Error occurred while uploading file from Amazon S3: {} for application ID '{}' and company Document ID '{}' ", e,applicationId,companyDocumentId); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } @@ -296,12 +314,14 @@ public class CompanyDocumentDao { } public List getAllCompanyDocument(UserEntity user , Long companyId, CompanyDocumentTypeEnum typeEnum){ + log.info("Fetching all company documents for Company ID '{}', User ID '{}', Type '{}'", companyId, user.getId(), typeEnum); validator.validateUserWithCompany(request, companyId); companyService.validateCompany(companyId); Specification spec = filterCompanyDocuments(companyId, user.getId(), typeEnum); List companyDocumentEntities = companyDocumentRepository.findAll(spec); + log.info("Retrieved all documents for Company ID '{}'", companyId); return companyDocumentEntities.stream() .map(this::convertToCompanyDocumentResponseBean) .collect(Collectors.toList()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 81400797..3b5b41f6 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -82,10 +82,11 @@ public class DocumentDao { // private String s3Folder; public List uploadFiles(Long userId,List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { - + log.info("Uploading files userId={}, sourceType={}, fileType={}", userId,sourceType,fileType); List documentEntities = new ArrayList<>(); Long source = resolveSourceId(sourceId, sourceType); for (MultipartFile file : files) { + log.info("Uploading file '{}'", file.getOriginalFilename()); UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, sourceType, sourceId); if (uploadFileOnAmazonS3Response != null) { DocumentEntity documentEntity = new DocumentEntity(); @@ -148,6 +149,7 @@ public class DocumentDao { private UploadFileOnAmazonS3Response uploadFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long sourceId) { + log.info("Starting S3 upload: fileName={}, documentType={}, sourceId={}", file.getOriginalFilename(), type, sourceId); Long applicationId = 0L; Long amendmentId = 0L; Long evaluationId = 0L; @@ -155,26 +157,32 @@ public class DocumentDao { if (type == DocumentSourceTypeEnum.APPLICATION) { applicationId = sourceId; callId = applicationRepository.findCallIdById(applicationId); + log.info("Processing document of type APPLICATION .Resolved applicationId={}, callId={}", applicationId, callId); } else if (type == DocumentSourceTypeEnum.AMENDMENT) { amendmentId = sourceId; ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type AMENDMENT .Resolved amendmentId={}, applicationId={}, callId={}", amendmentId, applicationId, callId); }else if (type == DocumentSourceTypeEnum.EVALUATION) { evaluationId = sourceId; ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type EVALUATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } try { String s3Path = generateS3Path(type, callId, applicationId, amendmentId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { + log.error("Error uploading file to S3: fileName={}, documentType={}, sourceId={}, error={}", + file.getOriginalFilename(), type, sourceId, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } + public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId) { try { return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId); @@ -202,6 +210,7 @@ public class DocumentDao { DocumentEntity documentEntity = documentRepository.findById(documentId).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND))); if(Boolean.TRUE.equals(documentEntity.getIsDeleted())){ + log.info("Document with id={} is already marked as deleted. Skipping deletion.", documentId); return; } Long callId = null; @@ -211,24 +220,28 @@ public class DocumentDao { if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(documentEntity.getSource())) { callId = documentEntity.getSourceId(); + log.info("Processing document of type CALL. Resolved callId={}", callId); } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(documentEntity.getSource())) { applicationId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type APPLICATION. Resolved applicationId={}, callId={}", applicationId, callId); } else if(DocumentSourceTypeEnum.AMENDMENT.getValue().equalsIgnoreCase(documentEntity.getSource())){ amendmentId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type AMENDMENT. Resolved amendmentId={}, applicationId={}, callId={}", amendmentId, applicationId, callId); } else if(DocumentSourceTypeEnum.EVALUATION.getValue().equalsIgnoreCase(documentEntity.getSource())){ evaluationId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type EVALUATION. Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } deleteFileFromS3(documentEntity, callId, applicationId,amendmentId); - + log.info("Successfully deleted file from S3 for documentId={}", documentId); } public DocumentEntity validateDocument(Long id) { @@ -238,6 +251,9 @@ public class DocumentDao { public DocumentResponseBean updateDocument(Long documentId, MultipartFile file, DocumentTypeEnum documentTypeEnum) { + log.info("Starting document update: documentId={} , newDocumentType={}", + documentId , documentTypeEnum); + DocumentEntity documentEntity = validateDocument(documentId); //cloned entity for old data DocumentEntity oldDocumentData = Utils.getClonedEntityForData(documentEntity); @@ -245,12 +261,15 @@ public class DocumentDao { String type = documentEntity.getSource(); UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = updateFileOnAmazonS3(file, DocumentSourceTypeEnum.valueOf(type), documentEntity.getSourceId()); if (uploadFileOnAmazonS3Response != null) { + log.info("Successfully uploaded new file to S3: fileName={}", + uploadFileOnAmazonS3Response.getFileName()); documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); documentEntity.setType(documentTypeEnum.getValue()); documentEntity.setSource(documentEntity.getSource()); documentEntity.setSourceId(documentEntity.getSourceId()); documentRepository.save(documentEntity); + log.info("Document updated in database for documentId={}", documentId); /** This code is responsible for adding a version history log for the "updating doc or image" operation. **/ loggingUtil.addVersionHistory( @@ -260,7 +279,6 @@ public class DocumentDao { } private UploadFileOnAmazonS3Response updateFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long id) { - try { Long callId=null; Long applicationId=null; @@ -269,27 +287,32 @@ public class DocumentDao { if (type.equals(DocumentSourceTypeEnum.APPLICATION)) { callId = applicationRepository.findCallIdById(id); applicationId = id; + log.info("Processing document of type APPLICATION . Resolved applicationId={}, callId={}", applicationId, callId); } else if(type.equals(DocumentSourceTypeEnum.AMENDMENT)){ amendmentId = id; ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type AMENDMENT . Resolved amendmentId={}, applicationId={}, callId={}", amendmentId, applicationId, callId); }else if(type.equals(DocumentSourceTypeEnum.EVALUATION)){ evaluationId = id; ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + log.info("Processing document of type EVALUATION . Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } else { callId = id; applicationId = 0L; + log.info("Processing document of type CALL . Resolved callId={}", callId); } String s3Path = generateS3Path(type, callId, applicationId,amendmentId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { + log.error("Error during file update to S3: documentType={}, sourceId={}, error={}",type, id, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } @@ -304,6 +327,7 @@ public class DocumentDao { DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); String oldS3Path = documentEntity.getFilePath(); String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId); + log.info("Moving file to deleted path: oldS3Path={}, newS3Path={}", oldS3Path, newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(documentEntity.getFileName(), oldS3Path, newS3Path); documentEntity.setFileName(response.getFileName()); documentEntity.setFilePath(response.getFilePath()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 46cae083..9eda7968 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -62,6 +62,7 @@ public class PdfDao { public byte[] generatePdf(HttpServletRequest request,Long applicationId) { try { + log.info("Start generating PDF for applicationId: {}", applicationId); UserEntity userEntity = validator.validateUser(request); ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); @@ -125,6 +126,7 @@ public class PdfDao { return pdfBytes; } catch (Exception e) { + log.error("Error generating PDF for applicationId: {}", applicationId, e); e.printStackTrace(); } return null;