diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index a90f9c4a..276c5c23 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -2423,61 +2423,90 @@ public class ApplicationDao { public byte[] downloadRankingCsv(Long callId) { CallEntity callEntity = callService.validateCall(callId); - BigDecimal scoreList = BigDecimal.ZERO; - List evaluationCriteriaEntities = - evaluationCriteriaRepository.findByCallIdAndIsDeletedFalse(callId); - List headers = Arrays.asList( - "ApplicationID", - "VatNumber", - "Company Name", - "Protocol", - "Requested Amount", - "Status", - "Total Score", - "Individual Scores" - ); + List applications = + applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn( + callId, + List.of( + ApplicationStatusForEvaluation.APPROVED.getValue(), + ApplicationStatusForEvaluation.ADMISSIBLE.getValue(), + ApplicationStatusForEvaluation.TECHNICAL_EVALUATION.getValue() + )); + List dynamicLabels = new ArrayList<>(); // Maintain insertion order, allow duplicates only once + Map> appLabelScoresMap = new HashMap<>(); - for (EvaluationCriteriaEntity evaluationCriteria : evaluationCriteriaEntities) { - scoreList = scoreList.add(evaluationCriteria.getScore()); + Map applicationMap = new HashMap<>(); + Map appTotalScoreMap = new HashMap<>(); + + for (ApplicationEntity app : applications) { + Long appId = app.getId(); + applicationMap.put(appId, app); + + ApplicationEvaluationEntity evaluation = + applicationEvaluationRepository.findByApplicationId(appId); + + BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore(evaluation.getCriteria()); + appTotalScoreMap.put(appId, totalScore); + + List criteriaList = + evaluation.getCriteria() != null ? + Utils.convertJsonToList(evaluation.getCriteria(), new TypeReference>() {}) : + List.of(); + + List dbCriteriaList = applicationEvaluationDao.getCriteriaResponse(appId); + + Map scoreByLabel = new HashMap<>(); + + for (CriteriaResponse criteria : criteriaList) { + Optional matchedDb = dbCriteriaList.stream() + .filter(db -> Objects.equals(db.getId(), criteria.getId())) + .findFirst(); + + String label = matchedDb.map(CriteriaResponse::getLabel).orElse(""); + + if (!dynamicLabels.contains(label)) { + dynamicLabels.add(label); + } + + scoreByLabel.put(label, criteria.getScore() != null ? criteria.getScore() : BigDecimal.ZERO); + } + + appLabelScoresMap.put(appId, scoreByLabel); } - List applications = - applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn(callId,List.of(ApplicationStatusForEvaluation.APPROVED.getValue(),ApplicationStatusForEvaluation.ADMISSIBLE.getValue(),ApplicationStatusForEvaluation.TECHNICAL_EVALUATION.getValue())); + // Build headers dynamically + List headers = new ArrayList<>(List.of( + "ApplicationID", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status", "Total Score" + )); + headers.addAll(dynamicLabels); - // Collect all rows with totalScore for sorting + // Prepare data rows List> rows = new ArrayList<>(); for (ApplicationEntity app : applications) { + Long appId = app.getId(); CompanyEntity company = companyService.validateCompany(app.getCompanyId()); - String name = company.getCompanyName(); - String vat = company.getVatNumber(); - Long applicationId = app.getId(); ProtocolEntity protocolEntity = app.getProtocol(); - Long protocol = (protocolEntity != null) ? protocolEntity.getProtocolNumber() : 0L; - BigDecimal requestedAmount = app.getAmountRequested(); - String status = app.getStatus(); - ApplicationEvaluationEntity applicationEvaluationEntity = - applicationEvaluationRepository.findByApplicationId(app.getId()); + List row = new ArrayList<>(); + row.add(appId); + row.add(company.getVatNumber()); + row.add(company.getCompanyName()); + row.add(protocolEntity != null ? protocolEntity.getProtocolNumber() : 0L); + row.add(app.getAmountRequested()); + row.add(app.getStatus()); + row.add(appTotalScoreMap.get(appId)); - BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore( - applicationEvaluationEntity.getCriteria() - ); + Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); - rows.add(Arrays.asList( - applicationId, - vat, - name, - protocol, - requestedAmount, - status, - scoreList, - totalScore - )); + for (String label : dynamicLabels) { + row.add(scores.getOrDefault(label, BigDecimal.ZERO)); + } + + rows.add(row); } - // 5. Write the CSV using Commons CSV, with headers: + // Generate CSV ByteArrayOutputStream out = new ByteArrayOutputStream(); try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); CSVPrinter csvPrinter = new CSVPrinter(writer, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index ccc4e315..6d574394 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1549,13 +1549,13 @@ public class ApplicationEvaluationDao { return callRepository.findCallEntityByApplicationId(applicationId); } - private List getEvaluationCriterias(CallEntity call) { + public List getEvaluationCriterias(CallEntity call) { log.info("Fetching evaluation criterias for callId: {}", call.getId()); return evaluationCriteriaRepository .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); } - private CriteriaResponse buildCriteriaResponse(Long applicationId, EvaluationCriteriaEntity criteria) { + public CriteriaResponse buildCriteriaResponse(Long applicationId, EvaluationCriteriaEntity criteria) { CriteriaResponse response = new CriteriaResponse(); response.setId(criteria.getId()); response.setLabel(criteria.getLookupData().getValue());