diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index e46e6979..21522588 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -63,6 +63,7 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.sql.Timestamp; import java.text.MessageFormat; +import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; @@ -218,6 +219,9 @@ public class ApplicationDao { @Autowired private EvaluationCriteriaRepository evaluationCriteriaRepository; + @Autowired + private CallRepository callRepository; + public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -594,11 +598,9 @@ public class ApplicationDao { String fieldType = content.getName(); // Define handlers for different (fieldType + settingName) combinations - Map handlers = new HashMap<>(); // Add handler for isRequestedAmount if ("numberinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isRequestedAmount"))) { - handlers.put("isRequestedAmount", () -> { try { BigDecimal amountRequested = new BigDecimal(fieldValue.toString()); applicationFormEntity.getApplication().setAmountRequested(amountRequested); @@ -607,19 +609,20 @@ public class ApplicationDao { log.error("Invalid number format for requested amount: {}", fieldValue, e); throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e); } - }); } // Add handler for isPecEmail if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPecEmail"))) { - handlers.put("isPecEmail", () -> { applicationFormEntity.getApplication().setPecEmail(fieldValue.toString()); log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId()); - }); + } + + if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPIVA"))) { + applicationFormEntity.getApplication().setVatNumber(fieldValue.toString()); + log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId()); } // Run all applicable handlers - handlers.values().forEach(Runnable::run); }); @@ -2422,8 +2425,9 @@ public class ApplicationDao { emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(GepafinConstant.RINALDO_EMAIL),emailLogRequest); } - public byte[] downloadRankingCsv(Long callId) { - CallEntity callEntity = callService.validateCall(callId); + public byte[] downloadRankingCsv(Long callId,UserEntity userEntity) { + + CallEntity callEntity = validator.validateUserWithCall(userEntity,callId); List applications = applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn( @@ -2435,10 +2439,11 @@ public class ApplicationDao { )); List dynamicLabels = new ArrayList<>(); // Maintain insertion order, allow duplicates only once - Map> appLabelScoresMap = new HashMap<>(); + Map> appLabelScoresMap = new HashMap<>(); Map applicationMap = new HashMap<>(); - Map appTotalScoreMap = new HashMap<>(); + Map appTotalScoreMap = new HashMap<>(); + Map appInstructorMap = new HashMap<>(); // New map to store instructor name per app for (ApplicationEntity app : applications) { Long appId = app.getId(); @@ -2447,8 +2452,19 @@ public class ApplicationDao { ApplicationEvaluationEntity evaluation = applicationEvaluationRepository.findByApplicationId(appId); + if (evaluation != null && evaluation.getAssignedApplicationsEntity() != null) { + Long userId = evaluation.getAssignedApplicationsEntity().getUserId(); + if (userId != null) { + userRepository.findById(userId).ifPresent(user -> { + String firstName = user.getFirstName() != null ? user.getFirstName() : ""; + String lastName = user.getLastName() != null ? user.getLastName() : ""; + appInstructorMap.put(appId, firstName + " " + lastName); + }); + } + } + BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore(evaluation.getCriteria()); - appTotalScoreMap.put(appId, totalScore); + appTotalScoreMap.put(appId, Utils.convertToItalianFormatWithOnlyDecimalValue(String.valueOf(totalScore))); List criteriaList = evaluation.getCriteria() != null ? @@ -2457,7 +2473,7 @@ public class ApplicationDao { List dbCriteriaList = applicationEvaluationDao.getCriteriaResponse(appId); - Map scoreByLabel = new HashMap<>(); + Map scoreByLabel = new HashMap<>(); for (CriteriaResponse criteria : criteriaList) { Optional matchedDb = dbCriteriaList.stream() @@ -2469,8 +2485,9 @@ public class ApplicationDao { if (!dynamicLabels.contains(label)) { dynamicLabels.add(label); } + String criteriaScore= String.valueOf(criteria.getScore() != null ? criteria.getScore() : BigDecimal.ZERO); - scoreByLabel.put(label, criteria.getScore() != null ? criteria.getScore() : BigDecimal.ZERO); + scoreByLabel.put(label, Utils.convertToItalianFormatWithOnlyDecimalValue(criteriaScore)); } appLabelScoresMap.put(appId, scoreByLabel); @@ -2478,7 +2495,7 @@ public class ApplicationDao { // Build headers dynamically List headers = new ArrayList<>(List.of( - "ApplicationID", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status", "Total Score" + "ApplicationID","Application VatNumber", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status","Instructor Name","Application PEC","Company PEC","Total Score" )); headers.addAll(dynamicLabels); @@ -2492,17 +2509,22 @@ public class ApplicationDao { List row = new ArrayList<>(); row.add(appId); + row.add(app.getVatNumber()); row.add(company.getVatNumber()); row.add(company.getCompanyName()); row.add(protocolEntity != null ? protocolEntity.getProtocolNumber() : 0L); - row.add(app.getAmountRequested()); + String formattedAmount=Utils.convertToItalianFormatWithOnlyDecimalValue(String.valueOf(app.getAmountRequested())); + row.add(formattedAmount); row.add(app.getStatus()); + row.add(appInstructorMap.getOrDefault(appId, "")); + row.add(app.getPecEmail()); + row.add(company.getPec()); row.add(appTotalScoreMap.get(appId)); - Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); + Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); for (String label : dynamicLabels) { - row.add(scores.getOrDefault(label, BigDecimal.ZERO)); + row.add(scores.getOrDefault(label, "")); } rows.add(row); @@ -2512,7 +2534,9 @@ public class ApplicationDao { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); CSVPrinter csvPrinter = new CSVPrinter(writer, - CSVFormat.DEFAULT.withHeader(headers.toArray(new String[0])))) { + CSVFormat.DEFAULT + .withDelimiter(';') + .withHeader(headers.toArray(new String[0])))) { for (List row : rows) { csvPrinter.printRecord(row); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index 8e783c70..dacc3541 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -76,4 +76,7 @@ public class ApplicationEntity extends BaseEntity { @Column(name = "PEC_EMAIL") private String pecEmail; + @Column(name="VAT_NUMBER") + private String vatNumber; + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index aca38d23..e311340e 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -180,6 +180,6 @@ public class ApplicationServiceImpl implements ApplicationService { @Override public byte[] downloadRankingCsv(HttpServletRequest request, Long callId) { UserEntity userEntity = validator.validateUser(request); - return applicationDao.downloadRankingCsv(callId); + return applicationDao.downloadRankingCsv(callId,userEntity); } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 19feb0e2..13cf6e87 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -6,9 +6,7 @@ import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.sql.Timestamp; -import java.text.NumberFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.text.*; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.OffsetDateTime; @@ -1063,6 +1061,37 @@ public class Utils { ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); RequestContextHolder.setRequestAttributes(attributes, true); } + public static String convertToItalianFormatWithOnlyDecimalValue(String amount) { + try { + // Step 1: Sanitize and standardize the input + String sanitizedAmount = amount.trim(); + + // Remove thousand separators (either . or , depending on input style) + sanitizedAmount = sanitizedAmount.replace(",", "").replace(" ", ""); + + // Step 2: Ensure it uses '.' as decimal separator for parsing + if (sanitizedAmount.contains(".")) { + // It already uses dot as decimal separator + } else if (sanitizedAmount.contains(",")) { + // If input uses comma as decimal separator (like "1234,56") + sanitizedAmount = sanitizedAmount.replace(",", "."); + } + + // Step 3: Parse to double + double parsedAmount = Double.parseDouble(sanitizedAmount); + + // Step 4: Format without thousand separator and with comma as decimal + DecimalFormatSymbols symbols = new DecimalFormatSymbols(); + symbols.setDecimalSeparator(','); + + DecimalFormat italianDecimalFormat = new DecimalFormat("0.00", symbols); + italianDecimalFormat.setGroupingUsed(false); // no thousand separator + + return italianDecimalFormat.format(parsedAmount); + } catch (NumberFormatException e) { + return "Invalid amount format"; + } + } } diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index 39f73ce4..f459961b 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -2985,6 +2985,12 @@ path="db/dump/insert_system_email_template_technical_evaluation_rejected.sql"/> + + + + + +