From cac4a7efacd6d975697199197217e57ff2409d4c Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 2 Dec 2024 18:20:08 +0530 Subject: [PATCH 01/49] User management --- .../config/SamlSuccessHandler.java | 2 +- .../constants/GepafinConstant.java | 1 + .../gepafin/tendermanagement/dao/UserDao.java | 195 ++++++++++++++---- .../entities/SystemEmailTemplatesEntity.java | 2 + .../enums/EmailScenarioTypeEnum.java | 2 + .../enums/UserActionContextEnum.java | 4 +- .../repositories/UserRepository.java | 32 ++- .../tendermanagement/service/UserService.java | 2 +- .../service/impl/AuthenticationService.java | 19 +- .../service/impl/UserServiceImpl.java | 4 +- .../gepafin/tendermanagement/util/Utils.java | 11 +- .../web/rest/api/UserApi.java | 4 +- .../api/impl/CustomUserDetailsService.java | 6 +- .../web/rest/api/impl/UserApiController.java | 23 ++- .../db/changelog/db.changelog-1.0.0.xml | 12 +- ...template_for_reset_password_28_11_2024.sql | 65 ++++++ ...tem_email_template_for_user_28_11_2024.sql | 29 +++ 17 files changed, 351 insertions(+), 62 deletions(-) create mode 100644 src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql create mode 100644 src/main/resources/db/dump/insert_system_email_template_for_user_28_11_2024.sql diff --git a/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java b/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java index 14f2b1bf..850d2451 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java @@ -63,7 +63,7 @@ public class SamlSuccessHandler implements AuthenticationSuccessHandler { Saml2AuthenticatedPrincipal principal = (Saml2AuthenticatedPrincipal) samlAuth.getPrincipal(); Map> userAttributes = principal.getAttributes(); - String token = Utils.generateSecureToken(); + String token = Utils.generateSecureSamlToken(); logger.info("SAML User Attributes: " + userAttributes); // Extracting raw SAML response diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 97730f80..aaa3279b 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -302,5 +302,6 @@ public class GepafinConstant { public static final String USER_ID = "userId"; public static final String LOGIN_ATTEMPT_ID = "loginAttemptId"; public static final String USER_ACTION_ID = "userActionId"; + public static final String RESET_PASSWORD_URL_FORMAT = "/reset-password?token=%s&email=%s"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index da5c6f07..41483d36 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -6,21 +6,15 @@ import net.gepafin.tendermanagement.config.SamlSuccessHandler; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; -import net.gepafin.tendermanagement.enums.RoleStatusEnum; -import net.gepafin.tendermanagement.enums.UserActionContextEnum; -import net.gepafin.tendermanagement.enums.UserActionLogsEnum; -import net.gepafin.tendermanagement.enums.UserStatusEnum; -import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.*; -import net.gepafin.tendermanagement.model.response.CompanyResponse; -import net.gepafin.tendermanagement.model.response.RoleResponseBean; -import net.gepafin.tendermanagement.model.response.UserSamlResponse; -import net.gepafin.tendermanagement.model.response.UserResponseBean; +import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.repositories.BeneficiaryRepository; import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.service.HubService; import net.gepafin.tendermanagement.service.RoleService; +import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; import net.gepafin.tendermanagement.service.impl.AuthenticationService; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; @@ -39,6 +33,7 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @@ -90,6 +85,18 @@ public class UserDao { @Autowired private HttpServletRequest request; + @Autowired + private SystemEmailTemplatesService systemEmailTemplatesService; + + @Autowired + private EmailLogDao emailLogDao; + + @Autowired + private EmailNotificationDao emailNotificationDao; + + @Value("${fe.base.url}") + private String feBaseUrl; + public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) { if (StringUtils.isEmpty(userReq.getHubUuid())) { @@ -120,9 +127,35 @@ public class UserDao { /** This code is responsible for adding a version history log for the "Create user" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).newData(userEntity).build()); + if(beneficiary == null){ + sendEmailToOnboardingUser(userEntity); + } return token; } - + public void sendEmailToOnboardingUser(UserEntity userEntity){ + SystemEmailTemplateResponse emailTemplate = systemEmailTemplatesService.retrieveTemplateByTypeAndCall( + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.USER_ONBOARDING, userEntity.getHub(), null); + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(), RecipientTypeEnum.USER, userEntity.getId(), userEntity.getEmail(), + userEntity.getId(), null, null, null); + String firstName = userEntity.getFirstName() != null ? userEntity.getFirstName() : ""; + String lastName = userEntity.getLastName() != null ? userEntity.getLastName() : ""; + String userName = String.join(" ", firstName, lastName).trim(); + String subject = Utils.replacePlaceholders(emailTemplate.getSubject(), Map.of( + "{{user_name}}", userName + )); + String body = Utils.replacePlaceholders(emailTemplate.getHtmlContent(), Map.of( + "{{user_name}}", userName, + "{{user_email}}", userEntity.getEmail() + )); + + emailNotificationDao.sendMail( + userEntity.getHub().getId(), + subject, + body, + List.of(userEntity.getEmail()), + emailLogRequest + ); + } private BeneficiaryEntity createBeneficiary(RoleEntity roleEntity, UserReq userReq, HubEntity hub) { BeneficiaryEntity beneficiaryEntity = null; if (RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleEntity.getRoleType())) { @@ -164,12 +197,10 @@ public class UserDao { Translator.toLocale(GepafinConstant.VALIDATE_EMAIL)); } log.info("Creating user with email: {}", userReq.getEmail()); - if (userRepository.existsByEmailIgnoreCaseAndHubUniqueUuid(userReq.getEmail(), userReq.getHubUuid())) { - log.error("User creation failed: Email {} already exists", userReq.getEmail()); - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); - } - if (Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getCodiceFiscale())) + RoleEntity roleEntity = roleService.validateRole(userReq.getRoleId()); + validateDuplicateEmail(userReq.getEmail(), userReq.getHubUuid(), roleEntity.getRoleType()); + + if (Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getCodiceFiscale())) && userRepository.existsByBeneficiaryCodiceFiscaleAndHubId(userReq.getCodiceFiscale(), hub.getId())) { log.error("User creation failed: CodiceFiscale {} already exists", userReq.getCodiceFiscale()); throw new CustomValidationException(Status.VALIDATION_ERROR, @@ -191,8 +222,29 @@ public class UserDao { } } } + private void validateDuplicateEmail(String email, String hubUuid, String roleType) { + Boolean existsForNonBeneficiaries = userRepository.existsByEmailIgnoreCaseForNonBeneficiaries( + email, hubUuid, RoleStatusEnum.ROLE_BENEFICIARY.getValue()); - private void validatePassword(String password, String confirmPassword, String tempToken) { + Boolean beneficiaryExistsInHub = userRepository.existsByEmailIgnoreCaseForBeneficiaries( + email, hubUuid, RoleStatusEnum.ROLE_BENEFICIARY.getValue()); + + if (Boolean.TRUE.equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleType))) { + if (beneficiaryExistsInHub) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); + } + } + else { + if (existsForNonBeneficiaries) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); + } + } + } + + + private void validatePassword(String password, String confirmPassword, String tempToken) { if (StringUtils.isEmpty(password) || StringUtils.isEmpty(confirmPassword)) { if(tempToken == null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATE_PASSWORD)); @@ -263,7 +315,7 @@ public class UserDao { userEntity.setAddress(userReq.getAddress()); userEntity.setPhoneNumber(userReq.getPhoneNumber()); userEntity.setDateOfBirth(userReq.getDateOfBirth()); - } + } return userRepository.save(userEntity); } @@ -362,25 +414,83 @@ public class UserDao { return user; } - public String initiatePasswordReset(InitiatePasswordResetReq resetReq) { - UserEntity user = userRepository - .findByEmailIgnoreCaseAndHubUniqueUuid(resetReq.getEmail(), resetReq.getHubUuid()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + public void initiatePasswordReset(InitiatePasswordResetReq resetReq) { + UserEntity user = userRepository.findUserExcludingRoleType( + resetReq.getEmail(), + resetReq.getHubUuid(), + RoleStatusEnum.ROLE_BENEFICIARY.getValue() + ).orElseThrow(() -> new ResourceNotFoundException( + Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG) + )); + UserEntity oldUserEntity = Utils.getClonedEntityForData(user); String token = Utils.generateSecureToken(); user.setResetPasswordToken(token); userRepository.save(user); + + /** This code is responsible for adding a version history log for the "Initiate password reset request" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserEntity).newData(user).build()); + log.info("Password reset token generated for user: {}", resetReq.getEmail()); - return token; + + sendResetPasswordTokenEmail(user, token); + } + public void sendResetPasswordTokenEmail(UserEntity user, String token) { + + SystemEmailTemplateResponse emailTemplate = systemEmailTemplatesService.retrieveTemplateByTypeAndCall( + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.PASSWORD_RESET, user.getHub(), null); + String redirectUrl = feBaseUrl; + if (Boolean.FALSE.equals(StringUtils.isEmpty(user.getHub().getDomainName()))) { + redirectUrl = user.getHub().getDomainName(); + } + + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest( + emailTemplate.getEmailScenario(), + RecipientTypeEnum.USER, + user.getId(), + user.getEmail(), + user.getId(), + null, + null, + null); + redirectUrl = String.format( + user.getHub().getDomainName() + GepafinConstant.RESET_PASSWORD_URL_FORMAT, + token, + user.getEmail() + ); + String firstName = user.getFirstName() != null ? user.getFirstName() : ""; + String lastName = user.getLastName() != null ? user.getLastName() : ""; + String userName = String.join(" ", firstName, lastName).trim(); + String subject = Utils.replacePlaceholders(emailTemplate.getSubject(), Map.of( + "{{user_name}}", userName + )); + String body = Utils.replacePlaceholders(emailTemplate.getHtmlContent(), Map.of( + "{{user_name}}", userName, + "{{reset_password_link}}", redirectUrl + )); + emailNotificationDao.sendMail( + user.getHub().getId(), + subject, + body, + List.of(user.getEmail()), + emailLogRequest + ); + + log.info("Password reset token email sent to: {}", user.getEmail()); } public Boolean resetPassword(ResetPasswordReq resetPasswordReq) { - UserEntity user = userRepository - .findByEmailIgnoreCaseAndHubUniqueUuid(resetPasswordReq.getEmail(), resetPasswordReq.getHubUuid()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); - + UserEntity user = userRepository.findUserExcludingRoleType( + resetPasswordReq.getEmail(), + resetPasswordReq.getHubUuid(), + RoleStatusEnum.ROLE_BENEFICIARY.getValue() + ).orElseThrow(() -> new ResourceNotFoundException( + Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG) + )); + + UserEntity oldUserEntity = Utils.getClonedEntityForData(user); if (!resetPasswordReq.getNewPassword().equals(resetPasswordReq.getConfirmPassword())) { log.info("User creation failed: Passwords do not match for email {}", user.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); @@ -395,25 +505,36 @@ public class UserDao { user.setPassword(passwordEncoder.encode(resetPasswordReq.getNewPassword())); user.setResetPasswordToken(null); userRepository.save(user); + + /** This code is responsible for adding a version history log for the "Reset Password " operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserEntity).newData(user).build()); + log.info("Password successfully reset for user: {}", resetPasswordReq.getEmail()); return true; } - public Boolean changePassword(UserEntity userEntity, ChangePasswordRequest request) { + public Boolean changePassword(UserEntity userEntity, ChangePasswordRequest changePasswordRequest) { UserEntity user = userRepository - .findByEmailIgnoreCaseAndHubUniqueUuid(request.getEmail(), userEntity.getHub().getUniqueUuid()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); - - if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { + .findUserExcludingRoleType(changePasswordRequest.getEmail(), userEntity.getHub().getUniqueUuid(),RoleStatusEnum.ROLE_BENEFICIARY.getValue()) + .orElseThrow(() -> new ResourceNotFoundException( + Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG) + )); + UserEntity oldUserEntity = Utils.getClonedEntityForData(userEntity); + if (!passwordEncoder.matches(changePasswordRequest.getPassword(), user.getPassword())) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CURRENT_PASSWORD_INCORRECT)); } - if (!request.getNewPassword().equals(request.getConfirmPassword())) { + if (!changePasswordRequest.getNewPassword().equals(changePasswordRequest.getConfirmPassword())) { log.info("User creation failed: Passwords do not match for email {}", user.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); } - user.setPassword(passwordEncoder.encode(request.getNewPassword())); + user.setPassword(passwordEncoder.encode(changePasswordRequest.getNewPassword())); userRepository.save(user); + + /** This code is responsible for adding a version history log for the "Change user password" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserEntity).newData(user).build()); + + return true; } public void logout(HttpServletRequest request, HttpServletResponse response) { diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java index f7974eca..dac3a432 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java @@ -47,6 +47,8 @@ public class SystemEmailTemplatesEntity extends BaseEntity { INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE("INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE"), ADMISSIBILITY_NOTIFICATION("ADMISSIBILITY_NOTIFICATION"), AMENDMENT_REMINDER("AMENDMENT_REMINDER"), + USER_ONBOARDING("USER_ONBOARDING"), + PASSWORD_RESET("PASSWORD_RESET"), INADMISSIBILITY_TEMPLATE("INADMISSIBILITY_NOTIFICATION"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java index 493f987c..415f1dd2 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java @@ -9,6 +9,8 @@ public enum EmailScenarioTypeEnum { APPLICATION_AMENDMENT_EXPIRED("APPLICATION_AMENDMENT_EXPIRED"), APPLICATION_AMENDMENT_REMINDER("APPLICATION_AMENDMENT_REMINDER"), APPLICATION_APPROVED("APPLICATION_APPROVED"), + USER_CREATION("USER_CREATION"), + PASSWORD_RESET_REQUEST("PASSWORD_RESET_REQUEST"), APPLICATION_REJECTED("APPLICATION_REJECTED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 0a92143b..a4d7f3c2 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -24,7 +24,9 @@ public enum UserActionContextEnum { VALIDATE_EXISTING_USER_WITH_SPID_TOKEN("VALIDATE_EXISTING_USER_WITH_SPID_TOKEN"), GET_VALID_USER_DETAILS("GET_VALID_USER_DETAILS"), GET_ALL_USERS_BY_ROLE("GET_ALL_USERS_BY_ROLE"), - + CHANGE_USER_PASSWORD("CHANGE_USER_PASSWORD"), + INITIATE_PASSWORD_RESET_REQUEST("INITIATE_PASSWORD_RESET_REQUEST"), + RESET_USER_PASSWORD("RESET_USER_PASSWORD"), /** application action context **/ GET_APPLICATION("GET_APPLICATION"), CREATE_UPDATE_APPLICATION_FORM("CREATE_UPDATE_APPLICATION_FORM"), diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java index 47ab16b8..3a0cf957 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java @@ -2,6 +2,8 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -12,9 +14,16 @@ public interface UserRepository extends JpaRepository { UserEntity findByBeneficiaryId(Long beneficiaryId); - Optional findByEmailIgnoreCaseAndHubUniqueUuid(String email, String hubUuid); +// Optional findByEmailIgnoreCaseAndHubUniqueUuid(String email, String hubUuid); - boolean existsByEmailIgnoreCaseAndHubUniqueUuid(String email, String hubUuid); + @Query("SELECT u FROM UserEntity u WHERE LOWER(u.email) = LOWER(:email) AND u.hub.uniqueUuid = :hubUuid AND u.roleEntity.roleType <> :roleType") + Optional findUserExcludingRoleType( + @Param("email") String email, + @Param("hubUuid") String hubUuid, + @Param("roleType") String roleType + ); + +// boolean existsByEmailIgnoreCaseAndHubUniqueUuid(String email, String hubUuid); List findByRoleEntityIdAndHubId(Long roleId, Long hubId); @@ -24,5 +33,22 @@ public interface UserRepository extends JpaRepository { Optional findByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); - boolean existsByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); + Boolean existsByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); + + @Query("SELECT COUNT(u) > 0 " + + "FROM UserEntity u " + + "WHERE u.email = :email " + + "AND u.hub.uniqueUuid = :hubUuid " + + "AND u.roleEntity.roleType <> :beneficiaryRoleType") + Boolean existsByEmailIgnoreCaseForNonBeneficiaries(@Param("email") String email, + @Param("hubUuid") String hubUuid, + @Param("beneficiaryRoleType") String beneficiaryRoleType); + + @Query("SELECT CASE WHEN COUNT(u) > 0 THEN true ELSE false END " + + "FROM UserEntity u " + + "WHERE LOWER(u.email) = LOWER(:email) AND u.hub.uniqueUuid = :hubUuid " + + "AND u.roleEntity.roleType = :beneficiaryRoleType") + Boolean existsByEmailIgnoreCaseForBeneficiaries(String email, String hubUuid, String beneficiaryRoleType); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/UserService.java b/src/main/java/net/gepafin/tendermanagement/service/UserService.java index 21109a5e..aa534bea 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/UserService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/UserService.java @@ -27,7 +27,7 @@ public interface UserService { UserEntity validateUser(Long userId); - String initiatePasswordReset(InitiatePasswordResetReq resetReq); + void initiatePasswordReset(InitiatePasswordResetReq resetReq); Boolean resetPassword(ResetPasswordReq resetPasswordReq); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java index d4dab052..1f0194d9 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -12,10 +12,7 @@ import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.entities.LoginAttemptEntity; import net.gepafin.tendermanagement.entities.SamlResponseEntity; import net.gepafin.tendermanagement.entities.UserEntity; -import net.gepafin.tendermanagement.enums.LoginAttemptResultEnum; -import net.gepafin.tendermanagement.enums.LoginAttemptTypeEnum; -import net.gepafin.tendermanagement.enums.UserStatusEnum; -import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.LoginReq; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.CompanyResponse; @@ -40,6 +37,7 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Service; @@ -95,15 +93,22 @@ public class AuthenticationService { LoginAttemptEntity loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request); try { log.info("Attempting login for email: {}", loginReq.getEmail()); + user = userRepository.findUserExcludingRoleType( + loginReq.getEmail(), + loginReq.getHubUuid(), + RoleStatusEnum.ROLE_BENEFICIARY.getValue() + ).orElseThrow(() -> new ResourceNotFoundException( + Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG) + )); + String emailWithHubId = loginReq.getEmail()+":"+loginReq.getHubUuid(); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( emailWithHubId, loginReq.getPassword()); Authentication authentication = this.authenticationManager.authenticate(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); log.info("Authentication successful for email: {}", loginReq.getEmail()); - user = userRepository.findByEmailIgnoreCaseAndHubUniqueUuid(loginReq.getEmail(), loginReq.getHubUuid()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + loginAttemptEntity.setUserId(user.getId()); if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) { throw new ResourceNotFoundException(Status.NOT_FOUND, diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java index 9f95b830..744fbacb 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java @@ -77,8 +77,8 @@ public class UserServiceImpl implements UserService { } @Override - public String initiatePasswordReset(InitiatePasswordResetReq resetReq) { - return userDao.initiatePasswordReset(resetReq); + public void initiatePasswordReset(InitiatePasswordResetReq resetReq) { + userDao.initiatePasswordReset(resetReq); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 4949e5d5..b3993900 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -201,7 +201,7 @@ public class Utils { return new String(decodedBytes, StandardCharsets.UTF_8); } - public static String generateSecureToken() { + public static String generateSecureSamlToken() { SecureRandom secureRandom = new SecureRandom(); byte[] tokenBytes = new byte[24]; secureRandom.nextBytes(tokenBytes); @@ -209,7 +209,14 @@ public class Utils { log.debug("Generated secure token: {}", token); return token; } - + public static String generateSecureToken() { + SecureRandom secureRandom = new SecureRandom(); + byte[] tokenBytes = new byte[5]; + secureRandom.nextBytes(tokenBytes); + String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); + log.debug("Generated secure token: {}", token); + return token; + } public static Map> convertStringIntoMap(String jsonString) { try { return mapper.readValue(jsonString, new TypeReference>>() { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index c7b8e530..8bf9b780 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -118,7 +118,7 @@ public interface UserApi { @RequestMapping(value = "/reset-password/initiate", produces = {"application/json"}, method = RequestMethod.POST) - ResponseEntity> initiatePasswordReset( + ResponseEntity> initiatePasswordReset(HttpServletRequest request, @Parameter(description = "Initiate password reset request object", required = true) @Valid @RequestBody InitiatePasswordResetReq initiatePasswordResetReq); @Operation(summary = "Api to reset password", @@ -131,7 +131,7 @@ public interface UserApi { @RequestMapping(value = "/reset-password", produces = {"application/json"}, method = RequestMethod.POST) - ResponseEntity> resetPassword( + ResponseEntity> resetPassword(HttpServletRequest request, @Parameter(description = "Reset password request object", required = true) @Valid @RequestBody ResetPasswordReq resetPasswordReq); @Operation(summary = "Api to change user password", responses = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CustomUserDetailsService.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CustomUserDetailsService.java index d26ab560..dd6ef1ae 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CustomUserDetailsService.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CustomUserDetailsService.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.web.rest.api.impl; import net.gepafin.tendermanagement.entities.RoleEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.repositories.UserRepository; import org.slf4j.Logger; @@ -35,7 +36,10 @@ public class CustomUserDetailsService implements UserDetailsService { String email = loginParts[0]; String hubId = loginParts[1]; - UserEntity user = userRepository.findByEmailIgnoreCaseAndHubUniqueUuid(email, hubId) + UserEntity user = userRepository.findUserExcludingRoleType( + email, + hubId, + RoleStatusEnum.ROLE_BENEFICIARY.getValue()) .orElseThrow( () -> new UsernameNotFoundException("User " + email + " was not found in the database")); return createSpringSecurityUser(user); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java index 7ff12c2a..9f02a8f6 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java @@ -125,20 +125,35 @@ public class UserApiController implements UserApi { @Override public ResponseEntity> changePassword(HttpServletRequest httpServletRequest, @Valid @RequestBody ChangePasswordRequest request) { log.info("Change Password attempt for email: {}", request.getEmail()); + + /** This code is responsible for "Change user password" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.CHANGE_USER_PASSWORD).build()); + userService.changePassword(httpServletRequest, request); return ResponseEntity.ok(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.SUCCESS_PASSWORD_CHANGED))); } @Override - public ResponseEntity> initiatePasswordReset(InitiatePasswordResetReq request) { + public ResponseEntity> initiatePasswordReset(HttpServletRequest httpServletRequest,InitiatePasswordResetReq request) { log.info("Initiating password reset for email: {}", request.getEmail()); - String resetToken = userService.initiatePasswordReset(request); + + /** This code is responsible for "Initiating Password Reset Request" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.INITIATE_PASSWORD_RESET_REQUEST).build()); + + userService.initiatePasswordReset(request); log.info("Password reset token generated for email: {}", request.getEmail()); - return ResponseEntity.ok(new Response<>(resetToken, Status.SUCCESS, Translator.toLocale(GepafinConstant.RESET_PASSWORD_INITIATED))); + return ResponseEntity.ok(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.RESET_PASSWORD_INITIATED))); } @Override - public ResponseEntity> resetPassword(ResetPasswordReq request) { + public ResponseEntity> resetPassword(HttpServletRequest httpServletRequest,ResetPasswordReq request) { log.info("Resetting password for username: {}", request.getEmail()); + + /** This code is responsible for "Resest user password" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.RESET_USER_PASSWORD).build()); + Boolean success = userService.resetPassword(request); if (success) { log.info("Password reset successfully for username: {}", request.getEmail()); 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 c209f76a..cc2ee820 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 @@ -1875,5 +1875,15 @@ - + + select + setval('gepafin_schema.system_email_template_id_seq', (select + max(id)+1 + from gepafin_schema.system_email_template), false) + + + + diff --git a/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql b/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql new file mode 100644 index 00000000..facb4fdf --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql @@ -0,0 +1,65 @@ +INSERT INTO gepafin_schema.system_email_template +(template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date,email_scenario) +VALUES +( + 'Password Reset Link Email (Italian)', + 'PASSWORD_RESET', + ' + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+

Richiesta di Reimpostazione Password

+
+

Gentile {{user_name}},

+

Hai richiesto di reimpostare la tua password. Puoi farlo cliccando sul link sottostante:

+
+ {{reset_password_link}} +
+

Cordiali saluti,

+

{{email_signature}}

+
+ + Reimposta la Password +
+
', + 'Richiesta di Reimpostazione Password', + NULL, + true, + false, + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP, + 'PASSWORD_RESET_REQUEST'); diff --git a/src/main/resources/db/dump/insert_system_email_template_for_user_28_11_2024.sql b/src/main/resources/db/dump/insert_system_email_template_for_user_28_11_2024.sql new file mode 100644 index 00000000..cfe54849 --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_for_user_28_11_2024.sql @@ -0,0 +1,29 @@ +INSERT INTO gepafin_schema.system_email_template +(template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date, email_scenario) +VALUES +( + 'Welcome Email for New User', + 'USER_ONBOARDING', + ' + +
+

Benvenuto!

+

Ciao {{user_name}},

+

Siamo lieti di averti con noi. Di seguito trovi alcune informazioni utili:

+
    +
  • Nome Utente: {{user_email}}
  • +
+

Per accedere, utilizza il tuo indirizzo email registrato. Se hai bisogno di supporto, non esitare a contattarci.

+

Distinti saluti,

+

{{email_signature}}

+
+ + ', + 'Welcome - {{user_name}}', + NULL, + true, + false, + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP, + 'USER_CREATION' +); From dcaa7699037f985717a93d1c99bc2d3dbc0da08f Mon Sep 17 00:00:00 2001 From: nisha Date: Wed, 4 Dec 2024 20:02:45 +0530 Subject: [PATCH 02/49] Added json field in company --- .../constants/GepafinConstant.java | 1 + .../tendermanagement/dao/CompanyDao.java | 15 ++++++++- .../tendermanagement/dao/VatCheckDao.java | 33 +++++++++++-------- .../entities/CompanyEntity.java | 3 ++ .../model/request/CompanyRequest.java | 2 ++ .../model/response/VatCheckResponseBean.java | 12 +++++++ .../service/CompanyService.java | 4 +-- .../service/impl/CompanyServiceImpl.java | 3 +- .../web/rest/api/CompanyApi.java | 5 +-- .../rest/api/impl/CompanyApiController.java | 7 ++-- .../db/changelog/db.changelog-1.0.0.xml | 8 ++++- src/main/resources/message_en.properties | 1 + src/main/resources/message_it.properties | 1 + 13 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/VatCheckResponseBean.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index dbf39e8f..11f91511 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -305,5 +305,6 @@ public class GepafinConstant { public static final String USER_ID = "userId"; public static final String LOGIN_ATTEMPT_ID = "loginAttemptId"; public static final String USER_ACTION_ID = "userActionId"; + public static final String VALID_VATNUMBER_MSG = "valid.vatnumber.message"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 632d3226..e6a88c66 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.dao; import java.util.EnumSet; import java.util.List; +import java.util.Map; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; @@ -78,6 +79,8 @@ public class CompanyDao { } else { validateCompany(userEntity, companyRequest); CompanyEntity companyEntity = convertCompanyRequestToCompanyEntity(userEntity, companyRequest); + companyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) ); + CompanyEntity companyData = companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for "creating company" operation. **/ @@ -178,7 +181,6 @@ public class CompanyDao { CompanyEntity oldCompanyData = Utils.getClonedEntityForData(companyEntity); setIfUpdated(companyEntity::getCompanyName, companyEntity::setCompanyName, companyRequest.getCompanyName()); - setIfUpdated(companyEntity::getVatNumber, companyEntity::setVatNumber, companyRequest.getVatNumber()); setIfUpdated(companyEntity::getCodiceFiscale, companyEntity::setCodiceFiscale, companyRequest.getCodiceFiscale()); setIfUpdated(companyEntity::getAddress, companyEntity::setAddress, companyRequest.getAddress()); setIfUpdated(companyEntity::getPhoneNumber, companyEntity::setPhoneNumber, companyRequest.getPhoneNumber()); @@ -192,6 +194,17 @@ public class CompanyDao { setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, companyRequest.getAnnualRevenue()); setIfUpdated(companyEntity::getContactName, companyEntity::setContactName, companyRequest.getContactName()); setIfUpdated(companyEntity::getContactEmail, companyEntity::setContactEmail, companyRequest.getContactEmail()); + + if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { + CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); + if(existingCompany!=null){ + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); + } + companyEntity.setVatNumber(companyRequest.getVatNumber()); + String responseJson = companyRequest.getVatCheckResponse() != null ? Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) : null; + setIfUpdated(companyEntity::getJson, companyEntity::setJson, responseJson); + + } companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for the "Update company" operation. **/ diff --git a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java index 52321b43..85af1388 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java @@ -4,15 +4,11 @@ import feign.FeignException; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.enums.UserActionContextEnum; -import net.gepafin.tendermanagement.enums.UserActionLogsEnum; -import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import net.gepafin.tendermanagement.service.feignClient.VatCheckService; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; -import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; -import net.gepafin.tendermanagement.web.rest.api.errors.Status; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -49,10 +45,13 @@ public class VatCheckDao { @Autowired private HttpServletRequest request; - public Map checkVatNumberApi(String vatNumber) { - + public VatCheckResponseBean checkVatNumberApi(String vatNumber) { + VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); + vatCheckResponseBean.setValid(false); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); if (Boolean.TRUE.equals(Boolean.parseBoolean(isVatCheckGloballyDisabled))) { - return new HashMap<>(); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return vatCheckResponseBean; } Map responseBody = new HashMap<>(); try { @@ -77,22 +76,28 @@ public class VatCheckDao { responseBody.remove("id"); Map data = new LinkedHashMap<>(); data.put("data", responseBody); - return data; + vatCheckResponseBean.setValid(true); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); + vatCheckResponseBean.setVatCheckResponse(data); } } } catch (FeignException ex) { log.error("Exception occurred while checking vat number: {0}", ex); Utils.callException(ex.status(), ex); } - return responseBody; + return vatCheckResponseBean; } - public Map checkVatNumber(String vatNumber) { + public VatCheckResponseBean checkVatNumber(String vatNumber) { try { return checkVatNumberApi(vatNumber); } catch (Exception e) { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + log.error("Error in checkVatNumber: {}", e.getMessage()); + VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); + vatCheckResponseBean.setValid(false); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return vatCheckResponseBean; } } + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java index ed50268f..1d8ef4ca 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java @@ -62,5 +62,8 @@ public class CompanyEntity extends BaseEntity{ @ManyToOne @JoinColumn(name = "HUB_ID") private HubEntity hub; + + @Column(name = "JSON") + private String json; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java index b9f43932..22ade9a5 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.model.request; import java.math.BigDecimal; +import java.util.Map; import lombok.Data; @@ -23,4 +24,5 @@ public class CompanyRequest { private Boolean isLegalRepresentant; private String contactName; private String contactEmail; + private Map vatCheckResponse; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/VatCheckResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/VatCheckResponseBean.java new file mode 100644 index 00000000..611925d3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/VatCheckResponseBean.java @@ -0,0 +1,12 @@ +package net.gepafin.tendermanagement.model.response; +import lombok.Getter; +import lombok.Setter; +import java.util.Map; + +@Getter +@Setter +public class VatCheckResponseBean { + private Boolean valid; + private Map vatCheckResponse; + private String message; +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java index 2896419a..deb5b2f5 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletRequest; @@ -26,7 +27,7 @@ public interface CompanyService { List getCompanyByUserId(HttpServletRequest request, Long userId); - Map checkVatNumber(HttpServletRequest request, String vatNumber); + VatCheckResponseBean checkVatNumber(HttpServletRequest request, String vatNumber); CompanyEntity validateCompany(Long companyId); @@ -44,5 +45,4 @@ public interface CompanyService { UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId); void removeCompanyFromList(HttpServletRequest request, Long companyId); - } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java index 3f5e326f..a9095c8a 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -78,7 +79,7 @@ public class CompanyServiceImpl implements CompanyService { @Override @Transactional(readOnly = true) - public Map checkVatNumber(HttpServletRequest request, String vatNumber) { + public VatCheckResponseBean checkVatNumber(HttpServletRequest request, String vatNumber) { return vatCheckDao.checkVatNumber(vatNumber); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java index bc016334..4c14a114 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.web.rest.api; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -94,8 +95,8 @@ public interface CompanyApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/vatNumber", produces = { "application/json" }) - ResponseEntity>> checkVatNumber(HttpServletRequest request, - @Parameter(description = "The vatNumber of company", required = true) @RequestParam("vatNumber") String vatNumber); + ResponseEntity> checkVatNumber(HttpServletRequest request, + @Parameter(description = "The vatNumber of company", required = true) @RequestParam("vatNumber") String vatNumber); @Operation(summary = "Api to download company delegation template", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java index ef73e985..d9298c51 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java @@ -7,6 +7,7 @@ import java.util.Map; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import net.gepafin.tendermanagement.util.LoggingUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -111,15 +112,15 @@ public class CompanyApiController implements CompanyApi{ } @Override - public ResponseEntity>> checkVatNumber(HttpServletRequest request, String vatNumber) { + public ResponseEntity> checkVatNumber(HttpServletRequest request, String vatNumber) { log.info("check VatNumber with: {}", vatNumber); /** This code is responsible for creating user action logs for the "Check vat number" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.CHECK_COMPANY_VAT_NUMBER).build()); - Map data = companyService.checkVatNumber(request, vatNumber); + VatCheckResponseBean vatCheckResponseBean = companyService.checkVatNumber(request, vatNumber); return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.CHECK_VATNUMBER_SUCCESS_MSG))); + .body(new Response<>(vatCheckResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CHECK_VATNUMBER_SUCCESS_MSG))); } @Override 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 52a7dae3..2d0b51b1 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 @@ -1961,5 +1961,11 @@ - + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index d6aa4578..1549bcfe 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -313,3 +313,4 @@ company.id.required.for.preferred.call=Company ID is required when requesting on response.days.not.null=Response days should not be null and greater than zero. application.cannot.approved.or.rejected=Application cannot be approved and rejected because amendment is active. +valid.vatnumber.message=The VAT number is valid. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 051ed432..73bf149a 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -307,3 +307,4 @@ user.must.be.associated.with.company.to.create.application=Devi essere associato company.id.required.for.preferred.call=ID azienda obbligatorio quando si richiedono solo chiamate preferite. response.days.not.null=I giorni di risposta non devono essere nulli e maggiori di zero. application.cannot.approved.or.rejected=La domanda non può essere approvata o rifiutata perché l'emendamento è attivo. +valid.vatnumber.message=Il numero di partita IVA è valido. From d8e51f3a706a93a5e382aa16a6345d9aaa7fbe4b Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 13 Dec 2024 20:57:58 +0530 Subject: [PATCH 03/49] Notification Code. --- pom.xml | 14 +++ .../TendermanagementApplication.java | 4 +- .../config/SecurityConfig.java | 1 + .../config/WebSocketConfig.java | 32 ++++++ .../constants/GepafinConstant.java | 4 + .../constants/NotificationConstant.java | 5 + .../gepafin/tendermanagement/dao/CallDao.java | 41 +++++++- .../tendermanagement/dao/NotificationDao.java | 97 +++++++++++++++++++ .../entities/NotificationEntity.java | 31 ++++++ .../entities/NotificationTypeEntity.java | 21 ++++ .../enums/NotificationEnum.java | 27 ++++++ .../enums/NotificationTypeEnum.java | 29 ++++++ .../model/request/NotificationReq.java | 37 +++++++ .../model/response/UserResponseBean.java | 1 + .../repositories/BeneficiaryRepository.java | 5 + .../repositories/NotificationRepository.java | 7 ++ .../NotificationTypeRepository.java | 8 ++ .../service/NotificationService.java | 7 ++ .../service/impl/NotificationServiceImpl.java | 26 +++++ .../gepafin/tendermanagement/util/Utils.java | 4 + .../web/rest/api/NotificationApi.java | 30 ++++++ .../api/impl/NotificationApiController.java | 32 ++++++ .../resources/application-local.properties | 13 ++- .../db/changelog/db.changelog-1.0.0.xml | 45 +++++++++ ...n_template_for_notification_13_12_2024.sql | 5 + 25 files changed, 520 insertions(+), 6 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java create mode 100644 src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java create mode 100644 src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/NotificationEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/NotificationTypeRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/NotificationService.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java create mode 100644 src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql diff --git a/pom.xml b/pom.xml index 93a592ed..c463be91 100644 --- a/pom.xml +++ b/pom.xml @@ -231,6 +231,20 @@ spring-test + + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.boot + spring-boot-starter-amqp + + + io.projectreactor.netty + reactor-netty + + diff --git a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java index 7ec98464..1465ad7e 100644 --- a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java +++ b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java @@ -23,7 +23,9 @@ public class TendermanagementApplication { @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**").allowedOrigins("http://localhost:3000") + //remove after testing +//add url for a demo html and js project created on Vs code and ran it from go live on right bottim corner user gepafin_dev_local backup DB for gettng notification on FE. + registry.addMapping("/**").allowedOrigins("http://127.0.0.1:5500", "http://localhost:3000", "http://localhost:5500") .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD").allowCredentials(true); } } diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index 090f3688..8c11eac2 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -109,6 +109,7 @@ public class SecurityConfig { .requestMatchers("/v1/api-docs/**").permitAll() // API docs .requestMatchers("/v1/user/reset-password/initiate").permitAll() .requestMatchers("/v1/user/reset-password").permitAll() + .requestMatchers("/wss/**").permitAll() // if this is not running use this /gs-guide-websocket .anyRequest().authenticated()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) .exceptionHandling(exceptionHandling -> exceptionHandling diff --git a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java new file mode 100644 index 00000000..b12207e6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java @@ -0,0 +1,32 @@ +package net.gepafin.tendermanagement.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + // Enable a simple broker for both /topic (broadcast messages) and /queue (user-specific messages) + config.enableStompBrokerRelay("/topic") + .setRelayHost("localhost") + .setRelayPort(61613) // RabbitMQ is running on port 61613 + .setClientLogin("guest") + .setClientPasscode("guest"); + + // Prefix for application messages (user sends messages to /app endpoints) + config.setApplicationDestinationPrefixes("/app"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + + registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("http://127.0.0.1:5501/", "http://localhost:5500", "http://localhost:5501", "http://127.0.0.1:5500/") + .withSockJS(); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 14d82b91..f0d9a617 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -341,5 +341,9 @@ public class GepafinConstant { public static final String POLLING_THREAD_NAME = "Ndg-Polling-Thread-"; public static final String DOCUMENT_UPLOADING_IN_PROGRESS = "document.uploading.is.in.progress"; public static final String ASYNC_DOCUMENT_UPLOAD_NAME = "AsyncDocumentUpload-"; + + //Notification + public static final String COMMON_SINGLE_CHANNEL_PREFIX = "/topic/notifications_user_"; + public static final String COMPANY_PREFIX = "_company_"; } diff --git a/src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java new file mode 100644 index 00000000..3f5c1cdc --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java @@ -0,0 +1,5 @@ +package net.gepafin.tendermanagement.constants; + +public class NotificationConstant { + public static final String NOTIFICATION_SENT_SUCCESSFULLY = "Notification Sent Successfully."; +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 9b3b12a5..772538bb 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -15,7 +15,9 @@ import java.util.zip.ZipOutputStream; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; @@ -108,6 +110,18 @@ public class CallDao { @Autowired private HttpServletRequest request; + @Autowired + private NotificationDao notificationDao; + + @Autowired + private BeneficiaryRepository beneficiaryRepository; + + @Autowired + private NotificationTypeRepository notificationTypeRepository; + + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; + public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity); @@ -828,13 +842,36 @@ public class CallDao { validateStatusChange(currentStatus, statusReq); callEntity.setStatus(statusReq.getValue()); callEntity = callRepository.save(callEntity); - + + //Creating notification. + List userIds = beneficiaryRepository.findUserIdsByHubIdAndBeneficiaryId(callEntity.getHub().getId()); + Map placeholders = new HashMap<>(); + placeholders.put("{{call_name}}", callEntity.getName()); + userIds.forEach(userId -> { + NotificationReq notificationReq = createNotificationReq(NotificationTypeEnum.CALL_CREATED.getValue(), placeholders, userId); + List companyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(notificationReq.getUserId()); + notificationReq.setCompanyIds(companyIds); + notificationDao.sendNotification(notificationReq); + }); + /** This code is responsible for adding a version history log for the "update call status" operation **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); - + return convertToCallResponseBean(callEntity); } + public NotificationReq createNotificationReq(String notificationType, Map placeholders, Long userId) { + // Create NotificationReq object + NotificationReq notificationReq = new NotificationReq(); + NotificationTypeEntity notificationTypeEntity = notificationTypeRepository.findByNotificationNameAndIsDeletedFalse(notificationType); + notificationReq.setNotificationType(notificationType); + String message = Utils.replacePlaceholders(notificationTypeEntity.getJsonTemplate(), placeholders); + notificationReq.setMessage(message); + notificationReq.setUserId(userId); + return notificationReq; + } + + private void validateStatusChange(CallStatusEnum currentStatus, CallStatusEnum newStatus) { if (currentStatus == newStatus) { throw new CustomValidationException(Status.VALIDATION_ERROR, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java new file mode 100644 index 00000000..17c5a3c8 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -0,0 +1,97 @@ +package net.gepafin.tendermanagement.dao; + +import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.NotificationEntity; +import net.gepafin.tendermanagement.enums.NotificationEnum; +import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.repositories.NotificationRepository; +import net.gepafin.tendermanagement.repositories.NotificationTypeRepository; +import net.gepafin.tendermanagement.util.Utils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@Slf4j +public class NotificationDao { + + @Autowired + private SimpMessagingTemplate messagingTemplate; + + @Autowired + private NotificationRepository notificationRepository; + + @Autowired + private NotificationTypeRepository notificationTypeRepository; + + public NotificationReq sendNotification(NotificationReq notificationReq) { + + // Ensure userId is properly set in notificationReq if not already + Long userId = notificationReq.getUserId(); + if (userId == null) { + log.error("User ID is missing in the notification request."); + return null; + } + NotificationEntity notificationEntity = saveNotification(notificationReq); + log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); + List companyIds = notificationReq.getCompanyIds(); + + if (companyIds.isEmpty()) { + sendToUser(userId, notificationEntity); + } else { + sendToCompanies(userId, companyIds, notificationEntity); + } + + return convertToNotificationReq(notificationEntity); + } + + private NotificationEntity saveNotification(NotificationReq notificationReq) { + + NotificationEntity notificationEntity = convertToNotificationEntity(notificationReq); + return notificationRepository.save(notificationEntity); + } + + private void sendToUser(Long userId, NotificationEntity notificationEntity) { + + String userChannel = GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId; + log.info("Channel for User {}", userChannel); + messagingTemplate.convertAndSend(userChannel, notificationEntity); + } + + private void sendToCompanies(Long userId, List companyIds, NotificationEntity notificationEntity) { + // Send notification to each company provided in the companyIds list + companyIds.forEach(companyId -> { + String companyChannel = Utils.createChannelForUserAndCompany(userId, companyId); + log.info("Channel for User and Company {}, {}", userId, companyChannel); + messagingTemplate.convertAndSend(companyChannel, notificationEntity); + }); + } + + private NotificationReq convertToNotificationReq(NotificationEntity notificationEntity) { + + NotificationReq notificationReq = new NotificationReq(); + notificationReq.setId(notificationEntity.getId()); + notificationReq.setUserId(notificationEntity.getUserId()); + notificationReq.setStatus(NotificationEnum.UNREAD.getValue()); + notificationReq.setMessage(notificationEntity.getMessage()); + notificationReq.setCreatedDate(notificationEntity.getCreatedDate()); + notificationReq.setUpdatedDate(notificationEntity.getUpdatedDate()); + return notificationReq; + + } + + private NotificationEntity convertToNotificationEntity(NotificationReq notificationReq) { + + NotificationEntity notificationEntity = new NotificationEntity(); + String message = notificationReq.getMessage(); + notificationEntity.setNotificationType(notificationReq.getNotificationType()); + notificationEntity.setUserId(notificationReq.getUserId()); + notificationEntity.setStatus(NotificationEnum.UNREAD.getValue()); + notificationEntity.setIsDeleted(Boolean.FALSE); + notificationEntity.setMessage(message); + return notificationEntity; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java new file mode 100644 index 00000000..74131d4c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java @@ -0,0 +1,31 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "NOTIFICATION") +@Data +public class NotificationEntity extends BaseEntity { + + @Column(name = "USER_ID") + Long userId; + + @Column(name = "MESSAGE") + String message; + + @Column(name = "STATUS") + String status; + + @Column(name = "IS_DELETED") + Boolean isDeleted; + + @Column(name = "NOTIFICATION_TYPE") + String notificationType; + + @Column(name = "REDIRECT_LINK") + String redirectLink; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java new file mode 100644 index 00000000..5202c97a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Data +@Table(name = "NOTIFICATION_TYPE") +public class NotificationTypeEntity extends BaseEntity { + + @Column(name = "NOTIFICATION_NAME") + String notificationName; + + @Column(name = "JSON_TEMPLATE") + String jsonTemplate; + + @Column(name="IS_DELETED") + private Boolean isDeleted; +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/NotificationEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/NotificationEnum.java new file mode 100644 index 00000000..5b8bf633 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/NotificationEnum.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum NotificationEnum { + //status + READ("READ"), UNREAD("UNREAD"); + + private final String value; + + NotificationEnum(String value) { + + this.value = value; + } + + @JsonValue + public String getValue() { + + return value; + } + + @Override + public String toString() { + + return String.valueOf(value); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java new file mode 100644 index 00000000..86fd75dc --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java @@ -0,0 +1,29 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum NotificationTypeEnum { + CALL_CREATED("CALL_CREATED"), + APPLICATION_SUBMISSION("APPLICATION_SUBMISSION"), + AMENDMENT_CREATION("AMENDMENT_CREATION"), + EVALUATION_RESULT("EVALUATION_RESULT"); + + private final String value; + + NotificationTypeEnum(String value) { + + this.value = value; + } + + @JsonValue + public String getValue() { + + return value; + } + + @Override + public String toString() { + + return String.valueOf(value); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java new file mode 100644 index 00000000..8506694a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java @@ -0,0 +1,37 @@ +package net.gepafin.tendermanagement.model.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class NotificationReq { + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + Long id; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + Long userId; + + String message; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + String notificationType; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + String status; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private LocalDateTime createdDate; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private LocalDateTime updatedDate; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + String redirectUrl; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + List companyIds; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java index b0a5ef38..c8724d43 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java @@ -40,6 +40,7 @@ public class UserResponseBean extends BaseBean { private List companies; private Boolean privacy; + private Boolean terms; private Boolean marketing; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java index ecb6ed7d..984e477a 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java @@ -1,11 +1,16 @@ package net.gepafin.tendermanagement.repositories; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import net.gepafin.tendermanagement.entities.BeneficiaryEntity; +import java.util.List; + @Repository public interface BeneficiaryRepository extends JpaRepository { + @Query("SELECT u.id FROM UserEntity u JOIN u.beneficiary b WHERE b.id = u.beneficiary.id AND b.hubId = :hubId") + List findUserIdsByHubIdAndBeneficiaryId(Long hubId); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java new file mode 100644 index 00000000..a52c39de --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java @@ -0,0 +1,7 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.NotificationEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NotificationRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationTypeRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationTypeRepository.java new file mode 100644 index 00000000..78cef54d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationTypeRepository.java @@ -0,0 +1,8 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.NotificationTypeEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NotificationTypeRepository extends JpaRepository { + NotificationTypeEntity findByNotificationNameAndIsDeletedFalse(String value); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java new file mode 100644 index 00000000..0b6914c2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java @@ -0,0 +1,7 @@ +package net.gepafin.tendermanagement.service; + +import net.gepafin.tendermanagement.model.request.NotificationReq; + +public interface NotificationService { + NotificationReq sendNotification(Long userId, NotificationReq notificationReq); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java new file mode 100644 index 00000000..7928f166 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java @@ -0,0 +1,26 @@ +package net.gepafin.tendermanagement.service.impl; + +import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.dao.NotificationDao; +import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.service.NotificationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class NotificationServiceImpl implements NotificationService { + + @Autowired + private NotificationDao notificationDao; + + @Override + public NotificationReq sendNotification(Long userId, NotificationReq notificationReq) { + + log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); + notificationReq.setUserId(userId); + notificationReq = notificationDao.sendNotification(notificationReq); + return notificationReq; + } + +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index e93c8ed9..4290bfff 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -669,4 +669,8 @@ public class Utils { } return null; } + + public static String createChannelForUserAndCompany(Long userId, Long companyId) { + return GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId + GepafinConstant.COMPANY_PREFIX + companyId; + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java new file mode 100644 index 00000000..85a4ab27 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java @@ -0,0 +1,30 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.LookUpDataResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +public interface NotificationApi { + @Operation(summary = "Api to send notification.", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = + ErrorConstants.NOTFOUND_ERROR_EXAMPLE))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = + ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE))), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = + ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) }) + @PostMapping(value = "/{userId}", consumes = "application/json", produces = "application/json") + ResponseEntity> sendNotification(HttpServletRequest request, @RequestBody NotificationReq notificationReq, + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java new file mode 100644 index 00000000..054c4c63 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java @@ -0,0 +1,32 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.NotificationConstant; +import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.NotificationService; +import net.gepafin.tendermanagement.web.rest.api.NotificationApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/notification}") +public class NotificationApiController implements NotificationApi { + + @Autowired + private NotificationService notificationService; + + public ResponseEntity> sendNotification(HttpServletRequest request, NotificationReq notificationReq, Long userId) { + + NotificationReq notificationData = notificationService.sendNotification(userId, notificationReq); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(notificationData, Status.SUCCESS, Translator.toLocale(NotificationConstant.NOTIFICATION_SENT_SUCCESSFULLY))); + } + +} \ No newline at end of file diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 37bcabad..11f3d75e 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,6 +1,6 @@ # DataSource Configuration -spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_local -spring.datasource.username=postgres +spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_dev_local +spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=org.postgresql.Driver @@ -20,4 +20,11 @@ appointment.portal.user=UtenzaAPIPortal@621 appointment.portal.password=u13nzaAP1P0rtal appointment.portal.source=GEPAFINPORTAL appointment.portal.context=GEPAFINPORTAL -flagDaFirmare=false \ No newline at end of file +flagDaFirmare=false + +# RabbitMQ properties for STOMP broker relay +spring.rabbitmq.host=localhost +spring.rabbitmq.port=5672 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest +spring.rabbitmq.virtual-host=/ \ No newline at end of file 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 eb77049e..fde4441d 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 @@ -1992,4 +1992,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql b/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql new file mode 100644 index 00000000..50caaefa --- /dev/null +++ b/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql @@ -0,0 +1,5 @@ +INSERT INTO notification_type (notification_name, json_template) VALUES +('CALL_CREATED', 'Un nuovo bando intitolato {{call_name}} è stato pubblicato. Controllalo e invia le tue candidature prima della scadenza.'), +('APPLICATION_SUBMISSION', 'La tua richiesta per {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stata presentata con successo. È ora in fase di valutazione.'), +('AMENDMENT_CREATION', 'È stato creato un emendamento per la tua domanda in {{call_name}} ai sensi del protocollo n. {{protocol_number}}. Esamina le modifiche e procedi di conseguenza.'), +('EVALUATION_RESULT', 'Il risultato della valutazione per la tua domanda ai sensi del protocollo n. {{protocol_number}} è ora disponibile. Fai clic qui per visualizzare il tuo feedback.'); From 91ec06332715f14a172dd7d5cf070b9ede5c12f4 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 13 Dec 2024 22:09:23 +0530 Subject: [PATCH 04/49] Updated code. --- .../gepafin/tendermanagement/dao/CallDao.java | 19 +------------------ .../tendermanagement/dao/NotificationDao.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 772538bb..45d81d9c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -119,9 +119,6 @@ public class CallDao { @Autowired private NotificationTypeRepository notificationTypeRepository; - @Autowired - private UserWithCompanyRepository userWithCompanyRepository; - public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity); @@ -848,9 +845,7 @@ public class CallDao { Map placeholders = new HashMap<>(); placeholders.put("{{call_name}}", callEntity.getName()); userIds.forEach(userId -> { - NotificationReq notificationReq = createNotificationReq(NotificationTypeEnum.CALL_CREATED.getValue(), placeholders, userId); - List companyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(notificationReq.getUserId()); - notificationReq.setCompanyIds(companyIds); + NotificationReq notificationReq = notificationDao.createNotificationReq(NotificationTypeEnum.CALL_CREATED.getValue(), placeholders, userId); notificationDao.sendNotification(notificationReq); }); @@ -860,18 +855,6 @@ public class CallDao { return convertToCallResponseBean(callEntity); } - public NotificationReq createNotificationReq(String notificationType, Map placeholders, Long userId) { - // Create NotificationReq object - NotificationReq notificationReq = new NotificationReq(); - NotificationTypeEntity notificationTypeEntity = notificationTypeRepository.findByNotificationNameAndIsDeletedFalse(notificationType); - notificationReq.setNotificationType(notificationType); - String message = Utils.replacePlaceholders(notificationTypeEntity.getJsonTemplate(), placeholders); - notificationReq.setMessage(message); - notificationReq.setUserId(userId); - return notificationReq; - } - - private void validateStatusChange(CallStatusEnum currentStatus, CallStatusEnum newStatus) { if (currentStatus == newStatus) { throw new CustomValidationException(Status.VALIDATION_ERROR, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 17c5a3c8..1b02b144 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -3,16 +3,19 @@ package net.gepafin.tendermanagement.dao; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.NotificationEntity; +import net.gepafin.tendermanagement.entities.NotificationTypeEntity; import net.gepafin.tendermanagement.enums.NotificationEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.repositories.NotificationRepository; import net.gepafin.tendermanagement.repositories.NotificationTypeRepository; +import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; import net.gepafin.tendermanagement.util.Utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Map; @Component @Slf4j @@ -27,6 +30,9 @@ public class NotificationDao { @Autowired private NotificationTypeRepository notificationTypeRepository; + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; + public NotificationReq sendNotification(NotificationReq notificationReq) { // Ensure userId is properly set in notificationReq if not already @@ -94,4 +100,17 @@ public class NotificationDao { notificationEntity.setMessage(message); return notificationEntity; } + + public NotificationReq createNotificationReq(String notificationType, Map placeholders, Long userId) { + // Create NotificationReq object + NotificationReq notificationReq = new NotificationReq(); + List companyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(notificationReq.getUserId()); + notificationReq.setCompanyIds(companyIds); + NotificationTypeEntity notificationTypeEntity = notificationTypeRepository.findByNotificationNameAndIsDeletedFalse(notificationType); + notificationReq.setNotificationType(notificationType); + String message = Utils.replacePlaceholders(notificationTypeEntity.getJsonTemplate(), placeholders); + notificationReq.setMessage(message); + notificationReq.setUserId(userId); + return notificationReq; + } } From a30637ddaa59370d533d07af4b371541e5a7fea2 Mon Sep 17 00:00:00 2001 From: nisha Date: Thu, 19 Dec 2024 14:56:57 +0530 Subject: [PATCH 05/49] Changes in company json field --- .../tendermanagement/dao/CompanyDao.java | 100 +++++++++++------- .../entities/CompanyEntity.java | 14 --- .../entities/UserWithCompanyEntity.java | 16 +++ .../db/changelog/db.changelog-1.0.0.xml | 22 ++-- 4 files changed, 93 insertions(+), 59 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index e6a88c66..32d7e42e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -67,7 +67,7 @@ public class CompanyDao { if (existingCompany != null) { UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), existingCompany.getId()).orElse(null); if (existingRelation == null) { - userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant()); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant(),companyRequest.getVatCheckResponse()); /** This code is responsible for adding a version history log for "adding user with company" operation. **/ loggingUtil.addVersionHistory( @@ -79,14 +79,12 @@ public class CompanyDao { } else { validateCompany(userEntity, companyRequest); CompanyEntity companyEntity = convertCompanyRequestToCompanyEntity(userEntity, companyRequest); - companyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) ); - CompanyEntity companyData = companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for "creating company" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(companyData).build()); - userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant()); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant(),companyRequest.getVatCheckResponse()); return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } @@ -110,7 +108,7 @@ public class CompanyDao { } } - private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant) { + private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant,Map vatCheckResponse) { UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); if (userEntity.getBeneficiary() != null) { @@ -120,6 +118,11 @@ public class CompanyDao { userWithCompanyEntity.setCompanyId(companyEntity.getId()); userWithCompanyEntity.setUserId(userEntity.getId()); userWithCompanyEntity.setIsLegalRepresentant(isLegalRepresentant); + userWithCompanyEntity.setEmail(companyEntity.getEmail()); + userWithCompanyEntity.setPec(companyEntity.getPec()); + userWithCompanyEntity.setContactName(companyEntity.getContactName()); + userWithCompanyEntity.setContactEmail(companyEntity.getContactEmail()); + userWithCompanyEntity.setJson(Utils.convertMapIntoJsonString(vatCheckResponse) ); UserWithCompanyEntity userWithCompany = userWithCompanyRepository.save(userWithCompanyEntity); /** This code is responsible for adding a version history log for the "adding user with company" operation. **/ @@ -201,8 +204,6 @@ public class CompanyDao { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); } companyEntity.setVatNumber(companyRequest.getVatNumber()); - String responseJson = companyRequest.getVatCheckResponse() != null ? Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) : null; - setIfUpdated(companyEntity::getJson, companyEntity::setJson, responseJson); } companyRepository.save(companyEntity); @@ -214,8 +215,15 @@ public class CompanyDao { UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); //cloned entity for old data UserWithCompanyEntity oldUserWithCompanyData = Utils.getClonedEntityForData(userWithCompanyEntity); - - Utils.setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, companyRequest.getIsLegalRepresentant()); + if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { + String responseJson = companyRequest.getVatCheckResponse() != null ? Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) : null; + setIfUpdated(userWithCompanyEntity::getJson, userWithCompanyEntity::setJson, responseJson); + } + setIfUpdated(userWithCompanyEntity::getPec, userWithCompanyEntity::setPec, userWithCompanyEntity.getPec()); + setIfUpdated(userWithCompanyEntity::getEmail, userWithCompanyEntity::setEmail, userWithCompanyEntity.getEmail()); + setIfUpdated(userWithCompanyEntity::getContactName, userWithCompanyEntity::setContactName, companyRequest.getContactName()); + setIfUpdated(userWithCompanyEntity::getContactEmail, userWithCompanyEntity::setContactEmail, companyRequest.getContactEmail()); + setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, companyRequest.getIsLegalRepresentant()); userWithCompanyEntity = userWithCompanyRepository.save(userWithCompanyEntity); /** This code is responsible for adding a version history log for the "Update company" operation. **/ @@ -267,7 +275,7 @@ public class CompanyDao { return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, companyId).orElseThrow(() -> new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED))); } - + public UserWithCompanyEntity getUserWithCompany(Long userId, Long compnayId) { return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, compnayId).orElseThrow( () -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_COMPANY_RELATION_NOT_FOUND))); @@ -290,39 +298,59 @@ public class CompanyDao { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); } - for(ApplicationEntity application:userApplications){ - ApplicationEntity oldApplication = Utils.getClonedEntityForData(application); - application.setIsDeleted(Boolean.TRUE); + userApplications = userApplications.stream() + .peek(application -> { + ApplicationEntity oldApplication = Utils.getClonedEntityForData(application); + application.setIsDeleted(Boolean.TRUE); - /** This code is responsible for adding a version history log for the "Soft delete application" operation. **/ - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplication).newData(application).build()); - - } + /** This code is responsible for adding a version history log for the "Soft delete Faq" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.SOFT_DELETE) + .oldData(oldApplication) + .newData(application) + .build() + ); + }) + .toList(); applicationRepository.saveAll(userApplications); - for(FaqEntity faq:faqs){ - FaqEntity oldFaq = Utils.getClonedEntityForData(faq); - faq.setIsDeleted(Boolean.TRUE); - - /** This code is responsible for adding a version history log for the "Soft delete Faq" operation. **/ - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaq).newData(faq).build()); - } + faqs = faqs.stream() + .peek(faq -> { + FaqEntity oldFaq = Utils.getClonedEntityForData(faq); + faq.setIsDeleted(Boolean.TRUE); + /** This code is responsible for adding a version history log for the "Soft delete Faq" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.SOFT_DELETE) + .oldData(oldFaq) + .newData(faq) + .build() + ); + }) + .toList(); faqRepository.saveAll(faqs); - for(BeneficiaryPreferredCallEntity beneficiaryPreferredCall:preferredCallEntities){ - BeneficiaryPreferredCallEntity oldPreferredCall = Utils.getClonedEntityForData(beneficiaryPreferredCall); - beneficiaryPreferredCall.setIsDeleted(Boolean.TRUE); - - /** This code is responsible for adding a version history log for the "Soft Delete BeneficiaryPreferredCall" operation. **/ - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldPreferredCall).newData(beneficiaryPreferredCall).build()); - - } + preferredCallEntities = preferredCallEntities.stream() + .peek(beneficiaryPreferredCall -> { + BeneficiaryPreferredCallEntity oldPreferredCall = Utils.getClonedEntityForData(beneficiaryPreferredCall); + beneficiaryPreferredCall.setIsDeleted(Boolean.TRUE); + /** This code is responsible for adding a version history log for the "Soft Delete BeneficiaryPreferredCall" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.SOFT_DELETE) + .oldData(oldPreferredCall) + .newData(beneficiaryPreferredCall) + .build() + ); + }) + .toList(); beneficiaryPreferredCallRepository.saveAll(preferredCallEntities); - if(userCompanyDelegationEntity!=null){ + if(userCompanyDelegationEntity!=null){ UserCompanyDelegationEntity oldUserWithCompanyDelegation = Utils.getClonedEntityForData(userCompanyDelegationEntity); userCompanyDelegationEntity.setStatus( UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java index 1d8ef4ca..06dff314 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java @@ -41,29 +41,15 @@ public class CompanyEntity extends BaseEntity{ @Column(name = "COUNTRY") private String country; - @Column(name = "PEC") - private String pec; - - @Column(name = "EMAIL") - private String email; - @Column(name = "NUMBER_OF_EMPLOYEES") private String numberOfEmployees; @Column(name = "ANNUAL_REVENUE") private BigDecimal annualRevenue; - - @Column(name = "CONTACT_NAME") - private String contactName; - - @Column(name = "CONTACT_EMAIL") - private String contactEmail; @ManyToOne @JoinColumn(name = "HUB_ID") private HubEntity hub; - @Column(name = "JSON") - private String json; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java index 49770356..1f067a90 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java @@ -22,6 +22,22 @@ public class UserWithCompanyEntity extends BaseEntity{ @Column(name = "IS_LEGAL_REPRESENTANT") private Boolean isLegalRepresentant; + + @Column(name = "CONTACT_NAME") + private String contactName; + + @Column(name = "CONTACT_EMAIL") + private String contactEmail; + + @Column(name = "PEC") + private String pec; + + @Column(name = "EMAIL") + private String email; + + @Column(name = "JSON") + private String json; + @Column(name = "IS_DELETED") private Boolean isDeleted = false; 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 a59e40a6..233a1baa 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 @@ -1961,13 +1961,6 @@ - - - - - - - @@ -1977,6 +1970,17 @@ - - + + + + + + + + + + + + + From 5c7f96574b0e21c1ebaa3989eb7cf65bfeb41b12 Mon Sep 17 00:00:00 2001 From: nisha Date: Thu, 19 Dec 2024 17:58:44 +0530 Subject: [PATCH 06/49] Updated code --- .../tendermanagement/dao/ApplicationDao.java | 7 ++-- .../tendermanagement/dao/CompanyDao.java | 32 +++++++------------ .../dao/EmailNotificationDao.java | 6 ++-- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index e3726e41..8afebfa2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -926,7 +926,8 @@ public class ApplicationDao { private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call =applicationEntity.getCall(); CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); - ProtocolEntity protocol = applicationEntity.getProtocol(); + UserWithCompanyEntity userWithCompany=companyService.getUserWithCompany(userEntity.getId(),company.getId()); + ProtocolEntity protocol= applicationEntity.getProtocol(); HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, @@ -957,8 +958,8 @@ public class ApplicationDao { emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest); List recipientEmails = new ArrayList<>(); // recipientEmails.add(email); - String companyEmail = company.getEmail(); - String contactEmail = company.getContactEmail(); + String companyEmail = userWithCompany.getEmail(); + String contactEmail = userWithCompany.getContactEmail(); if (companyEmail != null && !companyEmail.isEmpty()) { recipientEmails.add(companyEmail); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 32d7e42e..48ec017b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -67,7 +67,7 @@ public class CompanyDao { if (existingCompany != null) { UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), existingCompany.getId()).orElse(null); if (existingRelation == null) { - userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant(),companyRequest.getVatCheckResponse()); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant(),companyRequest); /** This code is responsible for adding a version history log for "adding user with company" operation. **/ loggingUtil.addVersionHistory( @@ -84,7 +84,7 @@ public class CompanyDao { /** This code is responsible for adding a version history log for "creating company" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(companyData).build()); - userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant(),companyRequest.getVatCheckResponse()); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant(),companyRequest); return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } @@ -108,7 +108,7 @@ public class CompanyDao { } } - private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant,Map vatCheckResponse) { + private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant,CompanyRequest companyRequest) { UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); if (userEntity.getBeneficiary() != null) { @@ -118,11 +118,11 @@ public class CompanyDao { userWithCompanyEntity.setCompanyId(companyEntity.getId()); userWithCompanyEntity.setUserId(userEntity.getId()); userWithCompanyEntity.setIsLegalRepresentant(isLegalRepresentant); - userWithCompanyEntity.setEmail(companyEntity.getEmail()); - userWithCompanyEntity.setPec(companyEntity.getPec()); - userWithCompanyEntity.setContactName(companyEntity.getContactName()); - userWithCompanyEntity.setContactEmail(companyEntity.getContactEmail()); - userWithCompanyEntity.setJson(Utils.convertMapIntoJsonString(vatCheckResponse) ); + userWithCompanyEntity.setEmail(companyRequest.getEmail()); + userWithCompanyEntity.setPec(companyRequest.getPec()); + userWithCompanyEntity.setContactName(companyRequest.getContactName()); + userWithCompanyEntity.setContactEmail(companyRequest.getContactEmail()); + userWithCompanyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) ); UserWithCompanyEntity userWithCompany = userWithCompanyRepository.save(userWithCompanyEntity); /** This code is responsible for adding a version history log for the "adding user with company" operation. **/ @@ -141,12 +141,8 @@ public class CompanyDao { entity.setProvince(request.getProvince()); entity.setCap(request.getCap()); entity.setCountry(request.getCountry()); - entity.setPec(request.getPec()); - entity.setEmail(request.getEmail()); entity.setNumberOfEmployees(request.getNumberOfEmployees()); entity.setAnnualRevenue(request.getAnnualRevenue()); - entity.setContactName(request.getContactName()); - entity.setContactEmail(request.getContactEmail()); entity.setHub(userEntity.getHub()); return entity; } @@ -163,8 +159,8 @@ public class CompanyDao { response.setProvince(entity.getProvince()); response.setCap(entity.getCap()); response.setCountry(entity.getCountry()); - response.setPec(entity.getPec()); - response.setEmail(entity.getEmail()); + response.setPec(userWithCompanyEntity.getPec()); + response.setEmail(userWithCompanyEntity.getEmail()); response.setNumberOfEmployees(entity.getNumberOfEmployees()); response.setAnnualRevenue(entity.getAnnualRevenue()); if(userWithCompanyEntity!=null) { @@ -172,8 +168,8 @@ public class CompanyDao { } response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); - response.setContactName(entity.getContactName()); - response.setContactEmail(entity.getContactEmail()); + response.setContactName(userWithCompanyEntity.getContactName()); + response.setContactEmail(userWithCompanyEntity.getContactEmail()); return response; } @@ -191,12 +187,8 @@ public class CompanyDao { setIfUpdated(companyEntity::getProvince, companyEntity::setProvince, companyRequest.getProvince()); setIfUpdated(companyEntity::getCap, companyEntity::setCap, companyRequest.getCap()); setIfUpdated(companyEntity::getCountry, companyEntity::setCountry, companyRequest.getCountry()); - setIfUpdated(companyEntity::getPec, companyEntity::setPec, companyRequest.getPec()); - setIfUpdated(companyEntity::getEmail, companyEntity::setEmail, companyRequest.getEmail()); setIfUpdated(companyEntity::getNumberOfEmployees, companyEntity::setNumberOfEmployees, companyRequest.getNumberOfEmployees()); setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, companyRequest.getAnnualRevenue()); - setIfUpdated(companyEntity::getContactName, companyEntity::setContactName, companyRequest.getContactName()); - setIfUpdated(companyEntity::getContactEmail, companyEntity::setContactEmail, companyRequest.getContactEmail()); if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 4bf99110..bdc84e78 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -92,8 +92,10 @@ public class EmailNotificationDao { Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); - String companyEmail = company.getEmail(); - String contactEmail = company.getContactEmail(); + + UserWithCompanyEntity userWithCompany=companyService.getUserWithCompany(userEntity.getId(),company.getId()); + String companyEmail = userWithCompany.getEmail(); + String contactEmail = userWithCompany.getContactEmail(); if (companyEmail != null && !companyEmail.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY,company.getId() , From 288fde0a8812d7df79a54a5612d148e18b3ac392 Mon Sep 17 00:00:00 2001 From: Piyush Date: Mon, 23 Dec 2024 11:24:25 +0530 Subject: [PATCH 07/49] Updated code for notification --- .../dao/ApplicationAmendmentRequestDao.java | 19 +++++++++-- .../tendermanagement/dao/ApplicationDao.java | 12 +++++++ .../dao/ApplicationEvaluationDao.java | 19 ++++++++++- .../tendermanagement/dao/AppointmentDao.java | 14 ++++++++ .../tendermanagement/dao/NotificationDao.java | 34 +++++++++++++++++++ .../enums/NotificationTypeEnum.java | 7 +++- .../repositories/UserRepository.java | 3 ++ .../ApplicationAmendmentScheduler.java | 13 ++++++- .../ApplicationEvaluationScheduler.java | 14 +++++++- .../db/changelog/db.changelog-1.0.0.xml | 16 +++------ ...n_template_for_notification_13_12_2024.sql | 15 +++++--- 11 files changed, 144 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 41d43b1e..e6ccd62b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -105,6 +105,12 @@ public class ApplicationAmendmentRequestDao { @Autowired private AssignedApplicationsDao assignedApplicationsDao; + @Autowired + private NotificationDao notificationDao; + + @Autowired + private UserRepository userRepository; + public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); @@ -294,6 +300,10 @@ public class ApplicationAmendmentRequestDao { assignedApplicationsEntity.setStatus(AssignedApplicationEnum.SOCCORSO.getValue()); assignedApplicationsRepository.save(assignedApplicationsEntity); + Map placeHolders = notificationDao.sendNotificationToBeneficiary(applicationEntity, NotificationTypeEnum.AMENDMENT_CREATION); + + notificationDao.sendNotificationToInstructor(placeHolders,applicationAmendmentRequestEntity.getApplicationEvaluationEntity(),NotificationTypeEnum.AMENDMENT_CREATION); + /** This code is responsible for adding a version history log for the "Update Assigned Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build()); } @@ -829,8 +839,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); //cloned entity for old data and versioning ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); - - List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( + List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( existingApplicationAmendment.getApplicationEvaluationEntity().getId() ); @@ -875,6 +884,11 @@ public class ApplicationAmendmentRequestDao { AssignedApplicationsEntity oldAssignedApplicationData = Utils.getClonedEntityForData(assignedApplicationsEntity); assignedApplicationsEntity = assignedApplicationsRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity()); + + Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.AMENDMENT_CLOSED); + + notificationDao.sendNotificationToInstructor(placeHolders,existingApplicationAmendment.getApplicationEvaluationEntity(),NotificationTypeEnum.AMENDMENT_CLOSED); + /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity) .newData(existingApplicationEvaluationEntity).build()); @@ -894,6 +908,7 @@ public class ApplicationAmendmentRequestDao { return response; } + public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index dbccf3b3..c687fd67 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -10,6 +10,7 @@ import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBea import net.gepafin.tendermanagement.model.request.ApplicationRequest; import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.request.EmailLogRequest; +import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; @@ -162,6 +163,15 @@ public class ApplicationDao { @Autowired private ApplicationEvaluationService applicationEvaluationService; + @Autowired + private NotificationDao notificationDao; + + @Autowired + private UserRepository userRepository; + + @Autowired + private RoleRepository roleRepository; + public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); // callService.validatePublishedCall(formEntity.getCall().getId()); @@ -818,6 +828,8 @@ public class ApplicationDao { applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationEntity = applicationRepository.save(applicationEntity); + Map placeHolders=notificationDao.sendNotificationToBeneficiary(applicationEntity,NotificationTypeEnum.APPLICATION_SUBMISSION); + notificationDao.sendNotificationToSuperUser(applicationEntity,placeHolders,NotificationTypeEnum.APPLICATION_SUBMISSION); /** This code is responsible for adding a version history log for "Update application status" operation. **/ loggingUtil.addVersionHistory( diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 924999f2..6c5e46c7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -92,6 +92,12 @@ public class ApplicationEvaluationDao { @Autowired private CompanyService companyService; + + @Autowired + private NotificationDao notificationDao; + + @Autowired + private UserRepository userRepository; private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) { @@ -493,8 +499,14 @@ public class ApplicationEvaluationDao { setIfUpdated(entity::getMotivation, entity::setMotivation, req.getMotivation()); actionType = VersionActionTypeEnum.UPDATE; } else { + ApplicationEntity application=entity.getAssignedApplicationsEntity().getApplication(); entity = convertToEntity(user, req, assignedApplicationId); actionType = VersionActionTypeEnum.INSERT; + + Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_CREATION); + notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.EVALUATION_CREATION); + notificationDao.sendNotificationToInstructor(placeHolders,entity,NotificationTypeEnum.EVALUATION_CREATION); + } ApplicationStatusForEvaluation status = req.getApplicationStatus(); @@ -1442,12 +1454,17 @@ public class ApplicationEvaluationDao { if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.REJECTED.getValue())))) { emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity); } + + Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_RESULT); + notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.EVALUATION_RESULT); + notificationDao.sendNotificationToInstructor(placeHolders,existingEntity,NotificationTypeEnum.EVALUATION_RESULT); + return convertToResponse(entity); } return null; } - public ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId) { + public ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId) { return applicationEvaluationRepository .findByApplicationIdAndIsDeletedFalse(applicationId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index 1b644d6e..49a672a8 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -16,14 +16,18 @@ import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.entities.HubEntity; +import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.AppointmentCreationRequest; import net.gepafin.tendermanagement.model.request.AppointmentNdgRequest; import net.gepafin.tendermanagement.model.request.AppointmentVisuraListRequest; import net.gepafin.tendermanagement.model.request.AppointmentVisuraRequest; import net.gepafin.tendermanagement.model.request.CreateAppointmentRequest; +import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.model.request.UploadDocToExternalSystemRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.AppointmentCreationResponse; @@ -34,6 +38,7 @@ import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.CompanyRepository; import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.repositories.HubRepository; +import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.feignClient.AppointmentApiService; @@ -58,6 +63,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -130,6 +136,12 @@ public class AppointmentDao { @Autowired private TokenProvider tokenProvider; + @Autowired + private NotificationDao notificationDao; + + @Autowired + private UserRepository userRepository; + private final Map executorMap = new ConcurrentHashMap<>(); private final ConcurrentHashMap threadForDocumentMap = new ConcurrentHashMap<>(); @@ -312,6 +324,8 @@ public class AppointmentDao { company.setNdg(ndg); companyRepository.save(company); applicationRepository.save(application); + Map placeHolders=notificationDao.sendNotificationToBeneficiary(application,NotificationTypeEnum.NDG_GENERATION); + notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.NDG_GENERATION); // /** This code is responsible for adding a version history log for the "update application ndg code, status, and Id visura" operation. **/ // loggingUtil.addVersionHistory( diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 1b02b144..6d95a77a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -2,18 +2,25 @@ package net.gepafin.tendermanagement.dao; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.NotificationEntity; import net.gepafin.tendermanagement.entities.NotificationTypeEntity; +import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.NotificationEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.repositories.NotificationRepository; import net.gepafin.tendermanagement.repositories.NotificationTypeRepository; +import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; import net.gepafin.tendermanagement.util.Utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Component; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,6 +40,9 @@ public class NotificationDao { @Autowired private UserWithCompanyRepository userWithCompanyRepository; + @Autowired + private UserRepository userRepository; + public NotificationReq sendNotification(NotificationReq notificationReq) { // Ensure userId is properly set in notificationReq if not already @@ -113,4 +123,28 @@ public class NotificationDao { notificationReq.setUserId(userId); return notificationReq; } + public Map sendNotificationToBeneficiary(ApplicationEntity application, NotificationTypeEnum notificationTypeEnum) { + Map placeHolders = new HashMap<>(); + placeHolders.put("{{call_name}}", application.getCall().getName()); + placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber())); + NotificationReq notificationReq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, application.getUserId()); + sendNotification(notificationReq); + return placeHolders; + } + + public void sendNotificationToInstructor(Map placeHolders, ApplicationEvaluationEntity applicationEvaluationEntity, NotificationTypeEnum notificationTypeEnum) { + Long instructorId=applicationEvaluationEntity.getUserId(); + if(instructorId != null){ + NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders,instructorId); + sendNotification(notificationreq); + } + } + public void sendNotificationToSuperUser(ApplicationEntity application,Map placeHolders,NotificationTypeEnum notificationTypeEnum) { + List user=userRepository.findByRoleEntity_RoleTypeAndHubId(RoleStatusEnum.ROLE_SUPER_ADMIN.getValue(), application.getHubId()); + UserEntity userEntity1=user.get(0); + if(userEntity1 != null) { + NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders,userEntity1.getId()); + sendNotification(notificationreq); + } + } } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java index 86fd75dc..54a13768 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java @@ -6,7 +6,12 @@ public enum NotificationTypeEnum { CALL_CREATED("CALL_CREATED"), APPLICATION_SUBMISSION("APPLICATION_SUBMISSION"), AMENDMENT_CREATION("AMENDMENT_CREATION"), - EVALUATION_RESULT("EVALUATION_RESULT"); + EVALUATION_RESULT("EVALUATION_RESULT"), + AMENDMENT_EXPIRED("AMENDMENT_EXPIRED"), + AMENDMENT_CLOSED("AMENDMENT_CLOSED"), + NDG_GENERATION("NDG_GENERATION"), + EVALUATION_CREATION("EVALUATION_CREATION"), + EVALUATION_EXPIRED("EVALUATION_EXPIRED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java index 47ab16b8..bce13359 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java @@ -25,4 +25,7 @@ public interface UserRepository extends JpaRepository { Optional findByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); boolean existsByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); + + List findByRoleEntity_RoleTypeAndHubId(String roleType, Long hubId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java index a3112a1c..1b6ed976 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -2,10 +2,16 @@ package net.gepafin.tendermanagement.scheduler; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import net.gepafin.tendermanagement.dao.NotificationDao; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; +import net.gepafin.tendermanagement.model.request.NotificationReq; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -49,6 +55,9 @@ public class ApplicationAmendmentScheduler { @Autowired private LoggingUtil loggingUtil; + @Autowired + private NotificationDao notificationDao; + private static final Logger log = LoggerFactory.getLogger(ApplicationAmendmentScheduler.class); @Scheduled(cron = "0 0 1 * * ?") @@ -80,8 +89,10 @@ public class ApplicationAmendmentScheduler { try { ApplicationAmendmentRequestEntity oldAmendmentRequestEntity = Utils.getClonedEntityForData(request); request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + ApplicationEntity application=oldAmendmentRequestEntity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); request = applicationAmendmentRepository.save(request); - + Map placeHolders=notificationDao.sendNotificationToBeneficiary(application,NotificationTypeEnum.AMENDMENT_EXPIRED); + notificationDao.sendNotificationToInstructor(placeHolders,oldAmendmentRequestEntity.getApplicationEvaluationEntity(),NotificationTypeEnum.AMENDMENT_EXPIRED); /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendmentRequestEntity).newData(request).build()); diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java index a0444349..e7249645 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -1,8 +1,11 @@ package net.gepafin.tendermanagement.scheduler; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.NotificationDao; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; @@ -22,6 +25,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; +import java.util.Map; @Component public class ApplicationEvaluationScheduler { @@ -35,6 +39,9 @@ public class ApplicationEvaluationScheduler { @Autowired private HttpServletRequest httpServletRequest; + @Autowired + private NotificationDao notificationDao; + private static final Logger log = LoggerFactory.getLogger(ApplicationEvaluationScheduler.class); @Scheduled(cron = "0 0 2 * * ?") // Runs daily at midnight @@ -76,10 +83,15 @@ public class ApplicationEvaluationScheduler { ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils .getClonedEntityForData(evaluation); - + ApplicationEntity application=evaluation.getAssignedApplicationsEntity().getApplication(); evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); evaluation = applicationEvaluationRepository.save(evaluation); + Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_EXPIRED); + notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.EVALUATION_EXPIRED); + notificationDao.sendNotificationToInstructor(placeHolders,evaluation,NotificationTypeEnum.EVALUATION_EXPIRED); + + // Logging version history for the update operation loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest) .actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity) 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 fde4441d..b93ffa9c 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 @@ -2003,6 +2003,7 @@ + @@ -2015,9 +2016,13 @@ primaryKeyName="pk_notification_type"/> + + + + @@ -2026,15 +2031,4 @@ path="db/dump/insert_json_template_for_notification_13_12_2024.sql"/> - - - - - - - - - - - diff --git a/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql b/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql index 50caaefa..9856d855 100644 --- a/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql +++ b/src/main/resources/db/dump/insert_json_template_for_notification_13_12_2024.sql @@ -1,5 +1,10 @@ -INSERT INTO notification_type (notification_name, json_template) VALUES -('CALL_CREATED', 'Un nuovo bando intitolato {{call_name}} è stato pubblicato. Controllalo e invia le tue candidature prima della scadenza.'), -('APPLICATION_SUBMISSION', 'La tua richiesta per {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stata presentata con successo. È ora in fase di valutazione.'), -('AMENDMENT_CREATION', 'È stato creato un emendamento per la tua domanda in {{call_name}} ai sensi del protocollo n. {{protocol_number}}. Esamina le modifiche e procedi di conseguenza.'), -('EVALUATION_RESULT', 'Il risultato della valutazione per la tua domanda ai sensi del protocollo n. {{protocol_number}} è ora disponibile. Fai clic qui per visualizzare il tuo feedback.'); +INSERT INTO notification_type (notification_name,title, json_template,created_date,updated_date,is_deleted) VALUES +('CALL_CREATED', 'Un Nuovo Bando È Stato Pubblicato','Un nuovo bando intitolato {{call_name}} è stato pubblicato. Controllalo e invia le candidature prima della scadenza.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('APPLICATION_SUBMISSION','Candidatura Inviata con Successo per la Valutazione', 'La richiesta per {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stata presentata con successo. È ora in fase di valutazione.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('AMENDMENT_CREATION','È Stato Creato un Emendamento per la Richiesta', 'È stato creato un emendamento per la richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}}. Esamina le modifiche e procedi di conseguenza.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('EVALUATION_RESULT','Il Risultato della Valutazione per la Richiesta È Disponibile','Il risultato della valutazione per la richiesta ai sensi del protocollo n. {{protocol_number}} è ora disponibile.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('AMENDMENT_EXPIRED','L Emendamento per la Richiesta È Scaduto', 'L’emendamento per la richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}} è scaduto.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('AMENDMENT_CLOSED','L Emendamento È Stato Chiuso ed È Ora Inattivo','L’emendamento per {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stato chiuso ed è ora inattivo.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('NDG_GENERATION','È Stato Generato un Nuovo NDG per la Richiesta','È stato generato un nuovo NDG per {{call_name}} ai sensi del protocollo n. {{protocol_number}}.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('EVALUATION_CREATION','La Richiesta È Stata Assegnata per la Valutazione','La richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stata assegnata alla fase di valutazione.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'), +('EVALUATION_EXPIRED','La Valutazione per la Richiesta È Scaduta','La valutazione per la richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}} è scaduta.','2024-12-19T10:16:26.472Z','2024-12-19T10:16:26.472Z','false'); \ No newline at end of file From d7e2e35746fe0e5d135bbab6a1374967b4b7087c Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 23 Dec 2024 13:15:56 +0530 Subject: [PATCH 08/49] Updated notification code. --- .../entities/NotificationEntity.java | 2 ++ .../model/response/NotificationResponse.java | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java diff --git a/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java index 74131d4c..c0571fab 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java @@ -28,4 +28,6 @@ public class NotificationEntity extends BaseEntity { @Column(name = "REDIRECT_LINK") String redirectLink; + @Column(name = "USER_WITH_COMPANY_ID") + Long userWithCompanyId; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java new file mode 100644 index 00000000..655fa905 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class NotificationResponse { + private Long id; + private Long userId; + private String message; + private String notificationType; + private String status; + private LocalDateTime createdDate; + private LocalDateTime updatedDate; + private String redirectUrl; + private Long companyId; +} From db48cf950285d92c8ff532d0e93a40900ad2bde4 Mon Sep 17 00:00:00 2001 From: Piyush Date: Mon, 23 Dec 2024 19:28:37 +0530 Subject: [PATCH 09/49] Created endpoint for get,update,delete --- .../constants/GepafinConstant.java | 11 +++ .../constants/NotificationConstant.java | 5 - .../tendermanagement/dao/NotificationDao.java | 93 ++++++++++++++++++- .../repositories/NotificationRepository.java | 12 +++ .../service/NotificationService.java | 15 ++- .../service/impl/NotificationServiceImpl.java | 32 ++++++- .../web/rest/api/NotificationApi.java | 66 ++++++++++++- .../api/impl/NotificationApiController.java | 42 ++++++++- .../db/changelog/db.changelog-1.0.0.xml | 6 +- src/main/resources/message_en.properties | 8 ++ src/main/resources/message_it.properties | 8 ++ 11 files changed, 279 insertions(+), 19 deletions(-) delete mode 100644 src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index f0d9a617..d7b8e6a7 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -1,5 +1,7 @@ package net.gepafin.tendermanagement.constants; +import com.amazonaws.services.dynamodbv2.xspec.S; + public class GepafinConstant { public static final String USER_CREATED_SUCCESS_MSG = "user.created.success"; @@ -345,5 +347,14 @@ public class GepafinConstant { //Notification public static final String COMMON_SINGLE_CHANNEL_PREFIX = "/topic/notifications_user_"; public static final String COMPANY_PREFIX = "_company_"; + public static final String NOTIFICATION_SENT_SUCCESSFULLY = "notification.sent.successfully"; + public static final String NOTIFICATION_FETCHED_SUCCESSFULLY= "notification.fetched.successfully"; + public static final String NOTIFICATION_NOT_FOUND= "notification.not.found"; + public static final String NOTIFICATION_ALREADY_IN_THAT_STATE="notification.already.in.state"; + public static final String NOTIFICATION_DELETED_SUCCESSFULLY="notification.deleted.successfully"; + public static final String NOTIFICATION_UPDATED_SUCCESSFULLY="notification.updated.successfully"; + + } + diff --git a/src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java deleted file mode 100644 index 3f5c1cdc..00000000 --- a/src/main/java/net/gepafin/tendermanagement/constants/NotificationConstant.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.gepafin.tendermanagement.constants; - -public class NotificationConstant { - public static final String NOTIFICATION_SENT_SUCCESSFULLY = "Notification Sent Successfully."; -} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 6d95a77a..97e9b568 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -1,28 +1,38 @@ package net.gepafin.tendermanagement.dao; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.NotificationEntity; import net.gepafin.tendermanagement.entities.NotificationTypeEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import net.gepafin.tendermanagement.enums.NotificationEnum; import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.NotificationResponse; import net.gepafin.tendermanagement.repositories.NotificationRepository; import net.gepafin.tendermanagement.repositories.NotificationTypeRepository; import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Component @Slf4j @@ -43,7 +53,10 @@ public class NotificationDao { @Autowired private UserRepository userRepository; - public NotificationReq sendNotification(NotificationReq notificationReq) { + @Autowired + private CompanyDao companyDao; + + public NotificationResponse sendNotification(NotificationReq notificationReq) { // Ensure userId is properly set in notificationReq if not already Long userId = notificationReq.getUserId(); @@ -55,13 +68,13 @@ public class NotificationDao { log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); List companyIds = notificationReq.getCompanyIds(); - if (companyIds.isEmpty()) { + if (companyIds==null || companyIds.isEmpty()) { sendToUser(userId, notificationEntity); } else { sendToCompanies(userId, companyIds, notificationEntity); } - return convertToNotificationReq(notificationEntity); + return convertNotificationEntityToNotificationResponse(notificationEntity); } private NotificationEntity saveNotification(NotificationReq notificationReq) { @@ -147,4 +160,78 @@ public class NotificationDao { sendNotification(notificationreq); } } + public NotificationResponse getNotificationById(Long id) { + NotificationEntity notificationEntity = validateNotificationEntity(id); + NotificationResponse notificationReq=convertNotificationEntityToNotificationResponse(notificationEntity); + return notificationReq; + } + + private NotificationEntity validateNotificationEntity(Long id) { + NotificationEntity notificationEntity=notificationRepository.findByIdAndIsDeletedFalse(id); + if(notificationEntity ==null){ + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.NOTIFICATION_NOT_FOUND)); + } + return notificationEntity; + } + + public List getNotificationByUserId(Long userId, Long companyId, List statuses) { + List notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalse(userId); + UserWithCompanyEntity userWithCompany=null; + List statusStrings=new ArrayList<>(); + if(companyId!=null){ + userWithCompany=companyDao.validateUserWithCompny(userId,companyId); + } + + if (statuses != null ) { + statusStrings = statuses.stream() + .map(NotificationEnum::name) // Convert enum to its name as String + .toList(); + notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalseAndStatusIn(userId,statusStrings); + + if(userWithCompany != null){ + notificationEntities = notificationRepository.findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(userId, userWithCompany.getId(), statusStrings); + } + } + + List notificationReq= notificationEntities.stream() + .map(this::convertNotificationEntityToNotificationResponse) + .collect(Collectors.toList()); + + return notificationReq; + } + + public NotificationResponse convertNotificationEntityToNotificationResponse(NotificationEntity entity) { + if (entity == null) { + return null; // Handle null entity gracefully + } + + NotificationResponse response = new NotificationResponse(); + response.setId(entity.getId()); + response.setUserId(entity.getUserId()); + response.setMessage(entity.getMessage()); + response.setNotificationType(entity.getNotificationType()); + response.setStatus(entity.getStatus()); + response.setCreatedDate(entity.getCreatedDate()); + response.setUpdatedDate(entity.getUpdatedDate()); + response.setRedirectUrl(entity.getRedirectLink()); + response.setCompanyId(entity.getUserWithCompanyId()); + + return response; + } + public NotificationResponse updateNotificationStatus(Long id,NotificationEnum status){ + NotificationEntity notificationEntity=validateNotificationEntity(id); + if(notificationEntity.getStatus().equals(status.getValue())){ + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.NOTIFICATION_ALREADY_IN_THAT_STATE)); + } + notificationEntity.setStatus(status.getValue()); + notificationEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + notificationRepository.save(notificationEntity); + return convertNotificationEntityToNotificationResponse(notificationEntity); + } + + public void deleteNotification(Long id){ + NotificationEntity notificationEntity=validateNotificationEntity(id); + notificationEntity.setIsDeleted(true); + notificationRepository.save(notificationEntity); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java index a52c39de..91374bf7 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java @@ -1,7 +1,19 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.NotificationEntity; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface NotificationRepository extends JpaRepository { + + NotificationEntity findByIdAndIsDeletedFalse(Long id); + + List findByUserIdAndIsDeletedFalse(Long userId); + + List findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(Long userId,Long + userWithCompanyId,List statuses); + + List findByUserIdAndIsDeletedFalseAndStatusIn(Long userId, List statuses); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java index 0b6914c2..7dd37193 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java @@ -1,7 +1,20 @@ package net.gepafin.tendermanagement.service; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.enums.NotificationEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.NotificationResponse; + +import java.util.List; public interface NotificationService { - NotificationReq sendNotification(Long userId, NotificationReq notificationReq); + NotificationResponse sendNotification(Long userId, NotificationReq notificationReq); + + public NotificationResponse getNotificationById(HttpServletRequest servletRequest,Long id); + + public List getNotificationByUserId(HttpServletRequest servletRequest, Long userId, Long companyId, List statuses); + + public NotificationResponse updateNotificationStatus(HttpServletRequest request,Long id,NotificationEnum status); + + public void deleteNotification(HttpServletRequest request, Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java index 7928f166..99c35092 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java @@ -1,12 +1,17 @@ package net.gepafin.tendermanagement.service.impl; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.dao.NotificationDao; +import net.gepafin.tendermanagement.enums.NotificationEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.NotificationResponse; import net.gepafin.tendermanagement.service.NotificationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; + @Service @Slf4j public class NotificationServiceImpl implements NotificationService { @@ -15,12 +20,33 @@ public class NotificationServiceImpl implements NotificationService { private NotificationDao notificationDao; @Override - public NotificationReq sendNotification(Long userId, NotificationReq notificationReq) { + public NotificationResponse sendNotification(Long userId, NotificationReq notificationReq) { log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); notificationReq.setUserId(userId); - notificationReq = notificationDao.sendNotification(notificationReq); - return notificationReq; + NotificationResponse notificationResponse = notificationDao.sendNotification(notificationReq); + return notificationResponse; + } + + @Override + public NotificationResponse getNotificationById(HttpServletRequest servletRequest, Long id) { + return notificationDao.getNotificationById(id); + } + + @Override + public List getNotificationByUserId(HttpServletRequest servletRequest, Long userId, Long companyId, List statuses) { + return notificationDao.getNotificationByUserId(userId,companyId,statuses); + } + + @Override + public NotificationResponse updateNotificationStatus(HttpServletRequest request, Long id,NotificationEnum status) { + return notificationDao.updateNotificationStatus(id,status); + } + + @Override + public void deleteNotification(HttpServletRequest request, Long id) { + notificationDao.deleteNotification(id); + return; } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java index 85a4ab27..7e3c4caa 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java @@ -6,15 +6,25 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.enums.NotificationEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; import net.gepafin.tendermanagement.model.response.LookUpDataResponseBean; +import net.gepafin.tendermanagement.model.response.NotificationResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; public interface NotificationApi { @Operation(summary = "Api to send notification.", responses = { @ApiResponse(responseCode = "200", description = "OK"), @@ -24,7 +34,59 @@ public interface NotificationApi { ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) }) - @PostMapping(value = "/{userId}", consumes = "application/json", produces = "application/json") - ResponseEntity> sendNotification(HttpServletRequest request, @RequestBody NotificationReq notificationReq, + @PostMapping(value = "/user/{userId}/sent", consumes = "application/json", produces = "application/json") + ResponseEntity> sendNotification(HttpServletRequest request, @RequestBody NotificationReq notificationReq, @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId); + + @Operation(summary = "Api to get notification by id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/{id}", produces = "application/json") + ResponseEntity> getNotificationById(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); + + @Operation(summary = "Api to get notification by user id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/user/{userId}", produces = "application/json") + ResponseEntity>> getNotificationByUserId(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable(value = "userId", required = true) Long userId,@Parameter(description = "The company id", required = false) @RequestParam(value = "companyId",required = false) Long companyId,@Parameter(description = "The notification status", required = false) @RequestParam(value = "status",required = false) List statuses); + + @Operation(summary = "Api to update notification status", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PutMapping(value = "/{id}", produces = "application/json") + ResponseEntity> updateNotificationStatus(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id,@Parameter(description = "The notification status", required = true) @RequestParam(value = "status",required = true) NotificationEnum status); + + + @Operation(summary = "Api to delete notification", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @DeleteMapping(value = "/{id}", produces = "application/json") + ResponseEntity> deleteNotification(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); + } + + diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java index 054c4c63..7b065b8c 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java @@ -2,8 +2,11 @@ package net.gepafin.tendermanagement.web.rest.api.impl; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; -import net.gepafin.tendermanagement.constants.NotificationConstant; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.enums.NotificationEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.NotificationResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.NotificationService; import net.gepafin.tendermanagement.web.rest.api.NotificationApi; @@ -14,6 +17,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + @RestController @RequestMapping("${openapi.gepafin.base-path:/v1/notification}") public class NotificationApiController implements NotificationApi { @@ -21,12 +26,41 @@ public class NotificationApiController implements NotificationApi { @Autowired private NotificationService notificationService; - public ResponseEntity> sendNotification(HttpServletRequest request, NotificationReq notificationReq, Long userId) { + public ResponseEntity> sendNotification(HttpServletRequest request, NotificationReq notificationReq, Long userId) { - NotificationReq notificationData = notificationService.sendNotification(userId, notificationReq); + NotificationResponse notificationData = notificationService.sendNotification(userId, notificationReq); return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(notificationData, Status.SUCCESS, Translator.toLocale(NotificationConstant.NOTIFICATION_SENT_SUCCESSFULLY))); + .body(new Response<>(notificationData, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_SENT_SUCCESSFULLY))); + } + + @Override + public ResponseEntity> getNotificationById(HttpServletRequest request, Long id) { + NotificationResponse notificationResponse=notificationService.getNotificationById(request,id); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(notificationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_FETCHED_SUCCESSFULLY))); + } + + @Override + public ResponseEntity>> getNotificationByUserId(HttpServletRequest request, Long userId, Long companyId, List statuses) { + List notificationResponses=notificationService.getNotificationByUserId(request,userId,companyId,statuses); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response>(notificationResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_FETCHED_SUCCESSFULLY))); + + } + + @Override + public ResponseEntity> updateNotificationStatus(HttpServletRequest request, Long id,NotificationEnum notificationEnums) { + NotificationResponse notificationResponse=notificationService.updateNotificationStatus(request,id,notificationEnums); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(notificationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_UPDATED_SUCCESSFULLY))); + } + + @Override + public ResponseEntity> deleteNotification(HttpServletRequest request, Long id) { + notificationService.deleteNotification(request,id); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_DELETED_SUCCESSFULLY))); } } \ No newline at end of file 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 b93ffa9c..61ba0949 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 @@ -2030,5 +2030,9 @@ - + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 24150081..966358df 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -335,3 +335,11 @@ upload.document.is.only.for.gepafin = Document cant be uploaded, this is only av appointment.created.successfully = Appointment created successfully. error.try.again = Service call error while performing the operation. Please try again. document.uploading.is.in.progress = Document uploading is in progress. + +#notification messsages +notification.already.in.state=Notification is already in provided status. +notification.fetched.successfully=Notification fetched successfully. +notification.not.found=Notification not found. +notification.sent.successfully=Notification sent successfully. +notification.deleted.successfully=Notification deleted successfully. +notification.updated.successfully=Notification updated successfully. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 084fe6aa..da111f9f 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -325,3 +325,11 @@ upload.document.is.only.for.gepafin = Il documento non pu? essere caricato, ques appointment.created.successfully = Appuntamento creato con successo. error.try.again = Errore di chiamata di servizio durante l'esecuzione dell'operazione. Riprovare. document.uploading.is.in.progress = Il documento è in fase di caricamento. + +#notification messsages +notification.already.in.state=La notifica è già nello stato fornito. +notification.fetched.successfully=Notifica recuperata con successo. +notification.not.found=Notifica non trovata. +notification.sent.successfully=Notifica inviata con successo. +notification.deleted.successfully=Notifica eliminata con successo. +notification.updated.successfully=Notifica aggiornata con successo. \ No newline at end of file From 96b57519fbe6f243653049b662e2026946bf89fd Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 24 Dec 2024 16:07:42 +0530 Subject: [PATCH 10/49] Updated Apis, Code, Configurations for Notification. --- .../TendermanagementApplication.java | 5 +- .../config/WebSocketConfig.java | 24 ++- .../constants/GepafinConstant.java | 5 +- .../gepafin/tendermanagement/dao/CallDao.java | 4 +- .../tendermanagement/dao/NotificationDao.java | 155 ++++++++++-------- .../entities/NotificationEntity.java | 22 ++- .../entities/NotificationTypeEntity.java | 7 +- .../model/request/NotificationReq.java | 12 +- .../model/response/NotificationResponse.java | 19 ++- .../repositories/NotificationRepository.java | 6 +- .../UserWithCompanyRepository.java | 19 ++- .../service/NotificationService.java | 6 +- .../service/impl/NotificationServiceImpl.java | 22 ++- .../gepafin/tendermanagement/util/Utils.java | 5 - .../web/rest/api/NotificationApi.java | 84 +++++----- .../api/impl/NotificationApiController.java | 26 +-- src/main/resources/application-dev.properties | 9 +- .../resources/application-local.properties | 6 +- .../application-production.properties | 9 +- .../resources/application-testing.properties | 16 +- .../db/changelog/db.changelog-1.0.0.xml | 14 +- src/main/resources/message_en.properties | 1 + src/main/resources/message_it.properties | 3 +- 23 files changed, 278 insertions(+), 201 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java index 1465ad7e..c220b176 100644 --- a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java +++ b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java @@ -23,10 +23,7 @@ public class TendermanagementApplication { @Override public void addCorsMappings(CorsRegistry registry) { - //remove after testing -//add url for a demo html and js project created on Vs code and ran it from go live on right bottim corner user gepafin_dev_local backup DB for gettng notification on FE. - registry.addMapping("/**").allowedOrigins("http://127.0.0.1:5500", "http://localhost:3000", "http://localhost:5500") - .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD").allowCredentials(true); + registry.addMapping("/**").allowedOrigins("http://localhost:3000").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD").allowCredentials(true); } } diff --git a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java index b12207e6..8aa01986 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; @@ -10,23 +11,28 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + @Value("${spring.rabbitmq.host}") + private String relayHost; + + @Value("${spring.rabbitmq.port}") + private int relayPort; + + @Value("${spring.rabbitmq.username}") + private String clientUserName; + + @Value("${spring.rabbitmq.password}") + private String clientPassword; + @Override public void configureMessageBroker(MessageBrokerRegistry config) { - // Enable a simple broker for both /topic (broadcast messages) and /queue (user-specific messages) - config.enableStompBrokerRelay("/topic") - .setRelayHost("localhost") - .setRelayPort(61613) // RabbitMQ is running on port 61613 - .setClientLogin("guest") - .setClientPasscode("guest"); - // Prefix for application messages (user sends messages to /app endpoints) + config.enableStompBrokerRelay("/topic").setRelayHost(relayHost).setRelayPort(relayPort).setClientLogin(clientUserName).setClientPasscode(clientPassword); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("http://127.0.0.1:5501/", "http://localhost:5500", "http://localhost:5501", "http://127.0.0.1:5500/") - .withSockJS(); + registry.addEndpoint("/wss").setAllowedOrigins("http://localhost:3000").withSockJS(); } } diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index d7b8e6a7..f0ebabeb 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -1,7 +1,5 @@ package net.gepafin.tendermanagement.constants; -import com.amazonaws.services.dynamodbv2.xspec.S; - public class GepafinConstant { public static final String USER_CREATED_SUCCESS_MSG = "user.created.success"; @@ -353,8 +351,7 @@ public class GepafinConstant { public static final String NOTIFICATION_ALREADY_IN_THAT_STATE="notification.already.in.state"; public static final String NOTIFICATION_DELETED_SUCCESSFULLY="notification.deleted.successfully"; public static final String NOTIFICATION_UPDATED_SUCCESSFULLY="notification.updated.successfully"; - - + public static final String USER_WITH_COMPANY_NOT_FOUND = "user.with.company.not.found"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 45d81d9c..7382f1c6 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -51,6 +51,7 @@ 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.setIfUpdated; +import static org.hibernate.internal.util.collections.CollectionHelper.listOf; @Component public class CallDao { @@ -845,7 +846,8 @@ public class CallDao { Map placeholders = new HashMap<>(); placeholders.put("{{call_name}}", callEntity.getName()); userIds.forEach(userId -> { - NotificationReq notificationReq = notificationDao.createNotificationReq(NotificationTypeEnum.CALL_CREATED.getValue(), placeholders, userId); + List companyIds = notificationDao.getAllCompanyIdsForUser(userId); + NotificationReq notificationReq = notificationDao.createNotificationReq(NotificationTypeEnum.CALL_CREATED.getValue(), placeholders, userId, null, companyIds); notificationDao.sendNotification(notificationReq); }); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 97e9b568..5f7d700f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -1,6 +1,5 @@ package net.gepafin.tendermanagement.dao; -import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; @@ -19,6 +18,7 @@ import net.gepafin.tendermanagement.repositories.NotificationRepository; import net.gepafin.tendermanagement.repositories.NotificationTypeRepository; import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; +import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; @@ -34,6 +34,8 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static org.hibernate.internal.util.collections.CollectionHelper.listOf; + @Component @Slf4j public class NotificationDao { @@ -56,6 +58,9 @@ public class NotificationDao { @Autowired private CompanyDao companyDao; + @Autowired + private ApplicationService applicationService; + public NotificationResponse sendNotification(NotificationReq notificationReq) { // Ensure userId is properly set in notificationReq if not already @@ -68,7 +73,7 @@ public class NotificationDao { log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); List companyIds = notificationReq.getCompanyIds(); - if (companyIds==null || companyIds.isEmpty()) { + if (companyIds == null || companyIds.isEmpty()) { sendToUser(userId, notificationEntity); } else { sendToCompanies(userId, companyIds, notificationEntity); @@ -79,40 +84,50 @@ public class NotificationDao { private NotificationEntity saveNotification(NotificationReq notificationReq) { - NotificationEntity notificationEntity = convertToNotificationEntity(notificationReq); - return notificationRepository.save(notificationEntity); + return notificationRepository.save(convertNotificationRequestToNotificationEntity(notificationReq)); } private void sendToUser(Long userId, NotificationEntity notificationEntity) { String userChannel = GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId; log.info("Channel for User {}", userChannel); - messagingTemplate.convertAndSend(userChannel, notificationEntity); + NotificationResponse notificationResponse = convertNotificationEntityToNotificationResponse(notificationEntity); + messagingTemplate.convertAndSend(userChannel, notificationResponse); } private void sendToCompanies(Long userId, List companyIds, NotificationEntity notificationEntity) { // Send notification to each company provided in the companyIds list companyIds.forEach(companyId -> { + UserWithCompanyEntity userWithCompany = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalseForNotification(userId, companyId); String companyChannel = Utils.createChannelForUserAndCompany(userId, companyId); log.info("Channel for User and Company {}, {}", userId, companyChannel); - messagingTemplate.convertAndSend(companyChannel, notificationEntity); + if (userWithCompany == null) { + throw new CustomValidationException(Status.BAD_REQUEST, GepafinConstant.USER_WITH_COMPANY_NOT_FOUND); + } + notificationEntity.setUserWithCompany(userWithCompany); + notificationRepository.save(notificationEntity); + NotificationResponse notificationResponse = convertNotificationEntityToNotificationResponse(notificationEntity); + messagingTemplate.convertAndSend(companyChannel, notificationResponse); }); } - private NotificationReq convertToNotificationReq(NotificationEntity notificationEntity) { - - NotificationReq notificationReq = new NotificationReq(); - notificationReq.setId(notificationEntity.getId()); - notificationReq.setUserId(notificationEntity.getUserId()); - notificationReq.setStatus(NotificationEnum.UNREAD.getValue()); - notificationReq.setMessage(notificationEntity.getMessage()); - notificationReq.setCreatedDate(notificationEntity.getCreatedDate()); - notificationReq.setUpdatedDate(notificationEntity.getUpdatedDate()); - return notificationReq; + private NotificationResponse convertNotificationEntityToNotificationResponse(NotificationEntity notificationEntity) { + NotificationResponse notificationResponse = new NotificationResponse(); + notificationResponse.setId(notificationEntity.getId()); + notificationResponse.setUserId(notificationEntity.getUserId()); + notificationResponse.setStatus(notificationEntity.getStatus()); + notificationResponse.setMessage(notificationEntity.getMessage()); + notificationResponse.setCreatedDate(notificationEntity.getCreatedDate()); + notificationResponse.setUpdatedDate(notificationEntity.getUpdatedDate()); + notificationResponse.setRedirectUrl(notificationEntity.getNotificationType()); + notificationResponse.setCompanyId(notificationEntity.getUserWithCompany() != null ? notificationEntity.getUserWithCompany().getCompanyId() : null); + notificationResponse.setNotificationType(notificationEntity.getNotificationType()); + notificationResponse.setTitle(notificationEntity.getTitle()); + return notificationResponse; } - private NotificationEntity convertToNotificationEntity(NotificationReq notificationReq) { + private NotificationEntity convertNotificationRequestToNotificationEntity(NotificationReq notificationReq) { NotificationEntity notificationEntity = new NotificationEntity(); String message = notificationReq.getMessage(); @@ -120,108 +135,107 @@ public class NotificationDao { notificationEntity.setUserId(notificationReq.getUserId()); notificationEntity.setStatus(NotificationEnum.UNREAD.getValue()); notificationEntity.setIsDeleted(Boolean.FALSE); + notificationEntity.setUserWithCompany(notificationReq.getUserWithCompanyEntity() != null ? notificationReq.getUserWithCompanyEntity() : null); notificationEntity.setMessage(message); + notificationEntity.setTitle(notificationReq.getTitle()); return notificationEntity; } - public NotificationReq createNotificationReq(String notificationType, Map placeholders, Long userId) { + public NotificationReq createNotificationReq(String notificationType, Map placeholders, Long userId, UserWithCompanyEntity userWithCompanyEntity, + List companyIds) { // Create NotificationReq object NotificationReq notificationReq = new NotificationReq(); - List companyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(notificationReq.getUserId()); - notificationReq.setCompanyIds(companyIds); NotificationTypeEntity notificationTypeEntity = notificationTypeRepository.findByNotificationNameAndIsDeletedFalse(notificationType); notificationReq.setNotificationType(notificationType); String message = Utils.replacePlaceholders(notificationTypeEntity.getJsonTemplate(), placeholders); notificationReq.setMessage(message); notificationReq.setUserId(userId); + notificationReq.setCompanyIds(companyIds); + String title = Utils.replacePlaceholders(notificationTypeEntity.getTitle(), placeholders); + notificationReq.setTitle(title); + notificationReq.setUserWithCompanyEntity(userWithCompanyEntity); return notificationReq; } + public Map sendNotificationToBeneficiary(ApplicationEntity application, NotificationTypeEnum notificationTypeEnum) { + Map placeHolders = new HashMap<>(); placeHolders.put("{{call_name}}", application.getCall().getName()); placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber())); - NotificationReq notificationReq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, application.getUserId()); + NotificationReq notificationReq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, application.getUserId(), application.getUserWithCompany(), + listOf(application.getCompanyId())); sendNotification(notificationReq); return placeHolders; } public void sendNotificationToInstructor(Map placeHolders, ApplicationEvaluationEntity applicationEvaluationEntity, NotificationTypeEnum notificationTypeEnum) { - Long instructorId=applicationEvaluationEntity.getUserId(); - if(instructorId != null){ - NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders,instructorId); + + Long instructorId = applicationEvaluationEntity.getUserId(); + ApplicationEntity application = applicationService.validateApplication(applicationEvaluationEntity.getApplicationId()); + if (instructorId != null) { + NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, instructorId, application.getUserWithCompany(), + listOf(application.getCompanyId())); sendNotification(notificationreq); } } - public void sendNotificationToSuperUser(ApplicationEntity application,Map placeHolders,NotificationTypeEnum notificationTypeEnum) { - List user=userRepository.findByRoleEntity_RoleTypeAndHubId(RoleStatusEnum.ROLE_SUPER_ADMIN.getValue(), application.getHubId()); - UserEntity userEntity1=user.get(0); - if(userEntity1 != null) { - NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders,userEntity1.getId()); + public void sendNotificationToSuperUser(ApplicationEntity application, Map placeHolders, NotificationTypeEnum notificationTypeEnum) { + + List user = userRepository.findByRoleEntity_RoleTypeAndHubId(RoleStatusEnum.ROLE_SUPER_ADMIN.getValue(), application.getHubId()); + UserEntity userEntity1 = user.get(0); + if (userEntity1 != null) { + NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, userEntity1.getId(), application.getUserWithCompany(), + listOf(application.getCompanyId())); sendNotification(notificationreq); } } + + public List getAllCompanyIdsForUser(Long userId) { + + return userWithCompanyRepository.findActiveCompanyIdsByUserId(userId); + } + public NotificationResponse getNotificationById(Long id) { + NotificationEntity notificationEntity = validateNotificationEntity(id); - NotificationResponse notificationReq=convertNotificationEntityToNotificationResponse(notificationEntity); - return notificationReq; + return convertNotificationEntityToNotificationResponse(notificationEntity); } private NotificationEntity validateNotificationEntity(Long id) { - NotificationEntity notificationEntity=notificationRepository.findByIdAndIsDeletedFalse(id); - if(notificationEntity ==null){ + + NotificationEntity notificationEntity = notificationRepository.findByIdAndIsDeletedFalse(id); + if (notificationEntity == null) { throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.NOTIFICATION_NOT_FOUND)); } return notificationEntity; } public List getNotificationByUserId(Long userId, Long companyId, List statuses) { + List notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalse(userId); - UserWithCompanyEntity userWithCompany=null; - List statusStrings=new ArrayList<>(); - if(companyId!=null){ - userWithCompany=companyDao.validateUserWithCompny(userId,companyId); + UserWithCompanyEntity userWithCompany = null; + List statusStrings = new ArrayList<>(); + if (companyId != null) { + userWithCompany = companyDao.validateUserWithCompny(userId, companyId); } - if (statuses != null ) { - statusStrings = statuses.stream() - .map(NotificationEnum::name) // Convert enum to its name as String + if (statuses != null) { + statusStrings = statuses.stream().map(NotificationEnum::name) // Convert enum to its name as String .toList(); - notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalseAndStatusIn(userId,statusStrings); + notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalseAndStatusIn(userId, statusStrings); - if(userWithCompany != null){ + if (userWithCompany != null) { notificationEntities = notificationRepository.findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(userId, userWithCompany.getId(), statusStrings); } } - List notificationReq= notificationEntities.stream() - .map(this::convertNotificationEntityToNotificationResponse) - .collect(Collectors.toList()); - - return notificationReq; + return notificationEntities.stream().map(this::convertNotificationEntityToNotificationResponse).collect(Collectors.toList()); } - public NotificationResponse convertNotificationEntityToNotificationResponse(NotificationEntity entity) { - if (entity == null) { - return null; // Handle null entity gracefully - } + public NotificationResponse updateNotificationStatus(Long id, NotificationEnum status) { - NotificationResponse response = new NotificationResponse(); - response.setId(entity.getId()); - response.setUserId(entity.getUserId()); - response.setMessage(entity.getMessage()); - response.setNotificationType(entity.getNotificationType()); - response.setStatus(entity.getStatus()); - response.setCreatedDate(entity.getCreatedDate()); - response.setUpdatedDate(entity.getUpdatedDate()); - response.setRedirectUrl(entity.getRedirectLink()); - response.setCompanyId(entity.getUserWithCompanyId()); - - return response; - } - public NotificationResponse updateNotificationStatus(Long id,NotificationEnum status){ - NotificationEntity notificationEntity=validateNotificationEntity(id); - if(notificationEntity.getStatus().equals(status.getValue())){ - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.NOTIFICATION_ALREADY_IN_THAT_STATE)); + NotificationEntity notificationEntity = validateNotificationEntity(id); + if (notificationEntity.getStatus().equals(status.getValue())) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NOTIFICATION_ALREADY_IN_THAT_STATE)); } notificationEntity.setStatus(status.getValue()); notificationEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); @@ -229,8 +243,9 @@ public class NotificationDao { return convertNotificationEntityToNotificationResponse(notificationEntity); } - public void deleteNotification(Long id){ - NotificationEntity notificationEntity=validateNotificationEntity(id); + public void deleteNotification(Long id) { + + NotificationEntity notificationEntity = validateNotificationEntity(id); notificationEntity.setIsDeleted(true); notificationRepository.save(notificationEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java index c0571fab..718a7367 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/NotificationEntity.java @@ -2,6 +2,8 @@ package net.gepafin.tendermanagement.entities; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import lombok.Data; @@ -11,23 +13,27 @@ import lombok.Data; public class NotificationEntity extends BaseEntity { @Column(name = "USER_ID") - Long userId; + private Long userId; @Column(name = "MESSAGE") - String message; + private String message; + + @Column(name = "TITLE") + private String title; @Column(name = "STATUS") - String status; + private String status; @Column(name = "IS_DELETED") - Boolean isDeleted; + private Boolean isDeleted; @Column(name = "NOTIFICATION_TYPE") - String notificationType; + private String notificationType; @Column(name = "REDIRECT_LINK") - String redirectLink; + private String redirectLink; - @Column(name = "USER_WITH_COMPANY_ID") - Long userWithCompanyId; + @ManyToOne + @JoinColumn(name = "USER_WITH_COMPANY_ID") + private UserWithCompanyEntity userWithCompany; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java index 5202c97a..40d3f220 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/NotificationTypeEntity.java @@ -11,10 +11,13 @@ import lombok.Data; public class NotificationTypeEntity extends BaseEntity { @Column(name = "NOTIFICATION_NAME") - String notificationName; + private String notificationName; @Column(name = "JSON_TEMPLATE") - String jsonTemplate; + private String jsonTemplate; + + @Column(name = "TITLE") + private String title; @Column(name="IS_DELETED") private Boolean isDeleted; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java index 8506694a..9582d700 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/NotificationReq.java @@ -1,7 +1,9 @@ package net.gepafin.tendermanagement.model.request; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import java.time.LocalDateTime; import java.util.List; @@ -30,8 +32,14 @@ public class NotificationReq { private LocalDateTime updatedDate; @JsonProperty(access = JsonProperty.Access.READ_ONLY) - String redirectUrl; + private String redirectUrl; @JsonProperty(access = JsonProperty.Access.READ_ONLY) - List companyIds; + private String title; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private List companyIds; + + @JsonIgnore + private UserWithCompanyEntity userWithCompanyEntity; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java index 655fa905..0383cd25 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/NotificationResponse.java @@ -1,18 +1,21 @@ package net.gepafin.tendermanagement.model.response; import lombok.Data; - -import java.time.LocalDateTime; +import net.gepafin.tendermanagement.model.BaseBean; @Data -public class NotificationResponse { - private Long id; +public class NotificationResponse extends BaseBean { private Long userId; + + private String title; + private String message; - private String notificationType; + private String status; - private LocalDateTime createdDate; - private LocalDateTime updatedDate; - private String redirectUrl; + private Long companyId; + + private String redirectUrl; + + private String notificationType; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java index 91374bf7..f3c1d037 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java @@ -1,19 +1,17 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.NotificationEntity; -import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface NotificationRepository extends JpaRepository { - NotificationEntity findByIdAndIsDeletedFalse(Long id); + NotificationEntity findByIdAndIsDeletedFalse(Long id); List findByUserIdAndIsDeletedFalse(Long userId); - List findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(Long userId,Long - userWithCompanyId,List statuses); + List findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(Long userId, Long userWithCompanyId, List statuses); List findByUserIdAndIsDeletedFalseAndStatusIn(Long userId, List statuses); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java index ec93f2f6..13a197f1 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java @@ -1,22 +1,23 @@ package net.gepafin.tendermanagement.repositories; -import java.util.List; -import java.util.Optional; - +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; - +import java.util.List; +import java.util.Optional; public interface UserWithCompanyRepository extends JpaRepository { - void deleteByCompanyIdAndIsDeletedFalse(Long companyId); + void deleteByCompanyIdAndIsDeletedFalse(Long companyId); - @Query("SELECT u.companyId FROM UserWithCompanyEntity u WHERE u.userId = :userId AND u.isDeleted = false") - List findActiveCompanyIdsByUserId(@Param("userId") Long userId); + @Query("SELECT u.companyId FROM UserWithCompanyEntity u WHERE u.userId = :userId AND u.isDeleted = false") + List findActiveCompanyIdsByUserId(@Param("userId") Long userId); - Optional findByUserIdAndCompanyIdAndIsDeletedFalse(Long userId, Long companyId); + Optional findByUserIdAndCompanyIdAndIsDeletedFalse(Long userId, Long companyId); + + @Query("SELECT u FROM UserWithCompanyEntity u WHERE u.userId = :userId AND u.companyId = :companyId AND u.isDeleted = false") + UserWithCompanyEntity findByUserIdAndCompanyIdAndIsDeletedFalseForNotification(Long userId, Long companyId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java index 7dd37193..4657883d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java @@ -8,13 +8,13 @@ import net.gepafin.tendermanagement.model.response.NotificationResponse; import java.util.List; public interface NotificationService { - NotificationResponse sendNotification(Long userId, NotificationReq notificationReq); + NotificationResponse sendNotification(Long userId, NotificationReq notificationReq, Long companyId); - public NotificationResponse getNotificationById(HttpServletRequest servletRequest,Long id); + public NotificationResponse getNotificationById(HttpServletRequest servletRequest, Long id); public List getNotificationByUserId(HttpServletRequest servletRequest, Long userId, Long companyId, List statuses); - public NotificationResponse updateNotificationStatus(HttpServletRequest request,Long id,NotificationEnum status); + public NotificationResponse updateNotificationStatus(HttpServletRequest request, Long id, NotificationEnum status); public void deleteNotification(HttpServletRequest request, Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java index 99c35092..2a725935 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java @@ -12,6 +12,8 @@ import org.springframework.stereotype.Service; import java.util.List; +import static org.hibernate.internal.util.collections.CollectionHelper.listOf; + @Service @Slf4j public class NotificationServiceImpl implements NotificationService { @@ -20,33 +22,37 @@ public class NotificationServiceImpl implements NotificationService { private NotificationDao notificationDao; @Override - public NotificationResponse sendNotification(Long userId, NotificationReq notificationReq) { + public NotificationResponse sendNotification(Long userId, NotificationReq notificationReq, Long companyId) { log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); notificationReq.setUserId(userId); - NotificationResponse notificationResponse = notificationDao.sendNotification(notificationReq); - return notificationResponse; + notificationReq.setCompanyIds(listOf(companyId)); + return notificationDao.sendNotification(notificationReq); } @Override public NotificationResponse getNotificationById(HttpServletRequest servletRequest, Long id) { + return notificationDao.getNotificationById(id); } @Override public List getNotificationByUserId(HttpServletRequest servletRequest, Long userId, Long companyId, List statuses) { - return notificationDao.getNotificationByUserId(userId,companyId,statuses); + + return notificationDao.getNotificationByUserId(userId, companyId, statuses); } @Override - public NotificationResponse updateNotificationStatus(HttpServletRequest request, Long id,NotificationEnum status) { - return notificationDao.updateNotificationStatus(id,status); + public NotificationResponse updateNotificationStatus(HttpServletRequest request, Long id, NotificationEnum status) { + + return notificationDao.updateNotificationStatus(id, status); } @Override public void deleteNotification(HttpServletRequest request, Long id) { - notificationDao.deleteNotification(id); - return; + + notificationDao.deleteNotification(id); + return; } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 4290bfff..486ddd02 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -19,19 +19,15 @@ import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.jsonwebtoken.Claims; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.servlet.http.HttpServletRequest; -import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import com.fasterxml.jackson.core.JsonProcessingException; @@ -48,7 +44,6 @@ import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientForbiddenExce import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException; -import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java index 7e3c4caa..739a1516 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java @@ -7,10 +7,7 @@ import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.enums.NotificationEnum; -import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; -import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; -import net.gepafin.tendermanagement.model.response.LookUpDataResponseBean; import net.gepafin.tendermanagement.model.response.NotificationResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; @@ -36,56 +33,55 @@ public interface NotificationApi { ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) }) @PostMapping(value = "/user/{userId}/sent", consumes = "application/json", produces = "application/json") ResponseEntity> sendNotification(HttpServletRequest request, @RequestBody NotificationReq notificationReq, + @Parameter(description = "The company id", required = false) @RequestParam(value = "companyId", required = false) Long companyId, @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId); - @Operation(summary = "Api to get notification by id", - responses = { - @ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @Operation(summary = "Api to get notification by id", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/{id}", produces = "application/json") - ResponseEntity> getNotificationById(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); + ResponseEntity> getNotificationById(HttpServletRequest request, + @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); - @Operation(summary = "Api to get notification by user id", - responses = { - @ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @Operation(summary = "Api to get notification by user id", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/user/{userId}", produces = "application/json") - ResponseEntity>> getNotificationByUserId(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable(value = "userId", required = true) Long userId,@Parameter(description = "The company id", required = false) @RequestParam(value = "companyId",required = false) Long companyId,@Parameter(description = "The notification status", required = false) @RequestParam(value = "status",required = false) List statuses); + ResponseEntity>> getNotificationByUserId(HttpServletRequest request, + @Parameter(description = "The user id", required = true) @PathVariable(value = "userId", required = true) Long userId, + @Parameter(description = "The company id", required = false) @RequestParam(value = "companyId", required = false) Long companyId, + @Parameter(description = "The notification status", required = false) @RequestParam(value = "status", required = false) List statuses); - @Operation(summary = "Api to update notification status", - responses = { - @ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @Operation(summary = "Api to update notification status", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{id}", produces = "application/json") - ResponseEntity> updateNotificationStatus(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id,@Parameter(description = "The notification status", required = true) @RequestParam(value = "status",required = true) NotificationEnum status); + ResponseEntity> updateNotificationStatus(HttpServletRequest request, + @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id, + @Parameter(description = "The notification status", required = true) @RequestParam(value = "status", required = true) NotificationEnum status); - - @Operation(summary = "Api to delete notification", - responses = { - @ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @Operation(summary = "Api to delete notification", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @DeleteMapping(value = "/{id}", produces = "application/json") - ResponseEntity> deleteNotification(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); + ResponseEntity> deleteNotification(HttpServletRequest request, + @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java index 7b065b8c..11c61f23 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java @@ -19,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; +import static org.hibernate.internal.util.collections.CollectionHelper.listOf; + @RestController @RequestMapping("${openapi.gepafin.base-path:/v1/notification}") public class NotificationApiController implements NotificationApi { @@ -26,41 +28,43 @@ public class NotificationApiController implements NotificationApi { @Autowired private NotificationService notificationService; - public ResponseEntity> sendNotification(HttpServletRequest request, NotificationReq notificationReq, Long userId) { + public ResponseEntity> sendNotification(HttpServletRequest request, NotificationReq notificationReq, Long userId, Long companyId) { - NotificationResponse notificationData = notificationService.sendNotification(userId, notificationReq); + NotificationResponse notificationData = notificationService.sendNotification(userId, notificationReq, companyId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(notificationData, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_SENT_SUCCESSFULLY))); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(notificationData, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_SENT_SUCCESSFULLY))); } @Override public ResponseEntity> getNotificationById(HttpServletRequest request, Long id) { - NotificationResponse notificationResponse=notificationService.getNotificationById(request,id); + + NotificationResponse notificationResponse = notificationService.getNotificationById(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(notificationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_FETCHED_SUCCESSFULLY))); } @Override public ResponseEntity>> getNotificationByUserId(HttpServletRequest request, Long userId, Long companyId, List statuses) { - List notificationResponses=notificationService.getNotificationByUserId(request,userId,companyId,statuses); + + List notificationResponses = notificationService.getNotificationByUserId(request, userId, companyId, statuses); return ResponseEntity.status(HttpStatus.OK) .body(new Response>(notificationResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_FETCHED_SUCCESSFULLY))); } @Override - public ResponseEntity> updateNotificationStatus(HttpServletRequest request, Long id,NotificationEnum notificationEnums) { - NotificationResponse notificationResponse=notificationService.updateNotificationStatus(request,id,notificationEnums); + public ResponseEntity> updateNotificationStatus(HttpServletRequest request, Long id, NotificationEnum notificationEnums) { + + NotificationResponse notificationResponse = notificationService.updateNotificationStatus(request, id, notificationEnums); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(notificationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_UPDATED_SUCCESSFULLY))); } @Override public ResponseEntity> deleteNotification(HttpServletRequest request, Long id) { - notificationService.deleteNotification(request,id); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_DELETED_SUCCESSFULLY))); + + notificationService.deleteNotification(request, id); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_DELETED_SUCCESSFULLY))); } } \ No newline at end of file diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index f99634bc..1a74fc78 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -22,4 +22,11 @@ appointment.portal.user=UtenzaAPIPortal@621 appointment.portal.password=u13nzaAP1P0rtal appointment.portal.source=GEPAFINPORTAL appointment.portal.context=GEPAFINPORTAL -flagDaFirmare=false \ No newline at end of file +flagDaFirmare=false + +# RabbitMQ properties for STOMP broker relay for Notification +spring.rabbitmq.host=localhost +spring.rabbitmq.port=61613 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest +spring.rabbitmq.virtual-host=/ \ No newline at end of file diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 11f3d75e..7e78b539 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,6 +1,6 @@ # DataSource Configuration spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_dev_local -spring.datasource.username=root +spring.datasource.username=postgres spring.datasource.password=root spring.datasource.driver-class-name=org.postgresql.Driver @@ -22,9 +22,9 @@ appointment.portal.source=GEPAFINPORTAL appointment.portal.context=GEPAFINPORTAL flagDaFirmare=false -# RabbitMQ properties for STOMP broker relay +# RabbitMQ properties for STOMP broker relay for Notification spring.rabbitmq.host=localhost -spring.rabbitmq.port=5672 +spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.rabbitmq.virtual-host=/ \ No newline at end of file diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index 2007e166..e137691f 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -29,4 +29,11 @@ appointment.portal.user=UtenzaAPIPortal@621 appointment.portal.password=u13nzaAP1P0rtal appointment.portal.source=GEPAFINPORTAL appointment.portal.context=GEPAFINPORTAL -flagDaFirmare=true \ No newline at end of file +flagDaFirmare=true + +# RabbitMQ properties for STOMP broker relay for Notification +spring.rabbitmq.host=localhost +spring.rabbitmq.port=61613 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest +spring.rabbitmq.virtual-host=/ \ No newline at end of file diff --git a/src/main/resources/application-testing.properties b/src/main/resources/application-testing.properties index 1dbc41cc..0617f3cd 100644 --- a/src/main/resources/application-testing.properties +++ b/src/main/resources/application-testing.properties @@ -11,4 +11,18 @@ default_System_Receiver_Email=test@test.test gepafin_email=test@test.test rinaldo_email=test@test.test carlo_email=test@test.test -default.hub.uuid=p4lk3bcx1RStqTaIVVbXs \ No newline at end of file +default.hub.uuid=p4lk3bcx1RStqTaIVVbXs + +appointment.base.url=https://demo.galileonetwork.it/gateway/rest +appointment.portal.user=UtenzaAPIPortal@621 +appointment.portal.password=u13nzaAP1P0rtal +appointment.portal.source=GEPAFINPORTAL +appointment.portal.context=GEPAFINPORTAL +flagDaFirmare=false + +# RabbitMQ properties for STOMP broker relay for Notification +spring.rabbitmq.host=localhost +spring.rabbitmq.port=61613 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest +spring.rabbitmq.virtual-host=/ \ No newline at end of file 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 61ba0949..816716ad 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 @@ -2030,9 +2030,19 @@ - + + - + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 966358df..a1a01272 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -343,3 +343,4 @@ notification.not.found=Notification not found. notification.sent.successfully=Notification sent successfully. notification.deleted.successfully=Notification deleted successfully. notification.updated.successfully=Notification updated successfully. +user.with.company.not.found = User with company not found for user or company. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index da111f9f..03cf99d7 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -332,4 +332,5 @@ notification.fetched.successfully=Notifica recuperata con successo. notification.not.found=Notifica non trovata. notification.sent.successfully=Notifica inviata con successo. notification.deleted.successfully=Notifica eliminata con successo. -notification.updated.successfully=Notifica aggiornata con successo. \ No newline at end of file +notification.updated.successfully=Notifica aggiornata con successo. +user.with.company.not.found = Utente con azienda non trovato per utente o azienda. \ No newline at end of file From 47aa1d73b9ffc315904e984ded45760b7bcbbb7b Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 24 Dec 2024 16:21:34 +0530 Subject: [PATCH 11/49] Updated Code. --- src/main/resources/application-local.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 7e78b539..e52a9577 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,5 +1,5 @@ # DataSource Configuration -spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_dev_local +spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_local spring.datasource.username=postgres spring.datasource.password=root spring.datasource.driver-class-name=org.postgresql.Driver From 549478b610df211656d6abd7740bbcfba9300e0b Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 24 Dec 2024 18:20:53 +0530 Subject: [PATCH 12/49] Amendment Scheduler updates --- .../dao/ApplicationEvaluationDao.java | 1 + .../entities/ApplicationEvaluationEntity.java | 3 + .../ApplicationAmendmentScheduler.java | 75 ++++++++++++++++--- .../db/changelog/db.changelog-1.0.0.xml | 5 ++ 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 50fdb16d..aad85864 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1775,6 +1775,7 @@ public class ApplicationEvaluationDao { String statusType = application.getStatus(); if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) { existingEntity.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue()); + existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); } entity = applicationEvaluationRepository.save(existingEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index 45a8c842..15e3d3d7 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -62,4 +62,7 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @Column(name = "STOP_DATE_TIME") private LocalDateTime stopDateTime; + @Column(name = "CLOSING_DATE") + private LocalDateTime closingDate; + } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java index 56cb3663..b9d63acd 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -6,24 +6,24 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; +import net.gepafin.tendermanagement.enums.*; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; +import net.gepafin.tendermanagement.service.ApplicationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; + import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; -import net.gepafin.tendermanagement.dao.EmailNotificationDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; -import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.enums.UserActionContextEnum; -import net.gepafin.tendermanagement.enums.UserActionLogsEnum; -import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; @@ -40,8 +40,6 @@ public class ApplicationAmendmentScheduler { @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRepository; - @Autowired - private EmailNotificationDao emailNotificationDao; @Autowired private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; @@ -49,6 +47,18 @@ public class ApplicationAmendmentScheduler { @Autowired private LoggingUtil loggingUtil; + @Autowired + private AssignedApplicationsRepository assignedApplicationsRepository; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + private static final Logger log = LoggerFactory.getLogger(ApplicationAmendmentScheduler.class); @Scheduled(cron = "0 0 1 * * ?") @@ -79,14 +89,14 @@ public class ApplicationAmendmentScheduler { amendmentRequests.forEach(request -> { try { ApplicationAmendmentRequestEntity oldAmendmentRequestEntity = Utils.getClonedEntityForData(request); - request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + request.setStatus(ApplicationAmendmentRequestEnum.EXPIRED.getValue()); request = applicationAmendmentRepository.save(request); /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendmentRequestEntity).newData(request).build()); // emailNotificationDao.sendApplicationFailureNotificationEmail(request); - log.info("Updated status to CLOSED for ApplicationAmendmentRequest with ID: {}", request.getId()); + log.info("Updated status to EXPIRED for ApplicationAmendmentRequest with ID: {}", request.getId()); } catch (Exception e) { log.error("Error expiring ApplicationAmendmentRequest with ID {}: {}", request.getId(), e.getMessage(), e); @@ -104,6 +114,16 @@ public class ApplicationAmendmentScheduler { evaluationsWithoutActiveAmendmentList.forEach(evaluation -> { try { applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(evaluation); + + updateEvaluationStatus(evaluation); + + // Update AssignedApplicationsEntity status + updateAssignedApplicationStatus(evaluation.getAssignedApplicationsEntity()); + + // Update ApplicationEntity status + updateApplicationStatus(evaluation.getAssignedApplicationsEntity().getApplication()); + + log.info("Updated EndDate and suspension days for ApplicationEvaluation with ID: {}", evaluation.getId()); } catch (Exception e) { @@ -119,4 +139,35 @@ public class ApplicationAmendmentScheduler { } + public void updateAssignedApplicationStatus(AssignedApplicationsEntity assignedApplicationsEntity){ + AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.OPEN.getValue()); + assignedApplicationsRepository.save(assignedApplicationsEntity); + log.info("Updated status to OPEN for Assigned Application with ID: {}", assignedApplicationsEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Assigned Application status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); + + } + + public void updateApplicationStatus(ApplicationEntity applicationEntity){ + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + applicationEntity.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + applicationRepository.save(applicationEntity); + log.info("Updated status to EVALUATION for Application with ID: {}",applicationEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Application Status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + + } + public void updateEvaluationStatus(ApplicationEvaluationEntity applicationEvaluationEntity){ + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); + applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); + applicationEvaluationRepository.save(applicationEvaluationEntity); + log.info("Updated status to OPEN for ApplicationEvaluation with ID: {}", applicationEvaluationEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Application Status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); + + } } 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 6eee497f..90ab3ca8 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 @@ -2064,5 +2064,10 @@ + + + + + From 034d17d1fb689a27b74d1c398609e56da31bcda0 Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 24 Dec 2024 18:20:53 +0530 Subject: [PATCH 13/49] Amendment Scheduler updates --- .../dao/ApplicationEvaluationDao.java | 1 + .../entities/ApplicationEvaluationEntity.java | 3 + .../ApplicationAmendmentScheduler.java | 75 ++++++++++++++++--- .../db/changelog/db.changelog-1.0.0.xml | 5 ++ 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 50fdb16d..aad85864 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1775,6 +1775,7 @@ public class ApplicationEvaluationDao { String statusType = application.getStatus(); if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) { existingEntity.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue()); + existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); } entity = applicationEvaluationRepository.save(existingEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index 45a8c842..15e3d3d7 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -62,4 +62,7 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @Column(name = "STOP_DATE_TIME") private LocalDateTime stopDateTime; + @Column(name = "CLOSING_DATE") + private LocalDateTime closingDate; + } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java index 56cb3663..b9d63acd 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -6,24 +6,24 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; +import net.gepafin.tendermanagement.enums.*; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; +import net.gepafin.tendermanagement.service.ApplicationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; + import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; -import net.gepafin.tendermanagement.dao.EmailNotificationDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; -import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.enums.UserActionContextEnum; -import net.gepafin.tendermanagement.enums.UserActionLogsEnum; -import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; @@ -40,8 +40,6 @@ public class ApplicationAmendmentScheduler { @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRepository; - @Autowired - private EmailNotificationDao emailNotificationDao; @Autowired private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; @@ -49,6 +47,18 @@ public class ApplicationAmendmentScheduler { @Autowired private LoggingUtil loggingUtil; + @Autowired + private AssignedApplicationsRepository assignedApplicationsRepository; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + private static final Logger log = LoggerFactory.getLogger(ApplicationAmendmentScheduler.class); @Scheduled(cron = "0 0 1 * * ?") @@ -79,14 +89,14 @@ public class ApplicationAmendmentScheduler { amendmentRequests.forEach(request -> { try { ApplicationAmendmentRequestEntity oldAmendmentRequestEntity = Utils.getClonedEntityForData(request); - request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + request.setStatus(ApplicationAmendmentRequestEnum.EXPIRED.getValue()); request = applicationAmendmentRepository.save(request); /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendmentRequestEntity).newData(request).build()); // emailNotificationDao.sendApplicationFailureNotificationEmail(request); - log.info("Updated status to CLOSED for ApplicationAmendmentRequest with ID: {}", request.getId()); + log.info("Updated status to EXPIRED for ApplicationAmendmentRequest with ID: {}", request.getId()); } catch (Exception e) { log.error("Error expiring ApplicationAmendmentRequest with ID {}: {}", request.getId(), e.getMessage(), e); @@ -104,6 +114,16 @@ public class ApplicationAmendmentScheduler { evaluationsWithoutActiveAmendmentList.forEach(evaluation -> { try { applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(evaluation); + + updateEvaluationStatus(evaluation); + + // Update AssignedApplicationsEntity status + updateAssignedApplicationStatus(evaluation.getAssignedApplicationsEntity()); + + // Update ApplicationEntity status + updateApplicationStatus(evaluation.getAssignedApplicationsEntity().getApplication()); + + log.info("Updated EndDate and suspension days for ApplicationEvaluation with ID: {}", evaluation.getId()); } catch (Exception e) { @@ -119,4 +139,35 @@ public class ApplicationAmendmentScheduler { } + public void updateAssignedApplicationStatus(AssignedApplicationsEntity assignedApplicationsEntity){ + AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.OPEN.getValue()); + assignedApplicationsRepository.save(assignedApplicationsEntity); + log.info("Updated status to OPEN for Assigned Application with ID: {}", assignedApplicationsEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Assigned Application status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); + + } + + public void updateApplicationStatus(ApplicationEntity applicationEntity){ + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + applicationEntity.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + applicationRepository.save(applicationEntity); + log.info("Updated status to EVALUATION for Application with ID: {}",applicationEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Application Status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + + } + public void updateEvaluationStatus(ApplicationEvaluationEntity applicationEvaluationEntity){ + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); + applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); + applicationEvaluationRepository.save(applicationEvaluationEntity); + log.info("Updated status to OPEN for ApplicationEvaluation with ID: {}", applicationEvaluationEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Application Status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); + + } } 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 6eee497f..90ab3ca8 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 @@ -2064,5 +2064,10 @@ + + + + + From 42e1f6a0c5af8c1f55c6e7fdacbd7b9988138153 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 27 Dec 2024 15:03:07 +0530 Subject: [PATCH 14/49] Updated RabbitMQ config for notification. --- src/main/resources/application-dev.properties | 2 +- src/main/resources/application-production.properties | 2 +- src/main/resources/application-testing.properties | 2 +- src/main/resources/application.properties | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 1a74fc78..2b3482bf 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -25,7 +25,7 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=false # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=localhost +spring.rabbitmq.host=rabitmq.bflows.ai spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index e137691f..007831ca 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -32,7 +32,7 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=true # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=localhost +spring.rabbitmq.host=rabitmq.bflows.ai spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest diff --git a/src/main/resources/application-testing.properties b/src/main/resources/application-testing.properties index 0617f3cd..e8088376 100644 --- a/src/main/resources/application-testing.properties +++ b/src/main/resources/application-testing.properties @@ -21,7 +21,7 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=false # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=localhost +spring.rabbitmq.host=rabitmq.bflows.ai spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 60f61aec..c1095613 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.application.name=tendermanagement spring.servlet.multipart.max-file-size=300MB spring.servlet.multipart.max-request-size=300MB -spring.profiles.active=testing +spring.profiles.active=testing # JPA Configuration From f8099fd4238f36ede2d82d17078c6a34b060560f Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 27 Dec 2024 17:31:58 +0530 Subject: [PATCH 15/49] Updated response --- .../dao/ApplicationAmendmentRequestDao.java | 5 ++++- .../gepafin/tendermanagement/dao/ApplicationDao.java | 10 ++++++++++ .../dao/ApplicationEvaluationDao.java | 11 ++++++++++- .../response/ApplicationAmendmentRequestResponse.java | 1 + .../model/response/ApplicationEvaluationResponse.java | 2 ++ .../model/response/ApplicationResponse.java | 4 ++++ 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 2937da2c..5cb93052 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -110,6 +110,8 @@ public class ApplicationAmendmentRequestDao { @Autowired private DocumentRepository documentRepository; + @Autowired + private CompanyService companyService; public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); @@ -454,7 +456,8 @@ public class ApplicationAmendmentRequestDao { UserEntity userEntity = userService.validateUser(application.getUserId()); response.setBeneficiaryName(buildBeneficiaryName(userEntity)); - + CompanyEntity company = companyService.validateCompany(application.getCompanyId()); + response.setCompanyName(company.getCompanyName()); Long protocolNumber = entity.getProtocol() != null ? entity.getProtocol().getProtocolNumber() : null; response.setProtocolNumber(protocolNumber); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 45a69384..5353f215 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -387,6 +387,16 @@ public class ApplicationDao { responseBean.setStatus(applicationEntity.getStatus()); responseBean.setComments(applicationEntity.getComments()); responseBean.setCompanyId(applicationEntity.getCompanyId()); + Optional assignedApplicationsOptional = + assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); + if(assignedApplicationsOptional.isPresent()){ + responseBean.setAssignedUserId(assignedApplicationsOptional.get().getUserId()); + UserEntity user = userService.validateUser(assignedApplicationsOptional.get().getUserId()); + String firstName = user.getFirstName() != null ? user.getFirstName() : ""; + String lastName = user.getLastName() != null ? user.getLastName() : ""; + String userName = String.join(" ", firstName, lastName).trim(); + responseBean.setAssignedUserName(userName); + } CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); responseBean.setCompanyName(company.getCompanyName()); if(applicationEntity.getProtocol() != null) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index aad85864..4986dce7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -558,7 +558,16 @@ public class ApplicationEvaluationDao { response.setAssignedAt(assignedApplications.getAssignedAt()); } response.setEvaluationEndDate(entity.getEndDate()); - + Optional assignedApplicationsOptional = + assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(application.getId()); + if(assignedApplicationsOptional.isPresent()){ + response.setAssignedUserId(assignedApplicationsOptional.get().getUserId()); + UserEntity assignedUser = userService.validateUser(assignedApplicationsOptional.get().getUserId()); + String assignedUserFirstName = assignedUser.getFirstName() != null ? assignedUser.getFirstName() : ""; + String assignedUserLastName = assignedUser.getLastName() != null ? assignedUser.getLastName() : ""; + String userName = String.join(" ", assignedUserFirstName, assignedUserLastName).trim(); + response.setAssignedUserName(userName); + } LocalDateTime callEndDate = application.getCall().getEndDate(); response.setCallEndDate(callEndDate); if (application.getCompanyId() != null) { diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index 01390777..776ad10f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -19,6 +19,7 @@ public class ApplicationAmendmentRequestResponse { private Long protocolNumber; private String callName; private String beneficiaryName; + private String companyName; private List formFields; private List applicationFormFields; private List amendmentDocuments; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index b890b327..7da6d25f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -26,6 +26,8 @@ public class ApplicationEvaluationResponse { private LocalDateTime createdDate; private LocalDateTime updatedDate; private String beneficiary; + private Long assignedUserId; + private String assignedUserName; private Long protocolNumber; private String callName; private String motivation; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java index d5df459e..24ad5a34 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java @@ -33,4 +33,8 @@ public class ApplicationResponse{ private Long protocolNumber; + private Long assignedUserId; + + private String assignedUserName; + } \ No newline at end of file From 8074d5d73d6b906053c7fe2d78ceb3e8d12daa7a Mon Sep 17 00:00:00 2001 From: piyushkag Date: Sat, 28 Dec 2024 12:19:39 +0530 Subject: [PATCH 16/49] Added API for getting notifications by compnayId and userId. --- .../tendermanagement/dao/NotificationDao.java | 19 +++++++++++++++++++ .../repositories/NotificationRepository.java | 3 +++ .../service/NotificationService.java | 3 +++ .../service/impl/NotificationServiceImpl.java | 4 ++++ .../web/rest/api/NotificationApi.java | 12 ++++++++++++ .../api/impl/NotificationApiController.java | 10 +++++++--- 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 5f7d700f..64db69ca 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -61,6 +61,9 @@ public class NotificationDao { @Autowired private ApplicationService applicationService; + @Autowired + private UserDao userDao; + public NotificationResponse sendNotification(NotificationReq notificationReq) { // Ensure userId is properly set in notificationReq if not already @@ -249,4 +252,20 @@ public class NotificationDao { notificationEntity.setIsDeleted(true); notificationRepository.save(notificationEntity); } + + public List getNotificationByCompanyIdAndUserId(Long userId, Long companyId) { + + companyDao.validateCompany(companyId); + userDao.validateUser(userId); + + UserWithCompanyEntity userWithCompanyData = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalseForNotification(userId, companyId); + if (userWithCompanyData == null) { + throw new CustomValidationException(Status.BAD_REQUEST, GepafinConstant.USER_MUST_BE_ASSOCIATED_WITH_COMPANY); + } + + List notifications = notificationRepository.findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(userWithCompanyData.getId(), + userWithCompanyData.getUserId()); + return notifications.stream().map(this::convertNotificationEntityToNotificationResponse).toList(); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java index f3c1d037..bce3ba68 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/NotificationRepository.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.NotificationEntity; +import org.springframework.data.domain.Page; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -14,4 +15,6 @@ public interface NotificationRepository extends JpaRepository findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(Long userId, Long userWithCompanyId, List statuses); List findByUserIdAndIsDeletedFalseAndStatusIn(Long userId, List statuses); + + List findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(Long userWithCompanyId, Long userId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java index 4657883d..4d5d3ba6 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java @@ -17,4 +17,7 @@ public interface NotificationService { public NotificationResponse updateNotificationStatus(HttpServletRequest request, Long id, NotificationEnum status); public void deleteNotification(HttpServletRequest request, Long id); + + public List getNotificationsByCompanyIdAndUserId(Long userId, Long companyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java index 2a725935..9fa0956a 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java @@ -55,4 +55,8 @@ public class NotificationServiceImpl implements NotificationService { return; } + @Override + public List getNotificationsByCompanyIdAndUserId(Long userId, Long companyId) { + return notificationDao.getNotificationByCompanyIdAndUserId(userId, companyId); + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java index 739a1516..6f46244b 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java @@ -83,6 +83,18 @@ public interface NotificationApi { ResponseEntity> deleteNotification(HttpServletRequest request, @Parameter(description = "The notification id", required = true) @PathVariable(value = "id", required = true) Long id); + @Operation(summary = "API to get notifications by user ID and company ID", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/user/{userId}/company/{companyId}/notifications", produces = "application/json") + ResponseEntity>> getNotificationsByUserIdAndCompanyId(HttpServletRequest request, + @Parameter(description = "The user id", required = true) @PathVariable(value = "userId") Long userId, + @Parameter(description = "The company ID", required = true) @PathVariable(value = "companyId") Long companyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java index 11c61f23..586a5f9e 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java @@ -4,7 +4,6 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.NotificationEnum; -import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.model.response.NotificationResponse; import net.gepafin.tendermanagement.model.util.Response; @@ -19,8 +18,6 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; -import static org.hibernate.internal.util.collections.CollectionHelper.listOf; - @RestController @RequestMapping("${openapi.gepafin.base-path:/v1/notification}") public class NotificationApiController implements NotificationApi { @@ -67,4 +64,11 @@ public class NotificationApiController implements NotificationApi { return ResponseEntity.status(HttpStatus.OK).body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_DELETED_SUCCESSFULLY))); } + @Override + public ResponseEntity>> getNotificationsByUserIdAndCompanyId(HttpServletRequest request,Long userId, Long companyId) { + List notificationResponses = notificationService.getNotificationsByCompanyIdAndUserId(userId, companyId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(notificationResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_FETCHED_SUCCESSFULLY))); + } + } \ No newline at end of file From 60cb721a14de3f2c779a2eab674de0bcd55405a4 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 30 Dec 2024 12:22:43 +0530 Subject: [PATCH 17/49] Resolved RabbitMQ issue and added configuration. --- .../net/gepafin/tendermanagement/config/WebSocketConfig.java | 3 ++- src/main/resources/application-dev.properties | 2 +- src/main/resources/application-local.properties | 4 ++-- src/main/resources/application-production.properties | 2 +- src/main/resources/application-testing.properties | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java index 8aa01986..1b90a882 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java @@ -33,6 +33,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/wss").setAllowedOrigins("http://localhost:3000").withSockJS(); + registry.addEndpoint("/wss").setAllowedOrigins("http://localhost:3000", "http://127.0.0.1:5500/", "https://bandi-staging.memento.credit/**", "https://bandi.gepafin.it/**") + .withSockJS(); } } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 2b3482bf..e211e883 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -25,7 +25,7 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=false # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=rabitmq.bflows.ai +spring.rabbitmq.host=rabbitmq.bflows.ai spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index e52a9577..bcf5beab 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,6 +1,6 @@ # DataSource Configuration -spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_local -spring.datasource.username=postgres +spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_dev_local +spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=org.postgresql.Driver diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index 007831ca..df295088 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -32,7 +32,7 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=true # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=rabitmq.bflows.ai +spring.rabbitmq.host=rabbitmq.bflows.ai spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest diff --git a/src/main/resources/application-testing.properties b/src/main/resources/application-testing.properties index e8088376..8ee53329 100644 --- a/src/main/resources/application-testing.properties +++ b/src/main/resources/application-testing.properties @@ -21,7 +21,7 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=false # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=rabitmq.bflows.ai +spring.rabbitmq.host=rabbitmq.bflows.ai spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest From 4774f9383e143a2114f15d5006f99207d1921865 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 30 Dec 2024 12:35:30 +0530 Subject: [PATCH 18/49] Added configuration for rabbitMQ connection. --- src/main/resources/application.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c1095613..d0af99d3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -67,4 +67,5 @@ default.hub.pdf.banner=https://mementoresources.s3.amazonaws.com/gepafin/staging #feign client config spring.cloud.openfeign.client.config.default.connectTimeout=300000 -spring.cloud.openfeign.client.config.default.readTimeout=300000 \ No newline at end of file +spring.cloud.openfeign.client.config.default.readTimeout=300000 +spring.rabbitmq.connection-timeout=120000 \ No newline at end of file From 83141d009f7baf1e2a8ee24230bb6c84328991c8 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 30 Dec 2024 13:02:50 +0530 Subject: [PATCH 19/49] Updated code. --- src/main/resources/application-local.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index bcf5beab..e52a9577 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,6 +1,6 @@ # DataSource Configuration -spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_dev_local -spring.datasource.username=root +spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_local +spring.datasource.username=postgres spring.datasource.password=root spring.datasource.driver-class-name=org.postgresql.Driver From e56b8aa9beef39e3c21bad8e2820a1c56786fa68 Mon Sep 17 00:00:00 2001 From: nisha Date: Mon, 30 Dec 2024 13:27:51 +0530 Subject: [PATCH 20/49] Added emailTemplate field in amendment response --- .../dao/ApplicationAmendmentRequestDao.java | 34 ++++++++++++------- .../dao/EmailNotificationDao.java | 29 ++++++++++++---- .../ApplicationAmendmentRequestResponse.java | 2 +- .../model/response/EmailContentResponse.java | 10 ++++++ 4 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/EmailContentResponse.java diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 2937da2c..4e56814a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -231,7 +231,7 @@ public class ApplicationAmendmentRequestDao { log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId); - ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity); + ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity,false); log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); if (Boolean.TRUE.equals(applicationAmendmentRequestResponse.getIsSendEmail())) { emailNotificationDao.sendMailToNotifyBeneficiaryRegardingNewAmendment(applicationAmendmentRequestEntity); @@ -362,8 +362,8 @@ public class ApplicationAmendmentRequestDao { return applicationAmendmentRequest; } - public ApplicationAmendmentRequestResponse convertEntityToResponse(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity) { - ApplicationAmendmentRequestResponse response = initializeBasicResponse(applicationAmendmentRequestEntity); + public ApplicationAmendmentRequestResponse convertEntityToResponse(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,boolean includeEmailContent) { + ApplicationAmendmentRequestResponse response = initializeBasicResponse(applicationAmendmentRequestEntity,includeEmailContent); List forms = applicationFormRepository.findByApplicationId(applicationAmendmentRequestEntity.getApplicationId()); Map fieldIdToLabelMap = extractFieldIdToLabelMap(forms); @@ -431,8 +431,12 @@ public class ApplicationAmendmentRequestDao { } - private ApplicationAmendmentRequestResponse initializeBasicResponse(ApplicationAmendmentRequestEntity entity) { + private ApplicationAmendmentRequestResponse initializeBasicResponse(ApplicationAmendmentRequestEntity entity,boolean includeEmailContent) { ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse(); + ApplicationEntity applicationEntity = entity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); + Long hubId = applicationEntity.getHubId(); + HubEntity hubEntity = hubService.valdateHub(hubId); + response.setId(entity.getId()); response.setApplicationId(entity.getApplicationId()); response.setApplicationEvaluationId(entity.getApplicationEvaluationEntity().getId()); @@ -458,6 +462,12 @@ public class ApplicationAmendmentRequestDao { Long protocolNumber = entity.getProtocol() != null ? entity.getProtocol().getProtocolNumber() : null; response.setProtocolNumber(protocolNumber); + if (includeEmailContent) { + Map bodyPlaceholders = emailNotificationDao.prepareEmailPlaceholders(applicationEntity, entity); + EmailContentResponse emailContent = emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, hubEntity, bodyPlaceholders); + String body = emailContent.getBody(); + response.setEmailTemplate(body); + } return response; } @@ -564,7 +574,7 @@ public class ApplicationAmendmentRequestDao { public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(Long id) { log.info("Fetching application amendment with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); - ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity); + ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity,true); log.info("Application Amendment fetched successfully by ID: {}", response); return response; } @@ -581,7 +591,7 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestRepository.findAll(spec); return applicationAmendmentRequestEntities.stream() - .map(this::convertEntityToResponse) + .map(entity -> convertEntityToResponse(entity, false)) .collect(Collectors.toList()); } @@ -641,7 +651,7 @@ public class ApplicationAmendmentRequestDao { setAmendmentDocuments(updateRequest.getAmendmentNotes(),updateRequest.getAmendmentDocuments(), existingApplicationAmendment); } ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE); - ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); + ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false); log.info("Application Amendment updated successfully: {}", response); return response; } @@ -942,7 +952,7 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestRepository.findByUserId(beneficiaryUserId); return entities.stream() - .map(this::convertEntityToResponse) + .map(entity -> convertEntityToResponse(entity, false)) .collect(Collectors.toList()); } @@ -971,7 +981,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment, oldApplicationAmendmentEntity, VersionActionTypeEnum.UPDATE); - ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); + ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false); List amendmentRequests = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( existingApplicationAmendment.getApplicationEvaluationEntity().getId()); @@ -1030,7 +1040,7 @@ public class ApplicationAmendmentRequestDao { /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(applicationAmendmentRequestEntity).build()); } - return convertEntityToResponse(applicationAmendmentRequestEntity); + return convertEntityToResponse(applicationAmendmentRequestEntity,false); } public List getAmendmentByApplicationId(HttpServletRequest request, Long applicationId, List statuses) { @@ -1055,7 +1065,7 @@ public class ApplicationAmendmentRequestDao { List response = new ArrayList<>(); if (applicationAmendmentRequestEntity != null) { response = applicationAmendmentRequestEntity.stream() - .map(this::convertEntityToResponse) + .map(entity -> convertEntityToResponse(entity, false)) .collect(Collectors.toList()); } return response; @@ -1075,7 +1085,7 @@ public class ApplicationAmendmentRequestDao { /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(existingApplicationAmendment).build()); } - ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment); + ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment,false); log.info("Amendment status updated successfully: {}", response); return response; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 42eb2ee0..12d868a5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -8,6 +8,7 @@ import net.gepafin.tendermanagement.enums.RecipientTypeEnum; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; import net.gepafin.tendermanagement.model.response.AmendmentFormFieldResponse; +import net.gepafin.tendermanagement.model.response.EmailContentResponse; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.*; @@ -61,9 +62,6 @@ public class EmailNotificationDao { @Autowired private ApplicationFormRepository applicationFormRepository; - @Autowired - private ApplicationFormFieldRepository applicationFormFieldRepository; - @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; @@ -77,7 +75,19 @@ public class EmailNotificationDao { // String service = determineService(applicationEntity.getHubId()); // String legalMail = service.equals("Gepafin S.p.a.") ? "bandi.gepafin@legalmail.it" : "bandi.sviluppumbria@legalmail.it"; + EmailContentResponse emailContent = prepareEmailContent(applicationEntity, templateType, hubEntity, bodyPlaceholders); + UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); + sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,emailContent.getSystemEmailTemplateResponse(),emailContent.getSubject(),emailContent.getBody()); + } + + public EmailContentResponse prepareEmailContent( + ApplicationEntity applicationEntity, + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, + HubEntity hubEntity, + Map bodyPlaceholders + ) { SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, hubEntity, null); + Map subjectPlaceholders = new HashMap<>(); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); @@ -85,9 +95,10 @@ public class EmailNotificationDao { // bodyPlaceholders.put("{{legal_mail}}", legalMail); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,systemEmailTemplateResponse,subject,body); + + return new EmailContentResponse(subject, body, systemEmailTemplateResponse); } + private void sendEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients,Long amendmentId,SystemEmailTemplateResponse systemEmailTemplateResponse,String subject,String body) { Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); @@ -150,6 +161,11 @@ public class EmailNotificationDao { public void sendMailToNotifyBeneficiaryRegardingNewAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity) { ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequestEntity.getApplicationId()); + Map bodyPlaceholders = prepareEmailPlaceholders(applicationEntity, applicationAmendmentRequestEntity); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null, + applicationAmendmentRequestEntity.getId()); + } + public Map prepareEmailPlaceholders(ApplicationEntity applicationEntity, ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); bodyPlaceholders.put("{{protocol_number}}", applicationEntity.getProtocol().getProtocolNumber().toString()); @@ -185,8 +201,7 @@ public class EmailNotificationDao { bodyPlaceholders.put("{{note}}", applicationAmendmentRequestEntity.getNote()); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null, - applicationAmendmentRequestEntity.getId()); + return bodyPlaceholders; } public List getIdAndLabelFromResult(List> result) { diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index 01390777..0760217b 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -1,7 +1,6 @@ package net.gepafin.tendermanagement.model.response; import lombok.Data; -import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import java.time.LocalDateTime; @@ -31,4 +30,5 @@ public class ApplicationAmendmentRequestResponse { private List commentsList; private String internalNote; private ApplicationAmendmentRequestEnum status; + private String emailTemplate; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/EmailContentResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/EmailContentResponse.java new file mode 100644 index 00000000..dfeaf074 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/EmailContentResponse.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +@Data +public class EmailContentResponse { + private final String subject; + private final String body; + private final SystemEmailTemplateResponse systemEmailTemplateResponse; +} From 58127910147d42d7ef2a2bb2131ac19a922bba0d Mon Sep 17 00:00:00 2001 From: rbonazzo-kz Date: Mon, 30 Dec 2024 09:28:55 +0100 Subject: [PATCH 21/49] Test Change RabbtiMq Address --- mvnw | 2 +- mvnw.cmd | 298 +++++++++--------- src/main/resources/application-dev.properties | 3 +- 3 files changed, 152 insertions(+), 151 deletions(-) mode change 100644 => 100755 mvnw diff --git a/mvnw b/mvnw old mode 100644 new mode 100755 index d7c358e5..19529ddf --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an diff --git a/mvnw.cmd b/mvnw.cmd index 6f779cff..b150b91e 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,149 +1,149 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.2 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' -$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" -if ($env:MAVEN_USER_HOME) { - $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" -} -$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index e211e883..87a38095 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -25,7 +25,8 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=false # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=rabbitmq.bflows.ai +#spring.rabbitmq.host=rabbitmq.bflows.ai +spring.rabbitmq.host=172.18.0.7 spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest From 54a75b6930f0f4135b2ff61f75a8d5b014c7c713 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 30 Dec 2024 14:54:17 +0530 Subject: [PATCH 22/49] Done ticket GEPAFINBE-132 --- .../tendermanagement/web/rest/api/CommunicationApi.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java index a648b08b..e50dae85 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java @@ -33,7 +33,7 @@ public interface CommunicationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "/{amendmentId}", produces = { "application/json" }) - @PreAuthorize("hasRole('ROLE_PRE_INSTRUCTOR') || hasRole('ROLE_BENEFICIARY')") + @PreAuthorize("hasRole('ROLE_PRE_INSTRUCTOR') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_INSTRUCTOR_MANAGER')") ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, @RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @PathVariable(value = "amendmentId") Long amendmentId); @@ -55,7 +55,7 @@ public interface CommunicationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{amendmentId}/{commentId}", produces = { "application/json" }) - @PreAuthorize("hasRole('ROLE_PRE_INSTRUCTOR') || hasRole('ROLE_BENEFICIARY')") + @PreAuthorize("hasRole('ROLE_PRE_INSTRUCTOR') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_INSTRUCTOR_MANAGER')") ResponseEntity> updateCommunicationAmendment(HttpServletRequest request, @RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @PathVariable(value = "amendmentId") Long amendmentId, @PathVariable(value = "commentId") Long commentId); From 8fba9a1c81cd6bec2a255da6fa5a9eb84c5d9270 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 30 Dec 2024 15:25:32 +0530 Subject: [PATCH 23/49] Added Read/Unread filter in notification API. --- .../tendermanagement/dao/NotificationDao.java | 27 ++++++++++++------- .../service/NotificationService.java | 2 +- .../service/impl/NotificationServiceImpl.java | 4 +-- .../web/rest/api/NotificationApi.java | 7 ++--- .../api/impl/NotificationApiController.java | 4 +-- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 64db69ca..eb74d57e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -253,19 +253,26 @@ public class NotificationDao { notificationRepository.save(notificationEntity); } - public List getNotificationByCompanyIdAndUserId(Long userId, Long companyId) { + public List getNotificationByCompanyIdAndUserId(Long userId, Long companyId, List statuses) { - companyDao.validateCompany(companyId); - userDao.validateUser(userId); - - UserWithCompanyEntity userWithCompanyData = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalseForNotification(userId, companyId); - if (userWithCompanyData == null) { - throw new CustomValidationException(Status.BAD_REQUEST, GepafinConstant.USER_MUST_BE_ASSOCIATED_WITH_COMPANY); + List notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalse(userId); + UserWithCompanyEntity userWithCompany = null; + List statusStrings; + if (companyId != null) { + userWithCompany = companyDao.validateUserWithCompny(userId, companyId); } - List notifications = notificationRepository.findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(userWithCompanyData.getId(), - userWithCompanyData.getUserId()); - return notifications.stream().map(this::convertNotificationEntityToNotificationResponse).toList(); + if (statuses != null) { + statusStrings = statuses.stream().map(NotificationEnum::name) + .toList(); + notificationEntities = notificationRepository.findByUserIdAndIsDeletedFalseAndStatusIn(userId, statusStrings); + + if (userWithCompany != null) { + notificationEntities = notificationRepository.findByUserIdAndUserWithCompanyIdAndIsDeletedFalseAndStatusIn(userId, userWithCompany.getId(), statusStrings); + } + } + + return notificationEntities.stream().map(this::convertNotificationEntityToNotificationResponse).toList(); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java index 4d5d3ba6..ca5927c0 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/NotificationService.java @@ -18,6 +18,6 @@ public interface NotificationService { public void deleteNotification(HttpServletRequest request, Long id); - public List getNotificationsByCompanyIdAndUserId(Long userId, Long companyId); + public List getNotificationsByCompanyIdAndUserId(Long userId, Long companyId, List statuses); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java index 9fa0956a..86eaa5cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/NotificationServiceImpl.java @@ -56,7 +56,7 @@ public class NotificationServiceImpl implements NotificationService { } @Override - public List getNotificationsByCompanyIdAndUserId(Long userId, Long companyId) { - return notificationDao.getNotificationByCompanyIdAndUserId(userId, companyId); + public List getNotificationsByCompanyIdAndUserId(Long userId, Long companyId, List statuses) { + return notificationDao.getNotificationByCompanyIdAndUserId(userId, companyId, statuses); } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java index 6f46244b..ca059499 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/NotificationApi.java @@ -33,8 +33,8 @@ public interface NotificationApi { ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) }) @PostMapping(value = "/user/{userId}/sent", consumes = "application/json", produces = "application/json") ResponseEntity> sendNotification(HttpServletRequest request, @RequestBody NotificationReq notificationReq, - @Parameter(description = "The company id", required = false) @RequestParam(value = "companyId", required = false) Long companyId, - @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId); + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, + @Parameter(description = "The company id", required = false) @RequestParam(value = "companyId", required = false) Long companyId); @Operation(summary = "Api to get notification by id", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @@ -93,7 +93,8 @@ public interface NotificationApi { @GetMapping(value = "/user/{userId}/company/{companyId}/notifications", produces = "application/json") ResponseEntity>> getNotificationsByUserIdAndCompanyId(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable(value = "userId") Long userId, - @Parameter(description = "The company ID", required = true) @PathVariable(value = "companyId") Long companyId); + @Parameter(description = "The company ID", required = true) @PathVariable(value = "companyId") Long companyId, + @Parameter(description = "The notification status", required = false) @RequestParam(value = "status", required = false) List statuses); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java index 586a5f9e..d2047d7a 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/NotificationApiController.java @@ -65,8 +65,8 @@ public class NotificationApiController implements NotificationApi { } @Override - public ResponseEntity>> getNotificationsByUserIdAndCompanyId(HttpServletRequest request,Long userId, Long companyId) { - List notificationResponses = notificationService.getNotificationsByCompanyIdAndUserId(userId, companyId); + public ResponseEntity>> getNotificationsByUserIdAndCompanyId(HttpServletRequest request,Long userId, Long companyId, List statuses) { + List notificationResponses = notificationService.getNotificationsByCompanyIdAndUserId(userId, companyId, statuses); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(notificationResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.NOTIFICATION_FETCHED_SUCCESSFULLY))); } From 9e002ee9dba4656eb2165b2a24d5dbe7a16e5589 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 30 Dec 2024 15:45:16 +0530 Subject: [PATCH 24/49] Fixed notification issue in updating application status. --- .../net/gepafin/tendermanagement/dao/NotificationDao.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index eb74d57e..9acacdb0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -177,7 +177,7 @@ public class NotificationDao { ApplicationEntity application = applicationService.validateApplication(applicationEvaluationEntity.getApplicationId()); if (instructorId != null) { NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, instructorId, application.getUserWithCompany(), - listOf(application.getCompanyId())); + null); sendNotification(notificationreq); } } @@ -187,7 +187,7 @@ public class NotificationDao { UserEntity userEntity1 = user.get(0); if (userEntity1 != null) { NotificationReq notificationreq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, userEntity1.getId(), application.getUserWithCompany(), - listOf(application.getCompanyId())); + null); sendNotification(notificationreq); } } From 33fb2d70919d9620d7256b36eae03808d2799048 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 30 Dec 2024 19:44:20 +0530 Subject: [PATCH 25/49] Added folder structured documents in download Zip API. --- .../tendermanagement/dao/ApplicationDao.java | 123 ++++++++++++------ .../repositories/DocumentRepository.java | 2 + 2 files changed, 82 insertions(+), 43 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 621fea19..0c56fb16 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -172,6 +172,12 @@ public class ApplicationDao { @Autowired private RoleRepository roleRepository; + @Autowired + private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); // callService.validatePublishedCall(formEntity.getCall().getId()); @@ -1225,90 +1231,121 @@ public class ApplicationDao { } public byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) { + ApplicationEntity applicationEntity = validateApplication(applicationId); validateAssignedUser(request, applicationId); - Set documentIds = extractDocumentIdsFromApplicationForms(applicationId); List documents = documentRepository.findAllByIdInAndIsDeletedFalse(documentIds); - - ApplicationSignedDocumentEntity signedDocument = applicationSignedDocumentRepository - .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); - if (documents.isEmpty() && signedDocument == null) { + ApplicationSignedDocumentEntity signedDocument = applicationSignedDocumentRepository.findByApplicationIdAndStatus(applicationId, + ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + List amendmentDocuments = fetchAmendmentDocuments(applicationId); + List evaluationDocuments = fetchEvaluationDocuments(applicationId); + if (documents.isEmpty() && signedDocument == null && amendmentDocuments.isEmpty() && evaluationDocuments.isEmpty()) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } - return createZipWithDocuments(applicationEntity, documents, signedDocument, applicationId); + return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId); } + private void validateAssignedUser(HttpServletRequest request, Long applicationId) { - AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository - .findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); + + AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); if (assignedApplications != null) { validator.validatePreInstructor(request, assignedApplications.getUserId()); } } private Set extractDocumentIdsFromApplicationForms(Long applicationId) { + Set documentIds = new HashSet<>(); List applicationForms = applicationFormRepository.findByApplicationId(applicationId); - applicationForms.forEach(applicationForm -> { FormEntity formEntity = applicationForm.getForm(); if (formEntity != null) { List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); - contentResponseBeans.stream() - .filter(content -> "fileupload".equals(content.getName())) - .forEach(content -> { - Optional formField = applicationFormFieldRepository - .findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId( - content.getId(), applicationForm.getId(), applicationId); - formField.ifPresent(field -> { - if (field.getFieldValue() != null) { - Arrays.stream(field.getFieldValue().split(",")) - .map(String::trim) - .map(Long::valueOf) - .forEach(documentIds::add); - } - }); - }); + contentResponseBeans.stream().filter(content -> "fileupload".equals(content.getName())).forEach(content -> { + Optional formField = applicationFormFieldRepository.findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId( + content.getId(), applicationForm.getId(), applicationId); + formField.ifPresent(field -> { + if (field.getFieldValue() != null) { + Arrays.stream(field.getFieldValue().split(",")).map(String::trim).map(Long::valueOf).forEach(documentIds::add); + } + }); + }); } }); return documentIds; } - private void addDocumentToZip(ZipOutputStream zos, String s3Folder, String filePath, String fileName) { + private List fetchAmendmentDocuments(Long 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) { + + Optional evaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + if (evaluationEntity.isPresent()) { + Long evaluationId = evaluationEntity.get().getId(); + return documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(Collections.singleton(evaluationId), DocumentSourceTypeEnum.EVALUATION.getValue()); + } + return Collections.emptyList(); + } + private String fetchProtocolNumberForAmendment(Long amendmentRequestId) { + + ApplicationAmendmentRequestEntity amendmentRequest = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentRequestId).orElse(null); + if (amendmentRequest != null && amendmentRequest.getProtocol() != null) { + return amendmentRequest.getProtocol().getProtocolNumber().toString(); + } + return "unknown"; + } + private void addDocumentToZip(ZipOutputStream zos, String s3Folder, String filePath, String fullPath) { + try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, filePath)) { - zos.putNextEntry(new ZipEntry(fileName)); + zos.putNextEntry(new ZipEntry(fullPath)); IOUtils.copy(fileInputStream, zos); zos.closeEntry(); } catch (IOException e) { - throw new RuntimeException("Error downloading or adding document to ZIP: " + fileName, e); + throw new RuntimeException("Error downloading or adding document to ZIP: " + fullPath, e); } } + private byte[] createZipWithDocuments(ApplicationEntity applicationEntity, List documents, ApplicationSignedDocumentEntity signedDocument, + List amendmentDocuments, List evaluationDocuments, Long applicationId) { - private byte[] createZipWithDocuments(ApplicationEntity applicationEntity, List documents, - ApplicationSignedDocumentEntity signedDocument, Long applicationId) { - try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); - ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { - - String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, applicationEntity.getCall().getId(), applicationId,0L); - + try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { + Long callId = applicationEntity.getCall().getId(); + // Add Application Documents + String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L); for (DocumentEntity document : documents) { String fileName = Utils.extractFileName(document.getFilePath()); - addDocumentToZip(zos, s3Folder, document.getFilePath(), fileName); + addDocumentToZip(zos, appS3Folder, document.getFilePath(), fileName); } - + // Add Signed Document if (signedDocument != null) { - String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, applicationEntity.getCall().getId(), applicationId,0L); - String signedDocFileName = signedDocument.getFileName(); - addDocumentToZip(zos, signedDocS3Folder, signedDocument.getFilePath(), signedDocFileName); + String signedFolder = "SIGNED_DOCUMENT/"; + String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L); + String fileName = signedDocument.getFileName(); + addDocumentToZip(zos, signedDocS3Folder, signedDocument.getFilePath(), signedFolder + fileName); + } + // Add Amendment (Soccorso) Documents + for (DocumentEntity amendmentDocument : amendmentDocuments) { + String protocolNumber = fetchProtocolNumberForAmendment(amendmentDocument.getSourceId()); + String amendmentFolder = "SOCCORSO_" + protocolNumber + "/"; + String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId()); + String fileName = Utils.extractFileName(amendmentDocument.getFilePath()); + addDocumentToZip(zos, amendmentS3Folder, amendmentDocument.getFilePath(), amendmentFolder + fileName); + } + // Add Evaluation Documents + for (DocumentEntity evaluationDocument : evaluationDocuments) { + String evaluationFolder = "EVALUATION/"; + String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId()); + String fileName = Utils.extractFileName(evaluationDocument.getFilePath()); + addDocumentToZip(zos, evaluationS3Folder, evaluationDocument.getFilePath(), evaluationFolder + fileName); } - zos.finish(); return zipOutputStream.toByteArray(); - } catch (IOException e) { throw new RuntimeException("Error while creating ZIP file", e); } } - - } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java index 9e808114..0ca46f8e 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java @@ -33,5 +33,7 @@ public interface DocumentRepository extends JpaRepository List findAllByIsDeleteTrue(); List findAllByIdInAndIsDeletedFalse(Set documentIds); + + List findBySourceIdInAndSourceAndIsDeletedFalse(Set sourceId, String type); } From aaa0d2ccf752a8beaa8c2c2798a8bc76b898a10d Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 31 Dec 2024 12:49:15 +0530 Subject: [PATCH 26/49] Updated code --- .../tendermanagement/dao/ApplicationEvaluationDao.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 5a67b2ae..5992314b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -594,7 +594,7 @@ public class ApplicationEvaluationDao { Optional assignedApplications = assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationId); ApplicationEvaluationEntity oldApplicationEvaluation = null; - VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; + VersionActionTypeEnum actionType; if (existingEntityOptional.isPresent()) { entity = existingEntityOptional.get(); oldApplicationEvaluation = Utils.getClonedEntityForData(entity); @@ -612,7 +612,8 @@ public class ApplicationEvaluationDao { setIfUpdated(entity::getMotivation, entity::setMotivation, req.getMotivation()); actionType = VersionActionTypeEnum.UPDATE; } else { - ApplicationEntity application=entity.getAssignedApplicationsEntity().getApplication(); + AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); + ApplicationEntity application = applicationService.validateApplication(assignedApplicationsEntity.getApplication().getId()); entity = convertToEntity(user, req, assignedApplicationId); actionType = VersionActionTypeEnum.INSERT; From 6268c2e4180f7a8cdab34aa2db01553ab1deb829 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 31 Dec 2024 14:49:33 +0530 Subject: [PATCH 27/49] Updatd Notification title and template. --- .../db/changelog/db.changelog-1.0.0.xml | 5 ++ ...n_template_for_notification_31_12_2024.sql | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/main/resources/db/dump/update_json_template_for_notification_31_12_2024.sql 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 0fdebf9e..f7ada723 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 @@ -2123,4 +2123,9 @@ + + + + diff --git a/src/main/resources/db/dump/update_json_template_for_notification_31_12_2024.sql b/src/main/resources/db/dump/update_json_template_for_notification_31_12_2024.sql new file mode 100644 index 00000000..57a01984 --- /dev/null +++ b/src/main/resources/db/dump/update_json_template_for_notification_31_12_2024.sql @@ -0,0 +1,62 @@ +UPDATE notification_type +SET + title = 'Un Nuovo Bando È Stato Pubblicato', + json_template = 'Un nuovo bando intitolato {{call_name}} è stato pubblicato. Controllalo e invia le candidature prima della scadenza.' +WHERE + notification_name = 'CALL_CREATED'; + +UPDATE notification_type +SET + title = 'Richiesta Finanziamento Inviata con Successo per la Valutazione', + json_template = 'La richiesta per {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stata presentata con successo. È ora in fase di valutazione.' +WHERE + notification_name = 'APPLICATION_SUBMISSION'; + +UPDATE notification_type +SET + title = 'È Stato Creato un Soccorso Istruttorio per la Richiesta', + json_template = 'È stato creato un soccorso istruttorio per la richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}}. Esamina le richieste e procedi di conseguenza.' +WHERE + notification_name = 'AMENDMENT_CREATION'; + +UPDATE notification_type +SET + title = 'Il Risultato della Valutazione per la Richiesta È Disponibile', + json_template = 'Il risultato della valutazione per la richiesta ai sensi del protocollo n. {{protocol_number}} è ora disponibile.' +WHERE + notification_name = 'EVALUATION_RESULT'; + +UPDATE notification_type +SET + title = 'Soccorso Scaduto', + json_template = 'Il soccorso istruttorio per la richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}} è scaduto.' +WHERE + notification_name = 'AMENDMENT_EXPIRED'; + +UPDATE notification_type +SET + title = 'Scorso Chiuso ed È Ora Inattivo', + json_template = 'Il soccorso istruttorio per {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stato chiuso ed è ora inattivo.' +WHERE + notification_name = 'AMENDMENT_CLOSED'; + +UPDATE notification_type +SET + title = 'NDG creato per la Richiesta', + json_template = 'È stato generato un nuovo NDG per {{call_name}} ai sensi del protocollo n. {{protocol_number}}.' +WHERE + notification_name = 'NDG_GENERATION'; + +UPDATE notification_type +SET + title = 'La domanda è stata assegnata per la Valutazione', + json_template = 'La richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}} è stata assegnata alla fase di valutazione.' +WHERE + notification_name = 'EVALUATION_CREATION'; + +UPDATE notification_type +SET + title = 'La Valutazione per la Richiesta È Scaduta', + json_template = 'La valutazione per la richiesta in {{call_name}} ai sensi del protocollo n. {{protocol_number}} è scaduta.' +WHERE + notification_name = 'EVALUATION_EXPIRED'; From 89bff4d79926029cbb54180067e40d4fe71ccec3 Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 31 Dec 2024 15:44:06 +0530 Subject: [PATCH 28/49] updated code --- .../db/changelog/db.changelog-1.0.0.xml | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) 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 28ea5c6d..cf3c3987 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 @@ -1970,19 +1970,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + From e2d78dbba28c8a1725b91cf4d6ab51ba0cb4b29e Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 31 Dec 2024 16:00:39 +0530 Subject: [PATCH 29/49] updated code --- .../gepafin/tendermanagement/entities/CompanyEntity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java index 8d5e3f34..e7aa0f40 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java @@ -51,9 +51,9 @@ public class CompanyEntity extends BaseEntity{ @JoinColumn(name = "HUB_ID") private HubEntity hub; - @Column(name = "JSON") - private String json; - +// @Column(name = "JSON") +// private String json; + @Column(name = "NDG") private String ndg; } From 178d36ab42259d41b3bba629111de450a5b4e7b6 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Thu, 2 Jan 2025 12:20:34 +0530 Subject: [PATCH 30/49] Done ticket GEPAFINBE-131 --- .../gepafin/tendermanagement/dao/UserDao.java | 18 +++++++++++------- .../tendermanagement/web/rest/api/UserApi.java | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 7e35957b..e37873f3 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -219,7 +219,7 @@ public class UserDao { log.info("Current user details: {}", userEntity); log.info("New user details: {}", userReq); String newStatus = userReq.getStatus() != null ? userReq.getStatus().getValue() : null; - if (Boolean.FALSE.equals(userEntity.getStatus().equals(newStatus))) { + if (newStatus!=null && Boolean.FALSE.equals(userEntity.getStatus().equals(newStatus))) { userEntity.setStatus(newStatus); } setIfUpdated(userEntity::getFirstName, userEntity::setFirstName, userReq.getFirstName()); @@ -228,15 +228,19 @@ public class UserDao { setIfUpdated(userEntity::getAddress, userEntity::setAddress, userReq.getAddress()); setIfUpdated(userEntity::getPhoneNumber, userEntity::setPhoneNumber, userReq.getPhoneNumber()); setIfUpdated(userEntity::getDateOfBirth, userEntity::setDateOfBirth, userReq.getDateOfBirth()); - setIfUpdated(userEntity.getBeneficiary()::getCodiceFiscale, userEntity.getBeneficiary()::setCodiceFiscale, userReq.getCodiceFiscale()); - setIfUpdated(userEntity.getBeneficiary()::getMarketing, userEntity.getBeneficiary()::setMarketing, userReq.getMarketing()); - setIfUpdated(userEntity.getBeneficiary()::getOffers, userEntity.getBeneficiary()::setOffers, userReq.getOffers()); - setIfUpdated(userEntity.getBeneficiary()::getThirdParty, userEntity.getBeneficiary()::setThirdParty, userReq.getThirdParty()); if (userReq.getRoleId() != null) { RoleEntity roleEntity = roleDao.validateRole(userReq.getRoleId()); - setIfUpdated(userEntity::getRoleEntity, userEntity::setRoleEntity, roleEntity); + if((userEntity.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_INSTRUCTOR_MANAGER.getValue()) && roleEntity.getRoleType().equals(RoleStatusEnum.ROLE_PRE_INSTRUCTOR.getValue())) || (userEntity.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_PRE_INSTRUCTOR.getValue()) && roleEntity.getRoleType().equals(RoleStatusEnum.ROLE_INSTRUCTOR_MANAGER.getValue()))) { + setIfUpdated(userEntity::getRoleEntity, userEntity::setRoleEntity, roleEntity); + } + } + if(userEntity.getBeneficiary()!=null) { + setIfUpdated(userEntity.getBeneficiary()::getCodiceFiscale, userEntity.getBeneficiary()::setCodiceFiscale, userReq.getCodiceFiscale()); + setIfUpdated(userEntity.getBeneficiary()::getMarketing, userEntity.getBeneficiary()::setMarketing, userReq.getMarketing()); + setIfUpdated(userEntity.getBeneficiary()::getOffers, userEntity.getBeneficiary()::setOffers, userReq.getOffers()); + setIfUpdated(userEntity.getBeneficiary()::getThirdParty, userEntity.getBeneficiary()::setThirdParty, userReq.getThirdParty()); + setIfUpdated(userEntity.getBeneficiary()::getEmailPec, userEntity.getBeneficiary()::setEmailPec, userReq.getEmailPec()); } - setIfUpdated(userEntity.getBeneficiary()::getEmailPec, userEntity.getBeneficiary()::setEmailPec, userReq.getEmailPec()); userEntity = userRepository.save(userEntity); /** This code is responsible for adding a version history log for the "Update user details" operation **/ diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index 86122344..f2010e90 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -59,6 +59,7 @@ public interface UserApi { @RequestMapping(value = "/{userId}", produces = {"application/json"}, method = RequestMethod.PUT) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") default ResponseEntity> updateUser(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, @Parameter(description = "User request object", required = true) @Valid @RequestBody UpdateUserReq userReq) { From 252a019d5f839108a403bca69c747ada387271e4 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 2 Jan 2025 15:08:20 +0530 Subject: [PATCH 31/49] Changes in beneficiary dashboard api --- .../tendermanagement/dao/DashboardDao.java | 38 ++++++++++++------- .../repositories/CallRepository.java | 2 + 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java index 0afc8fc8..c87c863a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java @@ -1,23 +1,20 @@ package net.gepafin.tendermanagement.dao; -import net.gepafin.tendermanagement.entities.CompanyEntity; -import net.gepafin.tendermanagement.entities.UserEntity; -import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; +import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.Widget1; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.repositories.CallRepository; -import net.gepafin.tendermanagement.repositories.CompanyRepository; -import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.CompanyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; +import java.util.List; +import java.util.stream.Collectors; @Component public class DashboardDao { @@ -33,9 +30,12 @@ public class DashboardDao { @Autowired private CompanyRepository companyRepository; - + @Autowired private CompanyService companyService; + @Autowired + private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository; + public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) { SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean(); @@ -106,14 +106,26 @@ public class DashboardDao { } public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(UserEntity userEntity, - CompanyEntity company) { + CompanyEntity company) { BeneficiaryWidgetResponseBean beneficiaryWidgetResponseBean = BeneficiaryWidgetResponseBean.builder() .numberOfApplications(0L).numberOfCalls(0L).numberOfIntegratedDocuments(0L).build(); - Long activeCalls = callRepository.countByStatusAndHubId(CallStatusEnum.PUBLISH.getValue(), userEntity.getHub().getId()); - if (activeCalls != null) { - beneficiaryWidgetResponseBean.setNumberOfCalls(activeCalls); + UserWithCompanyEntity userWithCompanyEntity = companyService.getUserWithCompany(userEntity.getId(), company.getId()); + + List preferredCalls = beneficiaryPreferredCallRepository + .findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(userEntity.getId(), userWithCompanyEntity.getId()); + + if (preferredCalls != null && !preferredCalls.isEmpty()) { + List callIds = preferredCalls.stream() + .map(BeneficiaryPreferredCallEntity::getCallId) + .collect(Collectors.toList()); + List callEntities = callRepository.findByIdIn(callIds); + long activeCallsCount = callEntities.stream() + .filter(call -> CallStatusEnum.PUBLISH.getValue().equals(call.getStatus()) + && userEntity.getHub().getId().equals(call.getHub().getId())) + .count(); + + beneficiaryWidgetResponseBean.setNumberOfCalls(activeCallsCount); } - UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),company.getId()); Long activeApplication = applicationRepository.countSubmittedApplicationsByUserId(userEntity.getId(), userWithCompanyEntity.getId()); if (activeApplication != null) { diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java index 833e1d68..938f19f6 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java @@ -47,4 +47,6 @@ public interface CallRepository extends JpaRepository { BigDecimal findTotalAmountOfPublishedCallsAndHubId(@Param("hubId") Long hubId); @Query("SELECT c FROM CallEntity c WHERE c.id IN :ids AND c.status IN :status") List findByIdInAndStatusIn(@Param("ids") List ids, @Param("status") List status); + List findByIdIn(@Param("ids") List ids); + } From ab1afaf90aab375fdb9d31380813581160db80ff Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 2 Jan 2025 17:36:05 +0530 Subject: [PATCH 32/49] Updated code --- .../gepafin/tendermanagement/dao/UserDao.java | 20 ++++++----- .../repositories/UserRepository.java | 34 +++++++++++-------- ...template_for_reset_password_28_11_2024.sql | 7 +--- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 6622ca95..1c06ccaf 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -222,21 +222,23 @@ public class UserDao { } } } + private void validateDuplicateEmail(String email, String hubUuid, String roleType) { - Boolean existsForNonBeneficiaries = userRepository.existsByEmailIgnoreCaseForNonBeneficiaries( - email, hubUuid, RoleStatusEnum.ROLE_BENEFICIARY.getValue()); + String beneficiaryRoleType = RoleStatusEnum.ROLE_BENEFICIARY.getValue(); - Boolean beneficiaryExistsInHub = userRepository.existsByEmailIgnoreCaseForBeneficiaries( - email, hubUuid, RoleStatusEnum.ROLE_BENEFICIARY.getValue()); + if (beneficiaryRoleType.equals(roleType)) { + Boolean beneficiaryExistsInHub = userRepository.existsByEmailIgnoreCaseForBeneficiaries( + email, hubUuid, beneficiaryRoleType); - if (Boolean.TRUE.equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleType))) { - if (beneficiaryExistsInHub) { + if (Boolean.TRUE.equals(beneficiaryExistsInHub)) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); } - } - else { - if (existsForNonBeneficiaries) { + } else { + Boolean existsForNonBeneficiaries = userRepository.existsByEmailIgnoreCaseForNonBeneficiaries( + email, hubUuid, beneficiaryRoleType); + + if (Boolean.TRUE.equals(existsForNonBeneficiaries)) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java index ae41b9b1..ab00d3e0 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java @@ -33,24 +33,28 @@ public interface UserRepository extends JpaRepository { Optional findByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); - Boolean existsByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); +// Boolean existsByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); - @Query("SELECT COUNT(u) > 0 " + - "FROM UserEntity u " + - "WHERE u.email = :email " + - "AND u.hub.uniqueUuid = :hubUuid " + - "AND u.roleEntity.roleType <> :beneficiaryRoleType") - Boolean existsByEmailIgnoreCaseForNonBeneficiaries(@Param("email") String email, - @Param("hubUuid") String hubUuid, - @Param("beneficiaryRoleType") String beneficiaryRoleType); + @Query("SELECT COUNT(u) > 0 " + + "FROM UserEntity u " + + "WHERE LOWER(u.email) = LOWER(:email) " + + "AND u.hub.uniqueUuid = :hubUuid " + + "AND u.roleEntity.roleType <> :beneficiaryRoleType") + Boolean existsByEmailIgnoreCaseForNonBeneficiaries(@Param("email") String email, + @Param("hubUuid") String hubUuid, + @Param("beneficiaryRoleType") String beneficiaryRoleType); - @Query("SELECT CASE WHEN COUNT(u) > 0 THEN true ELSE false END " + - "FROM UserEntity u " + - "WHERE LOWER(u.email) = LOWER(:email) AND u.hub.uniqueUuid = :hubUuid " + - "AND u.roleEntity.roleType = :beneficiaryRoleType") - Boolean existsByEmailIgnoreCaseForBeneficiaries(String email, String hubUuid, String beneficiaryRoleType); + @Query("SELECT COUNT(u) > 0 " + + "FROM UserEntity u " + + "WHERE LOWER(u.email) = LOWER(:email) " + + "AND u.hub.uniqueUuid = :hubUuid " + + "AND u.roleEntity.roleType = :beneficiaryRoleType") + Boolean existsByEmailIgnoreCaseForBeneficiaries(@Param("email") String email, + @Param("hubUuid") String hubUuid, + @Param("beneficiaryRoleType") String beneficiaryRoleType); - // existsByBebooleanneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); + + boolean existsByBeneficiaryCodiceFiscaleAndHubId(String codiceFiscale, Long hubId); List findByRoleEntity_RoleTypeAndHubId(String roleType, Long hubId); diff --git a/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql b/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql index facb4fdf..927345b0 100644 --- a/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql +++ b/src/main/resources/db/dump/insert_system_email_template_for_reset_password_28_11_2024.sql @@ -20,12 +20,7 @@ VALUES

Gentile {{user_name}},

-

Hai richiesto di reimpostare la tua password. Puoi farlo cliccando sul link sottostante:

- - - - - {{reset_password_link}} +

Hai richiesto di reimpostare la tua password.

From 3a7ca2b2224b083ffa30956a60fb7b030d00626c Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 2 Jan 2025 19:22:58 +0530 Subject: [PATCH 33/49] Updated code --- .../tendermanagement/dao/CompanyDao.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 48ec017b..6c5f0856 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -189,15 +189,15 @@ public class CompanyDao { setIfUpdated(companyEntity::getCountry, companyEntity::setCountry, companyRequest.getCountry()); setIfUpdated(companyEntity::getNumberOfEmployees, companyEntity::setNumberOfEmployees, companyRequest.getNumberOfEmployees()); setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, companyRequest.getAnnualRevenue()); - - if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { - CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); - if(existingCompany!=null){ - throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); - } - companyEntity.setVatNumber(companyRequest.getVatNumber()); - - } +// +// if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { +// CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); +// if(existingCompany!=null){ +// throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); +// } +// companyEntity.setVatNumber(companyRequest.getVatNumber()); +// +// } companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for the "Update company" operation. **/ From 0445a371333cbb0128173f2300bcbd0f094893fb Mon Sep 17 00:00:00 2001 From: nisha Date: Fri, 3 Jan 2025 13:15:07 +0530 Subject: [PATCH 34/49] Updated form field data --- .../db/changelog/db.changelog-1.0.0.xml | 7 ++ .../update_form_field_data_03_01_2025.sql | 101 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/main/resources/db/dump/update_form_field_data_03_01_2025.sql 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 cf3c3987..1a25de27 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 @@ -2139,5 +2139,12 @@
+ + + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; + + + diff --git a/src/main/resources/db/dump/update_form_field_data_03_01_2025.sql b/src/main/resources/db/dump/update_form_field_data_03_01_2025.sql new file mode 100644 index 00000000..c3c08ca7 --- /dev/null +++ b/src/main/resources/db/dump/update_form_field_data_03_01_2025.sql @@ -0,0 +1,101 @@ +INSERT INTO FORM_FIELD (SORT_ORDER, NAME, LABEL, DESCRIPTION, SETTINGS, VALIDATORS, CREATED_DATE, UPDATED_DATE) +VALUES +(1, 'textinput', 'Testo Breve', 'Per risposte concise (nomi, titoli, brevi descrizioni)', + '[{"name": "label", "value": "Testo Breve"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "minLength": null, "maxLength": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(2, 'textarea', 'Testo Lungo', 'Campo di testo esteso per paragrafi, descrizioni, proposte', + '[{"name": "label", "value": "Testo Lungo"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "minLength": null, "maxLength": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(3, 'wysiwyg', 'Campo di Testo Formattato', 'Editor avanzato per testo con formattazione', + '[{"name": "label", "value": "Testo Formattato"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "minLength": null, "maxLength": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(4, 'numberinput', 'Campo Numerico', 'Per l''inserimento di valori numerici (quantità, importi, percentuali)', + '[{"name": "label", "value": "Numero"}, {"name": "placeholder", "value": "0"}, {"name": "step", "value": "0"},{"name": "isRequestedAmount","value": false}]', + '{"isRequired": false, "min": null, "max": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(5, 'radio', 'Scelta Singola', 'Gruppo di opzioni per selezione singola', + '[{"name": "label", "value": "Scelta Singola"}, {"name": "options", "value": []}]', + '{"isRequired": false, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(6, 'select', 'Menu a Tendina', 'Selezione da opzioni predefinite', + '[{"name": "label", "value": "Menu a Tendina"}, {"name": "options", "value": []}]', + '{"isRequired": false, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(7, 'checkboxes', 'Scelta Multipla', 'Gruppo di opzioni per selezione singola o multipla', + '[{"name": "label", "value": "Scelta Multipla"}, {"name": "options", "value": []}]', + '{"isRequired": false, "min": null, "max": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(8, 'switch', 'Casella di Spunta', 'Per selezioni binarie, accettazioni, conferme', + '[{"name": "label", "value": "Casella di Spunta"}]', + '{"isRequired": false}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(9, 'datepicker', 'Data', 'Selezione di data', + '[{"name": "label", "value": "Data"}]', + '{"isRequired": false}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(10, 'fileupload', 'Caricamento File', 'Per l''upload di documenti o immagini', + '[{"name": "label", "value": "Caricamento File"}, {"name": "mime", "value": []}]', + '{"isRequired": false, "maxSize": 100000}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(11, 'textinput', 'Campo Partita IVA', 'Specifico per l''inserimento del numero di Partita IVA', + '[{"name": "label", "value": "Partita IVA"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isPIVA"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(12, 'textinput', 'Campo Codice Fiscale','Specifico per l''inserimento del Codice Fiscale italiano per persone fisiche e giuridiche', + '[{"name": "label", "value": "Codice Fiscale"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isCodiceFiscale"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(13, 'textinput', 'Campo CAP','Per l''inserimento del Codice di Avviamento Postale', + '[{"name": "label", "value": "CAP"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isCAP"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(14, 'textinput', 'Campo IBAN', 'Per l''inserimento del codice IBAN', + '[{"name": "label", "value": "IBAN"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isIBAN"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(15, 'textinput', 'Campo Email', 'Per l''inserimento di indirizzi email standard (non PEC)', + '[{"name": "label", "value": "Campo Email"}, {"name": "placeholder", "value": "nome@esempio.it"}]', + '{"isRequired": false, "custom": "isEmail"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(16, 'textinput', 'Campo PEC', 'Specifico per l''inserimento di un indirizzo di Posta Elettronica Certificata', + '[{"name": "label", "value": "Campo PEC"}, {"name": "placeholder", "value": "nome@pec.it"}]', + '{"isRequired": false, "custom": "isEmailPEC"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(17, 'textinput', 'Campo URL', 'Per l''inserimento di indirizzi web', + '[{"name": "label", "value": "Indirizzo URL"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "custom": "isUrl"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(18, 'textinput', 'Marca da bollo', 'Per inserire codice di marca da bollo', + '[{"name": "label", "value": "Marca da bollo"}, {"name": "placeholder", "value": "Numero identificativo"}]', + '{"isRequired": false, "custom": "isMarcaDaBollo"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(19, 'paragraph', 'Paragrafo', 'Semplice testo formattato', + '[{"name": "text", "value": ""}]', + '{}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(20, 'table', 'Tabella', 'Tabella', + '[{"name": "label", "value": "Tabella"}, {"name": "table_columns", "value": []}]', + '{}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); From dd5cf63a16d2a2647f55d0d0f109bb9e415f58ed Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 3 Jan 2025 15:12:44 +0530 Subject: [PATCH 35/49] Websocket config fix. --- .../gepafin/tendermanagement/TendermanagementApplication.java | 3 ++- .../net/gepafin/tendermanagement/config/WebSocketConfig.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java index c220b176..6cdd9142 100644 --- a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java +++ b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java @@ -23,7 +23,8 @@ public class TendermanagementApplication { @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**").allowedOrigins("http://localhost:3000").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD").allowCredentials(true); + registry.addMapping("/**").allowedOrigins("http://localhost:3000", "http://127.0.0.1:5500", "https://bandi-staging.memento.credit", "https://bandi.gepafin.it") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD").allowCredentials(true); } } diff --git a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java index 1b90a882..0212f720 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/WebSocketConfig.java @@ -33,7 +33,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/wss").setAllowedOrigins("http://localhost:3000", "http://127.0.0.1:5500/", "https://bandi-staging.memento.credit/**", "https://bandi.gepafin.it/**") + registry.addEndpoint("/wss").setAllowedOrigins("http://localhost:3000", "http://127.0.0.1:5500", "https://bandi-staging.memento.credit", "https://bandi.gepafin.it") .withSockJS(); } } From c687849c933898647988687bccd5c1cf52f06d55 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 3 Jan 2025 19:17:11 +0530 Subject: [PATCH 36/49] Done ticket GEPAFINBE-129 --- .../dao/ApplicationAmendmentRequestDao.java | 2 +- .../dao/ApplicationEvaluationDao.java | 7 ++ .../tendermanagement/dao/DashboardDao.java | 79 ++++++++++++++++++- .../entities/ApplicationEvaluationEntity.java | 3 + .../enums/UserActionContextEnum.java | 1 + .../ApplicationWidgetResponseBean.java | 23 ++++++ .../ApplicationEvaluationRepository.java | 25 ++++++ .../repositories/ApplicationRepository.java | 16 ++++ .../service/DashboardService.java | 3 +- .../service/impl/DashboardServiceImpl.java | 7 ++ .../web/rest/api/DashboardApi.java | 14 +++- .../rest/api/impl/DashboardApiController.java | 10 +++ .../db/changelog/db.changelog-1.0.0.xml | 6 +- 13 files changed, 188 insertions(+), 8 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/ApplicationWidgetResponseBean.java diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 2937da2c..e478061e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -298,7 +298,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); String evaluationStatusType = applicationEvaluationEntity.getStatus(); if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){ - applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); +// applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); //Set Status applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index aad85864..29fa8814 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -24,7 +24,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import java.time.Duration; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -1778,6 +1780,11 @@ public class ApplicationEvaluationDao { existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); } + 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); + } entity = applicationEvaluationRepository.save(existingEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java index 0afc8fc8..a9caba7b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java @@ -6,18 +6,20 @@ import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.Widget1; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.repositories.CallRepository; -import net.gepafin.tendermanagement.repositories.CompanyRepository; -import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.CompanyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; @Component public class DashboardDao { @@ -37,6 +39,9 @@ public class DashboardDao { @Autowired private CompanyService companyService; + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) { SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean(); widgetResponseBean.setWidget1(createWidget1(requestedUserEntity)); @@ -121,4 +126,70 @@ public class DashboardDao { } return beneficiaryWidgetResponseBean; } + + public ApplicationWidgetResponseBean getApplicationDetails(UserEntity userEntity) { + ApplicationWidgetResponseBean applicationWidgetResponseBean = initializeResponseBean(); + + Long hubId = userEntity.getHub().getId(); + + setApplicationCounts(applicationWidgetResponseBean, hubId); + calculateEvaluationAverageTime(applicationWidgetResponseBean, hubId); + + return applicationWidgetResponseBean; + } + + private ApplicationWidgetResponseBean initializeResponseBean() { + return ApplicationWidgetResponseBean.builder() + .numberOfApplication(0L) + .numberOfAssignedApplication(0L) + .numberOfAcceptedApplication(0L) + .numberOfApplicationInAmendmentState(0L) + .numberOfDueApplication(0L) + .evaluationAverageTime(BigDecimal.ZERO) + .build(); + } + + private void setApplicationCounts(ApplicationWidgetResponseBean responseBean, Long hubId) { + Long activeApplications = applicationRepository.countApplicationsByHubId(hubId); + if (activeApplications != null) { + responseBean.setNumberOfApplication(activeApplications); + } + + Long assignedApplications = applicationRepository.countAssignedApplicationsByHubId(hubId); + if (assignedApplications != null) { + responseBean.setNumberOfAssignedApplication(assignedApplications); + } + + Long approvedApplications = applicationRepository.countApprovedApplicationsByHubId(hubId); + if (approvedApplications != null) { + responseBean.setNumberOfAcceptedApplication(approvedApplications); + } + + Long soccorsoApplications = applicationRepository.countSoccorsoApplicationsByHubId(hubId); + if (soccorsoApplications != null) { + responseBean.setNumberOfApplicationInAmendmentState(soccorsoApplications); + } + } + + private void calculateEvaluationAverageTime(ApplicationWidgetResponseBean responseBean, Long hubId) { + List applicationIds = applicationRepository.findApplicationIdsByHubId(hubId); + + if (Boolean.FALSE.equals(applicationIds.isEmpty())) { + BigDecimal averageTime = applicationEvaluationRepository.findAverageEvaluationTimeByApplicationIds(applicationIds); + responseBean.setEvaluationAverageTime(averageTime != null ? averageTime : BigDecimal.ZERO); + } + LocalDate twoDaysLater = LocalDate.now().plusDays(2); + + Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween( + applicationIds, + LocalDate.now(), + twoDaysLater + ); + + if (dueApplications != null) { + responseBean.setNumberOfDueApplication(dueApplications); + } + } + + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index 15e3d3d7..6ab7b72c 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -65,4 +65,7 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @Column(name = "CLOSING_DATE") private LocalDateTime closingDate; + @Column(name = "ACTIVE_DAYS") + private Long activeDays; + } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 20f917fe..4a992e31 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -134,6 +134,7 @@ public enum UserActionContextEnum { /** Dashboard action context **/ GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN("GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN"), GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"), + GET_APPLICATION_DETAILS("GET_APPLICATION_DETAILS"), /** Evaluation criteria action context **/ GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"), diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationWidgetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationWidgetResponseBean.java new file mode 100644 index 00000000..c119121b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationWidgetResponseBean.java @@ -0,0 +1,23 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Builder +@Data +public class ApplicationWidgetResponseBean { + + private Long numberOfApplication; + + private Long numberOfAssignedApplication; + + private Long numberOfAcceptedApplication; + + private Long numberOfApplicationInAmendmentState; + + private Long numberOfDueApplication; + + private BigDecimal evaluationAverageTime; +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index f9a7b0ac..daaae5a8 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.math.BigDecimal; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -31,4 +33,27 @@ public interface ApplicationEvaluationRepository extends JpaRepository findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate); +// @Query("SELECT AVG(DATEDIFF(DAY, e.startDate, e.endDate)) FROM ApplicationEvaluationEntity e WHERE e.applicationId IN :applicationIds AND e.startDate IS NOT NULL AND e.endDate IS NOT NULL AND e.isDeleted = false ") + @Query(""" + SELECT AVG(e.activeDays) + FROM ApplicationEvaluationEntity e + WHERE e.applicationId IN :applicationIds + AND e.activeDays IS NOT NULL + AND e.isDeleted = false + """) + BigDecimal findAverageEvaluationTimeByApplicationIds(@Param("applicationIds") List applicationIds); + @Query(""" + SELECT COUNT(e) + FROM ApplicationEvaluationEntity e + WHERE e.applicationId IN :applicationIds + AND FUNCTION('DATE', e.endDate) BETWEEN :startDate AND :endDate + AND e.isDeleted = false +""") + Long countDueApplicationsBetween( + @Param("applicationIds") List applicationIds, + @Param("startDate") LocalDate startDate, + @Param("endDate") LocalDate endDate + ); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index db645f95..3b35e921 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -44,4 +44,20 @@ public interface ApplicationRepository extends JpaRepository findApplicationIdsByHubId(@Param("hubId") Long hubId); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java index 6328ca6e..0e34c1b6 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; @@ -9,5 +10,5 @@ public interface DashboardService { public SuperAdminWidgetResponseBean getDashboardWidgetForSuperAdmin(HttpServletRequest request); public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId); - + public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java index 1a6cd6fd..e578a3dc 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java @@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.DashboardDao; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.service.DashboardService; @@ -32,4 +33,10 @@ public class DashboardServiceImpl implements DashboardService { CompanyEntity company = validator.validateUserWithCompany(request, companyId); return dashboardDao.getDashboardWidgetForBeneficiary(userEntity, company); } + + @Override + public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request) { + UserEntity userEntity=validator.validateUser(request); + return dashboardDao.getApplicationDetails(userEntity); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java index 753473f2..e8e99aff 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; @@ -46,7 +47,18 @@ public interface DashboardApi { produces = { "application/json" }) ResponseEntity> getDashboardWidgetForBeneficiary(HttpServletRequest request, @Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId); - + @Operation(summary = "Api to get Application details", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/application", + produces = { "application/json" }) + ResponseEntity> getApplicationDetails(HttpServletRequest request); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java index 7ff7be61..ed1f3d68 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java @@ -6,6 +6,7 @@ import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; @@ -49,5 +50,14 @@ public class DashboardApiController implements DashboardApi { return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); } + @Override + public ResponseEntity> getApplicationDetails(HttpServletRequest request) { + /** This code is responsible for creating user action logs for the "Get complete application page" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_DETAILS).build()); + + ApplicationWidgetResponseBean widgetResponseBean= dashboardService.getApplicationDetails(request); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); + } } 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 90ab3ca8..f4ad96e7 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 @@ -2069,5 +2069,9 @@ - + + + + + From a63e1bd640e390885fbda00345dbab8777d850f5 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Jan 2025 12:53:01 +0530 Subject: [PATCH 37/49] Done ticket GEPAFINBE-135 --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 0b0edf19..e281615f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -295,7 +295,12 @@ public class ApplicationDao { log.info("Deleting application with ID: {}", id); ApplicationEntity applicationEntity= validateApplication(id); - + if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) { + throw new CustomValidationException( + Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS) + ); + } ApplicationEntity oldApplicationDataEntity = Utils.getClonedEntityForData(applicationEntity); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); From de8196c4617c726a9e9017690555dbb87223859b Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Jan 2025 13:11:02 +0530 Subject: [PATCH 38/49] Updated code --- .../net/gepafin/tendermanagement/web/rest/api/DashboardApi.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java index e8e99aff..31ae1be3 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java @@ -59,6 +59,7 @@ public interface DashboardApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/application", produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')") ResponseEntity> getApplicationDetails(HttpServletRequest request); } From 5e293c43e68d457a161eb00abd26c47ca74d7db2 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 6 Jan 2025 15:57:30 +0530 Subject: [PATCH 39/49] Added prod config for NDG. --- src/main/resources/application-production.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index df295088..07dd31ff 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -24,7 +24,7 @@ default.hub.uuid=p4lk3bcx1RStqTaIVVbXs # TEST DEPLOY Configuration #Login to Odessa, Appointment Creation, Upload document Configuration -appointment.base.url=https://demo.galileonetwork.it/gateway/rest +appointment.base.url=https://prd.galileonetwork.it/gateway/rest appointment.portal.user=UtenzaAPIPortal@621 appointment.portal.password=u13nzaAP1P0rtal appointment.portal.source=GEPAFINPORTAL From de85d6ba90d535b3ab326f4c10761c71bf825393 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Jan 2025 17:20:42 +0530 Subject: [PATCH 40/49] Done ticket GEPAFINBE-138 --- .../tendermanagement/dao/VatCheckDao.java | 51 +++++++++++++------ .../gepafin/tendermanagement/util/Utils.java | 19 +++++++ 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java index 85af1388..4d74fb71 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java @@ -68,25 +68,46 @@ public class VatCheckDao { if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { log.info("Successfully checked vat number"); Map responseMap = response.getBody(); - if (responseMap != null && responseMap.containsKey("data")) { - responseBody = (Map) responseMap.get("data"); - responseBody.remove("timestamp_creation"); - responseBody.remove("timestamp_last_update"); - responseBody.remove("data_iscrizione"); - responseBody.remove("id"); - Map data = new LinkedHashMap<>(); - data.put("data", responseBody); - vatCheckResponseBean.setValid(true); - vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); - vatCheckResponseBean.setVatCheckResponse(data); - } + processValidResponse(responseMap, vatCheckResponseBean); } } catch (FeignException ex) { - log.error("Exception occurred while checking vat number: {0}", ex); - Utils.callException(ex.status(), ex); - } + if (ex.status() == 406) { + try { + Map errorResponse = Utils.parseErrorResponse(ex.contentUTF8()); + processValidResponse(errorResponse, vatCheckResponseBean); + } catch (Exception parseEx) { + log.error("Failed to parse 406 error response: {0}", parseEx); + } + } else { + log.error("Exception occurred while checking vat number: {0}", ex); + Utils.callException(ex.status(), ex); + } + } return vatCheckResponseBean; } + public static void processValidResponse(Map responseMap, VatCheckResponseBean vatCheckResponseBean) { + if (responseMap != null && responseMap.containsKey("data")) { + Map responseBody = (Map) responseMap.get("data"); + + if (responseBody != null) { + responseBody.remove("timestamp_creation"); + responseBody.remove("timestamp_last_update"); + responseBody.remove("data_iscrizione"); + responseBody.remove("id"); + + Map data = new LinkedHashMap<>(); + data.put("data", responseBody); + + vatCheckResponseBean.setValid(true); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); + vatCheckResponseBean.setVatCheckResponse(data); + } else { + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + } + } else { + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + } + } public VatCheckResponseBean checkVatNumber(String vatNumber) { try { diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index fb15759f..40f95e3b 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -24,6 +24,7 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; @@ -697,4 +698,22 @@ public class Utils { public static String createChannelForUserAndCompany(Long userId, Long companyId) { return GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId + GepafinConstant.COMPANY_PREFIX + companyId; } + + public static Map parseErrorResponse(String responseBody) { + if (StringUtils.isBlank(responseBody)) { + return defaultErrorResponse(); + } + try { + return mapper.readValue(responseBody, Map.class); + } catch (Exception e) { + log.error("Failed to parse error response: {}", e.getMessage(), e); + return defaultErrorResponse(); + } + } + + private static Map defaultErrorResponse() { + return Collections.singletonMap("message", Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + } + + } \ No newline at end of file From 184cda9fd24c3203cd85bf6b0973832fb99a73a1 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 7 Jan 2025 12:25:28 +0530 Subject: [PATCH 41/49] removed code smells --- .../ApplicationAmendmentScheduler.java | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java index 045dfd45..6a4c7b81 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -6,29 +6,23 @@ import net.gepafin.tendermanagement.dao.NotificationDao; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; -import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; -import net.gepafin.tendermanagement.service.ApplicationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; - -import jakarta.servlet.http.HttpServletRequest; -import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; -import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; -import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; @@ -40,25 +34,9 @@ import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; -import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; -import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; @Component public class ApplicationAmendmentScheduler { @@ -82,9 +60,6 @@ public class ApplicationAmendmentScheduler { @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; - @Autowired - private ApplicationService applicationService; - @Autowired private ApplicationRepository applicationRepository; From af5d31b9fe46f31d8607899f18ab37df9027a242 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 7 Jan 2025 13:15:25 +0530 Subject: [PATCH 42/49] Done ticket GEPAFINBE-133 User action api response. --- pom.xml | 6 + .../config/JacksonConfig.java | 20 +++ .../constants/GepafinConstant.java | 5 + .../repositories/UserActionsRepository.java | 2 +- .../tendermanagement/util/LoggingUtil.java | 40 ++++- .../util/UserActionAspect.java | 148 ++++++++++++++++++ .../gepafin/tendermanagement/util/Utils.java | 3 + 7 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java create mode 100644 src/main/java/net/gepafin/tendermanagement/util/UserActionAspect.java diff --git a/pom.xml b/pom.xml index c463be91..02b5fb51 100644 --- a/pom.xml +++ b/pom.xml @@ -245,6 +245,12 @@ reactor-netty + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.15.2 + + diff --git a/src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java b/src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java new file mode 100644 index 00000000..51ad3191 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JacksonConfig { + + @Bean + public ObjectMapper objectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return mapper; + } +} + diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 42853112..5869fc81 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -355,5 +355,10 @@ public class GepafinConstant { public static final String NOTIFICATION_DELETED_SUCCESSFULLY="notification.deleted.successfully"; public static final String NOTIFICATION_UPDATED_SUCCESSFULLY="notification.updated.successfully"; public static final String USER_WITH_COMPANY_NOT_FOUND = "user.with.company.not.found"; + + //action log response + public static final String STATUS_CODE_STRING = "statusCode"; + public static final String GET_STATUS_CODE_STRING = "status"; + public static final String MESSAGE_STRING = "message"; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java index f0163c47..804fdb9b 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java @@ -6,5 +6,5 @@ import org.springframework.stereotype.Repository; @Repository public interface UserActionsRepository extends JpaRepository { - UserActionEntity findUserActionById(Long id); + UserActionEntity findUserActionByIdAndIsDeletedFalse(Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index e2ab4521..90b7a052 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -41,6 +41,8 @@ public class LoggingUtil { @Autowired private TokenProvider tokenProvider; + private static final ThreadLocal userActionIdHolder = new ThreadLocal<>(); + public UserActionEntity logUserAction(UserActionRequest userActionRequest) { UserActionEntity userAction = new UserActionEntity(); try { @@ -83,12 +85,22 @@ public class LoggingUtil { userAction.setResponse(response); userActionsRepository.save(userAction); userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); + userActionIdHolder.set(userAction.getId()); } catch (Exception e) { log.error("Error logging user action: {}", e.getMessage(), e); } return userAction; } + public Long getUserActionId() { + return userActionIdHolder.get(); + } + + public void clearUserActionId() { + userActionIdHolder.remove(); + log.info("UserActionId cleared from ThreadLocal"); + } + private String normalizeUrl(String url) { url = url.replaceAll("(? getVersionHistoryLogById(Long id) { return versionHistoryRepository.findVersionHistoryByUserActionId(id); } + + public void updateUserActionWithError(Long userActionId, String errorDetails) { + if (userActionId == null) { + return; + } + + UserActionEntity userAction = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId); + if (userAction != null) { + userAction.setResponse(errorDetails); + userActionsRepository.save(userAction); + } + } + + public void updateUserActionWithResponse(Long userActionId, String response) { + if (userActionId == null) { + return; + } + + UserActionEntity userAction = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId); + if (userAction != null) { + userAction.setResponse(response); + userActionsRepository.save(userAction); + } + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/util/UserActionAspect.java b/src/main/java/net/gepafin/tendermanagement/util/UserActionAspect.java new file mode 100644 index 00000000..0064bb82 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/UserActionAspect.java @@ -0,0 +1,148 @@ +package net.gepafin.tendermanagement.util; + +import com.amazonaws.services.alexaforbusiness.model.UnauthorizedException; +import jakarta.persistence.EntityNotFoundException; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.server.ResponseStatusException; + +import java.lang.reflect.InvocationTargetException; +import java.nio.file.AccessDeniedException; +import java.util.LinkedHashMap; +import java.util.Map; + +@Aspect +@Component +@Slf4j +public class UserActionAspect { + + @Autowired + private LoggingUtil loggingUtil; + + @Around("execution(public * net.gepafin.tendermanagement.web.rest.api.impl..*(..))") + public Object logApiResponse(ProceedingJoinPoint joinPoint) throws Throwable { + + Object result; + + HttpServletRequest request = getRequestFromContext(); + try { + Long userActionId = getUserActionIdFromRequest(request); + + if (userActionId != null) { + request.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId); + log.info("Stored userActionId in RequestContext: {}", userActionId); + } else { + userActionId = loggingUtil.getUserActionId(); + if (userActionId != null) { + request.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId); + } + } + + result = joinPoint.proceed(); + + if (result instanceof ResponseEntity) { + Long storedUserActionId = (Long) request.getAttribute(GepafinConstant.USER_ACTION_ID); + handleSuccessResponse((ResponseEntity) result, storedUserActionId == null ? userActionId : storedUserActionId); + } + } catch (Exception ex) { + log.error("Exception occurred: ", ex); + handleError(ex, getUserActionIdFromRequest(request)); + throw ex; + } finally { + loggingUtil.clearUserActionId(); + } + + return result; + } + + private void handleSuccessResponse(ResponseEntity responseEntity, Long userActionId) { + + if (userActionId != null) { + Map responseWithUserAction = new LinkedHashMap<>(); + responseWithUserAction.put(GepafinConstant.STATUS_CODE_STRING, responseEntity.getStatusCode().value()); + + // Log and update user action + loggingUtil.updateUserActionWithResponse(userActionId, Utils.convertMapIntoJsonString(responseWithUserAction)); + log.info("Updated userActionId with response: {}", userActionId); + } + } + + private void handleError(Throwable ex, Long userActionId) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + + HttpStatus status = getStatusCodeFromException(ex); + log.info("Status Code received from exception : {}", status); + String errorMessage = ex.getMessage(); + + Map errorResponse = new LinkedHashMap<>(); + errorResponse.put(GepafinConstant.STATUS_CODE_STRING, status.value()); + errorResponse.put(GepafinConstant.GET_STATUS_CODE_STRING, status); + errorResponse.put(GepafinConstant.MESSAGE_STRING, errorMessage); + + if (userActionId != null) { + String errorDetails = Utils.convertMapIntoJsonString(errorResponse); + loggingUtil.updateUserActionWithError(userActionId, errorDetails); + log.info("Updated userActionId with error details: {}", userActionId); + } + } + + private HttpServletRequest getRequestFromContext() { + + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + return attributes != null ? attributes.getRequest() : null; + } + + private Long getUserActionIdFromRequest(HttpServletRequest request) { + + if (request != null) { + Object userActionIdAttr = request.getAttribute(GepafinConstant.USER_ACTION_ID); + return userActionIdAttr != null ? Long.valueOf(userActionIdAttr.toString()) : null; + } + return null; + } + + private HttpStatus getStatusCodeFromException(Throwable ex) { + + if (ex instanceof ResourceNotFoundException) { + return HttpStatus.NOT_FOUND; + } + + if (ex instanceof ResponseStatusException responseStatusException) { + return (HttpStatus) responseStatusException.getStatusCode(); + } + + if (ex instanceof CustomValidationException) { + return HttpStatus.BAD_REQUEST; + } + + if (ex instanceof EntityNotFoundException) { + return HttpStatus.NOT_FOUND; + } + if (ex instanceof IllegalArgumentException || ex instanceof MissingServletRequestParameterException || ex instanceof MethodArgumentNotValidException) { + return HttpStatus.BAD_REQUEST; + } + if (ex instanceof AccessDeniedException) { + return HttpStatus.FORBIDDEN; + } + if (ex instanceof UnauthorizedException) { + return HttpStatus.UNAUTHORIZED; + } + + return HttpStatus.INTERNAL_SERVER_ERROR; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 40f95e3b..0770bce5 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -154,6 +154,9 @@ public class Utils { public static String convertMapIntoJsonString(Map map) { try { ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.INDENT_OUTPUT); if (MapUtils.isNotEmpty(map)) { return mapper.writeValueAsString(map); } From b4d8ad45f2b79b20fc56a3fedb665c792def2430 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 7 Jan 2025 14:10:53 +0530 Subject: [PATCH 43/49] Added config for frame error on FE. --- .../net/gepafin/tendermanagement/config/SecurityConfig.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index 8c11eac2..61f84825 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -12,6 +12,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -97,7 +98,9 @@ public class SecurityConfig { } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth + http.csrf(AbstractHttpConfigurer::disable).headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) + .contentSecurityPolicy(csp -> csp.policyDirectives("frame-ancestors 'self' https://bandi-staging.memento.credit, https://bandi.gepafin.it"))) + .authorizeHttpRequests(auth -> auth // Allow public access to the login endpoints .requestMatchers("/v1/user/login").permitAll() // JWT-based login .requestMatchers("/v1/user").permitAll() // User registration From c53b7e59d3e380087dd5df27da5722619c1f930d Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 7 Jan 2025 14:14:54 +0530 Subject: [PATCH 44/49] Updated cnfig code. --- .../net/gepafin/tendermanagement/config/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index 61f84825..462d5cc9 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -99,7 +99,7 @@ public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf(AbstractHttpConfigurer::disable).headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) - .contentSecurityPolicy(csp -> csp.policyDirectives("frame-ancestors 'self' https://bandi-staging.memento.credit, https://bandi.gepafin.it"))) + .contentSecurityPolicy(csp -> csp.policyDirectives("frame-ancestors 'self' https://bandi-staging.memento.credit https://bandi.gepafin.it"))) .authorizeHttpRequests(auth -> auth // Allow public access to the login endpoints .requestMatchers("/v1/user/login").permitAll() // JWT-based login From e28a9f2662e1a1f59f7a57a59bf25df8389c7805 Mon Sep 17 00:00:00 2001 From: Piyush Date: Tue, 7 Jan 2025 17:29:05 +0530 Subject: [PATCH 45/49] Done ticket GEPAFINBE-89 --- .../entities/ExpirationConfigEntity.java | 21 +++ .../enums/ExpirationTypeEnum.java | 20 +++ .../enums/NotificationTypeEnum.java | 4 +- ...ApplicationAmendmentRequestRepository.java | 6 + .../ApplicationEvaluationRepository.java | 7 + .../ExpirationConfigRepository.java | 13 ++ .../scheduler/ExpirationScheduler.java | 125 ++++++++++++++++++ .../db/changelog/db.changelog-1.0.0.xml | 25 ++++ ...t_expiration_scheduler_data_07_01_2025.sql | 9 ++ ...n_template_for_notification_03_01_2025.sql | 3 + 10 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/ExpirationConfigEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/ExpirationTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/ExpirationConfigRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/ExpirationScheduler.java create mode 100644 src/main/resources/db/dump/insert_expiration_scheduler_data_07_01_2025.sql create mode 100644 src/main/resources/db/dump/update_json_template_for_notification_03_01_2025.sql diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ExpirationConfigEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ExpirationConfigEntity.java new file mode 100644 index 00000000..83159e3a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ExpirationConfigEntity.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "expiration_config") +@Data +public class ExpirationConfigEntity extends BaseEntity { + + @Column(name="INTERVAL_DAYS") + private Long intervalDays; + + @Column(name="TYPE") + private String type; + + @Column(name="IS_DELETED") + private Boolean isDeleted; +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ExpirationTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ExpirationTypeEnum.java new file mode 100644 index 00000000..2aaa1ae2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/ExpirationTypeEnum.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ExpirationTypeEnum { + + AMENDMENT("AMENDMENT"), + EVALUATION("EVALUATION"); + + private String value; + + ExpirationTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java index 54a13768..96d89e91 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java @@ -11,7 +11,9 @@ public enum NotificationTypeEnum { AMENDMENT_CLOSED("AMENDMENT_CLOSED"), NDG_GENERATION("NDG_GENERATION"), EVALUATION_CREATION("EVALUATION_CREATION"), - EVALUATION_EXPIRED("EVALUATION_EXPIRED"); + EVALUATION_EXPIRED("EVALUATION_EXPIRED"), + AMENDMENT_EXPIRATION_REMINDER("AMENDMENT_EXPIRATION_REMINDER"), + EVALUATION_EXPIRATION_REMINDER("EVALUATION_EXPIRATION_REMINDER"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 68133efb..3c89993c 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -74,4 +74,10 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findEvaluationsWithoutActiveAmendmentsByIds(@Param("applicationEvaluationIds") Set applicationEvaluationIds); + @Query("SELECT a FROM ApplicationAmendmentRequestEntity a " + + "WHERE a.isDeleted = false " + + "AND a.status NOT IN ('CLOSE', 'EXPIRED') " + + "AND a.endDate BETWEEN :startTime AND :endTime") + List findExpiringBetween(LocalDateTime startTime, LocalDateTime endTime); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index f9a7b0ac..e5373f5c 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -31,4 +32,10 @@ public interface ApplicationEvaluationRepository extends JpaRepository findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate); + + @Query("SELECT a FROM ApplicationEvaluationEntity a " + + "WHERE a.isDeleted = false " + + "AND a.status NOT IN ('CLOSE', 'EXPIRED') " + + "AND a.endDate BETWEEN :startTime AND :endTime") + List findExpiringBetween(LocalDateTime startTime, LocalDateTime endTime); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ExpirationConfigRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ExpirationConfigRepository.java new file mode 100644 index 00000000..21c7b975 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ExpirationConfigRepository.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ExpirationConfigEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ExpirationConfigRepository extends JpaRepository { + List findByTypeAndIsDeletedFalse(String type); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ExpirationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ExpirationScheduler.java new file mode 100644 index 00000000..60025630 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ExpirationScheduler.java @@ -0,0 +1,125 @@ +package net.gepafin.tendermanagement.scheduler; + +import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; +import net.gepafin.tendermanagement.dao.ApplicationEvaluationDao; +import net.gepafin.tendermanagement.dao.NotificationDao; +import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.enums.ExpirationTypeEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import net.gepafin.tendermanagement.repositories.ExpirationConfigRepository; +import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.service.CompanyService; +import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ExpirationScheduler { + + @Autowired + private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + + @Autowired + private ExpirationConfigRepository expirationNotificationConfigRepository; + + @Autowired + private ApplicationEvaluationDao applicationEvaluationDao; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private UserService userService; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private NotificationDao notificationDao; + + @Autowired + private CompanyService companyService; + + private static final Logger log = LoggerFactory.getLogger(ExpirationScheduler.class); + + @Scheduled(cron = "0 0 3 * * ?") + public void processExpiration(){ + log.info("Starting the Expiration scheduler..."); + try { + Utils.setHttpServletRequestForScheduler(); + + log.info("Starting processing expiration notifications for Amendment"); + processExpiration(ExpirationTypeEnum.AMENDMENT); + + log.info("Starting processing expiration notifications for Evaluation"); + processExpiration(ExpirationTypeEnum.EVALUATION); + + log.info("Expiration scheduler completed successfully."); + + } + catch (Exception e){ + log.error("An error occurred during the Notification Expiration Scheduler: {}", e.getMessage(), e); + } + } + + private void processExpiration(ExpirationTypeEnum type) { + List configEntities = expirationNotificationConfigRepository.findByTypeAndIsDeletedFalse(type.getValue()); + + for (ExpirationConfigEntity config : configEntities) { + Long daysBefore = config.getIntervalDays(); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startDate = now.plusDays(daysBefore).withHour(0).withMinute(0).withSecond(0).withNano(0); + LocalDateTime endDate = startDate.plusDays(1).minusNanos(1).withNano(0); + + if (ExpirationTypeEnum.AMENDMENT.equals(type)) { + processAmendmentExpiration(startDate, endDate, daysBefore); + } else if (ExpirationTypeEnum.EVALUATION.equals(type)) { + processEvaluationExpiration(startDate, endDate, daysBefore); + } + } + } + + private void processAmendmentExpiration(LocalDateTime startDate, LocalDateTime endDate, Long daysBefore) { + List amendmentEntities = applicationAmendmentRequestRepository.findExpiringBetween(startDate, endDate); + + for (ApplicationAmendmentRequestEntity entity : amendmentEntities) { + ApplicationEntity application = entity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); + Map placeHolders = replacePlaceholders(application,daysBefore); + notificationDao.sendNotificationToInstructor(placeHolders,entity.getApplicationEvaluationEntity(), NotificationTypeEnum.AMENDMENT_EXPIRATION_REMINDER); + } + } + + private Map replacePlaceholders (ApplicationEntity application, Long daysBefore){ + Long companyId = application.getCompanyId(); + CompanyEntity company = companyService.validateCompany(companyId); + Map placeHolders = new HashMap<>(); + placeHolders.put("{{call_name}}",application.getCall().getName()); + placeHolders.put("{{company_name}}", company.getCompanyName()); + placeHolders.put("{{days_before}}", daysBefore.toString()); + return placeHolders; + } + + private void processEvaluationExpiration(LocalDateTime startDate, LocalDateTime endDate, Long daysBefore) { + List evaluationEntities = applicationEvaluationRepository.findExpiringBetween(startDate, endDate); + + for (ApplicationEvaluationEntity entity : evaluationEntities) { + ApplicationEntity application = entity.getAssignedApplicationsEntity().getApplication(); + Map placeHolders = replacePlaceholders(application,daysBefore); + notificationDao.sendNotificationToInstructor(placeHolders,entity,NotificationTypeEnum.EVALUATION_EXPIRATION_REMINDER); + } + } +} 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 cf3c3987..b62336e2 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 @@ -2140,4 +2140,29 @@ path="db/dump/update_json_template_for_notification_31_12_2024.sql"/> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/insert_expiration_scheduler_data_07_01_2025.sql b/src/main/resources/db/dump/insert_expiration_scheduler_data_07_01_2025.sql new file mode 100644 index 00000000..dca8f3a1 --- /dev/null +++ b/src/main/resources/db/dump/insert_expiration_scheduler_data_07_01_2025.sql @@ -0,0 +1,9 @@ + +INSERT INTO expiration_config (interval_days, type, created_date, updated_date) +VALUES +(5, 'AMENDMENT', '2024-12-03T11:00:51', '2024-12-03T11:00:51'), +(2, 'AMENDMENT', '2024-12-03T11:00:51', '2024-12-03T11:00:51'), +(0, 'AMENDMENT', '2024-12-03T11:00:51', '2024-12-03T11:00:51'), +(5, 'EVALUATION', '2024-12-03T11:00:51', '2024-12-03T11:00:51'), +(2, 'EVALUATION', '2024-12-03T11:00:51', '2024-12-03T11:00:51'), +(0, 'EVALUATION', '2024-12-03T11:00:51', '2024-12-03T11:00:51'); diff --git a/src/main/resources/db/dump/update_json_template_for_notification_03_01_2025.sql b/src/main/resources/db/dump/update_json_template_for_notification_03_01_2025.sql new file mode 100644 index 00000000..06bf6aa0 --- /dev/null +++ b/src/main/resources/db/dump/update_json_template_for_notification_03_01_2025.sql @@ -0,0 +1,3 @@ +INSERT INTO notification_type (notification_name,title, json_template,created_date,updated_date,is_deleted) VALUES +('AMENDMENT_EXPIRATION_REMINDER','Lemendamento sta per scadere','Lemendamento per {{call_name}} - {{company_name}} scadrà tra {{days_before}} giorni. Assicurati che tutte le azioni necessarie siano completate prima della scadenza.','2025-01-03T10:16:26.472Z','2025-01-03T10:16:26.472Z','false'), +('EVALUATION_EXPIRATION_REMINDER','La valutazione sta per scadere','Lemendamento per {{call_name}} - {{company_name}} scadrà tra {{days_before}} giorni. Assicurati che tutte le azioni necessarie siano completate prima della scadenza.','2025-01-03T10:16:26.472Z','2025-01-03T10:16:26.472Z','false'); \ No newline at end of file From 887100ed74eb05b4dceb2234b15ad3581c8718be Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 7 Jan 2025 18:17:23 +0530 Subject: [PATCH 46/49] Fixed issue during user creation from SPID --- src/main/java/net/gepafin/tendermanagement/dao/UserDao.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 1c06ccaf..0ffa0b42 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -190,6 +190,8 @@ public class UserDao { userReq.setHubUuid(userEntity.getHub().getUniqueUuid()); }else { samlSuccessHandler.validateToken(tempToken, userReq.getCodiceFiscale(), userReq.getHubUuid()); + RoleEntity roleEntity = roleDao.getRoleByType(RoleStatusEnum.ROLE_BENEFICIARY); + userReq.setRoleId(roleEntity.getId()); } if (Boolean.FALSE.equals(Utils.isValidEmail(userReq.getEmail()))) { From 8bb1ec0d02616642d919af2f64f1060b6bc9859a Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 8 Jan 2025 15:58:25 +0530 Subject: [PATCH 47/49] Updated jackson config --- pom.xml | 6 ------ .../config/JacksonConfig.java | 20 ------------------- 2 files changed, 26 deletions(-) delete mode 100644 src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java diff --git a/pom.xml b/pom.xml index 02b5fb51..c463be91 100644 --- a/pom.xml +++ b/pom.xml @@ -245,12 +245,6 @@ reactor-netty - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - 2.15.2 - - diff --git a/src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java b/src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java deleted file mode 100644 index 51ad3191..00000000 --- a/src/main/java/net/gepafin/tendermanagement/config/JacksonConfig.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.gepafin.tendermanagement.config; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class JacksonConfig { - - @Bean - public ObjectMapper objectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); - mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - return mapper; - } -} - From 179b076a8f4f3dee06e9f5b7aca6c234d2ef3f68 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Wed, 8 Jan 2025 17:11:45 +0530 Subject: [PATCH 48/49] Added RabbitMQ config for production. --- src/main/resources/application-production.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index 07dd31ff..2cbd72a3 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -32,7 +32,8 @@ appointment.portal.context=GEPAFINPORTAL flagDaFirmare=true # RabbitMQ properties for STOMP broker relay for Notification -spring.rabbitmq.host=rabbitmq.bflows.ai +#spring.rabbitmq.host=rabbitmq.bflows.ai +spring.rabbitmq.host=172.21.0.2 spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest From 3cf0e1dfef1eb792c64d4befbe8726ef2d9d65f3 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Wed, 8 Jan 2025 19:06:56 +0530 Subject: [PATCH 49/49] Updated rabbitMq config. --- src/main/resources/application-production.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index 2cbd72a3..c6a9cce8 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -33,7 +33,7 @@ flagDaFirmare=true # RabbitMQ properties for STOMP broker relay for Notification #spring.rabbitmq.host=rabbitmq.bflows.ai -spring.rabbitmq.host=172.21.0.2 +spring.rabbitmq.host=172.18.0.5 spring.rabbitmq.port=61613 spring.rabbitmq.username=guest spring.rabbitmq.password=guest