diff --git a/Dockerfile b/Dockerfile index ceacf16e..18ed6c1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ FROM amazoncorretto:17.0.8-alpine3.17 +ENV TZ="Europe/Rome" EXPOSE 8080 ADD /target/tendermanagement-0.0.1-SNAPSHOT.jar tendermanagement-0.0.1-SNAPSHOT.jar ENTRYPOINT ["java", "-jar","tendermanagement-0.0.1-SNAPSHOT.jar"] diff --git a/Jenkinsfile b/Jenkinsfile index 968d3a2b..d488b39e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -56,7 +56,7 @@ pipeline { } } script { - sh 'ssh ubuntu@46.105.65.89 "sh gepafin-production-api.sh"' + sh 'ssh ubuntu@79.137.88.15 "sh gepafin-production-api.sh"' } } } diff --git a/pom.xml b/pom.xml index a2a1e712..b443ec18 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ commons-io commons-io - 2.11.0 + 2.17.0 @@ -173,12 +173,51 @@ 4.1.3 + + org.apache.poi + poi-ooxml + 5.3.0 + + + + com.mailgun + mailgun-java + 1.0.2 + + org.apache.santuario xmlsec 2.3.0 + + com.itextpdf + itextpdf + 5.5.13.3 + + + + + com.itextpdf + itext7-core + 8.0.5 + pom + + + + + com.itextpdf + layout + 8.0.5 + + + + io.springfox + springfox-boot-starter + 3.0.0 + + diff --git a/src/main/java/net/gepafin/tendermanagement/config/SamlConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SamlConfig.java new file mode 100644 index 00000000..c66e26f1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/SamlConfig.java @@ -0,0 +1,203 @@ +package net.gepafin.tendermanagement.config; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.PKCS8EncodedKeySpec; +import java.time.Instant; +import java.util.UUID; + +import org.bouncycastle.util.io.pem.PemReader; +import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; +import org.opensaml.saml.common.SAMLVersion; +import org.opensaml.saml.common.xml.SAMLConstants; +import org.opensaml.saml.saml2.core.AuthnContextClassRef; +import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration; +import org.opensaml.saml.saml2.core.AuthnRequest; +import org.opensaml.saml.saml2.core.RequestedAuthnContext; +import org.opensaml.saml.saml2.core.impl.AuthnContextClassRefBuilder; +import org.opensaml.saml.saml2.core.impl.RequestedAuthnContextBuilder; +import org.opensaml.security.x509.BasicX509Credential; +import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap; +import org.opensaml.xmlsec.signature.Signature; +import org.opensaml.xmlsec.signature.support.SignatureConstants; +import org.opensaml.xmlsec.signature.support.Signer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.saml2.core.Saml2X509Credential; +import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository; +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; +import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; +import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; +import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; +import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; +import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver; + +@Configuration +public class SamlConfig { + + private final Logger logger = LoggerFactory.getLogger(SamlConfig.class); + + @Value("${base-url}") + String baseUrl; + + @Value("${spid.ipd.base.url}") + String ipdBaseUrl; + + @Value("${active.profile.folder}") + String activeProfileFolder; + + @Bean + public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { + + String entityId = baseUrl + "/v1/saml/gw/metadata"; + String acsUrl = baseUrl + "/login/saml2/sso/loginumbria"; + + RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("loginumbria") + .entityId(entityId) + .signingX509Credentials(credentials -> { + try { + credentials.add(Saml2X509Credential.signing(readPrivateKey(), readCertificate())); + } catch (Exception e) { + e.printStackTrace(); + } + }) + .assertionConsumerServiceLocation(acsUrl) + .assertingPartyDetails(details -> details.entityId(ipdBaseUrl + "/gw/metadata") + .singleSignOnServiceLocation(ipdBaseUrl + "/gw/SSOProxy/SAML2") + .singleSignOnServiceBinding(Saml2MessageBinding.POST) + .wantAuthnRequestsSigned(true) + .verificationX509Credentials(credentials -> { + try { + // Load the IDP's public certificate for verifying the SAML response signature + credentials.add(Saml2X509Credential.verification(readIdpCertificate())); + } catch (Exception e) { + e.printStackTrace(); + } + }) + ) + .build(); + + return new InMemoryRelyingPartyRegistrationRepository(registration); + } + + public AuthnRequest createSignedAuthnRequest(PrivateKey privateKey, X509Certificate certificate) throws Exception { + AuthnRequest authnRequest = (AuthnRequest) XMLObjectProviderRegistrySupport.getBuilderFactory() + .getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME) + .buildObject(AuthnRequest.DEFAULT_ELEMENT_NAME); + + authnRequest.setID("_" + UUID.randomUUID().toString()); + authnRequest.setVersion(SAMLVersion.VERSION_20); + // authnRequest.setIssueInstant(new DateTime()); + authnRequest.setIssueInstant(Instant.now()); + + + // Sign the AuthnRequest + // BasicCredential signingCredential = new BasicCredential(certificate, privateKey); + BasicX509Credential signingCredential = new BasicX509Credential(certificate, privateKey); + + Signature signature = (Signature) XMLObjectProviderRegistrySupport.getBuilderFactory() + .getBuilder(Signature.DEFAULT_ELEMENT_NAME) + .buildObject(Signature.DEFAULT_ELEMENT_NAME); + + signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signature.setSigningCredential(signingCredential); + signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); // Set RSA-SHA1 + + authnRequest.setSignature(signature); + DefaultSecurityConfigurationBootstrap.buildDefaultSignatureSigningConfiguration(); + + // Marshall and sign the object + XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(authnRequest).marshall(authnRequest); + Signer.signObject(signature); + + return authnRequest; + } + +@Bean +public Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationRepository registrations) { + RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(registrations); + OpenSaml4AuthenticationRequestResolver authenticationRequestResolver = new OpenSaml4AuthenticationRequestResolver(registrationResolver); + + authenticationRequestResolver.setAuthnRequestCustomizer((context) -> { + // Set the required attributes + AuthnRequest authnRequest = context.getAuthnRequest(); + authnRequest.setID("_" + UUID.randomUUID().toString()); // Add a unique ID + authnRequest.setVersion(SAMLVersion.VERSION_20); // Ensure version is 2.0 + authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI); // HTTP-POST + + // Set Authentication Context + authnRequest.setRequestedAuthnContext(buildRequestedAuthnContext()); + + // Log the SAML AuthnRequest after setting context + String samlRequest = SamlRequestLogger.convertSAMLObjectToString(authnRequest); + logger.info("SAML AuthnRequest after setting context: " + samlRequest); + }); + + return authenticationRequestResolver; +} + +private RequestedAuthnContext buildRequestedAuthnContext() { + AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder(); + AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject( + SAMLConstants.SAML20_NS, AuthnContextClassRef.DEFAULT_ELEMENT_LOCAL_NAME, SAMLConstants.SAML20_PREFIX + ); + // Set the SPID Level 2 authentication context + authnContextClassRef.setURI("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword"); + + RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder(); + RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject(); + requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT); + requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef); + + return requestedAuthnContext; +} + + public PrivateKey readPrivateKey() throws Exception { + // Path to your private key PEM file + try (PemReader pemReader = new PemReader(new InputStreamReader(readKey(activeProfileFolder + "/saml/private-key.pem")))) { + // Read the PEM content + byte[] pemContent = pemReader.readPemObject().getContent(); + // Decode the PEM content + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemContent); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // Use RSA algorithm + // Generate and return the PrivateKey + return keyFactory.generatePrivate(keySpec); + } + } + public X509Certificate readCertificate() throws Exception { + // Path to your certificate PEM fileFile + try (InputStream inStream = readKey(activeProfileFolder + "/saml/public-cert.pem")) { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + return (X509Certificate) certFactory.generateCertificate(inStream); + } + } + + public X509Certificate readIdpCertificate() throws Exception { + // Path to your IDP public certificate PEM file + try (InputStream inStream = readKey(activeProfileFolder + "/saml/idp-certificate.pem")) { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + return (X509Certificate) certFactory.generateCertificate(inStream); + } + } + + + public InputStream readKey(String path) throws IOException { + ClassLoader classLoader = getClass().getClassLoader(); + InputStream inputStream = classLoader.getResourceAsStream(path); + + if (inputStream == null) { + throw new FileNotFoundException("file not found : "+path); + } + return inputStream; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java b/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java new file mode 100644 index 00000000..171b7e12 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java @@ -0,0 +1,35 @@ +package net.gepafin.tendermanagement.config; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.stereotype.Component; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Component +public class SamlFailureHandler implements AuthenticationFailureHandler { + + private final Logger logger = LoggerFactory.getLogger(SamlFailureHandler.class); + + @Value("${fe.base.url}") + private String feBaseUrl; + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException { + try { + logger.error("SAML login failed: " + exception.getMessage()); + + response.sendRedirect(feBaseUrl + "/login"); + } catch (Exception e) { + logger.error("Error processing SAML failure handler", e); + } + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java b/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java new file mode 100644 index 00000000..868b0eae --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/SamlSuccessHandler.java @@ -0,0 +1,98 @@ +package net.gepafin.tendermanagement.config; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; +import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.SamlResponseEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.repositories.SamlResponseRepository; +import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; + +@Component +public class SamlSuccessHandler implements AuthenticationSuccessHandler { + + private final Logger logger = LoggerFactory.getLogger(SamlSuccessHandler.class); + + @Autowired + private SamlResponseRepository samlResponseLogRepository; + + @Autowired + private UserRepository userRepository; + + @Value("${fe.base.url}") + private String feBaseUrl; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException { + try { + logger.info("SAML login in Authentication Success Handler"); + Saml2Authentication samlAuth = (Saml2Authentication) authentication; + Saml2AuthenticatedPrincipal principal = (Saml2AuthenticatedPrincipal) samlAuth.getPrincipal(); + + Map> userAttributes = principal.getAttributes(); + String token = Utils.generateSecureToken(); + logger.info("SAML User Attributes: " + userAttributes); + + SamlResponseEntity samlResponseLogEntity = new SamlResponseEntity(); + samlResponseLogEntity.setAuthenticationObject(authentication.toString()); + + ObjectMapper objectMapper = new ObjectMapper(); + String userAttributesJson = objectMapper.writeValueAsString(userAttributes); + samlResponseLogEntity.setAuthenticationObject(userAttributesJson); + samlResponseLogEntity.setToken(token); + samlResponseLogRepository.save(samlResponseLogEntity); + + String redirectUrl = feBaseUrl; + + logger.info("SAML login successful for user: " + principal.getName()); + String cf = userAttributes.get("CodiceFiscale").get(0).toString(); + UserEntity userEntity = userRepository.findByBeneficiaryCodiceFiscale(cf).orElse(null); + if (userEntity == null) { + redirectUrl += "/registration?temp_token=" + token; + } else { + redirectUrl += "/login?temp_token=" + token; + } + response.sendRedirect(redirectUrl); + logger.info("SAML redirect Url: " + redirectUrl); + } catch (Exception e) { + logger.error("Error processing SAML success handler", e); + } + } + + public void validateToken(String token, String codiceFiscale) { + SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token); + if (samlResponseLogEntity == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG)); + } + Map> userAttributes = Utils + .convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject()); + String cf = userAttributes.get("CodiceFiscale").get(0).toString(); + if (codiceFiscale == null || Boolean.FALSE.equals(codiceFiscale.equals(cf))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG)); + } + samlResponseLogRepository.delete(samlResponseLogEntity); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index c83cc513..89182902 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -1,39 +1,5 @@ package net.gepafin.tendermanagement.config; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.PKCS8EncodedKeySpec; -import java.time.Instant; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.xml.security.Init; -import org.bouncycastle.util.io.pem.PemReader; -import org.opensaml.core.config.InitializationService; -import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; -import org.opensaml.saml.common.SAMLVersion; -import org.opensaml.saml.common.xml.SAMLConstants; -import org.opensaml.saml.saml2.core.AuthnContextClassRef; -import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration; -import org.opensaml.saml.saml2.core.AuthnRequest; -import org.opensaml.saml.saml2.core.RequestedAuthnContext; -import org.opensaml.saml.saml2.core.impl.AuthnContextClassRefBuilder; -import org.opensaml.saml.saml2.core.impl.RequestedAuthnContextBuilder; -import org.opensaml.security.x509.BasicX509Credential; -import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap; -import org.opensaml.xmlsec.signature.Signature; -import org.opensaml.xmlsec.signature.support.SignatureConstants; -import org.opensaml.xmlsec.signature.support.Signer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -49,17 +15,6 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.saml2.core.Saml2X509Credential; -import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; -import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; -import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; -import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; -import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; -import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; -import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; -import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; @@ -69,63 +24,34 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; -import jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.jwt.JWTFilter; import net.gepafin.tendermanagement.config.jwt.TokenProvider; -import net.gepafin.tendermanagement.entities.SamlResponseLogEntity; -import net.gepafin.tendermanagement.repositories.SamlResponseLogRepository; -//import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext; -//import org.springframework.security.saml2.core.Saml2AuthenticationRequest; + @Configuration @EnableWebSecurity @EnableMethodSecurity(prePostEnabled = true) public class SecurityConfig { - private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); private final TokenProvider tokenProvider; + private final SamlSuccessHandler samlSuccessHandler; + private final SamlFailureHandler samlFailureHandler; @Value("${base-url}") String baseUrl; @Autowired - private SamlResponseLogRepository samlResponseLogRepository; - - @Autowired - public SecurityConfig(TokenProvider tokenProvider) { + public SecurityConfig(TokenProvider tokenProvider, SamlSuccessHandler samlSuccessHandler, SamlFailureHandler samlFailureHandler) { this.tokenProvider = tokenProvider; + this.samlSuccessHandler =samlSuccessHandler; + this.samlFailureHandler=samlFailureHandler; } - - @PostConstruct - public void initXmlSecurity() throws Exception { - // Initialize Apache XML Security (Santuario) - Init.init(); - } - - - @PostConstruct - public void initOpenSAML() throws Exception { - InitializationService.initialize(); - } - -// -// @Bean -// public Saml2AuthenticationRequestResolver authenticationRequestResolver() { -// return (Saml2AuthenticationRequestContext context) -> { -// Saml2AuthenticationRequest request = Saml2AuthenticationRequest.withAuthenticationRequestContext(context) -// .authenticationContextClassRef("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword") // Add context here -// .build(); -// return request; -// }; -// } - @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); @@ -173,12 +99,23 @@ public class SecurityConfig { http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth // Allow public access to the login endpoints .requestMatchers("/v1/user/login").permitAll() // JWT-based login + .requestMatchers("/v1/user").permitAll() // User registration + .requestMatchers("/v1/user/sso/validate/existing-user/{token}").permitAll() + .requestMatchers("/v1/user/sso/validate/new-user/{token}").permitAll() .requestMatchers("/v1/saml/**").permitAll() // JWT-based login .requestMatchers("/saml2/**").permitAll() // SAML login initiation .requestMatchers("/swagger-ui/**").permitAll() // Swagger docs .requestMatchers("/v1/api-docs/**").permitAll() // API docs + .requestMatchers("/v1/user/reset-password/initiate").permitAll() + .requestMatchers("/v1/user/reset-password").permitAll() .anyRequest().authenticated()) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) + .exceptionHandling(exceptionHandling -> exceptionHandling + .authenticationEntryPoint((request, response, authException) -> { + // Send 403 Forbidden when there is no JWT token provided + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Authentication token is missing or invalid"); + }) + ) .addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class) // Add SAML2 login configuration (for BENEFICIARI) @@ -186,55 +123,8 @@ public class SecurityConfig { * .saml2Login(saml -> saml.loginPage("/saml/login") // Entry point for SAML * login .defaultSuccessUrl("/") // Redirect after successful SAML login ); */ - .saml2Login(saml -> - saml.defaultSuccessUrl("/") - .successHandler((request, response, authentication) -> { - try { - // Cast the authentication object to Saml2Authentication - Saml2Authentication samlAuth = (Saml2Authentication) authentication; - Saml2AuthenticatedPrincipal principal = (Saml2AuthenticatedPrincipal) samlAuth.getPrincipal(); - - // Extract the user attributes from the principal - Map> userAttributes = principal.getAttributes(); - - // Log the user attributes for debugging purposes - logger.info("SAML User Attributes: " + userAttributes); - - // Save the authentication details in the database (Optional) - SamlResponseLogEntity samlResponseLogEntity = new SamlResponseLogEntity(); - samlResponseLogEntity.setAuthenticationObject(authentication.toString()); - - // Convert user attributes to JSON and save in DB - ObjectMapper objectMapper = new ObjectMapper(); - String userAttributesJson = objectMapper.writeValueAsString(userAttributes); - samlResponseLogEntity.setAuthenticationObject(userAttributesJson); - samlResponseLogRepository.save(samlResponseLogEntity); - - // Successful login logic - logger.info("SAML login successful for user: " + principal.getName()); - response.sendRedirect("http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com/login"); - } catch (Exception e) { - logger.error("Error processing SAML success handler", e); - } - }) - .failureHandler((request, response, exception) -> { - try { - logger.error("SAML login failed: " + exception.getMessage()); - - // Log the failure details to the database (Optional) - SamlResponseLogEntity samlResponseLogEntity = new SamlResponseLogEntity(); - samlResponseLogEntity.setRequest(request.toString()); - samlResponseLogEntity.setResponse(response.toString()); - samlResponseLogEntity.setExceptionObject(exception.toString()); - samlResponseLogRepository.save(samlResponseLogEntity); - - // Handle failure redirection - response.sendRedirect("http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com/login"); - } catch (Exception e) { - logger.error("Error processing SAML failure handler", e); - } - }) - ); + .saml2Login(saml -> saml.defaultSuccessUrl("/").successHandler(samlSuccessHandler) + .failureHandler(samlFailureHandler)); return http.build(); @@ -250,148 +140,5 @@ public class SecurityConfig { .scheme("bearer").bearerFormat("JWT"))); } - @Bean - public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { - - String entityId = baseUrl + "/v1/saml/gw/metadata"; - String acsUrl = baseUrl + "/login/saml2/sso/loginumbria"; - - RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("loginumbria") - .entityId(entityId) - .signingX509Credentials(credentials -> { - try { - credentials.add(Saml2X509Credential.signing(readPrivateKey(), readCertificate())); - } catch (Exception e) { - e.printStackTrace(); - } - }) - .assertionConsumerServiceLocation(acsUrl) - .assertingPartyDetails(details -> details.entityId("https://federatest.umbriadigitale.it/gw/metadata") - .singleSignOnServiceLocation("https://federatest.umbriadigitale.it/gw/SSOProxy/SAML2") - .singleSignOnServiceBinding(Saml2MessageBinding.POST) - .wantAuthnRequestsSigned(true) - .verificationX509Credentials(credentials -> { - try { - // Load the IDP's public certificate for verifying the SAML response signature - credentials.add(Saml2X509Credential.verification(readIdpCertificate())); - } catch (Exception e) { - e.printStackTrace(); - } - }) - ) - .build(); - - return new InMemoryRelyingPartyRegistrationRepository(registration); - } - - public AuthnRequest createSignedAuthnRequest(PrivateKey privateKey, X509Certificate certificate) throws Exception { - AuthnRequest authnRequest = (AuthnRequest) XMLObjectProviderRegistrySupport.getBuilderFactory() - .getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME) - .buildObject(AuthnRequest.DEFAULT_ELEMENT_NAME); - - authnRequest.setID("_" + UUID.randomUUID().toString()); - authnRequest.setVersion(SAMLVersion.VERSION_20); - // authnRequest.setIssueInstant(new DateTime()); - authnRequest.setIssueInstant(Instant.now()); - - - // Sign the AuthnRequest - // BasicCredential signingCredential = new BasicCredential(certificate, privateKey); - BasicX509Credential signingCredential = new BasicX509Credential(certificate, privateKey); - - Signature signature = (Signature) XMLObjectProviderRegistrySupport.getBuilderFactory() - .getBuilder(Signature.DEFAULT_ELEMENT_NAME) - .buildObject(Signature.DEFAULT_ELEMENT_NAME); - - signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signature.setSigningCredential(signingCredential); - signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); // Set RSA-SHA1 - - authnRequest.setSignature(signature); - DefaultSecurityConfigurationBootstrap.buildDefaultSignatureSigningConfiguration(); - - // Marshall and sign the object - XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(authnRequest).marshall(authnRequest); - Signer.signObject(signature); - - return authnRequest; - } - -@Bean -public Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationRepository registrations) { - RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(registrations); - OpenSaml4AuthenticationRequestResolver authenticationRequestResolver = new OpenSaml4AuthenticationRequestResolver(registrationResolver); - - authenticationRequestResolver.setAuthnRequestCustomizer((context) -> { - // Set the required attributes - AuthnRequest authnRequest = context.getAuthnRequest(); - authnRequest.setID("_" + UUID.randomUUID().toString()); // Add a unique ID - authnRequest.setVersion(SAMLVersion.VERSION_20); // Ensure version is 2.0 - authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI); // HTTP-POST - - // Set Authentication Context - authnRequest.setRequestedAuthnContext(buildRequestedAuthnContext()); - - // Log the SAML AuthnRequest after setting context - String samlRequest = SamlRequestLogger.convertSAMLObjectToString(authnRequest); - logger.info("SAML AuthnRequest after setting context: " + samlRequest); - }); - - return authenticationRequestResolver; -} - -private RequestedAuthnContext buildRequestedAuthnContext() { - AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder(); - AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject( - SAMLConstants.SAML20_NS, AuthnContextClassRef.DEFAULT_ELEMENT_LOCAL_NAME, SAMLConstants.SAML20_PREFIX - ); - // Set the SPID Level 2 authentication context - authnContextClassRef.setURI("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword"); - - RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder(); - RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject(); - requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT); - requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef); - - return requestedAuthnContext; -} - - public PrivateKey readPrivateKey() throws Exception { - // Path to your private key PEM file - try (PemReader pemReader = new PemReader(new InputStreamReader(readKey("dev/saml/private-key.pem")))) { - // Read the PEM content - byte[] pemContent = pemReader.readPemObject().getContent(); - // Decode the PEM content - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemContent); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // Use RSA algorithm - // Generate and return the PrivateKey - return keyFactory.generatePrivate(keySpec); - } - } - public X509Certificate readCertificate() throws Exception { - // Path to your certificate PEM fileFile - try (InputStream inStream = readKey("dev/saml/public-cert.pem")) { - CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - return (X509Certificate) certFactory.generateCertificate(inStream); - } - } - - public X509Certificate readIdpCertificate() throws Exception { - // Path to your IDP public certificate PEM file - try (InputStream inStream = readKey("dev/saml/idp-certificate.pem")) { - CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - return (X509Certificate) certFactory.generateCertificate(inStream); - } - } - - - public InputStream readKey(String path) throws IOException { - ClassLoader classLoader = getClass().getClassLoader(); - InputStream inputStream = classLoader.getResourceAsStream(path); - - if (inputStream == null) { - throw new FileNotFoundException("file not found : "+path); - } - return inputStream; - } + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java index 15c51b7a..884c848f 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java +++ b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java @@ -82,10 +82,11 @@ public class TokenProvider { log.info("JWT Secret Key initialized."); } - public String createToken(Authentication authentication, Boolean rememberMe, UserEntity user) { - String authorities = authentication.getAuthorities().stream() - .map(GrantedAuthority::getAuthority) - .collect(Collectors.joining(",")); + public String createToken(Boolean rememberMe, UserEntity user) { +// String authorities = authentication.getAuthorities().stream() +// .map(GrantedAuthority::getAuthority) +// .collect(Collectors.joining(",")); + String authorities = user.getRoleEntity().getRoleType(); Long now; Date validity; @@ -99,10 +100,14 @@ public class TokenProvider { log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds); } - String payload = authentication.getName(); + String payload = user.getEmail(); if(user != null) { payload += ":"+user.getId(); } + + if(user != null) { + payload += ":"+user.getHub().getId(); + } String token = Jwts.builder() .setSubject(payload) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 4a7560e5..b60fc36a 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -24,7 +24,7 @@ public class GepafinConstant { public static final String GET_REGION_SUCCESS_MSG = "get.region.success"; public static final String DELETE_REGION_SUCCESS_MSG = "delete.region.success"; public static final String REGION_NOT_FOUND_MSG = "user.region.not.found"; - public static final String PASSWORD_DOESNT_MATCH ="password.doesnt.match"; + public static final String PASSWORD_DOESNT_MATCH = "password.doesnt.match"; public static final String USER_NOT_EXIST_MSG = "user.not.exist"; public static final String REGION_NOT_FOUND = "region.not.found"; public static final String USER_ID_NOT_NULL_MSG = "user.id.not.null"; @@ -36,13 +36,13 @@ public class GepafinConstant { public static final String LOOK_UP_DATA_NOT_VALID_MSG = "look.up.data.not.valid"; public static final String FILES_UPLOADED_MSG = "files.uploaded"; public static final String CALL_CREATED_SUCCESSFULLY_MSG = "call.created.successfully"; - public static final String FILE_DELETED_SUCCESSFULLY_MSG="file.deleted.successfully"; - public static final String DOCUMENT_NOT_FOUND="document.not.found"; - public static final String LOGIN_SUCCESS_MSG="login.successfully"; - public static final String PASSWORD_MIN_LEN ="pass.min.len.msg"; + public static final String FILE_DELETED_SUCCESSFULLY_MSG = "file.deleted.successfully"; + public static final String DOCUMENT_NOT_FOUND = "document.not.found"; + public static final String LOGIN_SUCCESS_MSG = "login.successfully"; + public static final String PASSWORD_MIN_LEN = "pass.min.len.msg"; public static final String EMAIL_ALREADY_EXISTS = "email.already.exists"; - public static final String DOCUMENT_ID_NOT_FOUND="document.id.not.found"; - public static final String INVALID_DATE_MSG = "call.invalid.date"; + public static final String DOCUMENT_ID_NOT_FOUND = "document.id.not.found"; + public static final String INVALID_DATE_MSG = "call.invalid.date"; public static final String FORM_NOT_FOUND = "form.not.found"; public static final String FORM_CREATED_SUCCESSFULLY = "form.created.successfully"; public static final String FORM_UPDATED_SUCCESSFULLY = "form.updated.suucessfully"; @@ -61,12 +61,12 @@ public class GepafinConstant { public static final String FORM_TEMPLATE_DELETED_SUCCESSFULLY = "form.template.deleted.successfully"; public static final String FORM_TEMPLATE_FETCHED_SUCCESSFULLY = "form.template.fetched.successfully"; public static final String REQUIRED_PARAMETER_NOT_FOUND_FOR_FORM_TEMPLATE = "required.parameter.not.found.for.form.template"; - public static final String FORM_NOT_FOUND_FOR_CALL_ID="form.not.found.for.call.id"; - public static final String STEP_1 = "STEP_1"; - public static final String STEP_2 = "STEP_2"; - public static final String VALIDATE_REQUEST = "VALIDATE_REQUEST"; - public static final String CALL_UPDATE_SUCCESSFULLY_MSG = "call.update.successfully"; - public static final String CALL_NOT_FOUND = "call.not.found"; + public static final String FORM_NOT_FOUND_FOR_CALL_ID = "form.not.found.for.call.id"; + public static final String STEP_1 = "STEP_1"; + public static final String STEP_2 = "STEP_2"; + public static final String VALIDATE_REQUEST = "VALIDATE_REQUEST"; + public static final String CALL_UPDATE_SUCCESSFULLY_MSG = "call.update.successfully"; + public static final String CALL_NOT_FOUND = "call.not.found"; public static final String CALL_FETCH_SUCCESS_MSG = "call.fetch.success"; public static final String EVALUATION_CRITERIA_NOT_FOUND = "evaluation.criteria.not.found"; @@ -74,7 +74,7 @@ public class GepafinConstant { public static final String EVALUATION_CRITERIA_FETCH_SUCCESSFULLY = "evaluation.criteria.fetch.successfully"; public static final String EVALUATION_CRITERIA_UPDATED_SUCCESSFULLY = "evaluation.criteria.updated.successfully"; public static final String EVALUATION_CRITERIA_DELETED_SUCCESSFULLY = "evaluation.criteria.deleted.successfully"; - public static final String SCORE_NOT_NULL_MSG="score.not.null"; + public static final String SCORE_NOT_NULL_MSG = "score.not.null"; public static final String FAQ_NOT_FOUND = "faq.not.found"; public static final String FAQ_CREATED_SUCCESSFULLY = "faq.created.successfully"; public static final String FAQ_FETCHED_SUCCESSFULLY = "faq.fetched.successfully"; @@ -102,42 +102,41 @@ public class GepafinConstant { public static final String INVALID_STATUS_CHANGE_FROM_DRAFT = "invalid.status.change.from.draft"; public static final String INVALID_STATUS_CHANGE_FROM_PUBLISH = "invalid.status.change.from.publish"; public static final String STATUS_CANNOT_BE_CHANGED = "status.cannot.be.changed"; - public static final String PUBLISHED_CALL_NOT_UPDATE = "published.call.not.update"; + public static final String PUBLISHED_CALL_NOT_UPDATE = "published.call.not.update"; public static final String INVALID_USER = "invalid_user"; - public static final String FLOW_CREATED_SUCCESSFULLY="flow.created.successfully"; - public static final String FLOW_FETCHED_SUCCESSFULLY="flow.fetched.successfully"; - public static final String FLOW_ALREADY_EXISTS="flow.already.exists"; - public static final String FLOW_REQUEST_NOT_PROPER="flow.request.not.complete"; + public static final String FLOW_CREATED_SUCCESSFULLY = "flow.created.successfully"; + public static final String FLOW_FETCHED_SUCCESSFULLY = "flow.fetched.successfully"; + public static final String FLOW_ALREADY_EXISTS = "flow.already.exists"; + public static final String FLOW_REQUEST_NOT_PROPER = "flow.request.not.complete"; public static final String APPLICATION_CREATED_SUCCESS_MSG = "application.created.success"; public static final String APPLICATION_UPDATED_SUCCESS_MSG = "application.updated.success"; public static final String DELETE_APPLICATION_SUCCESS_MSG = "application.deleted.success"; public static final String GET_APPLICATION_SUCCESS_MSG = "application.get.success"; public static final String APPLICATION_NOT_FOUND_MSG = "application.not.found"; - public static final String APPLICATION_FORM_FIELD_NOT_FOUND="application.form.field.not.found"; - public static final String FORM_ID_DOES_NOT_MACTHES="Form.not.matches.to.call.initial.form"; + public static final String APPLICATION_FORM_FIELD_NOT_FOUND = "application.form.field.not.found"; + public static final String FORM_ID_DOES_NOT_MACTHES = "Form.not.matches.to.call.initial.form"; public static final String VALIDATION_FIELD_REQUIRED = "validation.field.required"; public static final String VALIDATION_FIELD_MIN_LENGTH = "validation.field.min_length"; public static final String VALIDATION_FIELD_MAX_LENGTH = "validation.field.max_length"; public static final String VALIDATION_FIELD_PATTERN = "validation.field.pattern"; public static final String VALIDATION_FIELD_NOT_NULL = "validation.field.not_null"; public static final String VALIDATION_FIELD_NOT_EMPTY = "validation.field.not_empty"; - public static final String APPLICATION_ALREADY_EXISTS="application.already.exists"; - // public static final String NEXT_FORM_NOT_FOUND = "next.form.not.found"; - // public static final String PREVIOUS_FORM_NOT_FOUND = "previous.form.not.found"; - public static final String CURRENT_FORM_INCOMPLETE = "current.form.incomplete"; + public static final String APPLICATION_ALREADY_EXISTS = "application.already.exists"; + // public static final String NEXT_FORM_NOT_FOUND = "next.form.not.found"; + // public static final String PREVIOUS_FORM_NOT_FOUND = "previous.form.not.found"; + public static final String CURRENT_FORM_INCOMPLETE = "current.form.incomplete"; public static final String FLOW_NOT_FOUND = "flow.not.found"; - public static final String VALIDATION_MESSAGE = "validation.message"; - public static final String ACTION_REQUIRED = "action.required"; - public static final String CALL_NOT_PUBLISHED="call.not.published"; - public static final String APPLICATION_ALREADY_SUBMITTED="application.already.submitted"; - public static final String INITAL_AND_FINAL_FORM_CANNOT_NULL="initial.and.final.form.cannot.null"; - public static final String APPLICATION_FORM_NOT_FOUND="application.form.not.found"; - public static final String UPDATING_FORM_VALUE_IMPACT_ON_FLOW="updating.form.value.impact.on.flow"; + public static final String VALIDATION_MESSAGE = "validation.message"; + public static final String ACTION_REQUIRED = "action.required"; + public static final String CALL_NOT_PUBLISHED = "call.not.published"; + public static final String APPLICATION_ALREADY_SUBMITTED = "application.already.submitted"; + public static final String INITAL_AND_FINAL_FORM_CANNOT_NULL = "initial.and.final.form.cannot.null"; + public static final String APPLICATION_FORM_NOT_FOUND = "application.form.not.found"; + public static final String UPDATING_FORM_VALUE_IMPACT_ON_FLOW = "updating.form.value.impact.on.flow"; public static final String APPLICATION_IS_INCOMPLETE_MSG = "application.is.incomplete"; public static final String AUTHORIZATION = "Authorization"; public static final String CHECK_VATNUMBER_V2_NEW_URL = "https://imprese.openapi.it/advance"; - public static final String VATNUMBER_V2 = "https://imprese.openapi.it/advance"; - public static final String VALIDATION_FIELD_CUSTOM="validation.field.custom"; + public static final String VALIDATION_FIELD_CUSTOM = "validation.field.custom"; public static final String VALIDATION_CODICE_FISCALE = "validation.codice.fiscale"; public static final String VALIDATION_CAP = "validation.cap"; public static final String VALIDATION_IBAN = "validation.iban"; @@ -146,17 +145,95 @@ public class GepafinConstant { public static final String VALIDATION_URL = "validation.url"; public static final String VALIDATION_MARCA_DA_BOLLO = "validation.marca.da.bollo"; public static final String VALIDATION_PIVA = "validation.piva"; - public static final String VALIDATION_VALID_PIVA="valid.vat.number"; - public static final String IS_MARCA_DA_BOLLO="isMarcaDaBollo"; - public static final String IS_URL="isUrl"; - public static final String IS_EMAIL_PEC="isEmailPEC"; - public static final String IS_EMAIL="isEmail"; - public static final String IS_IBAN="isIBAN"; - public static final String IS_CAP="isCAP"; - public static final String IS_CODICE_FISCALE="isCodiceFiscale"; - public static final String IS_PIVA="isPIVA"; + public static final String VALIDATION_VALID_PIVA = "valid.vat.number"; + public static final String IS_MARCA_DA_BOLLO = "isMarcaDaBollo"; + public static final String IS_URL = "isUrl"; + public static final String IS_EMAIL_PEC = "isEmailPEC"; + public static final String IS_EMAIL = "isEmail"; + public static final String IS_IBAN = "isIBAN"; + public static final String IS_CAP = "isCAP"; + public static final String IS_CODICE_FISCALE = "isCodiceFiscale"; + public static final String IS_PIVA = "isPIVA"; + public static final String FAILED_RETAIN_FIELD = "failed.retain.field"; + public static final String USER_ALREADY_EXIST_MSG = "user.already.exist.msg"; + public static final String TOKEN_VALIDATE_SUCCESS_MSE = "token.validate.success"; + public static final String INVALID_REQUEST = "invalid.request"; + public static final String CODICE_FISCALE_EXISTS = "codice.fiscale.exists"; + public static final String TOTAL_STEPS_NOT_BE_ZERO = "total.steps.not.zero"; + public static final String COMPLETED_STEPS_NOT_VALID = "completed.steps.not.valid"; + public static final String FIELD_ID_NOT_FOUND = "field.id.not.found"; + public static final String VALIDATE_EMAIL = "validate.email"; + public static final String ROLE_ID_MANDATORY = "role.id.mandatory"; + public static final String VALIDATE_PASSWORD = "validate.password"; + + public static final String COMPANY_CREATED_SUCCESS_MSG = "company.created.success"; + public static final String COMPANY_UPDATED_SUCCESS_MSG = "company.updated.success"; + public static final String COMPANY_DELETE_SUCCESS_MSG = "company.delete.success"; + public static final String COMPANY_GET_SUCCESS_MSG = "company.get.success"; + public static final String COMPANY_NOT_FOUND_MSG = "company.not.found"; + public static final String CHECK_VATNUMBER_SUCCESS_MSG = "check.vatnumber.success"; + public static final String INVALID_VATNUMBER = "invalid.vatnumber"; + public static final String VATNUMBER_MANDATORY = "vatnumber.mandatory"; + public static final String VATNUMBER_ALREADY_EXISTS = "vatnumber.already.exists"; + public static final String INVALID_EMAIL = "invalid.email"; + public static final String UNAUTHORIZED = "UNAUTHORIZED"; + public static final String COMPANY_ID_MANDATORY = "company.id.mandatory"; + public static final String USER_ALREADY_CONNECTED_TO_COMPANY = "user.already.connected.to.company"; + public static final String YYYY_MM_DD_DASH = "yyyy-MM-dd"; + public static final String YYYY_MM_DD_SLASH = "yyyy/MM/dd"; + public static final String DELEGATION_TEMPLATE = "DELEGATION_TEMPLATE"; + public static final String VALIDATION_ERROR_MISSING_FIRSTNAME = "validation.error.missing.firstName"; + public static final String VALIDATION_ERROR_MISSING_LASTNAME = "validation.error.missing.lastName"; + public static final String VALIDATION_ERROR_MISSING_CODICEFISCALE = "validation.error.missing.codiceFiscale"; + public static final String DELEGATION_FILE_UPLOAD_SUCCESS = "delegation.file.upload.success"; + public static final String DELEGATION_FETCH_SUCCESS = "delegation.fetch.success"; + public static final String DELEGATION_TEMPLATE_GENERATION_ERROR = "delegation.template.generation.error"; + public static final String VALIDATION_ERROR_FILE_EMPTY = "validation.error.file.empty"; + public static final String VALIDATION_ERROR_FILE_INVALIDTYPE = "validation.error.file.invalidType"; + public static final String UPLOAD_ERROR_S3 = "upload.error.s3"; + + public static final String CALL_NOT_STARTED_YET = "call.not.started.yet"; + public static final String CALL_ALREADY_ENDED = "call.already.ended"; + public static final String APPLICATION_STATUS_UPDATED_SUCCESSFULLY = "application.status.updated.successfully"; + public static final String APPLICATION_ALREADY_IN_PREVIOUS_STATUS = "application.already.in.provided.status"; + public static final String DELEGATION_NOT_FOUND = "delegation.not.found"; + public static final String USER_COMPANY_RELATION_NOT_FOUND = "user.company.relation.not.found"; + public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success"; + public static final String HH_MM_SS = "HH:mm:ss"; + + public static final String USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION = "user.not.authorized.create.application"; + public static final String APPLICATION_SUBMITTED_CANNOT_CHANGE = "application.submitted.cannot.change"; + public static final String CALL_DOCUMENTS_FETCH_SUCCESS_MSG = "call.documents.fetch.success"; + public static final String CALL_DOCUMENTS_NOT_FOUND_MSG = "call.documents.not.found"; + + public static final String BENEFICIARY_PREFERRED_CALL_CREATED_SUCCESS_MSG = "beneficiary.preferred.call.created.success"; + public static final String GET_BENEFICIARY_PREFERRED_CALL_SUCCESS_MSG = "beneficiary.preferred.call.get.success"; + public static final String DELETE_BENEFICIARY_PREFERRED_CALL_SUCCESS_MSG = "beneficiary.preferred.call.delete.success"; + public static final String GET_BENEFICIARY_PREFERRED_CALLS_SUCCESS_MSG = "beneficiary.preferred.calls.get.success"; + public static final String BENEFICIARY_PREFERRED_CALL_UPDATED_SUCCESS_MSG = "beneficiary.preferred.call.updated.success"; + public static final String BENEFICIARY_CALL_NOT_FOUND = "beneficiary.preferred.call.not.found"; + public static final String BENEFICIARY_PREFERRED_CALL_STATUS_UPDATED_SUCCESS_MSG = "beneficiary.preferred.call.status.updated.success"; + public static final String GET_ALL_BENEFICIARY_PREFERRED_CALLS_SUCCESS_MSG = "beneficiary.preferred.calls.get.all.success"; + public static final String USER_ID_AND_BENEFICIARY_ID_ERROR = "userId.and.beneficiaryId.error"; + public static final String EITHER_USER_OR_BENEFICIARY_ID_REQUIRED = "either.user.or.beneficiary.id.required"; + public static final String USER_NOT_FOUND_WITH_BENEFICIARYID_MSG = "User.not.found.with.the.given.beneficiaryID"; + public static final String PERMISSION_DENIED = "permission.denied"; + public static final String SIGNED_DOCUMENT_FILE_UPLOAD_SUCCESS = "signed.document.file.upload.success"; + public static final String GET_SIGNED_DOCUMENT_FILE_SUCCESS = "get.signed.document.file.success"; + public static final String APPLICATION_SIGNED_DOCUMENT_NOT_FOUND = "application.signed.document.not.found"; + public static final String DELETE_SIGNED_DOCUMENT_FILE_SUCCESS = "delete.signed.document.file.success"; + public static final String DD_MM_YYYY = "dd/MM/yyyy"; + + public static final String DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY="dashboard.widget.fetched.successfully"; + public static final Integer DEFAULT_PAGE_LIMIT = 1000; + public static final Integer DEFAULT_PAGE = 1; + public static final String ATTEMPT_DATE = "attemptDate"; + public static final String LOGIN_ATTEMPTED_CREATED_SUCCESSFULLY="login_attempt_successfully_created"; + public static final String GET_LOGIN_ATTEMPT_MSG="get_login_attempt_se_msg"; + public static final String CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT = "application.in.submit.status.cannot.delete.company"; + public static final String GET_USERS_SUCCESS_MSG = "get.users.success.msg"; + public static final String CANNOT_CREATE_BENEFICIARY_USER="cannot.create.beneficiary.user"; - public static final String FAILED_RETAIN_FIELD="failed.retain.field"; public static final String HUB_CREATE_SUCCESS = "hub_create_success"; public static final String HUB_UPDATE_SUCCESS = "hub_update_success"; public static final String HUB_GET_SUCCESS = "hub_get_success"; @@ -164,3 +241,4 @@ public class GepafinConstant { public static final String HUB_DELETE_SUCCESS = "hub_delete_success"; public static final String HUB_NOT_FOUND = "hub_not_found"; } + diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index d153ed5c..83c93371 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -3,30 +3,46 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; +import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationRequest; import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.*; -import net.gepafin.tendermanagement.repositories.ApplicationFormFieldRepository; -import net.gepafin.tendermanagement.repositories.ApplicationFormRepository; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.*; +import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.DocumentService; import net.gepafin.tendermanagement.service.FormService; +import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.FieldValidator; +import net.gepafin.tendermanagement.util.MailUtil; import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.util.Validator; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import jakarta.persistence.criteria.Predicate; +import jakarta.servlet.http.HttpServletRequest; + +import java.text.MessageFormat; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.*; import java.util.stream.Collectors; @@ -56,11 +72,61 @@ public class ApplicationDao { @Autowired private CallDao callDao; - public ApplicationResponseBean createApplication(ApplicationRequestBean applicationRequestBean, UserEntity userEntity, Long formId,Long applicationId) { + @Autowired + private FlowFormDao flowFormDao; + + @Autowired + private FlowEdgesRepository flowEdgesRepository; + + @Autowired + private FlowDataRepository flowDataRepository; + + @Autowired + private UserCompanyDelegationRepository userCompanyDelegationRepository; + + @Autowired + private Validator validator; + + @Autowired + private CompanyService companyService; + + @Autowired + private ProtocolRepository protocolRepository; + + @Autowired + private SystemEmailTemplatesService systemEmailTemplatesService; + + @Autowired + private MailUtil mailUtil; + + @Value("${default_System_Receiver_Email}") + private String defaultSystemReceiverEmail; + + @Value("${gepafin_email}") + private String gepafinEmail; + + @Value("${rinaldo_email}") + private String rinaldoEmail; + + @Value("${carlo_email}") + private String carloEmail; + + @Autowired + private AmazonS3Service amazonS3Service; + + @Autowired + private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; + + @Value("${aws.s3.url.folder.signed.document}") + private String signedDocumentS3Folder; + + + public ApplicationResponseBean createApplication(ApplicationRequestBean applicationRequestBean, UserEntity userEntity, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); - CallEntity call = callService.validatePublishedCall(formEntity.getCall().getId()); +// callService.validatePublishedCall(formEntity.getCall().getId()); + validateFormFields(applicationRequestBean,formEntity); ApplicationEntity applicationEntity = validateApplication(applicationId); - if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))){ + if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_SUBMITTED)); } formService.validateFormField(applicationRequestBean.getFormFields(),applicationEntity,formEntity); @@ -68,18 +134,25 @@ public class ApplicationDao { createOrUpdateMultipleFormFields(applicationRequestBean.getFormFields(), applicationFormEntity,formEntity); return getApplicationById(applicationEntity.getId(),formEntity.getId()); } + public void validateDelegation(UserEntity user, CompanyEntity company) { + UserWithCompanyEntity userWithCompany = companyService.getUserWithCompanyEntity(user.getId(), company.getId()); + + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository + .findByUserIdAndCompanyIdAndStatus(user.getId(), company.getId(), + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + + if (!userWithCompany.getIsLegalRepresentant() && userCompanyDelegationEntity == null) { + throw new CustomValidationException(Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION)); + } + } + public ApplicationFormEntity saveApplicationFormEntity(ApplicationFormEntity applicationFormEntity) { ApplicationFormEntity applicationFormEntity1 = applicationFormRepository.save(applicationFormEntity); return applicationFormEntity1; } - public void validateFormId(FormEntity formEntity, CallEntity callEntity) { - if (Boolean.FALSE.equals(formEntity.getId().equals(callEntity.getInitialForm()))) { - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.FORM_ID_DOES_NOT_MACTHES)); - } - } - public ApplicationFormEntity createApplicationFormEntity(ApplicationEntity application, FormEntity formEntity) { ApplicationFormEntity applicationFormEntity = new ApplicationFormEntity(); applicationFormEntity.setApplication(application); @@ -88,9 +161,11 @@ public class ApplicationDao { return applicationFormEntity; } - public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call) { + public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call, CompanyEntity companyEntity) { + validateDelegation(user,companyEntity); ApplicationEntity entity = new ApplicationEntity(); - entity.setUser(user); + entity.setUserId(user.getId()); + entity.setCompany(companyEntity); entity.setCall(call); entity.setIsDeleted(false); entity.setStatus(ApplicationStatusTypeEnum.DRAFT.getValue()); @@ -103,7 +178,6 @@ public class ApplicationDao { ApplicationEntity applicationEntity = validateApplication(id); ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),formId); List applicationFormFieldResponseBeans=new ArrayList<>(); - ApplicationFormFieldResponseBean applicationFormFieldResponseBeans1=null; List applicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); applicationFormFieldResponseBeans=createApplicationFormFieldResponse(applicationFormFieldEntities, applicationFormEntity, applicationFormFieldResponseBeans); ApplicationResponseBean applicationResponseBean= convertApplicationEntityToApplicationResponseBean(applicationEntity); @@ -164,58 +238,102 @@ public class ApplicationDao { log.info("Application deleted with ID: {}", id); } - public List getAllApplications(UserEntity userEntity, Long callId) { - RoleStatusEnum roleStatus = RoleStatusEnum.valueOf(userEntity.getRoleEntity().getRoleType()); - boolean isBeneficiary = RoleStatusEnum.ROLE_BENEFICIARY.equals(roleStatus); - - log.info("Fetching applications for RoleType: {}", roleStatus); - List applicationResponses = new ArrayList<>(); +// public List getAllApplications(UserEntity userEntity, Long callId, CompanyEntity companyEntity) { +// boolean isBeneficiary = validator.checkIsBeneficiary(); +// +// log.info("Fetching applications for RoleType: {}", userEntity.getRoleEntity().getRoleType()); +// List applicationResponses = new ArrayList<>(); +// +// if (callId != null) { +// // Fetch based on callId and user if role is BENEFICIARY, otherwise fetch all for the call +// log.info("Fetching applications for callId: {}", callId); +// CallEntity call = callService.validateCall(callId); +// +// // Use a single method to handle both conditions for consistency +// List applicationEntities = isBeneficiary +// ? applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), call.getId()) +// .map(List::of) // Convert Optional to a List of one element +// .orElse(List.of()) // If not present, return an empty list +// : applicationRepository.findByCallIdAndIsDeletedFalse(call.getId()); +// +// applicationResponses = applicationEntities.stream() +// .map(this::getApplicationResponse) +// .collect(Collectors.toList()); +// +// } else { +// // Fetch all applications for the user if BENEFICIARY, or fetch all applications in general +// List applicationEntities = isBeneficiary +// ? applicationRepository.findByUserIdAndIsDeletedFalse(companyEntity.getId()) +// : applicationRepository.findByIsDeletedFalse(); +// +// applicationResponses = applicationEntities.stream() +// .map(this::getApplicationResponse) +// .collect(Collectors.toList()); +// } +// +// return applicationResponses; +// } + + public List getAllApplications(UserEntity userEntity, Long callId, Long companyId) { + + log.info("Fetching applications for RoleType: {}", userEntity.getRoleEntity().getRoleType()); - if (callId != null) { - // Fetch based on callId and user if role is BENEFICIARY, otherwise fetch all for the call - log.info("Fetching applications for callId: {}", callId); - CallEntity call = callService.validateCall(callId); + Specification spec = search(userEntity.getId(), callId, companyId); - // Use a single method to handle both conditions for consistency - List applicationEntities = isBeneficiary - ? applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), call.getId()) - .map(List::of) // Convert Optional to a List of one element - .orElse(List.of()) // If not present, return an empty list - : applicationRepository.findByCallIdAndIsDeletedFalse(call.getId()); + List applicationEntities = applicationRepository.findAll(spec); - applicationResponses = applicationEntities.stream() - .map(this::getApplicationResponse) - .collect(Collectors.toList()); - - } else { - // Fetch all applications for the user if BENEFICIARY, or fetch all applications in general - List applicationEntities = isBeneficiary - ? applicationRepository.findByUserIdAndIsDeletedFalse(userEntity.getId()) - : applicationRepository.findByIsDeletedFalse(); - - applicationResponses = applicationEntities.stream() - .map(this::getApplicationResponse) - .collect(Collectors.toList()); - } - - return applicationResponses; + return applicationEntities.stream() + .map(this::getApplicationResponse) + .collect(Collectors.toList()); } - private ApplicationResponse getApplicationResponse(ApplicationEntity applicationEntity) { + private Specification search(Long userId, Long callId, Long companyId) { + return (root, query, builder) -> { + Boolean isBeneficiary = validator.checkIsBeneficiary(); + Predicate predicate = builder.isFalse(root.get("isDeleted")); + if (isBeneficiary) { + predicate = builder.and(predicate, builder.equal(root.get("userId"), userId)); + } + if (callId != null) { + predicate = builder.and(predicate, builder.equal(root.get("call").get("id"), callId)); + } + if (companyId != null) { + predicate = builder.and(predicate, builder.equal(root.get("company").get("id"), companyId)); + } + return predicate; + }; + } + + private ApplicationResponse getApplicationResponse(ApplicationEntity applicationEntity) { ApplicationResponse responseBean = new ApplicationResponse(); + List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); + Long totalFormSteps = flowFormDao.calculateTotalSteps(flowEdgesList); + Long completedSteps= Long.valueOf(flowFormDao.getCompletedSteps(applicationEntity)); + Integer progress=calculateProgress(totalFormSteps,completedSteps); responseBean.setId(applicationEntity.getId()); + responseBean.setProgress(progress); + responseBean.setCallTitle(applicationEntity.getCall().getName()); + responseBean.setCallEndDate(applicationEntity.getCall().getEndDate()); + responseBean.setModifiedDate(applicationEntity.getCall().getUpdatedDate()); responseBean.setCallId(applicationEntity.getCall().getId()); responseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); responseBean.setStatus(applicationEntity.getStatus()); responseBean.setComments(applicationEntity.getComments()); + responseBean.setCompanyId(applicationEntity.getCompany().getId()); + responseBean.setCompanyName(applicationEntity.getCompany().getCompanyName()); + if(applicationEntity.getProtocol() != null) { + responseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); + } return responseBean; } - public ApplicationEntity validateApplication(Long id) { - ApplicationEntity applicationEntity= applicationRepository.findById(id).orElseThrow(() ->new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); - return applicationEntity; - } + public ApplicationEntity validateApplication(Long id) { + ApplicationEntity applicationEntity = applicationRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); + return applicationEntity; + } private ApplicationResponseBean convertApplicationEntityToApplicationResponseBean(ApplicationEntity entity) { ApplicationResponseBean response = new ApplicationResponseBean(); @@ -226,6 +344,9 @@ public class ApplicationDao { response.setCallId(entity.getCall().getId()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); + if(entity.getProtocol() != null) { + response.setProtocolNumber(entity.getProtocol().getProtocolNumber()); + } return response; } @@ -259,6 +380,9 @@ public class ApplicationDao { for (ApplicationFormFieldEntity applicationFormFieldEntity1 : applicationFormFieldEntities) { if (applicationFormFieldEntity1.getFieldId().equals(applicationFormFieldRequestBean.getFieldId())) { applicationFormFieldEntity = applicationFormFieldEntity1; + if(applicationFormEntity.getForm().getId().equals(applicationFormEntity.getApplication().getCall().getInitialForm())){ + validateRequiredFields(applicationFormEntity.getForm(),applicationFormEntity.getApplication(), applicationFormFieldRequestBean.getFieldId()); + } break; } else { applicationFormFieldEntity = new ApplicationFormFieldEntity(); @@ -267,7 +391,13 @@ public class ApplicationDao { } } Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); - Utils.setIfUpdated(applicationFormFieldEntity::getFieldValue, applicationFormFieldEntity::setFieldValue, applicationFormFieldRequestBean.getFieldValue()); + + if(applicationFormFieldRequestBean.getFieldValue() !=null ) { + applicationFormFieldEntity.setFieldValue(Utils.convertObjectToJsonString(applicationFormFieldRequestBean.getFieldValue())); + } + if(applicationFormFieldRequestBean.getFieldValue() ==null ) { + applicationFormFieldEntity.setFieldValue(null); + } return applicationFormFieldRepository.save(applicationFormFieldEntity); } @@ -275,10 +405,15 @@ public class ApplicationDao { List documentIds=null; List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); for (ContentResponseBean contentResponseBean:contentResponseBeans){ - if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))){ - if(contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { - String documentId = applicationFormFieldRequestBean.getFieldValue(); - documentIds = validateDocumentIds(documentId); + if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))) { + if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { + Object fieldValueObject = applicationFormFieldRequestBean.getFieldValue(); + if (fieldValueObject instanceof String) { + // Safely cast the object to a string + String documentId = (String) fieldValueObject; + // Now you can use documentId as needed + documentIds = validateDocumentIds(documentId); + } } } } @@ -319,7 +454,9 @@ public class ApplicationDao { ApplicationFormFieldResponseBean applicationFormFieldResponseBean = new ApplicationFormFieldResponseBean(); applicationFormFieldResponseBean.setApplicationFormId(applicationFormId); applicationFormFieldResponseBean.setFieldId(applicationFormFieldEntity.getFieldId()); - applicationFormFieldResponseBean.setFieldValue(applicationFormFieldEntity.getFieldValue()); + if(applicationFormFieldEntity.getFieldValue() != null) { + applicationFormFieldResponseBean.setFieldValue(Utils.getFieldValueAsObject(applicationFormFieldEntity.getFieldValue())); + } applicationFormFieldResponseBean.setId(applicationFormFieldEntity.getId()); applicationFormFieldResponseBean.setCreatedDate(applicationFormFieldEntity.getCreatedDate()); applicationFormFieldResponseBean.setUpdatedDate(applicationFormFieldEntity.getUpdatedDate()); @@ -330,15 +467,19 @@ public class ApplicationDao { return applicationEntity; } - public ApplicationGetResponseBean getApplicationByFormId( Long applicationId,Long formId, UserEntity userEntity) { + public ApplicationGetResponseBean getApplicationByFormId( Long applicationId, Long formId, UserEntity userEntity) { List formApplicationResponses = new ArrayList<>(); List formEntities = new ArrayList<>(); - ApplicationEntity applicationEntity = applicationRepository.findById(applicationId) + boolean isBeneficiary = isBeneficiary(userEntity); + ApplicationEntity applicationEntity = isBeneficiary + ? applicationRepository.findByIdAndUserIdAndIsDeletedFalse(applicationId, userEntity.getId()) + .orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))) + : applicationRepository.findById(applicationId) + .stream().findFirst() .orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); - if (formId != null) { FormEntity formEntity = formService.validateForm(formId); - Optional application = applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), + Optional application = applicationRepository.findByIdAndUserIdAndCallIdAndIsDeletedFalse(applicationId, userEntity.getId(), formEntity.getCall().getId()); applicationEntity=application.get(); formEntities.add(formEntity); @@ -356,6 +497,12 @@ public class ApplicationDao { return createApplicationGetResponseBean(applicationEntity, formEntities, formApplicationResponses); } + private boolean isBeneficiary(UserEntity userEntity) { + RoleStatusEnum roleStatus = RoleStatusEnum.valueOf(userEntity.getRoleEntity().getRoleType()); + boolean isBeneficiary = RoleStatusEnum.ROLE_BENEFICIARY.equals(roleStatus); + return isBeneficiary; + } + private void addFormApplication(FormEntity formEntity, ApplicationEntity applicationEntity, List formApplicationResponses) { FormApplicationResponse formApplicationResponse = processForm(formEntity, applicationEntity); @@ -379,7 +526,7 @@ public class ApplicationDao { } private ApplicationGetResponseBean createApplicationGetResponseBean(ApplicationEntity applicationEntity, List formEntities, List formApplicationResponses) { - ApplicationGetResponseBean applicationGetResponseBean =createApplicationGetResponseBean(applicationEntity); + ApplicationGetResponseBean applicationGetResponseBean = createApplicationGetResponseBean(applicationEntity); applicationGetResponseBean.setForm(formApplicationResponses); return applicationGetResponseBean; } @@ -392,6 +539,11 @@ public class ApplicationDao { applicationGetResponseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); applicationGetResponseBean.setCallId(applicationEntity.getCall().getId()); applicationGetResponseBean.setCallTitle(applicationEntity.getCall().getName()); + applicationGetResponseBean.setCompanyId(applicationEntity.getCompany().getId()); + if(applicationEntity.getProtocol() != null) { + applicationGetResponseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); + } + applicationGetResponseBean.setCompanyName(applicationEntity.getCompany().getCompanyName()); return applicationGetResponseBean; } @@ -404,51 +556,289 @@ public class ApplicationDao { return formApplicationResponse; } - public ApplicationResponse createApplicationByCallId(ApplicationRequest applicationRequest,Long callId,UserEntity userEntity){ - CallEntity call=callService.validateCall(callId); - call = callService.validatePublishedCall(call.getId()); - checkIfApplicationExists(call,userEntity); - ApplicationEntity applicationEntity=createApplicationEntity(userEntity,call); - applicationEntity.setComments(applicationRequest.getComments()); - applicationEntity=saveApplicationEntity(applicationEntity); - ApplicationResponse applicationResponse=getApplicationResponse(applicationEntity); - return applicationResponse; - } - public void checkIfApplicationExists(CallEntity call,UserEntity userEntity){ - Optional applicationEntity=applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(),call.getId()); + public ApplicationResponse createApplicationByCallId(CompanyEntity companyEntity, + ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) { + CallEntity call = callService.validateCall(callId); +// call = callService.validatePublishedCall(call.getId()); + checkIfApplicationExists(call, companyEntity, userEntity); + ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity); + applicationEntity.setComments(applicationRequest.getComments()); + applicationEntity = saveApplicationEntity(applicationEntity); + ApplicationResponse applicationResponse = getApplicationResponse(applicationEntity); + return applicationResponse; + } + public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity, UserEntity userEntity){ + Optional applicationEntity=applicationRepository.findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId(),call.getId()); if(applicationEntity.isPresent()){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); } } - - public ApplicationEntity getApplicationByCallAndUser(CallEntity call, UserEntity userEntity) { - return applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), call.getId()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); - - } - - public void updateApplicationStatus(Long applicationId, ApplicationStatusTypeEnum status) { + public ApplicationResponse updateApplicationStatus(UserEntity userEntity, Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); + if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); + } + if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))){ + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS)); + } if (status.equals(ApplicationStatusTypeEnum.SUBMIT)) { - CallEntity callEntity = applicationEntity.getCall(); - Long initialFormId = callEntity.getInitialForm(); - Long finalFormId = callEntity.getFinalForm(); -// if (initialFormId == null || finalFormId == null) { + callService.validatePublishedCall(applicationEntity.getCall().getId()); +// CallEntity callEntity = applicationEntity.getCall(); +// Long initialFormId = callEntity.getInitialForm(); +// Long finalFormId = callEntity.getFinalForm(); +//// if (initialFormId == null || finalFormId == null) { +//// throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); +//// } +// ApplicationFormEntity initialApplicationForm = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), initialFormId); +// ApplicationFormEntity finalApplicationForm = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), finalFormId); +// if (initialApplicationForm == null || finalApplicationForm == null) { // throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); // } - ApplicationFormEntity initialApplicationForm = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), initialFormId); - ApplicationFormEntity finalApplicationForm = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), finalFormId); - if (initialApplicationForm == null || finalApplicationForm == null) { + List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); + Long totalSteps=flowFormDao.calculateTotalSteps(flowEdgesList); + Integer completedSteps=flowFormDao.getCompletedSteps(applicationEntity); + if (totalSteps.intValue() != completedSteps) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); } + Long maxProtocolNumber=protocolRepository.findMaxProtocolNumber(); + Long protocolNumber = (maxProtocolNumber != null) ? maxProtocolNumber + 1 : 1; + ProtocolEntity protocolEntity=createProtocolEntity(applicationEntity,protocolNumber); + applicationEntity.setProtocol(protocolEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + sendMailToUserAndCompany(userEntity, applicationEntity); + sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity); } else { applicationEntity.setStatus(status.getValue()); } - saveApplicationEntity(applicationEntity); + applicationEntity = saveApplicationEntity(applicationEntity); + + return getApplicationResponse(applicationEntity); } + + public Integer calculateProgress(Long totalSteps, Long completedSteps) { + if (FieldValidator.isNullOrZero(totalSteps)) { + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.TOTAL_STEPS_NOT_BE_ZERO)); + } + + if (completedSteps < 0 || completedSteps > totalSteps) { + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.COMPLETED_STEPS_NOT_VALID)); + } + + double progress = ((double) completedSteps / totalSteps) * 100; + return (int) Math.round(progress); + } + public void validateFormFields(ApplicationRequestBean request, FormEntity formEntity) { + + List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); + + List requestFields = request.getFormFields(); + + Map contentMap = contentResponseBeans.stream() + .collect(Collectors.toMap(ContentResponseBean::getId, ContentResponseBean::getLabel)); // Change getLabel() if needed + FieldValidator validator = FieldValidator.create(); + for (ApplicationFormFieldRequestBean requestField : requestFields) { + String fieldId = requestField.getFieldId(); + + if (!contentMap.containsKey(fieldId)) { + validator.addError(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_ID_NOT_FOUND), fieldId)); + } + + } + validator.validate(); + } + + public void validateRequiredFields(FormEntity formEntity, ApplicationEntity applicationEntity, String fieldId) { + FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndCallId( + formEntity.getId(), applicationEntity.getCall().getId()); + + if (flowDataEntity == null) { + return; + } + + ApplicationFormFieldEntity applicationFormFieldEntity = applicationFormFieldRepository + .findByFieldIdAndApplicationFormFormIdAndApplicationFormApplicationId( + flowDataEntity.getChoosenField(), formEntity.getId(), applicationEntity.getId()) + .orElse(null); + + if (applicationFormFieldEntity == null || !fieldId.equals(applicationFormFieldEntity.getFieldId())) { + return; + } + List nextFormIds = flowEdgesRepository.findBySourceIdAndCallId( + formEntity.getId(), applicationEntity.getCall().getId()) + .stream() + .map(FlowEdgesEntity::getTargetId) + .collect(Collectors.toList()); + + Optional nextFormIdOptional = flowDataRepository.findByChoosenValueAndFormIdIn( + applicationFormFieldEntity.getFieldValue(), nextFormIds) + .map(FlowDataEntity::getFormId); + + if (nextFormIdOptional.isPresent()) { + Long nextFormId = nextFormIdOptional.get(); + + FormEntity nextForm = formService.validateForm(nextFormId); + ApplicationFormEntity nextApplicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId( + applicationEntity.getId(), nextForm.getId()); + + if (nextApplicationFormEntity != null) { + List nextApplicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(nextApplicationFormEntity.getId()); + applicationFormFieldRepository.deleteAll(nextApplicationFormFieldEntities); + applicationFormRepository.delete(nextApplicationFormEntity); + } + } + } + + public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber){ + ProtocolEntity protocolEntity=new ProtocolEntity(); + protocolEntity.setCall(applicationEntity.getCall().getId()); + LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + protocolEntity.setYear(utcDateTime.getYear()); + protocolEntity.setProtocolNumber(protocolNumber); + protocolEntity.setTime(LocalTime.now()); + protocolEntity.setApplicationId(applicationEntity.getId()); + protocolRepository.save(protocolEntity); + return protocolEntity; + } + private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { + CallEntity call =applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService + .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, + call, null); + + // Create the map for subject placeholders + Map subjectPlaceholders = new HashMap<>(); + subjectPlaceholders.put("{{call_name}}", call.getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); + + // Create the map for body placeholders + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", call.getName()); + bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString()); + bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY)); + bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS)); + + // Replace placeholders in the subject and body + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + + String email = userEntity.getEmail(); + if (userEntity.getBeneficiary() != null) { + email = userEntity.getBeneficiary().getEmail(); + } + mailUtil.sendByMailGun(subject, body, List.of(email), null); + mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null); + + } + + private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) { + CallEntity call = applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService + .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN, + call, null); + + // Create the map for subject placeholders + Map subjectPlaceholders = new HashMap<>(); + subjectPlaceholders.put("{{call_name}}", call.getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); + + // Create the map for body placeholders + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", call.getName()); + bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString()); + bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY)); + bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS)); + + // Replace placeholders in the subject and body + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + + + mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null); + + } + public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, + MultipartFile file) { + ApplicationEntity applicationEntity = validateApplication(applicationId); + validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validateFileType(file); + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository + .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + if (applicationSignedDocument != null) { + applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); + applicationSignedDocumentRepository.save(applicationSignedDocument); + } + UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = amazonS3Service.uploadFileOnAmazonS3(signedDocumentS3Folder, + file); + applicationSignedDocument = new ApplicationSignedDocumentEntity(); + applicationSignedDocument.setApplication(applicationEntity); + applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName()); + applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath()); + applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + applicationSignedDocumentRepository.save(applicationSignedDocument); + return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); + } + + private ApplicationSignedDocumentResponse convertApplicationSignedDocumentToApplicationSignedDocumentResponse( + ApplicationSignedDocumentEntity applicationSignedDocument) { + ApplicationSignedDocumentResponse applicationSignedDocumentResponse = new ApplicationSignedDocumentResponse(); + applicationSignedDocumentResponse.setId(applicationSignedDocument.getId()); + applicationSignedDocumentResponse.setApplicationId(applicationSignedDocument.getApplication().getId()); + applicationSignedDocumentResponse.setFileName(applicationSignedDocument.getFileName()); + applicationSignedDocumentResponse.setFilePath(applicationSignedDocument.getFilePath()); + applicationSignedDocumentResponse + .setStatus(ApplicationSignedDocumentStatusEnum.valueOf(applicationSignedDocument.getStatus())); + applicationSignedDocumentResponse.setCreatedDate(applicationSignedDocument.getCreatedDate()); + applicationSignedDocumentResponse.setUpdatedDate(applicationSignedDocument.getUpdatedDate()); + return applicationSignedDocumentResponse; + } + + private void validateFileType(MultipartFile file) { + if (file.isEmpty()) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_EMPTY)); + } + String filename = file.getOriginalFilename(); + if (filename == null || !filename.endsWith(".p7m")) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE)); + } + } + + public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) { + + ApplicationEntity applicationEntity = validateApplication(applicationId); + validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository + .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + if(applicationSignedDocument == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); + } + return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); + } + + public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { + ApplicationEntity applicationEntity = validateApplication(applicationId); + validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository + .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + if(applicationSignedDocument == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); + } + applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); + applicationSignedDocumentRepository.save(applicationSignedDocument); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java new file mode 100644 index 00000000..13b0f719 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java @@ -0,0 +1,131 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.BeneficiaryPreferredCallEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; +import net.gepafin.tendermanagement.enums.UserStatusEnum; +import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; + +import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; +import net.gepafin.tendermanagement.repositories.BeneficiaryPreferredCallRepository; +import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; + +@Component +public class BeneficiaryPreferredCallDao { + + private final Logger log = LoggerFactory.getLogger(BeneficiaryPreferredCallDao.class); + + @Autowired + private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository; + @Autowired + private UserService userService; + + public BeneficiaryPreferredCallResponseBean createBeneficiaryPreferredCall(BeneficiaryPreferredCallReq request,UserEntity user) { + log.info("Creating new beneficiary preferred call with details: {}", request); + BeneficiaryPreferredCallEntity entity = convertRequestToEntity(request,user); + entity = beneficiaryPreferredCallRepository.save(entity); + log.info("Beneficiary preferred call created with ID: {}", entity.getId()); + return convertEntityToResponse(entity); + } + + private BeneficiaryPreferredCallEntity convertRequestToEntity(BeneficiaryPreferredCallReq request,UserEntity userEntity) { + BeneficiaryPreferredCallEntity entity = new BeneficiaryPreferredCallEntity(); + UserEntity user= userService.validateUser(userEntity.getId()); + if (user.getBeneficiary()!=null) { + entity.setBeneficiaryId(user.getBeneficiary().getId()); + } + entity.setStatus(BeneficiaryCallStatus.ENABLED.getValue()); + entity.setCallId(request.getCallId()); + entity.setUserId(userEntity.getId()); + entity.setCompanyId(request.getCompanyId()); + return entity; + } + + public BeneficiaryPreferredCallResponseBean getBeneficiaryPreferredCallById(Long id) { + log.info("Fetching beneficiary preferred call with ID: {}", id); + BeneficiaryPreferredCallEntity entity = validateBeneficiaryPreferredCall(id); + log.info("Beneficiary preferred call found: {}", entity); + return convertEntityToResponse(entity); + } +// public BeneficiaryPreferredCallResponseBean updateBeneficiaryPreferredCall(Long id, BeneficiaryPreferredCallReq request, +// UserEntity userEntity) { +// log.info("Updating beneficiary preferred call with ID: {}", id); +// BeneficiaryPreferredCallEntity existingEntity = validateBeneficiaryPreferredCall(id); +// setIfUpdated(existingEntity::getCallId, existingEntity::setCallId, request.getCallId()); +// setIfUpdated(existingEntity::getCompanyId, existingEntity::setCompanyId, request.getCompanyId()); +// +// existingEntity = beneficiaryPreferredCallRepository.save(existingEntity); +// +// log.info("Beneficiary preferred call updated with ID: {}", existingEntity.getId()); +// return convertEntityToResponse(existingEntity); +// } + + private boolean isUserABeneficiary(Long userId) { + UserEntity user=userService.validateUser(userId); + return RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(user.getRoleEntity().getRoleType()); + } + public void deleteBeneficiaryPreferredCallById(Long id) { + log.info("Deleting beneficiary preferred call with ID: {}", id); + validateBeneficiaryPreferredCall(id); + beneficiaryPreferredCallRepository.deleteById(id); + log.info("Beneficiary preferred call deleted with ID: {}", id); + } + + public List getAllBeneficiaryPreferredCalls() { + log.info("Fetching all beneficiary preferred calls"); + List calls = beneficiaryPreferredCallRepository.findAll() + .stream() + .map(this::convertEntityToResponse) + .collect(Collectors.toList()); + log.info("Total beneficiary preferred calls found: {}", calls.size()); + return calls; + } + + private BeneficiaryPreferredCallEntity validateBeneficiaryPreferredCall(Long id) { + log.info("Validating beneficiary preferred call with ID: {}", id); + return beneficiaryPreferredCallRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.BENEFICIARY_CALL_NOT_FOUND))); + } + + private BeneficiaryPreferredCallResponseBean convertEntityToResponse(BeneficiaryPreferredCallEntity entity) { + BeneficiaryPreferredCallResponseBean response = new BeneficiaryPreferredCallResponseBean(); + response.setId(entity.getId()); + response.setBeneficiaryId(entity.getBeneficiaryId()); + response.setStatus(BeneficiaryCallStatus.valueOf(entity.getStatus())); + response.setCallId(entity.getCallId()); + response.setUserId(entity.getUserId()); + response.setCompanyId(entity.getCompanyId()); + response.setCreatedDate(entity.getCreatedDate()); + response.setUpdatedDate(entity.getUpdatedDate()); + + return response; + } + public void updateBeneficiaryPreferredCallStatus(Long id, BeneficiaryCallStatus status) { + log.info("Updating status for beneficiary preferred call with ID: {}", id); + BeneficiaryPreferredCallEntity existingEntity = validateBeneficiaryPreferredCall(id); + existingEntity.setStatus(status.getValue()); + beneficiaryPreferredCallRepository.save(existingEntity); + log.info("Beneficiary preferred call status updated with ID: {}", existingEntity.getId()); + } + public List getBeneficiaryPreferredCallByUserId(UserEntity userEntity, Long companyId) { + + List calls = beneficiaryPreferredCallRepository.findByUserIdAndCompanyId(userEntity.getId(), companyId); + return calls.stream() + .map(this::convertEntityToResponse) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 1b3f60d0..97ae3216 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -1,17 +1,27 @@ package net.gepafin.tendermanagement.dao; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.service.*; +import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; +import org.h2.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @@ -73,20 +83,24 @@ public class CallDao { @Autowired private CallTargetAudienceChecklistRepository callTargetAudienceChecklistRepository; - @Autowired - private UserService userService; - @Autowired private FaqService faqService; + @Autowired private FlowDao flowDao; + @Autowired private FormDao formDao; + + @Value("${aws.s3.url.folder}") + private String s3Folder; + + @Autowired + private AmazonS3Service amazonS3Service; - public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, Long userId) { - UserEntity userEntity = userService.validateUser(userId); + public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); - CallEntity callEntity = convertToCallEntity(createCallRequest); + CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity); updateFaq(createCallRequest.getFaq(), callEntity, userEntity,LookUpDataTypeEnum.FAQ); @@ -98,8 +112,37 @@ public class CallDao { return createCallResponseBean; } + public byte[] downloadCallDocumentsAsZip(Long callId) { + List documents = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callId, DocumentSourceTypeEnum.CALL.getValue(),DocumentTypeEnum.DOCUMENT.getValue()); + if (documents.isEmpty()) { + throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); + } - public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest) { + try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); + ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { + + for (DocumentEntity document : documents) { + try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFileName())) { + ZipEntry zipEntry = new ZipEntry(document.getFileName()); + zos.putNextEntry(zipEntry); + IOUtils.copy(fileInputStream, zos); + zos.closeEntry(); + } catch (IOException e) { + throw new RuntimeException("Error downloading or adding document to ZIP: " + document.getFileName(), e); + } + } + + zos.finish(); + return zipOutputStream.toByteArray(); + + } catch (IOException e) { + throw new RuntimeException("Error while creating ZIP file", e); + } + } + + + + public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { CallEntity callEntity = new CallEntity(); // validateCallEntity(createCallRequest); RegionEntity region = regionRepository.findById(createCallRequest.getRegionId()) @@ -124,6 +167,18 @@ public class CallDao { callEntity.setConfidi(createCallRequest.getConfidi()); } callEntity.setDocumentationRequested(createCallRequest.getDocumentationRequested()); + if (createCallRequest.getAmountMin() != null && createCallRequest.getAmountMin().compareTo(BigDecimal.ZERO) < 0) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.AMOUNT_GREATER_THAN_ZERO_MSG)); + } + callEntity.setAmountMin(createCallRequest.getAmountMin()); + if(createCallRequest.getEmail()!=null && Boolean.FALSE.equals(Utils.isValidEmail(createCallRequest.getEmail()))){ + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.VALIDATION_EMAIL,createCallRequest.getEmail())); + } + callEntity.setEmail(createCallRequest.getEmail()); + callEntity.setPhoneNumber(createCallRequest.getPhoneNumber()); + callEntity.setStartTime(DateTimeUtil.parseTime(createCallRequest.getStartTime())); + callEntity.setEndTime(DateTimeUtil.parseTime(createCallRequest.getEndTime())); + callEntity.setHub(userEntity.getHub()); callEntity = callRepository.save(callEntity); return callEntity; } @@ -259,6 +314,11 @@ public class CallDao { createCallResponseBean.setDocumentationRequested(callEntity.getDocumentationRequested()); createCallResponseBean.setPriorityArea(callEntity.getPriorityArea()); createCallResponseBean.setConfidi(callEntity.getConfidi()); + createCallResponseBean.setAmountMin(callEntity.getAmountMin()); + createCallResponseBean.setPhoneNumber(callEntity.getPhoneNumber()); + createCallResponseBean.setEndTime(callEntity.getEndTime()); + createCallResponseBean.setStartTime(callEntity.getStartTime()); + createCallResponseBean.setEmail(callEntity.getEmail()); createCallResponseBean.setCreatedDate(callEntity.getCreatedDate()); createCallResponseBean.setUpdatedDate(callEntity.getUpdatedDate()); return createCallResponseBean; @@ -358,13 +418,11 @@ public class CallDao { Translator.toLocale(GepafinConstant.CALL_NOT_FOUND))); } - public CallResponse getCallById(Long callId) { - CallEntity callEntity = validateCall(callId); + public CallResponse getCallById(CallEntity callEntity) { return getCallResponseBean(callEntity); } - public CallResponse createCallStep2(Long callId, CreateCallRequestStep2 createCallRequest, Long userId) { - CallEntity callEntity = validateCall(callId); + public CallResponse createCallStep2(CallEntity callEntity, CreateCallRequestStep2 createCallRequest, UserEntity user) { validateUpdate(callEntity); setIfUpdated(callEntity::getThreshold, callEntity::setThreshold, createCallRequest.getThreshold()); callRepository.save(callEntity); @@ -424,8 +482,7 @@ public class CallDao { } } - public CallResponse updateCallStep1(Long callId, UpdateCallRequestStep1 updateCallRequest, Long userId) { - CallEntity callEntity = validateCall(callId); + public CallResponse updateCallStep1(CallEntity callEntity, UpdateCallRequestStep1 updateCallRequest, UserEntity userEntity) { if(Boolean.TRUE.equals(callEntity.getStatus().equals(CallStatusEnum.PUBLISH.getValue()))) { try { Utils.retainOnlySpecificFields(updateCallRequest, Collections.singletonList("faq")); @@ -433,7 +490,6 @@ public class CallDao { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.FAILED_RETAIN_FIELD)); } } - UserEntity userEntity = userService.validateUser(userId); isValidDateRange(updateCallRequest, callEntity); setIfUpdated(callEntity::getName, callEntity::setName, updateCallRequest.getName()); setIfUpdated(callEntity::getDescriptionShort, callEntity::setDescriptionShort, @@ -456,6 +512,18 @@ public class CallDao { setIfUpdated(callEntity::getAmountMax, callEntity::setAmountMax, updateCallRequest.getAmountMax()); setIfUpdated(callEntity::getDocumentationRequested, callEntity::setDocumentationRequested, updateCallRequest.getDocumentationRequested()); + + if (updateCallRequest.getAmountMin() != null && updateCallRequest.getAmountMin().compareTo(BigDecimal.ZERO) < 0) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.AMOUNT_GREATER_THAN_ZERO_MSG)); + } + if(updateCallRequest.getEmail()!=null && Boolean.FALSE.equals(Utils.isValidEmail(updateCallRequest.getEmail()))){ + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.VALIDATION_EMAIL,updateCallRequest.getEmail())); + } + setIfUpdated(callEntity::getAmountMin, callEntity::setAmountMin, updateCallRequest.getAmountMin()); + setIfUpdated(callEntity::getEmail, callEntity::setEmail, updateCallRequest.getEmail()); + setIfUpdated(callEntity::getPhoneNumber, callEntity::setPhoneNumber, updateCallRequest.getPhoneNumber()); + setIfUpdated(callEntity::getStartTime, callEntity::setStartTime, DateTimeUtil.parseTime(updateCallRequest.getStartTime())); + setIfUpdated(callEntity::getEndTime, callEntity::setEndTime, DateTimeUtil.parseTime(updateCallRequest.getEndTime())); setIfUpdated(callEntity::getConfidi, callEntity::setConfidi, updateCallRequest.getConfidi()); updateLookUpData(callEntity, updateCallRequest.getAimedTo(), LookUpDataTypeEnum.AIMED_TO); updateFaq(updateCallRequest.getFaq(), callEntity, userEntity, LookUpDataTypeEnum.FAQ); @@ -475,9 +543,9 @@ public class CallDao { } List existingChecklist = callTargetAudienceChecklistRepository .findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), type.getValue()); - List incomingIds = lookupDataReqList.stream().map(LookUpDataReq::getLookUpDataId) + List incomingIds = lookupDataReqList.stream().map(LookUpDataReq::getId) .filter(id -> id != null && id > 0).collect(Collectors.toList()); - existingChecklist.stream().filter(checklist -> !incomingIds.contains(checklist.getLookupData().getId())) + existingChecklist.stream().filter(checklist -> !incomingIds.contains(checklist.getId())) .forEach(this::softDeleteCallTargetAudienceChecklist); lookupDataReqList .forEach(lookUpDataReq -> createOrUpdateCallTargetAudienceChecklist(lookUpDataReq, callEntity, type)); @@ -531,6 +599,11 @@ public class CallDao { callDetailsResponseBean.setThreshold(callEntity.getThreshold()); callDetailsResponseBean.setDocumentationRequested(callEntity.getDocumentationRequested()); callDetailsResponseBean.setPriorityArea(callEntity.getPriorityArea()); + callDetailsResponseBean.setAmountMin(callEntity.getAmountMin()); + callDetailsResponseBean.setEmail(callEntity.getEmail()); + callDetailsResponseBean.setEndTime(callEntity.getEndTime()); + callDetailsResponseBean.setStartTime(callEntity.getStartTime()); + callDetailsResponseBean.setPhoneNumber(callEntity.getPhoneNumber()); callDetailsResponseBean.setCreatedDate(callEntity.getCreatedDate()); callDetailsResponseBean.setUpdatedDate(callEntity.getUpdatedDate()); return callDetailsResponseBean; @@ -575,7 +648,7 @@ public class CallDao { validateUpdate(callEntity); CallResponse callResponseBean = getCallResponseBean(callEntity); FlowResponseBean flowResponseBean = flowDao.getFlowByCallId(callEntity.getId()); - List formResponseBean = formDao.getFormsByCallId(callEntity.getId()); + List formResponseBean = formDao.getFormsByCallId(callEntity); CallValidatorServiceImpl.validateResponse(callResponseBean,flowResponseBean,formResponseBean); callEntity.setStatus(CallStatusEnum.READY_TO_PUBLISH.getValue()); callRepository.save(callEntity); @@ -591,8 +664,7 @@ public class CallDao { return callEntity; } - public CallResponse updateCallStatus(Long callId, CallStatusEnum statusReq) { - CallEntity callEntity = validateCall(callId); + public CallResponse updateCallStatus(CallEntity callEntity, CallStatusEnum statusReq) { CallStatusEnum currentStatus = CallStatusEnum.valueOf(callEntity.getStatus()); validateStatusChange(currentStatus, statusReq); callEntity.setStatus(statusReq.getValue()); @@ -638,6 +710,25 @@ public class CallDao { Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CALL_NOT_PUBLISHED)); } + LocalDate currentDate = LocalDate.now(); + LocalTime currentTime = LocalTime.now(); + + if (currentDate.isBefore(callEntity.getStartDate().toLocalDate()) || + (currentDate.isEqual(callEntity.getStartDate().toLocalDate()) && currentTime.isBefore(callEntity.getStartTime()))) { + throw new CustomValidationException( + Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.CALL_NOT_STARTED_YET) + ); + } + + if (currentDate.isAfter(callEntity.getEndDate().toLocalDate()) || + (currentDate.isEqual(callEntity.getEndDate().toLocalDate()) && currentTime.isAfter(callEntity.getEndTime()))) { + throw new CustomValidationException( + Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.CALL_ALREADY_ENDED) + ); + } + return callEntity; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java new file mode 100644 index 00000000..2208962b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -0,0 +1,228 @@ +package net.gepafin.tendermanagement.dao; + +import java.util.List; + +import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.FaqRepository; +import net.gepafin.tendermanagement.web.rest.api.errors.*; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyResponse; +import net.gepafin.tendermanagement.repositories.CompanyRepository; +import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; +import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.Utils; + +import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; + +@Component +public class CompanyDao { + + @Autowired + private CompanyRepository companyRepository; + + @Autowired + private UserService userService; + + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; + @Autowired + private ApplicationRepository applicationRepository; + @Autowired + private FaqRepository faqRepository; + + + public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { + CompanyEntity existingCompany = companyRepository.findByVatNumber(companyRequest.getVatNumber()); + UserWithCompanyEntity userWithCompanyEntity = null; + if (existingCompany != null) { + UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), existingCompany.getId()) + .orElse(null); + if (existingRelation == null) { + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant()); + } else { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY)); + } + return convertCompanyEntityToCompanyResponse(existingCompany, userWithCompanyEntity); + } else { + validateCompany(companyRequest); + CompanyEntity companyEntity = convertCompanyRequestToCompanyEntity(companyRequest); + companyRepository.save(companyEntity); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant()); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); + } + } + + + private void validateCompany(CompanyRequest companyRequest) { + + if (Boolean.FALSE.equals(StringUtils.isEmpty(companyRequest.getEmail())) + && Boolean.FALSE.equals(Utils.isValidEmail(companyRequest.getEmail()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_EMAIL)); + } + if (StringUtils.isEmpty(companyRequest.getVatNumber())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VATNUMBER_MANDATORY)); + } + if (companyRepository.existsByVatNumber(companyRequest.getVatNumber())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); + } + } + + private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant) { + UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); + if (userEntity.getBeneficiary() != null) { + userWithCompanyEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); + } + userWithCompanyEntity.setIsDeleted(Boolean.FALSE); + userWithCompanyEntity.setCompanyId(companyEntity.getId()); + userWithCompanyEntity.setUserId(userEntity.getId()); + userWithCompanyEntity.setIsLegalRepresentant(isLegalRepresentant); + return userWithCompanyRepository.save(userWithCompanyEntity); + } + + private CompanyEntity convertCompanyRequestToCompanyEntity(CompanyRequest request) { + CompanyEntity entity = new CompanyEntity(); + entity.setCompanyName(request.getCompanyName()); + entity.setVatNumber(request.getVatNumber()); + entity.setCodiceFiscale(request.getCodiceFiscale()); + entity.setAddress(request.getAddress()); + entity.setPhoneNumber(request.getPhoneNumber()); + entity.setCity(request.getCity()); + 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()); + return entity; + } + + private CompanyResponse convertCompanyEntityToCompanyResponse(CompanyEntity entity, UserWithCompanyEntity userWithCompanyEntity) { + CompanyResponse response = new CompanyResponse(); + response.setId(entity.getId()); + response.setCompanyName(entity.getCompanyName()); + response.setVatNumber(entity.getVatNumber()); + response.setCodiceFiscale(entity.getCodiceFiscale()); + response.setAddress(entity.getAddress()); + response.setPhoneNumber(entity.getPhoneNumber()); + response.setCity(entity.getCity()); + response.setProvince(entity.getProvince()); + response.setCap(entity.getCap()); + response.setCountry(entity.getCountry()); + response.setPec(entity.getPec()); + response.setEmail(entity.getEmail()); + response.setNumberOfEmployees(entity.getNumberOfEmployees()); + response.setAnnualRevenue(entity.getAnnualRevenue()); + if(userWithCompanyEntity!=null) { + response.setIsLegalRepresentant(userWithCompanyEntity.getIsLegalRepresentant()); + } + response.setCreatedDate(entity.getCreatedDate()); + response.setUpdatedDate(entity.getUpdatedDate()); + response.setContactName(entity.getContactName()); + response.setContactEmail(entity.getContactEmail()); + return response; + } + + public CompanyResponse updateCompany(UserEntity userEntity, Long companyId, CompanyRequest companyRequest) { + CompanyEntity companyEntity = validateCompany(companyId); + 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()); + setIfUpdated(companyEntity::getCity, companyEntity::setCity, companyRequest.getCity()); + 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()); + companyRepository.save(companyEntity); + UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); + Utils.setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, + companyRequest.getIsLegalRepresentant()); + userWithCompanyRepository.save(userWithCompanyEntity); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); + } + + public CompanyEntity validateCompany(Long companyId) { + return companyRepository.findById(companyId).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.COMPANY_NOT_FOUND_MSG))); + } + + public CompanyResponse getCompany(UserEntity userEntity, Long companyId) { + UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); + return convertCompanyEntityToCompanyResponse(validateCompany(companyId), userWithCompanyEntity); + } + + public void deleteCompany(UserEntity userEntity, Long companyId) { + CompanyEntity companyEntity = validateCompany(companyId); + companyRepository.delete(companyEntity); + userWithCompanyRepository.deleteByCompanyIdAndIsDeletedFalse(companyId); + } + + public List getCompanyByUserId(Long userId) { + UserEntity userEntity = userService.validateUser(userId); + List activeCompanyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(userEntity.getId()); + List companies = companyRepository.findByIdIn(activeCompanyIds); + return companies.stream().map(companyEntity -> { + UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyEntity.getId()); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); + }).toList(); + } + + public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) { + 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))); + } + public void removeCompanyFromList(UserEntity userEntity, Long companyId) { + CompanyEntity companyEntity = validateCompany(companyId); + UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId()) + .orElseThrow(() -> new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY))); + List userApplications = applicationRepository.findByCompanyIdAndUserIdAndIsDeletedFalse(companyEntity.getId(), userEntity.getId()); + List faqs = faqRepository.findByCompanyIdAndUserIdAndIsDeletedFalse(companyEntity.getId(), userEntity.getId()); + for (ApplicationEntity application : userApplications) { + if(Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))) { + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); + } + if(Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { + application.setIsDeleted(Boolean.TRUE); + applicationRepository.save(application); + } + } + for(FaqEntity faq:faqs) { + faq.setIsDeleted(Boolean.TRUE); + faqRepository.save(faq); + } + existingRelation.setIsDeleted(Boolean.TRUE); + userWithCompanyRepository.save(existingRelation); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java new file mode 100644 index 00000000..5622aa8a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java @@ -0,0 +1,118 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +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 org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; + +@Component +public class DashboardDao { + + @Autowired + private CallRepository callRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private CompanyRepository companyRepository; + + public SuperAdminWidgetResponseBean getDashboardWidget() { + SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean(); + widgetResponseBean.setWidget1(createWidget1()); +// List widgetBars = callRepository.findApplicationsPerCall(); +// widgetResponseBean.setWidgetBars(widgetBars); + return widgetResponseBean; + } + + private Widget1 createWidget1() { + Widget1 widget1 = initializeWidget1(); + + setActiveCalls(widget1); + setRegisteredUsers(widget1); + setTotalActiveFinancing(widget1); + setSubmittedApplications(widget1); + setDraftApplications(widget1); + setNumberOfCompanies(widget1); + + return widget1; + } + + private Widget1 initializeWidget1() { + return Widget1.builder().numberOfActiveCalls(0L).numberOfCompany(0L).numberOfDraftApplications(0L) + .numberOfResgisteredUsers(0L).numberOfSubmittedApplications(0L).totalActiveFinancing(BigDecimal.ZERO) + .build(); + } + + private void setActiveCalls(Widget1 widget1) { + Long activeCalls = callRepository.countByStatus(CallStatusEnum.PUBLISH.getValue()); + if (activeCalls != null) { + widget1.setNumberOfActiveCalls(activeCalls); + } + } + + private void setRegisteredUsers(Widget1 widget1) { + Long activeUsers = userRepository.countByStatusAndRoleEntityRoleType(UserStatusEnum.ACTIVE.getValue(), + RoleStatusEnum.ROLE_BENEFICIARY.getValue()); + if (activeUsers != null) { + widget1.setNumberOfResgisteredUsers(activeUsers); + } + } + + private void setTotalActiveFinancing(Widget1 widget1) { + BigDecimal totalActiveFinancing = callRepository.findTotalAmountOfPublishedCalls(); + widget1.setTotalActiveFinancing(totalActiveFinancing); + } + + private void setSubmittedApplications(Widget1 widget1) { + Long submittedApplications = applicationRepository.countSubmittedApplications(); + if (submittedApplications != null) { + widget1.setNumberOfSubmittedApplications(submittedApplications); + } + } + + private void setDraftApplications(Widget1 widget1) { + Long draftApplications = applicationRepository.countDraftApplications(); + if (draftApplications != null) { + widget1.setNumberOfDraftApplications(draftApplications); + } + } + + private void setNumberOfCompanies(Widget1 widget1) { + Long numberOfCompanies = companyRepository.countTotalCompanies(); + if (numberOfCompanies != null) { + widget1.setNumberOfCompany(numberOfCompanies); + } + } + + public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(UserEntity userEntity, + CompanyEntity company) { + BeneficiaryWidgetResponseBean beneficiaryWidgetResponseBean = BeneficiaryWidgetResponseBean.builder() + .numberOfApplications(0L).numberOfCalls(0L).numberOfIntegratedDocuments(0L).build(); + Long activeCalls = callRepository.countByStatus(CallStatusEnum.PUBLISH.getValue()); + if (activeCalls != null) { + beneficiaryWidgetResponseBean.setNumberOfCalls(activeCalls); + } + Long activeApplication = applicationRepository.countSubmittedApplicationsByUserId(userEntity.getId(), + company.getId()); + if (activeApplication != null) { + beneficiaryWidgetResponseBean.setNumberOfApplications(activeApplication); + } + return beneficiaryWidgetResponseBean; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java new file mode 100644 index 00000000..ca58f8be --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -0,0 +1,256 @@ +package net.gepafin.tendermanagement.dao; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; +import net.gepafin.tendermanagement.model.response.UserResponseBean; +import net.gepafin.tendermanagement.repositories.DocumentRepository; +import net.gepafin.tendermanagement.repositories.UserCompanyDelegationRepository; +import net.gepafin.tendermanagement.service.AmazonS3Service; +import net.gepafin.tendermanagement.service.UserService; +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.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; + +@Component +public class DelegationDao { + + private static final String DEFAULT_PLACEHOLDER = "____________________"; + + @Autowired + private UserService userService; + + @Autowired + private CompanyDao companyDao; + + @Autowired + private AmazonS3Service amazonS3Service; + + @Autowired + private DocumentRepository documentRepository; + + @Value("${aws.s3.url.folder.delegation}") + private String s3Folder; + + @Autowired + private UserCompanyDelegationRepository userCompanyDelegationRepository; + + + public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { + try { + InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); + XWPFDocument doc = loadTemplate(templateStream); + replacePlaceholders(doc, placeholders); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + doc.write(byteArrayOutputStream); + return byteArrayOutputStream; + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.DELEGATION_TEMPLATE_GENERATION_ERROR)); + } + } + + public void replacePlaceholders(XWPFDocument doc, Map placeholders) { + doc.getParagraphs().forEach(paragraph -> { + placeholders.forEach((placeholder, value) -> { + if (paragraph.getText().contains(placeholder)) { + String updatedText = paragraph.getText().replace(placeholder, value); + paragraph.getRuns().forEach(run -> run.setText("", 0)); // Clear the existing text + paragraph.createRun().setText(updatedText); // Insert updated text + } + }); + }); + } + + public XWPFDocument loadTemplate(InputStream templateStream) throws IOException { + return new XWPFDocument(templateStream); + } + + public ByteArrayOutputStream downloadCompanyDelegation(UserEntity userEntity, Long companyId, CompanyDelegationRequest companyDelegationRequest) { + Map placeholders = getDefaultPlaceholders(); + UserResponseBean user = userService.getUserById(userEntity.getId()); + CompanyEntity companyEntity = companyDao.validateCompany(companyId); + companyDao.getUserWithCompany(userEntity.getId(), companyId); + updatePlaceholdersForDelegation(user, companyEntity, placeholders, companyDelegationRequest); + DocumentEntity documentEntity = documentRepository.findBySource(GepafinConstant.DELEGATION_TEMPLATE).get(0); + return generateDocument(placeholders, documentEntity.getFileName()); + } + + private Map updatePlaceholdersForDelegation(UserResponseBean user, CompanyEntity companyEntity, + Map placeholders, CompanyDelegationRequest companyDelegationRequest) { + validateMandatoryFields(companyDelegationRequest); + addIfNotEmpty(placeholders, "{{company_first_name}}", companyDelegationRequest.getFirstName()); + addIfNotEmpty(placeholders, "{{company_last_name}}", companyDelegationRequest.getLastName()); + addIfNotEmpty(placeholders, "{{company_codice_fiscale}}", companyDelegationRequest.getCodiceFiscale()); + addIfNotEmpty(placeholders, "{{company_name}}", companyEntity.getCompanyName()); + addIfNotEmpty(placeholders, "{{company_city}}", companyEntity.getCity()); + addIfNotEmpty(placeholders, "{{company_address}}", companyEntity.getAddress()); + addIfNotEmpty(placeholders, "{{company_province}}", companyEntity.getProvince()); + addIfNotEmpty(placeholders, "{{company_cap}}", companyEntity.getCap()); + addIfNotEmpty(placeholders, "{{company_vat_number}}", companyEntity.getVatNumber()); + + addIfNotEmpty(placeholders, "{{user_first_name}}", user.getFirstName()); + addIfNotEmpty(placeholders, "{{user_last_name}}", user.getLastName()); + addIfNotNull(placeholders, "{{user_date_of_birth}}", user.getDateOfBirth(), + date -> DateTimeUtil.formatLocalDateTime(date, GepafinConstant.YYYY_MM_DD_SLASH)); + addIfNotEmpty(placeholders, "{{user_codice_fiscale}}", user.getCodiceFiscale()); + + return placeholders; + } + + private Map getDefaultPlaceholders() { + Map placeholders = new HashMap<>(); + placeholders.put("{{company_first_name}}", ""); + placeholders.put("{{company_last_name}}", ""); + placeholders.put("{{company_codice_fiscale}}", ""); + placeholders.put("{{company_name}}", ""); + placeholders.put("{{company_city}}", ""); + placeholders.put("{{company_address}}", ""); + placeholders.put("{{company_province}}", ""); + placeholders.put("{{company_cap}}", ""); + placeholders.put("{{company_vat_number}}", ""); + + placeholders.put("{{user_first_name}}", ""); + placeholders.put("{{user_last_name}}", ""); + placeholders.put("{{user_date_of_birth}}", ""); + placeholders.put("{{user_codice_fiscale}}", ""); + return placeholders; + } + + private void validateMandatoryFields(CompanyDelegationRequest companyDelegationRequest) { + if (StringUtils.isAllEmpty(companyDelegationRequest.getFirstName())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_MISSING_FIRSTNAME)); + } + if (StringUtils.isAllEmpty(companyDelegationRequest.getLastName())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_MISSING_LASTNAME)); + } + if (StringUtils.isAllEmpty(companyDelegationRequest.getCodiceFiscale())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_MISSING_CODICEFISCALE)); + } + } + + private void addIfNotEmpty(Map placeholders, String key, String value) { + if (Boolean.FALSE.equals(StringUtils.isAllEmpty(value))) { + placeholders.put(key, value); + } + } + + private void addIfNotNull(Map placeholders, String key, T value, Function formatter) { + if (value != null) { + placeholders.put(key, formatter.apply(value)); + } + } + + + public CompanyDelegationResponse uploadCompanyDelegation(UserEntity userEntity, Long companyId, MultipartFile file) { + companyDao.validateCompany(companyId); + companyDao.getUserWithCompany(userEntity.getId(), companyId); + validateFileType(file); + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository + .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + if (userCompanyDelegationEntity != null) { + userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); + userCompanyDelegationRepository.save(userCompanyDelegationEntity); + } + UploadFileOnAmazonS3 uploadFileOnAmazonS3 = uploadFileOnAmazonS3(file); + userCompanyDelegationEntity = new UserCompanyDelegationEntity(); + userCompanyDelegationEntity.setCompanyId(companyId); + userCompanyDelegationEntity.setUserId(userEntity.getId()); + if (userEntity.getBeneficiary() != null) { + userCompanyDelegationEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); + } + userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + userCompanyDelegationEntity.setFileName(uploadFileOnAmazonS3.fileName()); + userCompanyDelegationEntity.setFilePath(uploadFileOnAmazonS3.filepath()); + userCompanyDelegationRepository.save(userCompanyDelegationEntity); + return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); + } + + private CompanyDelegationResponse convertUserCompanyDelegationToCompanyDelegationResponse( + UserCompanyDelegationEntity userCompanyDelegationEntity) { + return Utils.convertSourceObjectToDestinationObject(userCompanyDelegationEntity, CompanyDelegationResponse.class); + } + + private UploadFileOnAmazonS3 uploadFileOnAmazonS3(MultipartFile file){ + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + String fileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename()); + String firstNameContain = fileName.substring(0, fileName.lastIndexOf('.')); + firstNameContain+=Utils.randomKey(5); + fileName = (firstNameContain + "." + extension); + try { + String filepath = amazonS3Service.upload(fileName, s3Folder, file); + return new UploadFileOnAmazonS3(fileName, filepath); + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); + } + + } + + private record UploadFileOnAmazonS3(String fileName, String filepath) { + } + + private void validateFileType(MultipartFile file) { + if (file.isEmpty()) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_EMPTY)); + } + String filename = file.getOriginalFilename(); + if (filename == null || !filename.endsWith(".p7m")) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE)); + } + } + + public CompanyDelegationResponse getCompanyDelegation(UserEntity userEntity, Long companyId) { + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository + .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + companyDao.getUserWithCompany(userEntity.getId(), companyId); + if(userCompanyDelegationEntity == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); + } + return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); + } + + public void deleteCompanyDelegation(UserEntity userEntity, Long companyId) { + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository + .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + companyDao.getUserWithCompany(userEntity.getId(), companyId); + if(userCompanyDelegationEntity == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); + } + userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); + userCompanyDelegationRepository.save(userCompanyDelegationEntity); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 374c741b..224a21ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; @@ -40,6 +41,9 @@ public class DocumentDao { @Autowired private CallService callService; + + @Value("${aws.s3.url.folder}") + private String s3Folder; public List uploadFiles(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { List documentEntities = new ArrayList<>(); @@ -81,7 +85,7 @@ public class DocumentDao { String fileName = StringUtils.cleanPath(file.getOriginalFilename()); String firstNameContain = fileName.substring(0, fileName.lastIndexOf('.')); fileName = (firstNameContain + "." + extension); - String filepath = amazonS3Service.upload(fileName, file); + String filepath = amazonS3Service.upload(fileName, s3Folder, file); uploadFileOnAmazonS3 result = new uploadFileOnAmazonS3(fileName, filepath); return result; } @@ -99,7 +103,7 @@ public class DocumentDao { private DocumentEntity deleteFileOnAmazonS3(String fileName) { try { - amazonS3Service.delete(fileName); + amazonS3Service.delete(s3Folder, fileName); } catch (Exception e) { } return null; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java index b8ebd278..cfec2fe2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java @@ -12,8 +12,11 @@ import net.gepafin.tendermanagement.model.request.FaqReq; import net.gepafin.tendermanagement.model.response.FaqResponseBean; import net.gepafin.tendermanagement.repositories.FaqRepository; import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.LookUpDataService; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.Validator; +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.springframework.beans.factory.annotation.Autowired; @@ -35,12 +38,25 @@ public class FaqDao { @Autowired private LookUpDataService lookUpDataService; + + @Autowired + private Validator validator; + + @Autowired + private CompanyService companyService; - public FaqResponseBean createFaq(FaqReq faqRequest, UserEntity userEntity, Long callId) { - FaqEntity entity = new FaqEntity(); + public FaqResponseBean createFaq(FaqReq faqRequest, UserEntity userEntity, Long callId, Long companyId) { CallEntity callEntity = callService.validateCall(callId); - entity = createOrUpdateFaqEntity(faqRequest, callEntity, userEntity, + FaqEntity entity = createOrUpdateFaqEntity(faqRequest, callEntity, userEntity, LookUpDataEntity.LookUpDataTypeEnum.FAQ); + if (validator.checkIsBeneficiary() && companyId == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.COMPANY_ID_MANDATORY)); + } + if(companyId!=null) { + companyService.validateCompany(companyId); + entity.setCompanyId(companyId); + } faqRepository.save(entity); return convertToFaqResponseBean(entity); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java index 6b4d34d5..2fbf0943 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java @@ -4,20 +4,16 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.FlowDataEntity; -import net.gepafin.tendermanagement.entities.FlowDataEntity; import net.gepafin.tendermanagement.entities.FlowEdgesEntity; import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.model.request.FlowDataRequestBean; import net.gepafin.tendermanagement.model.request.FlowEdgesRequestBean; import net.gepafin.tendermanagement.model.request.FlowRequestBean; -import net.gepafin.tendermanagement.model.response.EvaluationCriteriaResponseBean; import net.gepafin.tendermanagement.model.response.FlowDataResponseBean; import net.gepafin.tendermanagement.model.response.FlowEdgesResponseBean; import net.gepafin.tendermanagement.model.response.FlowResponseBean; import net.gepafin.tendermanagement.repositories.CallRepository; import net.gepafin.tendermanagement.repositories.FlowDataRepository; -import net.gepafin.tendermanagement.repositories.FlowDataRepository; -import net.gepafin.tendermanagement.repositories.FlowEdgesRepository; import net.gepafin.tendermanagement.repositories.FlowEdgesRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.FormService; @@ -29,7 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java index a6f6a867..4ad912f4 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java @@ -1,11 +1,9 @@ package net.gepafin.tendermanagement.dao; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.repositories.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -22,7 +20,6 @@ import net.gepafin.tendermanagement.enums.FormActionEnum; import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; import net.gepafin.tendermanagement.service.FormService; 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; @Component @@ -46,7 +43,9 @@ public class FlowFormDao { @Autowired private FormService formService; @Autowired - private FormRepository formRepository; + private FormDao formDao; + + // Long getNextForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { // // vlaidation if next form findout and cuuent from is not fill the give error @@ -176,81 +175,83 @@ public class FlowFormDao { .orElse(null); } -// public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { -// // Retrieve the flow edges for the previous forms -// List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( -// currentFormEntity.getId(), applicationEntity.getCall().getId()); -// -// if (flowEdgesList.isEmpty()) { -// return null; -//// throw new ResourceNotFoundException(Status.NOT_FOUND, -//// Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); -// } -// -// // If only one edge exists, return the source form ID -// if (flowEdgesList.size() == 1) { -// return flowEdgesList.get(0).getSourceId(); -// } -// -// // For multiple edges, find the previous form based on the chosen value -// List previousFormIds = flowEdgesList.stream() -// .map(FlowEdgesEntity::getSourceId) -// .toList(); -// -// // Fetch the flow data based on previous form IDs -// List flowDataList = flowDataRepository.findByFormIdInAndCallId( -// previousFormIds, applicationEntity.getCall().getId()); -// -// List chosenValues = flowDataList.stream() -// .map(FlowDataEntity::getChoosenValue) -// .toList(); -// -// // Fetch the previous forms based on the chosen field values -// Set formList = applicationFormFieldRepository -// .findByFieldValueInAndApplicationFormApplicationId(chosenValues, applicationEntity.getId()).stream() -// .map(fieldEntity -> fieldEntity.getApplicationForm().getForm()) -// .collect(Collectors.toSet()); -// -// // Find next form IDs recursively for all forms in the formList -// List fieldIds = formList.stream() -// .map(formEntity -> getNextForm(formEntity, applicationEntity)) -// .toList(); -// -// // Return the first matching previous form ID that corresponds to a next form -// return previousFormIds.stream() -// .filter(fieldIds::contains) -// .findFirst().orElse(null); -// } - public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { + // Retrieve the flow edges for the previous forms + List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( + currentFormEntity.getId(), applicationEntity.getCall().getId()); - List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( - currentFormEntity.getId(), applicationEntity.getCall().getId()); - - if (flowEdgesList.isEmpty()) { - return null; + if (flowEdgesList.isEmpty()) { + return null; // throw new ResourceNotFoundException(Status.NOT_FOUND, // Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); } - // // If only one edge exists, return the source form ID - // if (flowEdgesList.size() == 1) { - // return flowEdgesList.get(0).getSourceId(); - // } + // If only one edge exists, return the source form ID + if (flowEdgesList.size() == 1) { + return flowEdgesList.get(0).getSourceId(); + } // For multiple edges, find the previous form based on the chosen value - List previousFormIds = flowEdgesList.stream() - .map(FlowEdgesEntity::getSourceId) - .toList(); + List previousFormIds = flowEdgesList.stream() + .map(FlowEdgesEntity::getSourceId) + .toList(); - List applicationFormEntities=applicationFormRepository.findByFormIdInAndApplicationId(previousFormIds,applicationEntity.getId()); + // Fetch the flow data based on previous form IDs + List flowDataList = flowDataRepository.findByFormIdInAndCallId( + previousFormIds, applicationEntity.getCall().getId()); - applicationFormEntities.sort(Comparator.comparing(ApplicationFormEntity::getCreatedDate).reversed()); + List chosenValues = flowDataList.stream() + .map(FlowDataEntity::getChoosenValue) + .toList(); - return applicationFormEntities.isEmpty() ? null : applicationFormEntities.get(0).getForm().getId(); + // Fetch the previous forms based on the chosen field values + Set formList = applicationFormFieldRepository + .findByFieldValueInAndApplicationFormApplicationId(chosenValues, applicationEntity.getId()).stream() + .map(fieldEntity -> fieldEntity.getApplicationForm().getForm()) + .collect(Collectors.toSet()); + + // Find next form IDs recursively for all forms in the formList + List fieldIds = formList.stream() + .map(formEntity -> getNextForm(formEntity, applicationEntity)) + .toList(); + + // Return the first matching previous form ID that corresponds to a next form + return previousFormIds.stream() + .filter(fieldIds::contains) + .findFirst().orElse(null); } - public NextOrPreviousFormResponse getnextOrPreviousForm(ApplicationEntity applicationEntity, Long formId, - FormActionEnum action) { + +// public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { +// +// List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( +// currentFormEntity.getId(), applicationEntity.getCall().getId()); +// +// if (flowEdgesList.isEmpty()) { +// return null; +//// throw new ResourceNotFoundException(Status.NOT_FOUND, +//// Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); +// } +// +// // // If only one edge exists, return the source form ID +// // if (flowEdgesList.size() == 1) { +// // return flowEdgesList.get(0).getSourceId(); +// // } +// +// // For multiple edges, find the previous form based on the chosen value +// List previousFormIds = flowEdgesList.stream() +// .map(FlowEdgesEntity::getSourceId) +// .toList(); +// if (previousFormIds.size() == 1) { +// return previousFormIds.get(0); +// } +// +// List applicationFormEntities=applicationFormRepository.findByFormIdInAndApplicationId(previousFormIds,applicationEntity.getId()); +// applicationFormEntities.sort(Comparator.comparing(ApplicationFormEntity::getCreatedDate).reversed()); +// +// return applicationFormEntities.isEmpty() ? null : applicationFormEntities.get(0).getForm().getId(); +// } + public NextOrPreviousFormResponse getNextOrPreviousForm(ApplicationEntity applicationEntity, Long formId, + FormActionEnum action) { Long calculatedFormId = null; FormEntity formEntity = null; if (formId == null) { @@ -274,48 +275,93 @@ public class FlowFormDao { } } NextOrPreviousFormResponse nextOrPreviousFormResponse = null; - if (calculatedFormId != null) { - nextOrPreviousFormResponse = setNextOrPreviousResponse(calculatedFormId, applicationEntity); + if (calculatedFormId == null && formId == null) { + FormEntity form=formService.validateForm(applicationEntity.getCall().getInitialForm()); + calculatedFormId=form.getId(); } + if (calculatedFormId == null) { + calculatedFormId=formId; + } + nextOrPreviousFormResponse = setNextOrPreviousResponse(calculatedFormId, applicationEntity); + return nextOrPreviousFormResponse; } private NextOrPreviousFormResponse setNextOrPreviousResponse(Long calculatedFormId, ApplicationEntity applicationEntity) { NextOrPreviousFormResponse nextOrPreviousFormResponse = new NextOrPreviousFormResponse(); + Integer completedSteps=0; FormEntity formEntity = formService.validateForm(calculatedFormId); nextOrPreviousFormResponse.setFormId(calculatedFormId); + nextOrPreviousFormResponse.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(applicationEntity.getStatus())); nextOrPreviousFormResponse.setApplicationFormResponse( applicationDao.processForm(formEntity, applicationEntity)); nextOrPreviousFormResponse.setCallId(applicationEntity.getCall().getId()); nextOrPreviousFormResponse.setCallTitle(applicationEntity.getCall().getName()); + nextOrPreviousFormResponse.setCompanyId(applicationEntity.getCompany().getId()); + nextOrPreviousFormResponse.setCompanyName(applicationEntity.getCompany().getCompanyName()); List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); + Long totalFormSteps = calculateTotalSteps(flowEdgesList); + Long currentStep = calculateCurrentStep(flowEdgesList, formEntity); + nextOrPreviousFormResponse.setTotalFormSteps(totalFormSteps); + completedSteps = getCompletedSteps(applicationEntity); + nextOrPreviousFormResponse.setCompletedSteps(Long.valueOf(completedSteps)); + nextOrPreviousFormResponse.setCurrentStep(currentStep); + if(applicationEntity.getProtocol() != null) { + nextOrPreviousFormResponse.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); + } + return nextOrPreviousFormResponse; + } + + public Integer getCompletedSteps(ApplicationEntity applicationEntity) { + Integer completedSteps=0; + List applicationFormList = applicationFormRepository.findByApplicationId(applicationEntity.getId()); + List applicationFormFieldEntities=new ArrayList<>(); + for (ApplicationFormEntity applicationFormEntity:applicationFormList){ + applicationFormFieldEntities=applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); + Boolean isCompleted=formDao.validateCompletedSteps(applicationFormFieldEntities, applicationEntity, applicationFormEntity.getForm()); + if(Boolean.TRUE.equals(isCompleted)){ + completedSteps++; + } + } + return completedSteps; + } + + public Long calculateCurrentStep(List flowEdgesList, FormEntity formEntity) { + Long currentStep = 2l; + if (formEntity.getId().equals(formEntity.getCall().getInitialForm())) { + currentStep = 1l; + } else if (flowEdgesList.size()>1 && formEntity.getId().equals(formEntity.getCall().getFinalForm())) { + currentStep = 3l; + } + return currentStep; + } + + public Long calculateTotalSteps(List flowEdgesList) { Long totalFormSteps = 3l; if (flowEdgesList.size() == 1) { totalFormSteps = 2l; } - Long currentStep = 2l; - if (formEntity.getId().equals(formEntity.getCall().getInitialForm())) { - currentStep = 1l; - } else if (formEntity.getId().equals(formEntity.getCall().getFinalForm())) { - currentStep = 3l; - } - List applicationFormList = applicationFormRepository.findByApplicationId(applicationEntity.getId()); - nextOrPreviousFormResponse.setTotalFormSteps(totalFormSteps); - nextOrPreviousFormResponse.setCompletedSteps(Long.valueOf(applicationFormList.size())); - nextOrPreviousFormResponse.setCurrentStep(currentStep); - return nextOrPreviousFormResponse; + return totalFormSteps; } private Long getDefaultForm(ApplicationEntity applicationEntity) { List applicationFormList = applicationFormRepository.findByApplicationIdOrderByCreatedDateAsc(applicationEntity.getId()); - if(applicationFormList.isEmpty()) { + if (applicationFormList.isEmpty()) { return applicationEntity.getCall().getInitialForm(); } - if(applicationFormList.get(applicationFormList.size()-1).getForm().getId().equals(applicationEntity.getCall().getFinalForm())) { - return applicationEntity.getCall().getInitialForm(); + if (applicationFormList.get(applicationFormList.size() - 1).getForm().getId().equals(applicationEntity.getCall().getFinalForm())) { + return applicationEntity.getCall().getInitialForm(); } - return getNextForm(applicationFormList.get(applicationFormList.size()-1).getForm(), applicationEntity); + FormEntity currentFormEntity = applicationFormList.get(applicationFormList.size() - 1).getForm(); + + for (ApplicationFormEntity applicationFormEntity : applicationFormList) { + Boolean isCompleted = formDao.validateCompletedSteps(applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()), applicationEntity, applicationFormEntity.getForm()); + if (Boolean.FALSE.equals(isCompleted)) { + return applicationFormEntity.getForm().getId(); + } + } + return getNextForm(currentFormEntity, applicationEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index 8121f9e6..7e17eb62 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -6,18 +6,17 @@ import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.ContentResponseBean; import net.gepafin.tendermanagement.model.response.FormResponseBean; -import net.gepafin.tendermanagement.model.response.VatNumberResponseBean; import net.gepafin.tendermanagement.repositories.*; -import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.FieldValidator; import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.util.Validator; 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.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; import java.text.MessageFormat; import java.time.LocalDateTime; @@ -32,9 +31,6 @@ public class FormDao { @Autowired private FormRepository formRepository; - @Autowired - private CallService callService; - @Autowired private ApplicationFormRepository applicationFormRepository; @@ -52,15 +48,17 @@ public class FormDao { @Autowired private CallRepository callRepository; + + @Autowired + private Validator validator; public FormEntity saveFormEntity(FormEntity formEntity){ formEntity=formRepository.save(formEntity); return formEntity; } - public FormEntity convertFormRequestToFormEntity(Long callId,FormRequest formRequest){ + public FormEntity convertFormRequestToFormEntity(CallEntity callEntity, FormRequest formRequest){ FormEntity formEntity=new FormEntity(); - CallEntity callEntity=callService.getCallEntityById(callId); formEntity.setCall(callEntity); formEntity.setLabel(formRequest.getLabel()); formEntity.setContent(setContentResponseBean(formRequest.getContent())); @@ -73,13 +71,13 @@ public class FormDao { formResponseBean.setContent(Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class)); formResponseBean.setLabel(formEntity.getLabel()); formResponseBean.setCallId(formEntity.getCall().getId()); + formResponseBean.setCallStatus(formEntity.getCall().getStatus()); return formResponseBean; } - public FormResponseBean createForm(Long callId,FormRequest formRequest){ + public FormResponseBean createForm(CallEntity callEntity,FormRequest formRequest){ validateForm(formRequest); - CallEntity callEntity=callService.validateCall(callId); - List flowDataEntities=flowDataRepository.findByCallId(callId); - List flowEdgesEntities=flowEdgesRepository.findByCallId(callId); + List flowDataEntities=flowDataRepository.findByCallId(callEntity.getId()); + List flowEdgesEntities=flowEdgesRepository.findByCallId(callEntity.getId()); if(Boolean.FALSE.equals(flowDataEntities.isEmpty() || flowDataEntities==null ) || Boolean.FALSE.equals(flowEdgesEntities.isEmpty() || flowEdgesEntities==null) ){ flowDataRepository.deleteAll(flowDataEntities); flowEdgesRepository.deleteAll(flowEdgesEntities); @@ -87,7 +85,7 @@ public class FormDao { callEntity.setFinalForm(null); callRepository.save(callEntity); } - FormEntity formEntity=convertFormRequestToFormEntity(callId,formRequest); + FormEntity formEntity=convertFormRequestToFormEntity(callEntity, formRequest); return convertFormEntityToFormResponseBean(formEntity); } public void validateForm(FormRequest formRequest){ @@ -95,11 +93,12 @@ public class FormDao { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.REQUIRED_PARAMETER_NOT_FOUND_FOR_FORM)); } } - public FormResponseBean updateForm(Long formId, FormRequest formRequest,Boolean forceDeleteFlow){ + public FormResponseBean updateForm(UserEntity user, Long formId, FormRequest formRequest,Boolean forceDeleteFlow){ ContentRequestBean contentRequestBean2=null; String choosenField=null; FormEntity formEntity = validateForm(formId); - callDao.validateUpdate(formEntity.getCall()); + validator.validateUserWithCall(user, formEntity.getCall().getId()); + callDao.validateUpdate(formEntity.getCall()); List contentRequestBean = Utils.convertJsonStringToList(formEntity.getContent(), ContentRequestBean.class); for (ContentRequestBean contentRequestBean1 : contentRequestBean) { FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndChoosenField(formEntity.getId(), contentRequestBean1.getId()); @@ -140,6 +139,13 @@ public class FormDao { ); } } + else { + Utils.setIfUpdated(formEntity::getLabel, formEntity::setLabel, formRequest.getLabel()); + Utils.setIfUpdated(formEntity::getContent, formEntity::setContent, setContentResponseBean(formRequest.getContent())); + formEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + formEntity = saveFormEntity(formEntity); + return convertFormEntityToFormResponseBean(formEntity); + } } } } @@ -162,12 +168,14 @@ public class FormDao { return formEntity; } - public FormResponseBean getFormEntityById(Long formId) { + public FormResponseBean getFormEntityById(UserEntity user, Long formId) { FormEntity formEntity = validateForm(formId); + validator.validateUserWithCall(user, formEntity.getCall().getId()); return convertFormEntityToFormResponseBean(formEntity); } - public void deleteFormById(Long formId){ + public void deleteFormById(UserEntity user, Long formId){ FormEntity formEntity = validateForm(formId); + validator.validateUserWithCall(user, formEntity.getCall().getId()); List flowDataEntities=flowDataRepository.findByCallId(formEntity.getCall().getId()); List flowEdgesEntities=flowEdgesRepository.findByCallId(formEntity.getCall().getId()); flowDataRepository.deleteAll(flowDataEntities); @@ -178,13 +186,12 @@ public class FormDao { callRepository.save(callEntity); formRepository.delete(formEntity); } - public List getFormsByCallId(Long callId){ - CallEntity callEntity=callService.validateCall(callId); + public List getFormsByCallId(CallEntity callEntity){ if(callEntity== null){ throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.CALL_NOT_FOUND)); } - List formEntities=formRepository.findByCallId(callId); + List formEntities=formRepository.findByCallId(callEntity.getId()); List formResponseBeanList = formEntities.stream() .map(req -> convertFormEntityToFormResponseBean(req)) .collect(Collectors.toList()); @@ -197,29 +204,33 @@ public class FormDao { public void validateFormField(List applicationFormFieldRequestList, ApplicationEntity applicationEntity, FormEntity formEntity) { Map formFieldMap = new LinkedHashMap(); for(ApplicationFormFieldRequestBean applicationFormFieldRequestBean:applicationFormFieldRequestList) { - formFieldMap.put(applicationFormFieldRequestBean.getFieldId(),applicationFormFieldRequestBean.getFieldValue()); - } + if(applicationFormFieldRequestBean.getFieldValue()==null ) + continue; + if (applicationFormFieldRequestBean.getFieldValue() != null ) { + Object fieldValue = applicationFormFieldRequestBean.getFieldValue(); + checkObjectData(applicationFormFieldRequestBean.getFieldId(), fieldValue, formFieldMap); + }} - FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); + FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); ApplicationFormEntity applicationFormEntity=applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),formEntity.getId()); Boolean isApplicationFormExist= getApplicationFormExist(applicationFormEntity); FieldValidator validator = FieldValidator.create(); formResponseBean.getContent().forEach(contentResponseBean -> { String fieldId = contentResponseBean.getId(); String value = (String) formFieldMap.get(fieldId); + String fieldLabel=contentResponseBean.getLabel(); if(value == null && isApplicationFormExist) { return; } FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean.getValidators(), FieldValidatorBean.class); validator - .isRequired(value,fieldValidatorBean.getIsRequired(),fieldId) - .minLength(value, fieldValidatorBean.getMinLength(), fieldId) // Only applies if minLength is not null - .maxLength(value, fieldValidatorBean.getMaxLength(), fieldId) // Only applies if maxLength is not null - .matchesPattern(value, fieldValidatorBean.getPattern(), fieldId) // Only applies if pattern is present - .validateCustom(value, fieldValidatorBean.getCustom(), fieldId); // Add the custom validation here + .minLength(value, fieldValidatorBean.getMinLength(), fieldLabel) // Only applies if minLength is not null + .maxLength(value, fieldValidatorBean.getMaxLength(), fieldLabel) // Only applies if maxLength is not null + .matchesPattern(value, fieldValidatorBean.getPattern(), fieldLabel) // Only applies if pattern is present + .validateCustom(value, fieldValidatorBean.getCustom(), fieldLabel); // Add the custom validation here if (fieldValidatorBean.getCustom() != null && fieldValidatorBean.getCustom().equals(GepafinConstant.IS_PIVA)) { - String error = validateVatNumber(value, fieldValidatorBean.getCustom(), fieldId); + String error = validateVatNumber(value, fieldValidatorBean.getCustom(), fieldLabel); if(error != null) { validator.addError(error); } @@ -228,6 +239,28 @@ public class FormDao { validator.validate(); } + private void checkObjectData(String fieldId, Object fieldValue, Map formFieldMap) { + if (fieldValue instanceof List) { + List list = (List) fieldValue; + + // Only map if the list is not empty and contains Strings + if (!list.isEmpty() && list.get(0) instanceof String) { + for (Object value : list) { + setFormFieldMap(fieldId, formFieldMap, value); + } + } + } + else setFormFieldMap(fieldId, formFieldMap, fieldValue); + } + + private void setFormFieldMap(String fieldId, Map formFieldMap, Object value) { + if (value instanceof String) { + if(value !=null && Boolean.FALSE.equals(StringUtils.isEmpty((String)value))) { + formFieldMap.put(fieldId, value); + } + } + } + private Boolean getApplicationFormExist(ApplicationFormEntity applicationFormEntity) { if(applicationFormEntity !=null) { return true; @@ -235,19 +268,43 @@ public class FormDao { return false; } + public Boolean validateCompletedSteps(List applicationFormFieldEntityList, ApplicationEntity applicationEntity, FormEntity formEntity) { + Map formFieldMap = new LinkedHashMap(); + for(ApplicationFormFieldEntity applicationFormFieldEntity:applicationFormFieldEntityList) { + formFieldMap.put(applicationFormFieldEntity.getFieldId(),applicationFormFieldEntity.getFieldValue()); + } + + FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); + FieldValidator validator = FieldValidator.create(); + formResponseBean.getContent().forEach(contentResponseBean -> { + String fieldId = contentResponseBean.getId(); + String value = (String) formFieldMap.get(fieldId); + + FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean.getValidators(), FieldValidatorBean.class); + validator + .isRequired(value,fieldValidatorBean.getIsRequired(),fieldId); + }); + if (validator.hasErrors()) { + return false; // Validation failed, return false + } + return true; + } public String validateVatNumber(String value,String customRule,String fieldId){ String error=null; - if (value.matches("^\\d{1,11}$")) { - Map customData=null; + + if (value!=null && value.matches("^\\d{1,11}$")) { +// Map customData=null; try { - Map vatCheckResponse = vatCheckDao.checkVatNumberApi(value); - if (Boolean.FALSE.equals(CollectionUtils.isEmpty(vatCheckResponse))) { - customData = vatCheckResponse; - } +// Map vatCheckResponse = vatCheckDao.checkVatNumberApi(value); + vatCheckDao.checkVatNumberApi(value); +// if (Boolean.FALSE.equals(CollectionUtils.isEmpty(vatCheckResponse))) { +// customData = vatCheckResponse; +// } } catch (Exception e) { error=(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_VALID_PIVA), fieldId)); } } return error; } + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java b/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java new file mode 100644 index 00000000..509d4843 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java @@ -0,0 +1,57 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.LoginAttemptEntity; +import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; +import net.gepafin.tendermanagement.repositories.LoginAttemptRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Component +public class LoginAttemptDao { + + @Autowired + LoginAttemptRepository loginAttemptRepository; + + public void createLoginAttempt(LoginAttemptEntity loginAttemptEntity) { + loginAttemptEntity.setAttemptDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + + loginAttemptRepository.save(loginAttemptEntity); + } + + public LoginAttemptPageableResponseBean> getLoginAttemptsList(Integer pageNo, Integer pageLimit) { + if (pageLimit == null || pageLimit <= 0) { + pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT; + } + + if (pageNo == null || pageNo <= 0) { + pageNo = GepafinConstant.DEFAULT_PAGE; + } + + Page page = loginAttemptRepository.findAll(PageRequest.of(pageNo - 1, pageLimit, Sort.by(GepafinConstant.ATTEMPT_DATE).descending())); + List list = new ArrayList<>(); + for (LoginAttemptEntity loginAttemptEntity : page.getContent()) { + list.add(loginAttemptEntity); + } + + LoginAttemptPageableResponseBean> pageableResponseBean = new LoginAttemptPageableResponseBean<>(); + pageableResponseBean.setBody(list); + pageableResponseBean.setCurrentPage(page.getNumber() + 1); + pageableResponseBean.setTotalPages(page.getTotalPages()); + pageableResponseBean.setTotalRecords(page.getTotalElements()); + pageableResponseBean.setPageSize(page.getSize()); + pageableResponseBean.setStatus(Status.SUCCESS); + pageableResponseBean.setMessage(Translator.toLocale(GepafinConstant.GET_LOGIN_ATTEMPT_MSG)); + return pageableResponseBean; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java new file mode 100644 index 00000000..17b57fc6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -0,0 +1,640 @@ +package net.gepafin.tendermanagement.dao; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.itextpdf.kernel.colors.ColorConstants; +import com.itextpdf.kernel.colors.DeviceRgb; +import com.itextpdf.kernel.pdf.canvas.PdfCanvas; +import com.itextpdf.layout.properties.UnitValue; +import com.itextpdf.layout.renderer.CellRenderer; +import com.itextpdf.layout.renderer.DrawContext; +import com.itextpdf.text.*; +import com.itextpdf.text.Element; +import com.itextpdf.text.Font; +import com.itextpdf.text.Image; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.*; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.model.request.CustomPageEvent; +import net.gepafin.tendermanagement.model.request.FieldLabelValuePairRequest; +import net.gepafin.tendermanagement.model.response.*; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.util.Validator; +import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.itextpdf.layout.element.Table; +import com.itextpdf.layout.element.Cell; +//import com.itextpdf.layout.element. + + +import java.awt.*; +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.*; +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class PdfDao { + + @Autowired + private CallService callService; + + @Autowired + private ApplicationDao applicationDao; + + @Autowired + private Validator validator; + + + public byte[] generatePdf(HttpServletRequest request,Long applicationId) { + try { + UserEntity userEntity = validator.validateUser(request); + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); + validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + CallEntity call=callService.validateCall(applicationEntity.getCall().getId()); + + // Create a byte stream to hold the PDF + ByteArrayOutputStream out = new ByteArrayOutputStream(); + float leftMargin = 50f; // Adjust this for the left margin + + Document document = new Document(PageSize.A4, leftMargin, 36f, 50f, 35); + PdfWriter writer = PdfWriter.getInstance(document, out); +// CustomPageEvent pageEvent = new CustomPageEvent(call.getName(), 0); +// writer.setPageEvent(pageEvent); + document.open(); +// pageEvent.setTotalPages(writer.getPageNumber()); + addLogo(document, "https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/logo.jpg"); // Add your image path here + + + BaseColor customColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed + // Define fonts and styles + BaseColor greenColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed + BaseColor darkGreenColor = new BaseColor(1, 50, 32); // Adjust RGB values as needed + Font titleFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 16, customColor); + Font sectionFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12,darkGreenColor); + Font labelFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12,new BaseColor(113,121,126)); // Light grey); + Font smallFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 8,new BaseColor(105, 105, 105)); + Font valueFont=FontFactory.getFont(FontFactory.HELVETICA_BOLD,10,new BaseColor(178, 190, 181)); + Paragraph title = new Paragraph(call.getName(), titleFont); + title.setAlignment(Element.ALIGN_LEFT); + document.add(title); + + BaseColor greyColor=new BaseColor(178, 190, 181); // Very light grey color + addColoredLines(writer,document,greyColor); + document.add(new Paragraph(" ")); + + // Application ID section (Centered) +// pageEvent.setTotalPages(writer.getPageNumber()); + String protocolNumber="XX00"; + if(applicationEntity.getProtocol()!=null) { + protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + Paragraph appId = new Paragraph("ID domanda :" +protocolNumber); + appId.setAlignment(Element.ALIGN_RIGHT); + document.add(appId); + + document.add(new Paragraph(" ")); + + addColoredLines(writer,document,greenColor); + document.add(new Paragraph(" ")); + document.add(new Paragraph("\n")); // Add line break +// String companyName= companyEntity.getCompanyName(); +// String vatNumber=companyEntity.getVatNumber(); +// String address=companyEntity.getAddress(); +// // Section: Dati Anagrafici Azienda +// document.add(new Paragraph("Dati Anagrafici Azienda", sectionFont)); +// addLabelValuePair(document, "Codice ATECO", "SEZIONE C “ATTIVITÀ MANUFATTURIERE”", regularFont); +// addLabelValuePair(document, "Ragione Sociale", companyName, regularFont); +// addLabelValuePair(document, "Partita IVA", vatNumber, regularFont); +// addLabelValuePair(document, "Indirizzo sede Legale", address, regularFont); +// +// document.add(new Paragraph("\n")); // Add line break +// +// // Section: Domanda presentata da +// document.add(new Paragraph("Domanda presentata da:", sectionFont)); +// addLabelValuePair(document, "Nome e cognome", userEntity.getBeneficiary().getFirstName()+" "+userEntity.getBeneficiary().getLastName(), regularFont); +// addLabelValuePair(document, "Codice fiscale", userEntity.getBeneficiary().getCodiceFiscale(), regularFont); +// addLabelValuePair(document, "Telefono", userEntity.getBeneficiary().getPhoneNumber(), regularFont); +// addLabelValuePair(document, "Email", userEntity.getBeneficiary().getEmail(), regularFont); +// addLabelValuePair(document, "Con il titolo di", "Rappresentante legale", regularFont); + document.add(new Paragraph(" ")); + + ApplicationGetResponseBean applicationGetResponseBean=applicationDao.getApplicationByFormId(applicationId,null, userEntity); + for(FormApplicationResponse formApplicationResponse: applicationGetResponseBean.getForm()) { + document.add(new Paragraph(formApplicationResponse.getLabel(),sectionFont)); + document.add(new Paragraph(" ")); // Add line break + List fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse); + for (FieldLabelValuePairRequest pair : fieldLabelValuePairRequests) { + String label = pair.getLabel(); + Object value = pair.getValue(); + Integer pages=0; + pages=addLabelValuePair(writer,document, label, value, labelFont,valueFont,call.getName(),pages); + if(pages !=0 ){ +// pageEvent.setTotalPages(writer.getPageNumber()); + } + } + addColoredLines(writer,document,greenColor); + document.add(new Paragraph(" ")); // Add line break + } + document.add(new Paragraph("\n")); // Add line break + Font boldSmallFont = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD,new BaseColor(105, 105, 105)); + + // Adding the "Documenti Allegati" section title + document.add(new Paragraph(" ")); + +// pageEvent.setTotalPages(writer.getPageNumber()); + document.newPage(); +// pageEvent.setTotalPages(writer.getPageNumber()); + document.add(new Paragraph("Documenti Allegati", sectionFont)); + document.add(new Paragraph(" ")); + + +// 1. Autocertificazione possesso Requisiti + Paragraph p1 = new Paragraph(); + p1.add(new Chunk("1. ", boldSmallFont)); + p1.add(new Chunk("Autocertificazione possesso Requisiti ", boldSmallFont)); + p1.add(new Chunk("ai sensi degli artt. 46 e 47 del DPR 445/2000", smallFont)); + document.add(p1); + document.add(new Paragraph(" ")); + + + +// 2. Informativa Privacy relativa al trattamento dei dati personali + Paragraph p2 = new Paragraph(); + p2.add(new Chunk("2. ", boldSmallFont)); + p2.add(new Chunk("Informativa Privacy relativa al trattamento dei dati personali", boldSmallFont)); + document.add(p2); + document.add(new Paragraph(" ")); + + +// 3. Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari + Paragraph p3 = new Paragraph(); + p3.add(new Chunk("3. ", boldSmallFont)); + p3.add(new Chunk("Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari prospettici come da tabella di cui all’Appendice 9", boldSmallFont)); + document.add(p3); + document.add(new Paragraph(" ")); + + +// 4. Rilevazione Centrale dei Rischi + Paragraph p4 = new Paragraph(); + p4.add(new Chunk("4. ", boldSmallFont)); + p4.add(new Chunk("Rilevazione Centrale dei Rischi riferita agli ultimi 36 mesi disponibili alla data di presentazione della Domanda", boldSmallFont)); + document.add(p4); + document.add(new Paragraph(" ")); + + +// 5. Schema di presentazione dei dati di bilancio + Paragraph p5 = new Paragraph(); + p5.add(new Chunk("5. ", boldSmallFont)); + p5.add(new Chunk("Schema di presentazione dei dati di bilancio", boldSmallFont)); + document.add(p5); + document.add(new Paragraph(" ")); + + +// 6. Dettagli bilanci in forma abbreviata + Paragraph p6 = new Paragraph(); + p6.add(new Chunk("6. ", boldSmallFont)); + p6.add(new Chunk("Dettagli bilanci in forma abbreviata", boldSmallFont)); + document.add(p6); + document.add(new Paragraph(" ")); + + +// 7. Relazione aziendale illustrativa + Paragraph p7 = new Paragraph(); + p7.add(new Chunk("7. ", boldSmallFont)); + p7.add(new Chunk("Relazione aziendale illustrativa", boldSmallFont)); + document.add(p7); + document.add(new Paragraph(" ")); + + addColoredLines(writer,document,greenColor); + +// System.out.println(writer.getPageSize()); +// System.out.println(document.getPageSize()); +// System.out.println(document.getPageNumber()); +// System.out.println(writer.getPageNumber()); +// document.setPageCount(100); +// document.setPageCount(writer.getPageNumber()); +// System.out.println(document.getPageNumber()); + + // Close the document + document.close(); + + // Convert to byte array for response + byte[] pdfBytes =PdfPageNumberInserter.addPageNumbers(out.toByteArray()); + + return pdfBytes; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private Integer addLabelValuePair(PdfWriter writer,Document document, String label, Object value, Font labelFont,Font valueFont,String title,Integer totalPages) throws DocumentException { + // Add label + Paragraph labelParagraph = new Paragraph(label, labelFont); + document.add(labelParagraph); + float leftMargin = 20f; + + PdfContentByte canvas = writer.getDirectContent(); + + // Setting the color and width of the line + float lineWidth = 1.0f; // Thickness of the line + canvas.setLineWidth(lineWidth); + + // Get the current vertical position in the document + float yPos = writer.getVerticalPosition(true) - 10f; // Adjust this to move line slightly below current content + + // Define start and end points for the line (relative to the page size and margins) + + if (yPos <= 140) { + // If xEnd is less than or equal to 200, generate a new page + + totalPages++; + document.newPage(); + } // Add a gap between the label and value + document.add(new Paragraph(" ")); // Adding an empty paragraph for spacing + // Create value cell with rounded corners + PdfPTable valueTable = new PdfPTable(1); + valueTable.setWidthPercentage(100); + if (value instanceof List) { + // Further check if the list contains Strings + List list = (List) value; + if (!list.isEmpty() && list.get(0) instanceof String) { + // Cast to List + List values = (List) value; + + // Loop through the list of strings and create a cell for each string + for (String item : values) { + PdfPCell valueCell = new PdfPCell(new Phrase(item, valueFont)); + valueCell.setPadding(5f); // Increase padding for better spacing + valueCell.setPaddingLeft(leftMargin); // Increase left margin for value + valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell + valueCell.setMinimumHeight(30f); + valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + + // Add the cell to the table + valueTable.addCell(valueCell); + } + + // Finally, add the table to the document + document.add(valueTable); + } else { + boolean containsThreeValues = false; // Variable to track if any map contains three keys + List> dataList = (List>) value; // Cast Object to List of Maps + for (Map entry : dataList) { + if (entry.size() == 3) { // Check if the current map has three keys + containsThreeValues = true; // If found, set the variable to true + break; // No need to check further, exit loop + } + } + List> extractedData = new ArrayList<>(); // To hold extracted data + for (Map entry : dataList) { + Map extractedMap = new HashMap<>(); // To hold the current extracted row of data + + List keys = new ArrayList<>(entry.keySet()); // Get all keys in the current map + + // Handle based on the number of keys in the map + if (Boolean.FALSE.equals(containsThreeValues) && keys.size() == 2) { + // Treat the first key as the "key" and second key as the "value" + String heading = (String) entry.get(keys.get(0)); // Get value of first key + String value1 = (String) entry.get(keys.get(1)); // Get value of second key + extractedMap.put(heading,value1); // Store the first key's value as "heading" + } if (Boolean.TRUE.equals(containsThreeValues) ) { + String amount=""; + // Treat the first as number, second as description, third as amount + if(keys.size()==3){ + amount = (String) entry.get(keys.get(2)); // Third key's value + } + String number = (String) entry.get(keys.get(0)); // First key's value + String description = (String) entry.get(keys.get(1)); // Second key's value + + // Store the combined result as a value in the map, with a suitable key + String combinedValue = number + "; " + description + "; " + amount; // Concatenate them as a single value + extractedMap.put("combined", combinedValue); // Store as a single entry, key as "combined" + } + + extractedData.add(extractedMap); // Add each extracted map to the list + } + document=createPdfTable(extractedData,document); + } + } + else { + PdfPCell valueCell = new PdfPCell(new Phrase(String.valueOf(value), valueFont)); + valueCell.setPadding(5f); // Increase padding for better spacing + valueCell.setPaddingLeft(leftMargin); // Increase left margin for value + valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell + valueCell.setMinimumHeight(30f); + valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + + valueTable.addCell(valueCell); + document.add(valueTable); + } + + document.add(new Paragraph("\n")); // Add line break after each value + return totalPages; + } + + private Document createPdfTable(List> extractedData,Document document) throws DocumentException { + // Create a PdfPTable with 2 columns + PdfPTable table = new PdfPTable(2); // Initial assumption for 2 columns + table.setWidthPercentage(100); // Set table width to 100% + table.setTableEvent(new RoundedBorderEvent()); + Font textFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new BaseColor(105, 105, 105)); // Gray text + boolean combinedHeaderAdded = false; // Flag to track if headers for combined have been added + float rowHeight = 50f; // Example row height, adjust as necessary + float maxTableHeight = 700f; // Maximum height of the table before a page break + float[] columnWidths = {0.7f, 0.3f}; + table.setWidths(columnWidths); + + +// Add table header +// Populate the table with extracted data and style rows + for (Map row : extractedData) { + for (Map.Entry entry : row.entrySet()) { + String key = entry.getKey(); // This will give you the key + String value = entry.getValue(); // This will give you the value + + // Check if the current entry is for the combined section + if ("combined".equals(key)) { + // Ensure the combined header is added only once + if (!combinedHeaderAdded) { + // Create a new table for combined entries + table = new PdfPTable(3); // 3 columns for combined entries + + PdfPCell headerCell1 = new PdfPCell(new Phrase("Number")); + headerCell1.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align + headerCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell1.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header + table.addCell(headerCell1); + + PdfPCell headerCell2 = new PdfPCell(new Phrase("Details")); + headerCell2.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align + headerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell2.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header + table.addCell(headerCell2); + + PdfPCell headerCell3 = new PdfPCell(new Phrase("Amount")); + headerCell3.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align + headerCell3.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell3.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header + table.addCell(headerCell3); + + combinedHeaderAdded = true; // Mark header as added + } + + // Split the value for "combined" into separate parts + String[] combinedValues = value.split("; "); + + // Check if we have 3 parts (number, description, amount) + String number = combinedValues[0]; // 1st part (number) + String description = combinedValues[1]; // 2nd part (description) + String amount = ""; + if (combinedValues.length == 3) { + amount = combinedValues[2]; // 3rd part (amount) + } + + // Create PDF cells using the split values + PdfPCell cellNumber = new PdfPCell(new Phrase(number, textFont)); // Cell for number + PdfPCell cellDescription = new PdfPCell(new Phrase(description, textFont)); // Cell for description + PdfPCell cellAmount = new PdfPCell(new Phrase(amount, textFont)); // Cell for amount + + // Set row background color for combined values + cellNumber.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for combined rows + cellDescription.setBackgroundColor(new BaseColor(239, 243, 248)); + cellAmount.setBackgroundColor(new BaseColor(239, 243, 248)); + + // Set cell height and add rounded borders +// cellNumber.setFixedHeight(rowHeight); +// cellDescription.setFixedHeight(rowHeight); +// cellAmount.setFixedHeight(rowHeight); + + cellNumber.setMinimumHeight(20f); // Set minimum height for better appearance + cellDescription.setMinimumHeight(20f); // Set minimum height for better appearance + cellAmount.setMinimumHeight(20f); // Set minimum height for better appearance + + cellNumber.setPadding(7f); + cellDescription.setPadding(7f); + cellAmount.setPadding(7f); + + // Add the cells to the table only once + table.addCell(cellNumber); + table.addCell(cellDescription); + table.addCell(cellAmount); + + + } else { + if (!combinedHeaderAdded) { + // Create a new table for combined entries + table= new PdfPTable(2); // 3 columns for combined entries + table.setWidthPercentage(100); + + PdfPCell headerCell1 = new PdfPCell(new Phrase("Details")); + headerCell1.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align + headerCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell1.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header + table.addCell(headerCell1); + + PdfPCell headerCell2 = new PdfPCell(new Phrase("Amount")); + headerCell2.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align + headerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell2.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header + table.addCell(headerCell2); + combinedHeaderAdded=true; +} + // Add cells for regular key-value pairs without headers + PdfPCell cellKey = new PdfPCell(new Phrase(key, textFont)); + PdfPCell cellValue = new PdfPCell(new Phrase(value, textFont)); + + // Set background color for both cells + cellKey.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for other rows + cellValue.setBackgroundColor(new BaseColor(239, 243, 248)); + + cellKey.setPadding(7f); + cellValue.setPadding(7f); + // Set cell height and add rounded borders + cellKey.setFixedHeight(rowHeight); + cellValue.setFixedHeight(rowHeight); + + // Add the cells to the table + table.addCell(cellKey); + table.addCell(cellValue); + } + if (table.getTotalHeight() + rowHeight > maxTableHeight) { + // Start a new page if needed + document.add(table); + table = new PdfPTable(2); // Reset table for new page + table.setWidthPercentage(100); // Reset width percentage + combinedHeaderAdded = false; // Reset header flag + } + } + } + document.add(table); // Add the last table before returning + + + // Check if adding a new row would exceed the maximum height +// Return the populated table + return document; + } + public static class RoundedBorderEvent implements PdfPTableEvent { + @Override + public void tableLayout(PdfPTable table, float[][] widths, float[] heights, + int headerRows, int rowStart, PdfContentByte[] canvases) { + PdfContentByte canvas = canvases[PdfPTable.BASECANVAS]; + + // Get the table boundaries + float left = widths[0][0]; + float right = widths[0][widths[0].length - 1]; + float top = heights[0]; + float bottom = heights[heights.length - 1]; + + // Define the corner radius + float radius = 20f; + + // Draw a rounded rectangle around the table + canvas.roundRectangle(left, bottom, right - left, top - bottom, radius); + canvas.stroke(); + } + } + public List getFormFieldsToLabels(FormApplicationResponse responseBean) { + List labelValuePairs = new ArrayList<>(); + + // Iterate through each form in the application response + + List formFields = responseBean.getFormFields(); + List contents = responseBean.getContent(); + + // Iterate through each formField in the current form + for (ApplicationFormFieldResponseBean formField : formFields) { + String fieldId = formField.getFieldId(); + Object fieldValue = formField.getFieldValue(); + + // Find the content in the form that matches the fieldId + Optional matchingContent = contents.stream() + .filter(content -> content.getId().equals(fieldId)) + .findFirst(); + + + // If the content with the matching fieldId is found, create a label-value pair + if (matchingContent.isPresent()) { + String name = matchingContent.get().getName(); + if (name.equals("fileupload")) { + +// Step 1: Check if fieldValue is an instance of List + if (fieldValue instanceof List && ((List) fieldValue).stream().allMatch(item -> item instanceof DocumentResponseBean)) { + // Step 2: Safely cast to List + List documentList = (List) fieldValue; + + // Step 3: Extract names from the document list + List names = documentList.stream() + .map(DocumentResponseBean::getName) // Extract the name from each DocumentResponseBean + .collect(Collectors.toList()); + + fieldValue=names; + } + } + if(name.equals("checkboxes")) { + List check = (List) fieldValue; + List settingResponseBeans = matchingContent.get().getSettings(); + for (SettingResponseBean settingResponseBean : settingResponseBeans) { + // Initialize a list to hold matched labels for each SettingResponseBean + List matchedLabels = new ArrayList<>(); + if (settingResponseBean.getValue() instanceof List) { + + List valueList = (List) settingResponseBean.getValue(); + if (!valueList.isEmpty() && valueList.get(0) instanceof Map) { + // Cast to List> + List> options = (List>) valueList; + for (Map field : options) { + for (String val : check) { + String name1=field.get("name"); + if (val.equals(name1)) { // Check if the key exists in the current field map + String label = field.get("label"); // Extract the label + if (field != null) { // Check if the value is not null + matchedLabels.add(label); // Add the value to the matchedValues list + } + } + } + } + fieldValue = matchedLabels; + } + } + } + } + String label = matchingContent.get().getLabel(); + // Add the label-value pair to the list + if (fieldValue != null && !fieldValue.toString().trim().isEmpty()) { + fieldValue = findLabelInOptions(matchingContent.get().getSettings(), fieldValue); + labelValuePairs.add(new FieldLabelValuePairRequest(label, fieldValue)); + } + } + } + + return labelValuePairs; + } + + public static Object findLabelInOptions(List settings, Object valueToFind) { + ObjectMapper objectMapper = new ObjectMapper(); + + try { + if (valueToFind instanceof String) { + String searchValue = (String) valueToFind; + for (SettingResponseBean setting : settings) { + Object value = setting.getValue(); + if (value instanceof List) { + List options = (List) value; + for (Object option : options) { + JsonNode optionNode = objectMapper.convertValue(option, JsonNode.class); + if (optionNode.get("name").asText().equals(searchValue)) { + return optionNode.get("label").asText(); + } + } + } + } + } + } catch (Exception e) { + } + return valueToFind; + } + + public void addLogo(Document document, String logoPath) throws Exception { + Image logo = Image.getInstance(logoPath); + logo.scaleToFit(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin(), // Fit to document width + document.getPageSize().getHeight() / 4); // Adjust the height as needed (1/4th of the page height) + logo.setAlignment(Image.ALIGN_CENTER); // Align logo to center + document.add(logo); + + // Add some space after logo + document.add(new Paragraph("\n")); // Adding space after the logo + } + public void addColoredLines(PdfWriter writer, Document document, BaseColor color){ + PdfContentByte canvas = writer.getDirectContent(); + + // Setting the color and width of the line + canvas.setColorStroke(color); + float lineWidth = 1.0f; // Thickness of the line + canvas.setLineWidth(lineWidth); + + // Get the current vertical position in the document + float yPos = writer.getVerticalPosition(true) - 10f; // Adjust this to move line slightly below current content + + // Define start and end points for the line (relative to the page size and margins) + float xStart = document.leftMargin(); // Start from the left margin + float xEnd = document.getPageSize().getWidth() - document.rightMargin(); // End at the right margin + + // Draw the line at the current Y position + canvas.moveTo(xStart, yPos); // Move to the starting point + canvas.lineTo(xEnd, yPos); // Draw the line to the end point + canvas.stroke(); // Apply the stroke (line) + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfPageNumberInserter.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfPageNumberInserter.java new file mode 100644 index 00000000..0ac9ce20 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfPageNumberInserter.java @@ -0,0 +1,45 @@ +package net.gepafin.tendermanagement.dao; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Font; +import com.itextpdf.text.FontFactory; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; +import com.itextpdf.text.pdf.PdfContentByte; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class PdfPageNumberInserter { + + public static byte[] addPageNumbers(byte[] pdfData) throws IOException, DocumentException { + PdfReader reader = new PdfReader(pdfData); // Read the generated PDF + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + BaseColor darkGreenColor = new BaseColor(1, 50, 32); // Adjust RGB values as needed + Font baseFont = FontFactory.getFont(FontFactory.HELVETICA, 4,darkGreenColor); + BaseFont font = baseFont.getBaseFont(); + + // PdfStamper allows us to modify the existing PDF + PdfStamper stamper = new PdfStamper(reader, outputStream); + int totalPages = reader.getNumberOfPages(); + + // Set the font for page numbers + + for (int i = 1; i <= totalPages; i++) { + // Get the content of the current page + PdfContentByte over = stamper.getOverContent(i); + over.beginText(); + over.setFontAndSize(font, 12); + + // Add the page number at the bottom center of the page + over.showTextAligned(PdfContentByte.ALIGN_CENTER, "Page " + i + " of " + totalPages, 300, 30, 0); + + over.endText(); + } + + stamper.close(); + reader.close(); + + return outputStream.toByteArray(); // Return the modified PDF with page numbers + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java b/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java index ef80acbb..cb4f41fd 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java @@ -4,6 +4,7 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.RegionEntity; import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.model.request.RoleReq; import net.gepafin.tendermanagement.model.response.RegionResponseBean; import net.gepafin.tendermanagement.model.response.RoleResponseBean; @@ -119,4 +120,8 @@ public class RoleDao { log.info("Total roles found: {}", roles.size()); return roles; } + + public RoleEntity getRoleByType(RoleStatusEnum roleStatus) { + return roleRepository.findByRoleType(roleStatus.getValue()); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/RoundedCorners.java b/src/main/java/net/gepafin/tendermanagement/dao/RoundedCorners.java new file mode 100644 index 00000000..9aa82dc1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/RoundedCorners.java @@ -0,0 +1,45 @@ +package net.gepafin.tendermanagement.dao; + +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfPCell; +import com.itextpdf.text.pdf.PdfPCellEvent; +import com.itextpdf.text.pdf.PdfPTable; + +public class RoundedCorners implements PdfPCellEvent { + @Override + public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvas) { + // Retrieve the canvas for drawing the background and border + PdfContentByte cbBackground = canvas[PdfPTable.BACKGROUNDCANVAS]; + PdfContentByte cb = canvas[PdfPTable.LINECANVAS]; + + cbBackground.saveState(); + cb.saveState(); + + // Define the rounded rectangle radius and padding + float radius = 10f; + float padding = 2f; // Small padding to avoid overlap + + // Get position values with adjusted height and width + float x = position.getLeft() + padding; + float y = position.getBottom() + padding; + float width = position.getWidth() - 2 * padding; + float height = position.getHeight() - 2 * padding; + + // Fill the rounded rectangle with lighter grey + cbBackground.setColorFill(new BaseColor(239, 243, 248)); // Very light grey color + cbBackground.roundRectangle(x, y, width, height, radius); + cbBackground.fill(); // Fill the background + + // Set the border stroke to thin and draw the rounded rectangle with dark grey color + cb.setLineWidth(0.5f); // Thin border width + cb.setColorStroke(new BaseColor(105, 105, 105)); // Dark grey border + cb.roundRectangle(x, y, width, height, radius); + cb.stroke(); // Draw the border + + // Restore the canvas states + cbBackground.restoreState(); + cb.restoreState(); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java new file mode 100644 index 00000000..9218a33d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java @@ -0,0 +1,116 @@ +package net.gepafin.tendermanagement.dao; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; +import net.gepafin.tendermanagement.repositories.SystemEmailTemplatesRespository; +import net.gepafin.tendermanagement.util.Utils; + +@Component +public class SystemEmailTemplatesDao { + + @Autowired + private SystemEmailTemplatesRespository systemEmailTemplatesRespository; + + @Value("${fe.base.url}") + private String feBaseUrl; + + + public SystemEmailTemplateResponse retrieveTemplate(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) { + SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity = null; + if(call != null){ +// dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository +// .findByTypeAndCallId(type.getValue(), call.getId()); + } + if(dbSystemEmailTemplatesEntity == null){ + dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository + .findByType(type.getValue()); + } + + SystemEmailTemplateResponse systemEmailTemplateResponse = replaceHtmlContant(dbSystemEmailTemplatesEntity, call, language, Boolean.TRUE); + return systemEmailTemplateResponse; + } + + private SystemEmailTemplateResponse replaceHtmlContant(SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity, + CallEntity call, Locale language1, Boolean isDefaultReplace) { + String language = null; + String htmlContent = dbSystemEmailTemplatesEntity.getHtmlContent(); + String subject = dbSystemEmailTemplatesEntity.getSubject(); + + if (language1 == null) { +// language = getLanguage(LocaleContextHolder.getLocale()); + language="italian"; + }else{ + language="italian"; + } + Map languageMap = new HashMap<>(); + String jsonContent = dbSystemEmailTemplatesEntity.getJson(); + if (Boolean.FALSE.equals(StringUtils.isEmpty(jsonContent))) { + Map> jsonMap = Utils.parseJsonContent(jsonContent); + if (jsonMap != null && jsonMap.containsKey(language)) { + languageMap = jsonMap.get(language); + htmlContent = replacePlaceholders(htmlContent, languageMap); + subject = replaceSubjectPlaceholders(subject, languageMap); + + } + } + if(Boolean.TRUE.equals(StringUtils.isEmpty(subject))){ + subject = ""; + } + + + htmlContent = replacePlatformLinkPlaceholder(call, htmlContent, languageMap); + SystemEmailTemplateResponse systemEmailTemplateResponse = new SystemEmailTemplateResponse(); + systemEmailTemplateResponse.setHtmlContent(htmlContent); + systemEmailTemplateResponse.setSubject(subject); + systemEmailTemplateResponse.setJsonMap(languageMap); + return systemEmailTemplateResponse; + } + + + +// private String getLanguage(Locale locale) { +// return switch (locale.getLanguage()) { +// case "en" -> "english"; +// case "it" -> "italian"; +// default -> "italian"; +// }; +// } + + private String replacePlaceholders(String htmlContent, Map languageMap) { + for (Map.Entry entry : languageMap.entrySet()) { + htmlContent = htmlContent.replace("{{" + entry.getKey() + "}}", entry.getValue()); + } + return htmlContent; + } + + private String replaceSubjectPlaceholders(String subject, Map languageMap) { + if(languageMap.containsKey("subject") && subject != null){ + String value = languageMap.get("subject"); + subject = subject.replace("{{subject}}", value); + return subject; + } + return ""; + } + private String replacePlatformLinkPlaceholder(CallEntity call, String htmlContent, + Map languageMap) { + String platformLink = feBaseUrl; + +// if(hubEntity != null && Boolean.FALSE.equals(isEmpty(hubEntity.getDomainName()))){ +// platformLink = hubEntity.getDomainName(); +// } + htmlContent = htmlContent.replace("{{platform_link}}", platformLink); + return htmlContent; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 8defef0a..d690f673 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -4,68 +4,158 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.BeneficiaryEntity; import net.gepafin.tendermanagement.entities.RoleEntity; import net.gepafin.tendermanagement.entities.UserEntity; -import net.gepafin.tendermanagement.entities.UserHubEntity; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; 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.util.JWTToken; -import net.gepafin.tendermanagement.repositories.UserHubRepository; +import net.gepafin.tendermanagement.repositories.BeneficiaryRepository; import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.service.RoleService; import net.gepafin.tendermanagement.service.impl.AuthenticationService; +import net.gepafin.tendermanagement.util.Utils; 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.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Repository; -import java.security.SecureRandom; +import org.springframework.stereotype.Component; import java.util.ArrayList; -import java.util.Base64; import java.util.List; +import java.util.stream.Collectors; + import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; -@Repository +@Component public class UserDao { private final Logger log = LoggerFactory.getLogger(UserDao.class); @Autowired private UserRepository userRepository; - + + @Autowired + private CompanyDao companyDao; + @Autowired private AuthenticationService authService; @Autowired private PasswordEncoder passwordEncoder; - @Autowired - private UserHubRepository userHubRepository; + @Autowired private RoleDao roleDao; + + @Autowired + private BeneficiaryRepository beneficiaryRepository; + + @Autowired + private RoleService roleService; + + @Value("${default.hub.uuid}") + private String defaultHubUuid; - public UserResponseBean createUser(UserReq userReq) { - log.info("Creating user with email: {}", userReq.getEmail()); - if (userRepository.existsByEmailIgnoreCase(userReq.getEmail())) { - log.error("User creation failed: Email {} already exists", userReq.getEmail()); - throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); + + public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) { + if(StringUtils.isEmpty(userReq.getHubUuid())) { + userReq.setHubUuid(defaultHubUuid); + } + validateUserRequest(tempToken, userReq); + validatePassword(userReq.getPassword(), userReq.getConfPassword(), tempToken); + + RoleEntity roleEntity = getRoleEntity(userReq.getRoleId()); + BeneficiaryEntity beneficiary = createBeneficiary(roleEntity, userReq); + UserEntity userEntity = convertUserRequestToUserEntity(beneficiary, roleEntity, userReq); + log.info("User created with ID: {}", userEntity.getId()); + return authService.getJWTTokenBean(userEntity, Boolean.TRUE); + } + + private BeneficiaryEntity createBeneficiary(RoleEntity roleEntity, UserReq userReq) { + BeneficiaryEntity beneficiaryEntity = null; + if (RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleEntity.getRoleType())) { + beneficiaryEntity = new BeneficiaryEntity(); + beneficiaryEntity.setAddress(userReq.getAddress()); + beneficiaryEntity.setCity(userReq.getCity()); + beneficiaryEntity.setCodiceFiscale(userReq.getCodiceFiscale()); + beneficiaryEntity.setCountry(userReq.getCountry()); + beneficiaryEntity.setDateOfBirth(userReq.getDateOfBirth()); + beneficiaryEntity.setEmail(userReq.getEmail()); + beneficiaryEntity.setFirstName(userReq.getFirstName()); + beneficiaryEntity.setLastName(userReq.getLastName()); + beneficiaryEntity.setOrganization(userReq.getOrganization()); + beneficiaryEntity.setPhoneNumber(userReq.getPhoneNumber()); + beneficiaryEntity.setPrivacy(userReq.getPrivacy()); + beneficiaryEntity.setTerms(userReq.getTerms()); + beneficiaryEntity.setOffers(userReq.getOffers()); + beneficiaryEntity.setMarketing(userReq.getMarketing()); + beneficiaryEntity.setThirdParty(userReq.getThirdParty()); + beneficiaryEntity.setEmailPec(userReq.getEmailPec()); + beneficiaryEntity =beneficiaryRepository.save(beneficiaryEntity); + } + return beneficiaryEntity; + } + + private void validateUserRequest(String tempToken, UserReq userReq) { + RoleEntity role = roleService.validateRole(userReq.getRoleId()); + if (Boolean.FALSE.equals(Utils.isValidEmail(userReq.getEmail()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + 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())) + && userRepository.existsByBeneficiaryCodiceFiscale(userReq.getCodiceFiscale())) { + log.error("User creation failed: CodiceFiscale {} already exists", userReq.getCodiceFiscale()); + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.CODICE_FISCALE_EXISTS)); + } + if (tempToken == null && userReq.getRoleId() == null) { + throw new ResourceNotFoundException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.ROLE_ID_MANDATORY)); + } + if (tempToken != null) { + userReq.setRoleId(null); + } + if(tempToken == null && Boolean.TRUE.equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(role.getRoleType()))){ + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.CANNOT_CREATE_BENEFICIARY_USER)); } - if (!userReq.getPassword().equals(userReq.getConfPassword())) { - log.error("User creation failed: Passwords do not match for email {}", userReq.getEmail()); + } + + 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)); + }else if(Boolean.FALSE.equals(StringUtils.isEmpty(password) && StringUtils.isEmpty(confirmPassword))){ + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATE_PASSWORD)); + } + } + + if (password != null && !password.equals(confirmPassword)) { + log.error("User creation failed: Passwords do not match"); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); } - if (userReq.getPassword().length() < 8) { - log.error("User creation failed: Password length is less than 8 characters for email {}", userReq.getEmail()); + + if (password != null && password.length() < 8) { + log.error("User creation failed: Password length is less than 8 characters"); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_MIN_LEN)); } - UserEntity userEntity = convertUserRequestToUserEntity(userReq); - userEntity = userRepository.save(userEntity); - log.info("User created with ID: {}", userEntity.getId()); - return convertUserEntityToUserResponse(userEntity); } public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { @@ -82,59 +172,101 @@ public class UserDao { setIfUpdated(userEntity::getOrganization, userEntity::setOrganization, userReq.getOrganization()); 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); } + setIfUpdated(userEntity.getBeneficiary()::getEmailPec, userEntity.getBeneficiary()::setEmailPec, userReq.getEmailPec()); userEntity = userRepository.save(userEntity); log.info("User updated with ID: {}", userEntity.getId()); return convertUserEntityToUserResponse(userEntity); } - private UserEntity convertUserRequestToUserEntity(UserReq userReq) { + private UserEntity convertUserRequestToUserEntity(BeneficiaryEntity beneficiary, RoleEntity roleEntity, UserReq userReq) { UserEntity userEntity = new UserEntity(); - userEntity.setPassword(passwordEncoder.encode(userReq.getPassword())); + if(Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getPassword()))) { + userEntity.setPassword(passwordEncoder.encode(userReq.getPassword())); + } + userEntity.setRoleEntity(roleEntity); userEntity.setEmail(userReq.getEmail()); - userEntity.setFirstName(userReq.getFirstName()); - userEntity.setStatus(UserStatusEnum.PENDING_VERIFICATION.getValue()); - userEntity.setLastName(userReq.getLastName()); - userEntity.setOrganization(userReq.getOrganization()); - userEntity.setAddress(userReq.getAddress()); - userEntity.setPhoneNumber(userReq.getPhoneNumber()); - userEntity.setRoleEntity(roleDao.validateRole(userReq.getRoleId())); - return userEntity; + userEntity.setStatus(UserStatusEnum.ACTIVE.getValue()); + userEntity.setBeneficiary(beneficiary); + if (Boolean.FALSE.equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleEntity.getRoleType()))) { + + userEntity.setFirstName(userReq.getFirstName()); + userEntity.setLastName(userReq.getLastName()); + userEntity.setOrganization(userReq.getOrganization()); + userEntity.setAddress(userReq.getAddress()); + userEntity.setPhoneNumber(userReq.getPhoneNumber()); + userEntity.setDateOfBirth(userReq.getDateOfBirth()); + } + return userRepository.save(userEntity); } - private UserResponseBean convertUserEntityToUserResponse(UserEntity userEntity) { - UserResponseBean userResponseBean = new UserResponseBean(); - userResponseBean.setId(userEntity.getId()); - userResponseBean.setCreatedDate(userEntity.getCreatedDate()); - userResponseBean.setUpdatedDate(userEntity.getUpdatedDate()); - userResponseBean.setEmail(userEntity.getEmail()); - userResponseBean.setFirstName(userEntity.getFirstName()); - userResponseBean.setLastName(userEntity.getLastName()); - userResponseBean.setPhoneNumber(userEntity.getPhoneNumber()); - userResponseBean.setOrganization(userEntity.getOrganization()); - userResponseBean.setAddress(userEntity.getAddress()); - userResponseBean.setCity(userEntity.getCity()); - userResponseBean.setCountry(userEntity.getCountry()); - userResponseBean.setStatus(UserStatusEnum.valueOf(userEntity.getStatus())); - RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(userEntity.getRoleEntity()); - userResponseBean.setRole(roleResponseBean); - userResponseBean.setLastLogin(userEntity.getLastLogin()); - return userResponseBean; - } + private RoleEntity getRoleEntity(Long roleId) { + if(roleId != null) { + return roleDao.validateRole(roleId); + } else { + return roleDao.getRoleByType(RoleStatusEnum.ROLE_BENEFICIARY); + } + } - public UserResponseBean getUserById(Long id) { - log.info("Fetching user with ID: {}", id); - UserEntity userEntity=validateUser(id); + private UserResponseBean convertUserEntityToUserResponse(UserEntity userEntity) { + UserResponseBean userResponseBean = new UserResponseBean(); + userResponseBean.setId(userEntity.getId()); + userResponseBean.setCreatedDate(userEntity.getCreatedDate()); + userResponseBean.setUpdatedDate(userEntity.getUpdatedDate()); + userResponseBean.setEmail(userEntity.getEmail()); + userResponseBean.setStatus(UserStatusEnum.valueOf(userEntity.getStatus())); + RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(userEntity.getRoleEntity()); + userResponseBean.setRole(roleResponseBean); + userResponseBean.setLastLogin(userEntity.getLastLogin()); + List companyResponseBeans = companyDao.getCompanyByUserId(userEntity.getId()); + userResponseBean.setCompanies(companyResponseBeans); + if (userEntity.getBeneficiary() == null) { + userResponseBean.setFirstName(userEntity.getFirstName()); + userResponseBean.setLastName(userEntity.getLastName()); + userResponseBean.setPhoneNumber(userEntity.getPhoneNumber()); + userResponseBean.setOrganization(userEntity.getOrganization()); + userResponseBean.setAddress(userEntity.getAddress()); + userResponseBean.setCity(userEntity.getCity()); + userResponseBean.setCountry(userEntity.getCountry()); + userResponseBean.setDateOfBirth(userEntity.getDateOfBirth()); + } else { + userResponseBean.setFirstName(userEntity.getBeneficiary().getFirstName()); + userResponseBean.setLastName(userEntity.getBeneficiary().getLastName()); + userResponseBean.setPhoneNumber(userEntity.getBeneficiary().getPhoneNumber()); + userResponseBean.setOrganization(userEntity.getBeneficiary().getOrganization()); + userResponseBean.setAddress(userEntity.getBeneficiary().getAddress()); + userResponseBean.setCity(userEntity.getBeneficiary().getCity()); + userResponseBean.setCountry(userEntity.getBeneficiary().getCountry()); + userResponseBean.setCodiceFiscale(userEntity.getBeneficiary().getCodiceFiscale()); + userResponseBean.setDateOfBirth(userEntity.getBeneficiary().getDateOfBirth()); + userResponseBean.setPrivacy(userEntity.getBeneficiary().getPrivacy()); + userResponseBean.setTerms(userEntity.getBeneficiary().getTerms()); + userResponseBean.setOffers(userEntity.getBeneficiary().getOffers()); + userResponseBean.setMarketing(userEntity.getBeneficiary().getMarketing()); + userResponseBean.setThirdParty(userEntity.getBeneficiary().getThirdParty()); + userResponseBean.setEmailPec(userEntity.getBeneficiary().getEmailPec()); + } + return userResponseBean; + } + + public UserResponseBean getUserById(Long id) { + log.info("Fetching user with ID: {}", id); + UserEntity userEntity = validateUser(id); // if (!UserStatusEnum.ACTIVE.getValue().equals(userEntity.getStatus())) { // log.info("User with ID: {} is not active", id); // throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); // } - log.info("User found: {}", userEntity); - return convertUserEntityToUserResponse(userEntity); - } + log.info("User found: {}", userEntity); + return convertUserEntityToUserResponse(userEntity); + } public void deleteUser(Long id) { log.info("Deleting user with ID: {}", id); @@ -143,9 +275,12 @@ public class UserDao { log.info("User deleted with ID: {}", id); } - public JWTToken login(LoginReq loginReq) { + public JWTToken login(LoginReq loginReq,HttpServletRequest request) { log.info("User login attempt for email: {}", loginReq.getEmail()); - JWTToken jwtToken = authService.login(loginReq); + if(StringUtils.isEmpty(loginReq.getHubUuid())) { + loginReq.setHubUuid(defaultHubUuid); + } + JWTToken jwtToken = authService.login(loginReq,request); log.info("Login successful for email: {}", loginReq.getEmail()); return jwtToken; } @@ -155,22 +290,22 @@ public class UserDao { .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); } - public String generateSecureToken() { - SecureRandom secureRandom = new SecureRandom(); - byte[] tokenBytes = new byte[24]; - secureRandom.nextBytes(tokenBytes); - String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); - log.debug("Generated secure token: {}", token); - return token; + public UserEntity getUserByBeneficiaryId(Long beneficiaryId) { + UserEntity user = userRepository.findByBeneficiaryId(beneficiaryId); + if (user == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_WITH_BENEFICIARYID_MSG)); + } + return user; } public String initiatePasswordReset(InitiatePasswordResetReq resetReq) { - UserEntity user = userRepository.findByEmail(resetReq.getEmail()); - if (user == null) { - log.info("Password reset attempt for non-existent user: {}", resetReq.getEmail()); - throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); - } - String token = generateSecureToken(); + UserEntity user = userRepository + .findByEmailIgnoreCaseAndhubUniqueUuid(resetReq.getEmail(), resetReq.getHubUuid()) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + + String token = Utils.generateSecureToken(); user.setResetPasswordToken(token); userRepository.save(user); log.info("Password reset token generated for user: {}", resetReq.getEmail()); @@ -178,11 +313,11 @@ public class UserDao { } public Boolean resetPassword(ResetPasswordReq resetPasswordReq) { - UserEntity user = userRepository.findByEmail(resetPasswordReq.getEmail()); - if (user == null) { - log.info("Password reset attempt for non-existent user: {}", resetPasswordReq.getEmail()); - throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); - } + UserEntity user = userRepository + .findByEmailIgnoreCaseAndhubUniqueUuid(resetPasswordReq.getEmail(), resetPasswordReq.getHubUuid()) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + 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)); @@ -201,12 +336,12 @@ public class UserDao { return true; } - public Boolean changePassword(ChangePasswordRequest request) { - UserEntity user = userRepository.findByEmail(request.getEmail()); - if (user == null) { - log.info("Password reset attempt for non-existent user: {}", request.getEmail()); - throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); - } + public Boolean changePassword(UserEntity userEntity, ChangePasswordRequest request) { + 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())) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CURRENT_PASSWORD_INCORRECT)); } @@ -232,24 +367,41 @@ public class UserDao { return convertUserEntityToUserResponse(userEntity); } public List getUserByHubId(String hubId) { - log.info("Fetching users for hub ID: {}", hubId); - List userHubMappings = userHubRepository.findByHubId(hubId); +// log.info("Fetching users for hub ID: {}", hubId); +// List userHubMappings = userHubRepository.findByHubId(hubId); List userResponseBeans = new ArrayList<>(); - for (UserHubEntity mapping : userHubMappings) { - UserEntity userEntity = validateUser(mapping.getUserId()); - userResponseBeans.add(convertUserEntityToUserResponse(userEntity)); - } +// for (UserHubEntity mapping : userHubMappings) { +// UserEntity userEntity = validateUser(mapping.getUserId()); +// userResponseBeans.add(convertUserEntityToUserResponse(userEntity)); +// } return userResponseBeans; } - public UserResponseBean createUserByHubId(String hubId, UserReq userReq) { - log.info("Creating user for hub ID: {}", hubId); - UserResponseBean createdUser = createUser(userReq); - UserHubEntity mapping = new UserHubEntity(); - mapping.setHubId(hubId); - mapping.setUserId(createdUser.getId()); - userHubRepository.save(mapping); - log.info("User created and mapped to hub ID: {} with User ID: {}", hubId, createdUser.getId()); - return createdUser; + public JWTToken validateExistingUserToken(String token) { + return authService.validateExistingUserToken(token); + } + + public UserSamlResponse validateNewUserToken(String token) { + return authService.validateNewUserToken(token); + } + + public List getAllUsers(Long roleId) { + List users; + if (roleId != null) { + log.info("Fetching users by role ID: {}", roleId); + RoleEntity roleEntity=roleService.validateRole(roleId); + users = userRepository.findByRoleEntityId(roleEntity.getId()); + } else { + log.info("Fetching all users"); + users = userRepository.findAll(); + } + List userResponseBeans = users.stream() + .map(this::convertUserEntityToUserResponse) + .collect(Collectors.toList()); + + log.info("Total users found with role ID {}: {}", roleId, userResponseBeans.size()); + return userResponseBeans; } + + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java index 4d1d0f58..f4a07849 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java @@ -1,8 +1,13 @@ package net.gepafin.tendermanagement.dao; import feign.FeignException; +import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.service.feignClient.VatCheckService; +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; @@ -67,8 +72,17 @@ public class VatCheckDao { } } catch (FeignException ex) { log.error("Exception occurred while checking vat number: {0}", ex); - throw ex; + Utils.callException(ex.status(), ex); } return responseBody; } + + public Map checkVatNumber(String vatNumber) { + try { + return checkVatNumberApi(vatNumber); + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + } + } } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index 8c9156e3..cc0f929e 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -13,9 +13,12 @@ import java.time.LocalDateTime; @Builder public class ApplicationEntity extends BaseEntity { + @Column(name = "USER_ID") + private Long userId; + @ManyToOne - @JoinColumn(name = "USER_ID", nullable = false) - private UserEntity user; + @JoinColumn(name = "COMPANY_ID", nullable = false) + private CompanyEntity company; @Column(name = "SUBMISSION_DATE") private LocalDateTime submissionDate; @@ -29,8 +32,11 @@ public class ApplicationEntity extends BaseEntity { @ManyToOne @JoinColumn(name = "CALL_ID", nullable = false) private CallEntity call; - + @Column(name="IS_DELETED") private Boolean isDeleted; + @OneToOne + @JoinColumn(name = "PROTOCOL_NUMBER") + private ProtocolEntity protocol; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java new file mode 100644 index 00000000..58975cca --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java @@ -0,0 +1,28 @@ +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; + +@Data +@Entity +@Table(name = "application_signed_document") +public class ApplicationSignedDocumentEntity extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "APPLICATION_ID") + private ApplicationEntity application; + + @Column(name = "FILE_NAME") + private String fileName; + + @Column(name = "FILE_PATH") + private String filePath; + + @Column(name="STATUS") + private String status; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java new file mode 100644 index 00000000..bae88c90 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java @@ -0,0 +1,64 @@ +package net.gepafin.tendermanagement.entities; + +import java.time.LocalDateTime; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Email; +import lombok.Data; + +@Entity +@Table(name = "BENEFICIARY") +@Data +public class BeneficiaryEntity extends BaseEntity { + + @Email + @Column(name = "EMAIL") + private String email; + + @Column(name = "FIRST_NAME") + private String firstName; + + @Column(name = "LAST_NAME") + private String lastName; + + @Column(name = "PHONE_NUMBER") + private String phoneNumber; + + @Column(name = "ORGANIZATION") + private String organization; + + @Column(name = "ADDRESS") + private String address; + + @Column(name = "CITY") + private String city; + + @Column(name = "COUNTRY") + private String country; + + @Column(name = "CODICE_FISCALE") + private String codiceFiscale; + + @Column(name = "DATE_OF_BIRTH") + private LocalDateTime dateOfBirth; + + @Column(name = "PRIVACY") + private Boolean privacy; + + @Column(name = "TERMS") + private Boolean terms; + + @Column(name = "MARKETING") + private Boolean marketing; + + @Column(name = "OFFERS") + private Boolean offers; + + @Column(name = "THIRD_PARTY") + private Boolean thirdParty; + + @Column(name = "EMAIL_PEC") + private String emailPec; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java new file mode 100644 index 00000000..83fbcc95 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java @@ -0,0 +1,37 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "beneficiary_preferred_call") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class BeneficiaryPreferredCallEntity extends BaseEntity{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "beneficiary_id") + private Long beneficiaryId; + + @Column(name = "user_id") + private Long userId; + + @Column(name = "company_id") + private Long companyId; + + @Column(name = "call_id") + private Long callId; + + @Column(name = "STATUS", length = 255) + private String status; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java index 02c53fca..1c6181b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java @@ -8,6 +8,7 @@ import lombok.Builder; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.LocalTime; @Entity @Table(name = "CALL") @@ -68,5 +69,24 @@ public class CallEntity extends BaseEntity { @Column(name="FINAL_FORM") private Long finalForm; + + @Column(name = "AMOUNT_MIN") + private BigDecimal amountMin; + + @Column(name="EMAIL") + private String email; + + @Column(name = "PHONE_NUMBER") + private String phoneNumber; + + @Column(name = "START_TIME") + private LocalTime startTime; + + @Column(name = "END_TIME") + private LocalTime endTime; + + @ManyToOne + @JoinColumn(name = "HUB_ID") + private HubEntity hub; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java new file mode 100644 index 00000000..c35a8cf0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java @@ -0,0 +1,59 @@ +package net.gepafin.tendermanagement.entities; + +import java.math.BigDecimal; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "COMPANY") +@Data +public class CompanyEntity extends BaseEntity{ + + @Column(name = "COMPANY_NAME") + private String companyName; + + @Column(name = "VAT_NUMBER") + private String vatNumber; + + @Column(name = "CODICE_FISCALE") + private String codiceFiscale; + + @Column(name = "ADDRESS") + private String address; + + @Column(name = "PHONE_NUMBER") + private String phoneNumber; + + @Column(name = "CITY") + private String city; + + @Column(name = "PROVINCE") + private String province; + + @Column(name = "CAP") + private String cap; + + @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; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java index 38cd3b2b..a476f2c5 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java @@ -41,6 +41,9 @@ public class FaqEntity extends BaseEntity { @Column(name ="IS_DELETED", nullable = false) private Boolean isDeleted = false; + + @Column(name ="COMPANY_ID") + private Long companyId; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java index e6cb9301..1b03f913 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java @@ -12,35 +12,34 @@ import lombok.Setter; @Getter public class HubEntity extends BaseEntity{ - - @Column(name = "COMPANY_NAME", length = 255,nullable = false) + @Column(name = "COMPANY_NAME") private String companyName; - @Column(name = "FIRST_NAME", length = 255) + @Column(name = "FIRST_NAME") private String firstName; - @Column(name = "LAST_NAME", length = 255) + @Column(name = "LAST_NAME") private String lastName; - @Column(name = "EMAIL", length = 255,nullable = false) + @Column(name = "EMAIL") private String email; - @Column(name = "CITY", length = 255) + @Column(name = "CITY") private String city; - @Column(name = "COUNTRY", length = 255, nullable = false) + @Column(name = "COUNTRY") private String country; @Size(min=5,max=15) - @Column(name = "VAT_NUMBER", length = 255,nullable = false, unique = true) + @Column(name = "VAT_NUMBER") private String vatNumber; - @Column(name = "DOMAIN_NAME", length = 255) + @Column(name = "DOMAIN_NAME") private String domainName; - @Column(name = "APP_CONFIG", columnDefinition = "TEXT") + @Column(name = "APP_CONFIG") private String appConfig; - @Column(name = "UNIQUE_UUID", length = 255,nullable = false, unique = true) + @Column(name = "UNIQUE_UUID") private String uniqueUuid; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java new file mode 100644 index 00000000..11fe1a99 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java @@ -0,0 +1,44 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "LOGIN_ATTEMPT") +@Getter +@Setter +public class LoginAttemptEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ID", unique = true) + private Long id; + + @Column(name = "USERNAME") + private String username; + + @Column(name = "USER_ID") + private Long userId; + + @Column(name = "ATTEMPT_DATE", nullable = false) + private LocalDateTime attemptDate; + + @Column(name = "IP_ADDRESS", length = 100) + private String ipAddress; + + @Column(name = "USER_AGENT") + private String userAgent; + + @Column(name = "RESULT", length = 100, nullable = false) + private String result; + + @Column(name = "ERROR_MSG") + private String errorMsg; + + @Column(name = "ATTEMPT_TYPE", length = 100, nullable = false) + private String type; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java new file mode 100644 index 00000000..0924c922 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalTime; + +@Entity +@Table(name = "PROTOCOL") +@Data +public class ProtocolEntity extends BaseEntity { + + @Column(name = "PROTOCOL_NUMBER", nullable = false) + private Long protocolNumber; + + @Column(name = "YEAR", nullable = false) + private Integer year; + + @Column(name="CALL_ID") + private Long call; + + @Column(name = "TIME", nullable = false) + private LocalTime time; + + @Column(name="APPLICATION_ID") + private Long applicationId; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SamlResponseLogEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SamlResponseEntity.java similarity index 50% rename from src/main/java/net/gepafin/tendermanagement/entities/SamlResponseLogEntity.java rename to src/main/java/net/gepafin/tendermanagement/entities/SamlResponseEntity.java index 53e262e9..732edfd9 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/SamlResponseLogEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/SamlResponseEntity.java @@ -6,21 +6,15 @@ import jakarta.persistence.Table; import lombok.Data; @Entity -@Table(name = "SAML_RESPONSE_LOG") +@Table(name = "SAML_RESPONSE") @Data -public class SamlResponseLogEntity extends BaseEntity{ - - @Column(name = "REQUEST") - private String request; - - @Column(name = "RESPONSE") - private String response; +public class SamlResponseEntity extends BaseEntity{ @Column(name = "AUTHENTICATION_OBJECT") private String authenticationObject; - @Column(name = "EXCEPTION_OBJECT") - private String exceptionObject; + @Column(name = "TOKEN") + private String token; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java new file mode 100644 index 00000000..9ae12cbf --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java @@ -0,0 +1,56 @@ +package net.gepafin.tendermanagement.entities; + +import com.fasterxml.jackson.annotation.JsonValue; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "system_email_template") +@Data +public class SystemEmailTemplatesEntity extends BaseEntity { + + + @Column(name = "TEMPLATE_NAME") + private String templateName; + + @Column(name = "TYPE") + private String type; + + @Column(name = "HTML_CONTENT", columnDefinition = "TEXT") + private String htmlContent; + + @Column(name = "SUBJECT") + private String subject; + + @Column(name = "JSON", columnDefinition = "TEXT") + private String json; + + @Column(name = "SYSTEM") + private Boolean system; + + @Column(name ="IS_DELETED", nullable = false) + private Boolean isDeleted = false; + + public enum SystemEmailTemplatesEntityTypeEnum { + + APPLICATION_SUBMISSION_TO_USER_AND_COMPANY("APPLICATION_SUBMISSION_TO_USER_AND_COMPANY"), + APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN"); + + private String value; + + SystemEmailTemplatesEntityTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java new file mode 100644 index 00000000..d682747d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.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; + +@Data +@Entity +@Table(name = "user_company_delegation") +public class UserCompanyDelegationEntity extends BaseEntity{ + + @Column(name="USER_ID") + private Long userId; + + @Column(name="COMPANY_ID") + private Long companyId; + + @Column(name = "BENEFICIARY_ID") + private Long beneficiaryId; + + @Column(name = "FILE_NAME") + private String fileName; + + @Column(name = "FILE_PATH") + private String filePath; + + @Column(name="STATUS") + private String status; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java index 5bd88f33..606f52d9 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java @@ -1,6 +1,5 @@ package net.gepafin.tendermanagement.entities; -import com.fasterxml.jackson.annotation.JsonValue; import jakarta.persistence.*; import jakarta.validation.constraints.Email; @@ -17,7 +16,7 @@ import java.time.LocalDateTime; @Setter public class UserEntity extends BaseEntity { - @Column(name = "PASSWORD", columnDefinition = "TEXT",nullable = false) + @Column(name = "PASSWORD", columnDefinition = "TEXT",nullable = true) @JsonIgnore private String password; @@ -29,8 +28,7 @@ public class UserEntity extends BaseEntity { @JoinColumn(name = "ROLE_ID") @JsonIgnore private RoleEntity roleEntity; - - + @Column(name = "LAST_LOGIN") private LocalDateTime lastLogin; @@ -60,4 +58,15 @@ public class UserEntity extends BaseEntity { @Column(name = "RESET_PASSWORD_TOKEN", length = 255, nullable = true) private String resetPasswordToken; + + @Column(name = "DATE_OF_BIRTH") + private LocalDateTime dateOfBirth; + + @OneToOne + @JoinColumn(name = "BENEFICIARY_ID") + private BeneficiaryEntity beneficiary; + + @ManyToOne + @JoinColumn(name = "HUB_ID") + private HubEntity hub; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserHubEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserHubEntity.java deleted file mode 100644 index 8534218e..00000000 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserHubEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.gepafin.tendermanagement.entities; - -import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Entity -@Table(name = "USER_HUB") -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -public class UserHubEntity extends BaseEntity { - - @Column(name = "hub_id") - private String hubId; - - @Column(name = "user_id") - private Long userId; - - -} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java new file mode 100644 index 00000000..49770356 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "USER_WITH_COMPANY") +@Data +public class UserWithCompanyEntity extends BaseEntity{ + + @Column(name = "USER_ID") + Long userId; + + @Column(name = "BENEFICIARY_ID") + Long beneficiaryId; + + @Column(name = "COMPANY_ID") + Long companyId; + + @Column(name = "IS_LEGAL_REPRESENTANT") + private Boolean isLegalRepresentant; + + @Column(name = "IS_DELETED") + private Boolean isDeleted = false; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationSignedDocumentStatusEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationSignedDocumentStatusEnum.java new file mode 100644 index 00000000..c0064d87 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationSignedDocumentStatusEnum.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ApplicationSignedDocumentStatusEnum { + ACTIVE("ACTIVE"), INACTIVE("INACTIVE"); + + private String value; + + ApplicationSignedDocumentStatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/BeneficiaryCallStatus.java b/src/main/java/net/gepafin/tendermanagement/enums/BeneficiaryCallStatus.java new file mode 100644 index 00000000..d7e5f244 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/BeneficiaryCallStatus.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum BeneficiaryCallStatus { + + ENABLED("ENABLED"), + DISABLED("DISABLED"), + APPLIED("APPLIED"); + + private String value; + + BeneficiaryCallStatus(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/LoginAttemptResultEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/LoginAttemptResultEnum.java new file mode 100644 index 00000000..bd039eb5 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/LoginAttemptResultEnum.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum LoginAttemptResultEnum { + + SUCCESS("SUCCESS"), + FAILED("FAILED"); + + private String value; + + LoginAttemptResultEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/enums/LoginAttemptTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/LoginAttemptTypeEnum.java new file mode 100644 index 00000000..dc597e13 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/LoginAttemptTypeEnum.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum LoginAttemptTypeEnum { + + LOGIN("LOGIN"), + SWITCH("SWITCH"); + + private String value; + + LoginAttemptTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserCompanyDelegationStatusEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserCompanyDelegationStatusEnum.java new file mode 100644 index 00000000..1f8f9725 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserCompanyDelegationStatusEnum.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum UserCompanyDelegationStatusEnum { + ACTIVE("ACTIVE"), INACTIVE("INACTIVE"); + + private String value; + + UserCompanyDelegationStatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java index 029eb470..993fc7e4 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java @@ -9,6 +9,6 @@ public class ApplicationFormFieldRequestBean { private String fieldId; - private String fieldValue; + private Object fieldValue; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/BeneficiaryPreferredCallReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/BeneficiaryPreferredCallReq.java new file mode 100644 index 00000000..2c457f81 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/BeneficiaryPreferredCallReq.java @@ -0,0 +1,12 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class BeneficiaryPreferredCallReq { + + private Long companyId; + private Long callId; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyDelegationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyDelegationRequest.java new file mode 100644 index 00000000..b47ed579 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyDelegationRequest.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class CompanyDelegationRequest { + + private String firstName; + + private String lastName; + + private String codiceFiscale; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java new file mode 100644 index 00000000..b9f43932 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java @@ -0,0 +1,26 @@ +package net.gepafin.tendermanagement.model.request; + +import java.math.BigDecimal; + +import lombok.Data; + +@Data +public class CompanyRequest { + + private String companyName; + private String vatNumber; + private String codiceFiscale; + private String address; + private String phoneNumber; + private String city; + private String province; + private String cap; + private String country; + private String pec; + private String email; + private String numberOfEmployees; + private BigDecimal annualRevenue; + private Boolean isLegalRepresentant; + private String contactName; + private String contactEmail; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java b/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java index bfa0e84d..bdc0d015 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java @@ -2,7 +2,9 @@ package net.gepafin.tendermanagement.model.request; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; + import lombok.Data; @Data @@ -26,6 +28,16 @@ public class CreateCallRequestStep1 { private String documentationRequested; + private BigDecimal amountMin; + + private String email; + + private String phoneNumber; + + private String startTime; + + private String endTime; + private Boolean confidi; private List faq; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CustomPageEvent.java b/src/main/java/net/gepafin/tendermanagement/model/request/CustomPageEvent.java new file mode 100644 index 00000000..72aef09a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CustomPageEvent.java @@ -0,0 +1,71 @@ +package net.gepafin.tendermanagement.model.request; + +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.ColumnText; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfPageEventHelper; +import com.itextpdf.text.pdf.PdfWriter; + +public class CustomPageEvent extends PdfPageEventHelper { + private String title; + private int totalPages; + + public CustomPageEvent(String title, int totalPages) { + this.title = title; + this.totalPages = totalPages; + } + + @Override + public void onEndPage(PdfWriter writer, Document document) { + PdfContentByte canvas = writer.getDirectContent(); + + // Header - Add a title to each page at the top + if (writer.getPageNumber() > 1) { + Font headerFont = new Font(Font.FontFamily.HELVETICA, 6, Font.BOLD, new BaseColor(113, 121, 126)); // Gray color for header + ColumnText.showTextAligned( + canvas, + Element.ALIGN_LEFT, + new Phrase(title, headerFont), + document.leftMargin(), // Use left margin to align fully to the left + document.getPageSize().getHeight() - 30, // Positioning header near top + 0 // No rotation + ); + } + + // Footer - Add page number at the bottom + String footerText = String.format("Page %d of %d", writer.getPageNumber(), totalPages); + + // Set font for the footer + Font footerFont = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL, BaseColor.BLACK); + + // Positioning footer near bottom + ColumnText.showTextAligned(writer.getDirectContent(), + Element.ALIGN_LEFT, + new Phrase(footerText, footerFont), + (document.right() + document.left()) / 2, + document.bottomMargin() - 10, // Positioning footer near bottom + 0); + + // Draw a yellow line below header + if (writer.getPageNumber() > 1) { + canvas.setLineWidth(1.5f); + canvas.setColorStroke(new BaseColor(255, 219, 88)); // Yellow color + float yPos = document.getPageSize().getHeight() - 50f; // Position for the line below header + canvas.moveTo(0, yPos); + canvas.lineTo(document.getPageSize().getWidth(), yPos); + canvas.stroke(); + } + + // Draw another line 50 points above the bottom of the document + canvas.setLineWidth(1.5f); + canvas.setColorStroke(new BaseColor(255, 219, 88)); // Yellow color + float lineYPos = document.bottomMargin() + 25f; // Position for the line above the bottom margin + canvas.moveTo(0, lineYPos); + canvas.lineTo(document.getPageSize().getWidth(), lineYPos); + canvas.stroke(); + } + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/FieldLabelValuePairRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/FieldLabelValuePairRequest.java new file mode 100644 index 00000000..8eb5f7b5 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/FieldLabelValuePairRequest.java @@ -0,0 +1,14 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +public class FieldLabelValuePairRequest { + + private String label; + private Object value; +} + diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/InitiatePasswordResetReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/InitiatePasswordResetReq.java index ae2ba0d0..fac4150e 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/InitiatePasswordResetReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/InitiatePasswordResetReq.java @@ -5,4 +5,5 @@ import lombok.Data; @Data public class InitiatePasswordResetReq { private String email; + private String hubUuid; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/LoginAttemptReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/LoginAttemptReq.java new file mode 100644 index 00000000..f7a48ad3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/LoginAttemptReq.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Getter; +import lombok.Setter; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +@Getter +@Setter +public class LoginAttemptReq { + + private String userName; + + @NotNull + private Long userId; +} + diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/LoginReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/LoginReq.java index d337d231..9675eae5 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/LoginReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/LoginReq.java @@ -14,5 +14,6 @@ public class LoginReq { private String email; @NotEmpty private String password; + private String hubUuid; private Boolean rememberMe; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ResetPasswordReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/ResetPasswordReq.java index 019ca582..f3d6b05c 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ResetPasswordReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ResetPasswordReq.java @@ -8,6 +8,6 @@ public class ResetPasswordReq { private String token; private String newPassword; private String confirmPassword; - + private String hubUuid; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java index 4d4de6e9..e57f8715 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.model.request; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; import lombok.Data; @@ -25,6 +26,16 @@ public class UpdateCallRequestStep1 { private String documentationRequested; + private BigDecimal amountMin; + + private String email; + + private String phoneNumber; + + private String startTime; + + private String endTime; + private Boolean confidi; private List faq; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java index 65eba841..ff267f33 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java @@ -4,6 +4,8 @@ import lombok.Getter; import lombok.Setter; import net.gepafin.tendermanagement.enums.UserStatusEnum; +import java.time.LocalDateTime; + @Getter @Setter public class UpdateUserReq { @@ -17,4 +19,11 @@ public class UpdateUserReq { private String city; private UserStatusEnum status; private String country; + private String codiceFiscale; + private LocalDateTime dateOfBirth; + private Boolean marketing; + private Boolean offers; + private Boolean thirdParty; + + private String emailPec; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java index 7dacab15..5365be30 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java @@ -1,20 +1,15 @@ package net.gepafin.tendermanagement.model.request; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; +import java.time.LocalDateTime; import lombok.Data; @Data public class UserReq { - @NotBlank - @Email private String email; - @NotEmpty + private String password; - @NotEmpty + private String confPassword; private String firstName; @@ -22,7 +17,7 @@ public class UserReq { private String lastName; private String phoneNumber; - @NotNull + private Long roleId; private String organization; @@ -32,5 +27,20 @@ public class UserReq { private String city; private String country; + + private String codiceFiscale; + + private LocalDateTime dateOfBirth; + private Boolean privacy; + private Boolean terms; + private Boolean marketing; + private Boolean offers; + private Boolean thirdParty; + + private String emailPec; + + private String hubUuid; + + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java index 50ce0c57..aa686023 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java @@ -19,6 +19,12 @@ public class ApplicationGetResponseBean { private Long callId; private String callTitle; + + private Long companyId; + + private String companyName; + + private Long protocolNumber; private List form; 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 fdb0f6f3..d5df459e 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java @@ -13,10 +13,24 @@ public class ApplicationResponse{ private Long callId; + private String callTitle; + + private LocalDateTime callEndDate; + + private LocalDateTime modifiedDate; + + private Integer progress; + private LocalDateTime submissionDate; private String status; private String comments; + + private Long companyId; + + private String companyName; + + private Long protocolNumber; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java index e621197c..6b99961f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java @@ -17,6 +17,8 @@ public class ApplicationResponseBean extends BaseBean { private String comments; + private Long protocolNumber; + private List formFields; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationSignedDocumentResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationSignedDocumentResponse.java new file mode 100644 index 00000000..64b380f5 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationSignedDocumentResponse.java @@ -0,0 +1,14 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum; +import net.gepafin.tendermanagement.model.BaseBean; + +@Data +public class ApplicationSignedDocumentResponse extends BaseBean{ + + private Long applicationId; + private String fileName; + private String filePath; + private ApplicationSignedDocumentStatusEnum status; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java new file mode 100644 index 00000000..9588b576 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import lombok.NoArgsConstructor; +import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.enums.UserStatusEnum; + +import java.time.LocalDateTime; + +@NoArgsConstructor +@Data +public class BeneficiaryPreferredCallResponseBean { + + + private Long id; + private Long beneficiaryId; + private Long userId; + private Long companyId; + private Long callId; + private BeneficiaryCallStatus status; + private LocalDateTime createdDate; + private LocalDateTime updatedDate; + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryWidgetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryWidgetResponseBean.java new file mode 100644 index 00000000..04eb2d8a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryWidgetResponseBean.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class BeneficiaryWidgetResponseBean { + + private Long numberOfApplications; + + private Long numberOfCalls; + + private Long numberOfIntegratedDocuments; + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java index a7bf60b7..51479254 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java @@ -5,6 +5,7 @@ import net.gepafin.tendermanagement.enums.CallStatusEnum; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; @Data public class CallDetailsResponseBean { @@ -37,6 +38,16 @@ public class CallDetailsResponseBean { private String documentationRequested; + private BigDecimal amountMin; + + private String email; + + private String phoneNumber; + + private LocalTime startTime; + + private LocalTime endTime; + private LocalDateTime createdDate; private LocalDateTime updatedDate; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java index f8fa4908..ed4a0206 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.model.response; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; import lombok.Data; @@ -40,6 +41,16 @@ public class CallResponse { private Boolean confidi; + private BigDecimal amountMin; + + private String email; + + private String phoneNumber; + + private LocalTime startTime; + + private LocalTime endTime; + private LocalDateTime createdDate; private LocalDateTime updatedDate; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDelegationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDelegationResponse.java new file mode 100644 index 00000000..f1b69b33 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDelegationResponse.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.entities.BaseEntity; +import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; +import net.gepafin.tendermanagement.model.BaseBean; + +@Data +public class CompanyDelegationResponse extends BaseBean{ + private Long userId; + private Long companyId; + private Long beneficiaryId; + private String fileName; + private String filePath; + private UserCompanyDelegationStatusEnum status; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java new file mode 100644 index 00000000..e54b040f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.model.response; + +import java.math.BigDecimal; + +import lombok.Data; +import net.gepafin.tendermanagement.model.BaseBean; + +@Data +public class CompanyResponse extends BaseBean{ + + private String companyName; + private String vatNumber; + private String codiceFiscale; + private String address; + private String phoneNumber; + private String city; + private String province; + private String cap; + private String country; + private String pec; + private String email; + private String numberOfEmployees; + private BigDecimal annualRevenue; + private Boolean isLegalRepresentant; + private String contactName; + private String contactEmail; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/FormResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/FormResponseBean.java index 7e3ebce1..7a1d178e 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/FormResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/FormResponseBean.java @@ -9,6 +9,8 @@ public class FormResponseBean { private Long id; + private String callStatus; + private String label; private Long callId; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/LoginAttemptPageableResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/LoginAttemptPageableResponseBean.java new file mode 100644 index 00000000..d28d1fd2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/LoginAttemptPageableResponseBean.java @@ -0,0 +1,38 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Getter; +import lombok.Setter; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; + +import java.io.Serializable; + +@Getter +@Setter +public class LoginAttemptPageableResponseBean implements Serializable { + + private transient T body; + + private Long totalRecords; + + private int currentPage; + + private int totalPages; + + private int pageSize; + + private Status status; + + private String message; + +} + + + + + + + + + + + diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java index 64af6b1a..39fdfb63 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java @@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.time.LocalDateTime; +import java.util.List; @Getter @Setter @@ -35,8 +36,26 @@ public class LoginResponse { private String status; private LocalDateTime lastLogin; + + private String codiceFiscale; + + private LocalDateTime dateOfBirth; + + private Boolean privacy; + + private Boolean terms; + + private Boolean marketing; + + private Boolean offers; + + private Boolean thirdParty; + + private String emailPec; private LocalDateTime createdDate; private LocalDateTime updatedDate; + + private List companies; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java index 55ee34be..8925e7f6 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.model.response; import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; @Data public class NextOrPreviousFormResponse { @@ -17,6 +18,14 @@ public class NextOrPreviousFormResponse { private Long currentStep; + private Long companyId; + + private String companyName; + + private Long protocolNumber; + + private ApplicationStatusTypeEnum applicationStatus; + private FormApplicationResponse applicationFormResponse; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/SuperAdminWidgetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/SuperAdminWidgetResponseBean.java new file mode 100644 index 00000000..6ed30e56 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/SuperAdminWidgetResponseBean.java @@ -0,0 +1,14 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class SuperAdminWidgetResponseBean { + + private Widget1 widget1; + +// private List widgetBars; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/SystemEmailTemplateResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/SystemEmailTemplateResponse.java new file mode 100644 index 00000000..cd65e6e4 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/SystemEmailTemplateResponse.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.response; + +import java.util.Map; + +import lombok.Data; + +@Data +public class SystemEmailTemplateResponse { + + String htmlContent; + + String subject; + + Map jsonMap; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/UploadFileOnAmazonS3Response.java b/src/main/java/net/gepafin/tendermanagement/model/response/UploadFileOnAmazonS3Response.java new file mode 100644 index 00000000..d0d78428 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UploadFileOnAmazonS3Response.java @@ -0,0 +1,14 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class UploadFileOnAmazonS3Response { + + private String fileName; + + private String filePath; + +} 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 5c1a8ef2..b0a5ef38 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java @@ -6,6 +6,7 @@ import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.BaseBean; import java.time.LocalDateTime; +import java.util.List; @Getter @Setter @@ -32,5 +33,18 @@ public class UserResponseBean extends BaseBean { private UserStatusEnum status; private LocalDateTime lastLogin; + + private String codiceFiscale; + + private LocalDateTime dateOfBirth; + private List companies; + private Boolean privacy; + private Boolean terms; + + private Boolean marketing; + private Boolean offers; + private Boolean thirdParty; + + private String emailPec; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java new file mode 100644 index 00000000..8fdcbdea --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class UserSamlResponse { + + private String codiceFiscale; + + private String firstName; + + private String lastName; + + private LocalDateTime dateOfBirth; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/Widget1.java b/src/main/java/net/gepafin/tendermanagement/model/response/Widget1.java new file mode 100644 index 00000000..75c68758 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/Widget1.java @@ -0,0 +1,26 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Builder +public class Widget1 { + + private Long numberOfActiveCalls; + + private Long numberOfResgisteredUsers; + +// private Long preInvestigationQuestions; + + private Long numberOfSubmittedApplications; + + private Long numberOfDraftApplications; + + private Long numberOfCompany; + + private BigDecimal totalActiveFinancing; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index 8d41608c..7b57fcf2 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -1,8 +1,8 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.entities.FaqEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -11,9 +11,7 @@ import java.util.List; import java.util.Optional; @Repository -public interface ApplicationRepository extends JpaRepository { - - public Optional findByUserIdAndCallIdAndIsDeletedFalse(Long userId,Long callId); +public interface ApplicationRepository extends JpaRepository, JpaSpecificationExecutor { public List findByUserIdAndIsDeletedFalse(Long userId); @@ -23,4 +21,24 @@ public interface ApplicationRepository extends JpaRepository findByCallIdAndIsDeletedFalse(Long callId); public List findByIsDeletedFalse(); + + public Optional findByIdAndUserIdAndIsDeletedFalse(Long id,Long userId); + + Optional findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(Long userId, Long companyId, Long callId); + + public Optional findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId, + Long callId); + + @Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.userId = :userId AND a.company.id = :companyId AND a.status = 'SUBMIT' ") + Long countSubmittedApplicationsByUserId(@Param("userId") Long userId, @Param("companyId") Long companyId); + + @Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'SUBMIT'") + Long countSubmittedApplications(); + + @Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'DRAFT'") + Long countDraftApplications(); + + List findByCompanyIdAndUserIdAndIsDeletedFalse(Long companyId,Long userId); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java new file mode 100644 index 00000000..35322a6a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import net.gepafin.tendermanagement.entities.ApplicationSignedDocumentEntity; + +@Repository +public interface ApplicationSignedDocumentRepository extends JpaRepository { + + ApplicationSignedDocumentEntity findByApplicationIdAndStatus(Long applicationId, String status); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java new file mode 100644 index 00000000..dd8d341e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.repositories; +import net.gepafin.tendermanagement.entities.BeneficiaryPreferredCallEntity; +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; + +@Repository +public interface BeneficiaryPreferredCallRepository extends JpaRepository { + List findByBeneficiaryId(Long beneficiaryId); + List findByUserId(Long userId); + + @Query("SELECT preferredCall FROM BeneficiaryPreferredCallEntity preferredCall where preferredCall.userId=:userId AND (:companyId is null OR preferredCall.companyId=:companyId)") + List findByUserIdAndCompanyId(@Param("userId") Long userId, @Param("companyId") Long companyId); + List findByBeneficiaryIdAndCompanyId(Long beneficiaryId,Long companyId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/SamlResponseLogRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java similarity index 52% rename from src/main/java/net/gepafin/tendermanagement/repositories/SamlResponseLogRepository.java rename to src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java index 3f98e083..ecb6ed7d 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/SamlResponseLogRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryRepository.java @@ -3,9 +3,9 @@ package net.gepafin.tendermanagement.repositories; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import net.gepafin.tendermanagement.entities.SamlResponseLogEntity; +import net.gepafin.tendermanagement.entities.BeneficiaryEntity; @Repository -public interface SamlResponseLogRepository extends JpaRepository { +public interface BeneficiaryRepository extends JpaRepository { } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java index 6fa6bbde..4e651fe0 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CallRepository.java @@ -2,8 +2,10 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.enums.CallStatusEnum; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.math.BigDecimal; import java.util.List; @Repository @@ -13,4 +15,14 @@ public interface CallRepository extends JpaRepository { List findByStatusIn(List callStatus); public CallEntity findByIdAndStatus(Long id,String status); + + public Long countByStatus(String status); + + @Query("SELECT COALESCE(SUM(c.amount), 0) FROM CallEntity c WHERE c.status = 'PUBLISH'") + BigDecimal findTotalAmountOfPublishedCalls(); + + @Query("SELECT c.name, COUNT(a.id) " + + "FROM CallEntity c LEFT JOIN ApplicationEntity a ON c.id = a.call.id " + + "GROUP BY c.name") + List findApplicationsPerCall(); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java new file mode 100644 index 00000000..c0c5f75d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java @@ -0,0 +1,23 @@ +package net.gepafin.tendermanagement.repositories; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import net.gepafin.tendermanagement.entities.CompanyEntity; + +@Repository +public interface CompanyRepository extends JpaRepository { + + List findByIdIn(List companyIds); + + Boolean existsByVatNumber(String vatNumber); + CompanyEntity findByVatNumber(String vatNumber); + + @Query("SELECT COUNT(c) FROM CompanyEntity c") + long countTotalCompanies(); + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java index 40361cd9..1543def3 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java @@ -19,5 +19,8 @@ public interface DocumentRepository extends JpaRepository Optional findByIdAndSourceIdAndIsDeletedFalse(Long id, Long sourceId); + List findBySource(String source); + List findBySourceIdAndSourceAndTypeAndIsDeletedFalse(Long sourceId, String source, String type); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java index 3727e4ef..51642934 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java @@ -19,5 +19,6 @@ public interface FaqRepository extends JpaRepository { List findByCallIdAndIsDeletedFalse(Long callId); Optional findByIdAndCallIdAndIsDeletedFalse(Long id, Long callId); + List findByCompanyIdAndUserIdAndIsDeletedFalse(Long companyId,Long userId); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/LoginAttemptRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/LoginAttemptRepository.java new file mode 100644 index 00000000..257b8ed8 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/LoginAttemptRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.LoginAttemptEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface LoginAttemptRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ProtocolRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ProtocolRepository.java new file mode 100644 index 00000000..b82fc311 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ProtocolRepository.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ProtocolEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProtocolRepository extends JpaRepository { + + @Query("SELECT MAX(p.protocolNumber) FROM ProtocolEntity p") + Long findMaxProtocolNumber(); +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java index e009e6a3..a48eade5 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java @@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository; @Repository public interface RoleRepository extends JpaRepository { + + RoleEntity findByRoleType(String roleType); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/SamlResponseRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/SamlResponseRepository.java new file mode 100644 index 00000000..9183f339 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/SamlResponseRepository.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import net.gepafin.tendermanagement.entities.SamlResponseEntity; + +@Repository +public interface SamlResponseRepository extends JpaRepository { + + SamlResponseEntity findByToken(String token); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/SystemEmailTemplatesRespository.java b/src/main/java/net/gepafin/tendermanagement/repositories/SystemEmailTemplatesRespository.java new file mode 100644 index 00000000..9e3e9bb9 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/SystemEmailTemplatesRespository.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.repositories; + +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.SystemEmailTemplatesEntity; + +public interface SystemEmailTemplatesRespository extends JpaRepository { + +// @Query("select s from SystemEmailTemplatesEntity s where s.type=:type and s.call.id=:callId and s.isDeleted =false and s.system = false") +// SystemEmailTemplatesEntity findByTypeAndCallId(@Param("type") String type, @Param("callId") Long callId); + + @Query("select s from SystemEmailTemplatesEntity s where s.type=:type and s.isDeleted =false and s.system = true") + SystemEmailTemplatesEntity findByType(@Param("type") String type); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java new file mode 100644 index 00000000..1224dd70 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; + +public interface UserCompanyDelegationRepository extends JpaRepository { + + UserCompanyDelegationEntity findByUserIdAndCompanyIdAndStatus(Long userId, Long companyId, String status); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserHubRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserHubRepository.java deleted file mode 100644 index 2976ab0a..00000000 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserHubRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.gepafin.tendermanagement.repositories; - - - import net.gepafin.tendermanagement.entities.UserHubEntity; - import org.springframework.data.jpa.repository.JpaRepository; - - import java.util.List; - -public interface UserHubRepository extends JpaRepository { - List findByHubId(String hubId); - UserHubEntity findByHubIdAndUserId(String hubId, Long userId); -} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java index 7720430c..caccc5ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java @@ -1,12 +1,31 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.response.UserResponseBean; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; +@Repository public interface UserRepository extends JpaRepository { - Optional findByEmailIgnoreCase(String email); - boolean existsByEmailIgnoreCase(String email); - UserEntity findByEmail(String email); + +// Optional findByEmailIgnoreCase(String email); + +// boolean existsByEmailIgnoreCase(String email); + +// UserEntity findByEmail(String email); + + Optional findByBeneficiaryCodiceFiscale(String codiceFiscale); + + boolean existsByBeneficiaryCodiceFiscale(String codiceFiscale); + UserEntity findByBeneficiaryId(Long beneficiaryId); + + Long countByStatusAndRoleEntityRoleType(String status, String roleName); + List findByRoleEntityId(Long roleId); + + Optional findByEmailIgnoreCaseAndhubUniqueUuid(String email, String hubId); + + boolean existsByEmailIgnoreCaseAndhubUniqueUuid(String email, String hubUuid); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java new file mode 100644 index 00000000..d17b93e2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java @@ -0,0 +1,24 @@ +package net.gepafin.tendermanagement.repositories; + +import java.util.List; +import java.util.Optional; + +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; + + +public interface UserWithCompanyRepository extends JpaRepository { + + 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); + + + + Optional findByUserIdAndCompanyIdAndIsDeletedFalse(Long userId, Long companyId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index 1ff3a7fd..ea3937a3 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -3,15 +3,19 @@ package net.gepafin.tendermanagement.service; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; +import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; + import java.io.IOException; import java.io.InputStream; @Component public interface AmazonS3Service { - public String upload(String fileName, MultipartFile file) throws IOException; + public String upload(String fileName, String s3Folder, MultipartFile file) throws IOException; - public Boolean delete(String fileName); + public Boolean delete(String s3Folder, String fileName); - InputStream getFile(String filePath) throws IOException; + InputStream getFile(String s3Folder, String filePath) throws IOException; + + public UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file); } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java index 152bc1b5..2d914b64 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java @@ -9,25 +9,35 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationResponse; import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse; import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; import java.util.List; +import org.springframework.web.multipart.MultipartFile; + public interface ApplicationService { public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean,Long applicationId, Long formId); ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId,Long formId); - List getAllApplications(HttpServletRequest request,Long callId); + List getAllApplications(HttpServletRequest request,Long callId, Long companyId); void deleteApplication(HttpServletRequest request, Long applicationId); public ApplicationEntity validateApplication(Long userId); - public ApplicationResponse createApplication(HttpServletRequest request, ApplicationRequest applicationRequest, Long callId); + public ApplicationResponse createApplication(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId); public NextOrPreviousFormResponse getNextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, FormActionEnum action); - public void updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status); + public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status); + + public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file); + + public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId); + + public void deleteSignedDocument(HttpServletRequest request, Long applicationId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/BeneficiaryPreferredCallService.java b/src/main/java/net/gepafin/tendermanagement/service/BeneficiaryPreferredCallService.java new file mode 100644 index 00000000..9c5e9e42 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/BeneficiaryPreferredCallService.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; + +import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; + +import java.util.List; + +public interface BeneficiaryPreferredCallService { + + BeneficiaryPreferredCallResponseBean createBeneficiaryPreferredCall(HttpServletRequest request, BeneficiaryPreferredCallReq beneficiaryPreferredCallRequest); + + BeneficiaryPreferredCallResponseBean getBeneficiaryPreferredCallById(HttpServletRequest request, Long id); + + void deleteBeneficiaryPreferredCall(HttpServletRequest request, Long id); + + List getAllBeneficiaryPreferredCalls(HttpServletRequest request); + +// BeneficiaryPreferredCallResponseBean updateBeneficiaryPreferredCall(HttpServletRequest request, Long id, BeneficiaryPreferredCallReq beneficiaryPreferredCallRequest); + void updateBeneficiaryPreferredCallStatus(HttpServletRequest request, Long id, BeneficiaryCallStatus status); + + List getBeneficiaryPreferredCallByUserId(HttpServletRequest request,Long userId,Long beneficiaryId,Long companyId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/CallService.java b/src/main/java/net/gepafin/tendermanagement/service/CallService.java index aa6ea872..8abe4cb5 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CallService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CallService.java @@ -19,18 +19,16 @@ public interface CallService { CallResponse updateCallStep1(HttpServletRequest request, Long callId, UpdateCallRequestStep1 updateCallRequest); - CallResponse getCallById (Long callId); + CallResponse getCallById (HttpServletRequest request, Long callId); List getAllCalls(HttpServletRequest request); - CallResponse validateCallData(Long callId); - - CallEntity getCallEntityById(Long id); + CallResponse validateCallData(HttpServletRequest request, Long callId); CallResponse updateCallStatus(HttpServletRequest request, Long callId, CallStatusEnum statusReq); CallEntity validateCall(Long callId); CallEntity validatePublishedCall(Long callId); - + byte[] downloadCallDocumentsAsZip(Long callId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java new file mode 100644 index 00000000..f11e0798 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -0,0 +1,46 @@ +package net.gepafin.tendermanagement.service; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Map; + +import org.springframework.web.multipart.MultipartFile; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; +import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; +import net.gepafin.tendermanagement.model.response.CompanyResponse; + +public interface CompanyService { + + CompanyResponse createCompany(HttpServletRequest request, CompanyRequest companyRequest); + + CompanyResponse updateCompany(HttpServletRequest request, Long companyId, CompanyRequest companyRequest); + + CompanyResponse getCompany(HttpServletRequest request, Long companyId); + + void deleteCompany(HttpServletRequest request, Long companyId); + + List getCompanyByUserId(HttpServletRequest request, Long userId); + + Map checkVatNumber(HttpServletRequest request, String vatNumber); + + CompanyEntity validateCompany(Long companyId); + + UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId); + + ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest); + + CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file); + + CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId); + + void deleteCompanyDelegation(HttpServletRequest request, Long companyId); + UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId); + void removeCompanyFromList(HttpServletRequest request, Long companyId); + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java new file mode 100644 index 00000000..6328ca6e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; + +public interface DashboardService { + + public SuperAdminWidgetResponseBean getDashboardWidgetForSuperAdmin(HttpServletRequest request); + + public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/FaqService.java b/src/main/java/net/gepafin/tendermanagement/service/FaqService.java index 55adc950..74fd414d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/FaqService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/FaqService.java @@ -11,7 +11,7 @@ import net.gepafin.tendermanagement.model.response.FaqResponseBean; public interface FaqService { - FaqResponseBean createFaq(HttpServletRequest request,Long callId, FaqReq faqRequest); + FaqResponseBean createFaq(HttpServletRequest request,Long callId, Long companyId, FaqReq faqRequest); FaqResponseBean getFaqById(HttpServletRequest request, Long id); diff --git a/src/main/java/net/gepafin/tendermanagement/service/LoginAttemptService.java b/src/main/java/net/gepafin/tendermanagement/service/LoginAttemptService.java new file mode 100644 index 00000000..3e4ed31a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/LoginAttemptService.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.entities.LoginAttemptEntity; +import net.gepafin.tendermanagement.model.request.LoginAttemptReq; +import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; + +import java.util.List; + +public interface LoginAttemptService { + + LoginAttemptPageableResponseBean> getLoginAttemptsList(Integer pageNo, Integer pageLimit); + + void createLoginAttempt(LoginAttemptReq loginAttemptReq, HttpServletRequest request); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/PdfService.java b/src/main/java/net/gepafin/tendermanagement/service/PdfService.java new file mode 100644 index 00000000..e4e6b528 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/PdfService.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; + + +public interface PdfService { + + public byte[] generatePdf(HttpServletRequest request, Long applicationId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/RoleService.java b/src/main/java/net/gepafin/tendermanagement/service/RoleService.java index 6c9c519d..aacecbaa 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/RoleService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/RoleService.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.service; +import net.gepafin.tendermanagement.entities.RoleEntity; import net.gepafin.tendermanagement.model.request.RoleReq; import net.gepafin.tendermanagement.model.response.RoleResponseBean; @@ -15,4 +16,5 @@ public interface RoleService { void deleteRole(Long roleId); List getAllRoles(); + RoleEntity validateRole(Long roleId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java b/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java new file mode 100644 index 00000000..b40dc80f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.service; + +import java.util.Locale; + +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; + +public interface SystemEmailTemplatesService { + + SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/UserService.java b/src/main/java/net/gepafin/tendermanagement/service/UserService.java index ca43b635..9e2c43ef 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/UserService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/UserService.java @@ -8,13 +8,14 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.*; +import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import java.util.List; public interface UserService { - UserResponseBean createUser(UserReq userReq); + JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq); UserResponseBean updateUser(Long userId, UpdateUserReq userReq); @@ -22,7 +23,7 @@ public interface UserService { void deleteUser(Long userId); - JWTToken login(LoginReq loginReq); + JWTToken login(LoginReq loginReq,HttpServletRequest request); UserEntity validateUser(Long userId); @@ -30,13 +31,22 @@ public interface UserService { Boolean resetPassword(ResetPasswordReq resetPasswordReq); - Boolean changePassword(ChangePasswordRequest request); + Boolean changePassword(HttpServletRequest httpServletRequest, ChangePasswordRequest request); void logoutUser(HttpServletRequest request, HttpServletResponse response); UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq); UserResponseBean getValidUser(HttpServletRequest request); + List getUserByHubId(String hubId); - UserResponseBean createUserByHubId(String hubId, UserReq userReq); + + JWTToken validateExistingUserToken(HttpServletRequest request, String token); + + UserSamlResponse validateNewUserToken(HttpServletRequest request, String token); + UserEntity getUserByBeneficiaryId(Long beneficiaryId); + + public UserEntity getUserEntityById(Long userId); + List getAllUsers(Long roleId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java b/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java index 6665690d..333ab3a1 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestHeader; import java.net.URI; import java.util.Map; -@FeignClient(value = "vat-check-service", url = GepafinConstant.VATNUMBER_V2) +@FeignClient(value = "vat-check-service", url = GepafinConstant.CHECK_VATNUMBER_V2_NEW_URL) public interface VatCheckService { diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 3657d115..a0470c15 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -2,7 +2,16 @@ package net.gepafin.tendermanagement.service.impl; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.*; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; import net.gepafin.tendermanagement.service.AmazonS3Service; +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.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; @@ -29,18 +38,16 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { @Value("${aws.s3.bucket.name}") private String bucketName; - @Value("${aws.s3.url.folder}") - private String s3Folder; - @Value("${aws.s3.url}") private String s3Url; @Override - public String upload(String fileName, + public String upload(String fileName, String s3Folder, MultipartFile file) throws IOException { - String path = bucketName+"/"+s3Folder; +// String path = bucketName+"/"+s3Folder; + String path = s3Folder +"/"+fileName; InputStream inputStream = file.getInputStream(); @@ -57,15 +64,15 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { }); if(Boolean.FALSE.equals(isTestProfileActivated())) { - amazonS3.putObject(path, fileName, inputStream, objectMetadata); + amazonS3.putObject(bucketName, path, inputStream, objectMetadata); } return s3Url + s3Folder +"/"+ fileName; } @Override - public Boolean delete(String fileName) { - - final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(bucketName, fileName); + public Boolean delete(String s3Folder, String fileName) { + String path = s3Folder +"/"+fileName; + final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(bucketName, path); if(Boolean.FALSE.equals(isTestProfileActivated())) { amazonS3.deleteObject(deleteObjectRequest); } @@ -78,14 +85,30 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { } @Override - public InputStream getFile(String filePath) throws IOException { + public InputStream getFile(String s3Folder, String filePath) throws IOException { try { - String path = bucketName+ s3Folder +"/"; - GetObjectRequest getObjectRequest = new GetObjectRequest(path, filePath); + String path = s3Folder +"/"+filePath; + GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, path); S3Object s3Object = amazonS3.getObject(getObjectRequest); return s3Object.getObjectContent(); } catch (AmazonS3Exception e) { throw new IOException("Error getting file from Amazon S3", e); } } + + @Override + public UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file) { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + String fileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename()); + String firstNameContain = fileName.substring(0, fileName.lastIndexOf('.')); + firstNameContain+=Utils.randomKey(5); + fileName = (firstNameContain + "." + extension); + try { + String filepath = upload(fileName, s3Folder, file); + return UploadFileOnAmazonS3Response.builder().fileName(fileName).filePath(filepath).build(); + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); + } + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index e2364698..1ea6e7ea 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.ApplicationDao; import net.gepafin.tendermanagement.dao.FlowFormDao; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.request.ApplicationRequest; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; @@ -12,12 +13,14 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationResponse; import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse; import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -35,10 +38,11 @@ public class ApplicationServiceImpl implements ApplicationService { @Override @Transactional(rollbackFor = Exception.class) - public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean,Long applicationId, Long formId) { - UserEntity userEntity = validator.validateUser(request); - return applicationDao.createApplication(applicationRequestBean,userEntity,formId,applicationId); - } + public ApplicationResponseBean createApplication(HttpServletRequest request, + ApplicationRequestBean applicationRequestBean, Long applicationId, Long formId) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.createApplication(applicationRequestBean, userEntity, formId, applicationId); + } @Override @Transactional(readOnly = true) @@ -60,28 +64,52 @@ public class ApplicationServiceImpl implements ApplicationService { @Override @Transactional(rollbackFor = Exception.class) - public ApplicationResponse createApplication(HttpServletRequest request, ApplicationRequest applicationRequest, Long callId) { + public ApplicationResponse createApplication(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId) { UserEntity userEntity = validator.validateUser(request); - return applicationDao.createApplicationByCallId(applicationRequest,callId,userEntity); + CompanyEntity companyEntity = validator.validateUserWithCompany(request, companyId); + return applicationDao.createApplicationByCallId(companyEntity, applicationRequest, callId, userEntity); } @Override public NextOrPreviousFormResponse getNextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, FormActionEnum action) { ApplicationEntity applicationEntity = validateApplication(applicationId); - return flowFormDao.getnextOrPreviousForm(applicationEntity, formId, action); + return flowFormDao.getNextOrPreviousForm(applicationEntity, formId, action); } @Override - public void updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { - applicationDao.updateApplicationStatus(applicationId, status); + @Transactional(rollbackFor = Exception.class) + public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.updateApplicationStatus(userEntity, applicationId, status); } @Override @Transactional(readOnly = true) - public List getAllApplications(HttpServletRequest request,Long callId) { - UserEntity userEntity = validator.validateUser(request); - return applicationDao.getAllApplications(userEntity,callId); + public List getAllApplications(HttpServletRequest request, Long callId, Long companyId) { + UserEntity userEntity = validator.validateUser(request); + if (companyId != null) { + validator.validateUserWithCompany(request, companyId); + } + return applicationDao.getAllApplications(userEntity, callId, companyId); + } + @Override + @Transactional(rollbackFor = Exception.class) + public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { + return applicationDao.uploadSignedDocument(request, applicationId, file); } + + @Override + @Transactional(readOnly = true) + public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) { + return applicationDao.getSignedDocument(request, applicationId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { + applicationDao.deleteSignedDocument(request, applicationId); + } + } 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 bf853124..009a5296 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -5,16 +5,27 @@ import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.CompanyDao; +import net.gepafin.tendermanagement.dao.LoginAttemptDao; import net.gepafin.tendermanagement.dao.RoleDao; +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.model.request.LoginReq; +import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.model.response.LoginResponse; import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.util.JWTToken; +import net.gepafin.tendermanagement.repositories.SamlResponseRepository; import net.gepafin.tendermanagement.repositories.UserRepository; 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.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +37,10 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Service; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; @Service public class AuthenticationService { @@ -35,6 +49,8 @@ public class AuthenticationService { private final TokenProvider tokenProvider; private final AuthenticationManager authenticationManager; + @Autowired + private CompanyDao companyDao; @Autowired private UserRepository userRepository; @@ -42,59 +58,118 @@ public class AuthenticationService { @Autowired private RoleDao roleDao; + @Autowired + private SamlResponseRepository samlResponseLogRepository; + + @Autowired + private LoginAttemptDao loginAttemptDao; + @Autowired public AuthenticationService(TokenProvider tokenProvider, AuthenticationManager authenticationManager) { this.tokenProvider = tokenProvider; this.authenticationManager = authenticationManager; } - public JWTToken login(LoginReq loginReq) { - log.info("Attempting login for email: {}", loginReq.getEmail()); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( - loginReq.getEmail(), loginReq.getPassword()); - Authentication authentication = this.authenticationManager.authenticate(authenticationToken); - SecurityContextHolder.getContext().setAuthentication(authentication); - log.info("Authentication successful for email: {}", loginReq.getEmail()); - UserEntity user = userRepository.findByEmailIgnoreCase(loginReq.getEmail()).orElseThrow(()-> new CustomValidationException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); - if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) { - throw new CustomValidationException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); - } + public JWTToken login(LoginReq loginReq, HttpServletRequest request) { + UserEntity user=null; + + LoginAttemptEntity loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request); + log.info("Attempting login for email: {}", loginReq.getEmail()); + 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, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); + } + createSuccessLoginAttempt(loginAttemptEntity); + return getJWTTokenBean(user, loginReq.getRememberMe()); + } + + private LoginAttemptEntity prepareLoginAttemptEntity(LoginReq loginUserReq, HttpServletRequest request) { + String ipAddress = Utils.getClientIpAddress(request); + String userAgent = request.getHeader("user-agent"); + LoginAttemptEntity loginAttemptEntity = new LoginAttemptEntity(); + loginAttemptEntity.setType(LoginAttemptTypeEnum.LOGIN.getValue()); + loginAttemptEntity.setUsername(loginUserReq.getEmail()); + loginAttemptEntity.setIpAddress(ipAddress); + loginAttemptEntity.setUserAgent(userAgent); + return loginAttemptEntity; + } + + private void createSuccessLoginAttempt(LoginAttemptEntity loginAttemptEntity) { + loginAttemptEntity.setResult(LoginAttemptResultEnum.SUCCESS.getValue()); + loginAttemptDao.createLoginAttempt(loginAttemptEntity); + } + private void createFailedLoginAttempt(LoginAttemptEntity loginAttemptEntity, String errorMsg) { + loginAttemptEntity.setResult(LoginAttemptResultEnum.FAILED.getValue()); + loginAttemptEntity.setErrorMsg(errorMsg); + loginAttemptDao.createLoginAttempt(loginAttemptEntity); + } + public JWTToken getJWTTokenBean(UserEntity user, Boolean rememberMe) { user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); userRepository.save(user); - String token = tokenProvider.createToken(authentication, loginReq.getRememberMe(), user); - log.info("JWT token generated for email: {}", loginReq.getEmail()); + String token = tokenProvider.createToken(rememberMe, user); + log.info("JWT token generated for email: {}", user.getEmail()); RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); LoginResponse loginResponse = getLoginResponse(user, roleResponseBean); JWTToken jwtToken = new JWTToken(token, loginResponse); - log.info("Login successful for email: {}", loginReq.getEmail()); - return jwtToken; - } - - private static LoginResponse getLoginResponse(UserEntity user, RoleResponseBean roleResponseBean) { - LoginResponse loginResponse = new LoginResponse(); - loginResponse.setId(user.getId()); - loginResponse.setEmail(user.getEmail()); - loginResponse.setFirstName(user.getFirstName()); - loginResponse.setLastName(user.getLastName()); - loginResponse.setRole(roleResponseBean); - loginResponse.setPhoneNumber(user.getPhoneNumber()); - loginResponse.setAddress(user.getAddress()); - loginResponse.setOrganization(user.getOrganization()); - loginResponse.setCountry(user.getCountry()); - loginResponse.setStatus(user.getStatus()); - loginResponse.setCity(user.getCity()); - loginResponse.setLastLogin(user.getLastLogin()); + log.info("Login successful for email: {}", user.getEmail()); + return jwtToken; + } + + private LoginResponse getLoginResponse(UserEntity user, RoleResponseBean roleResponseBean) { + LoginResponse loginResponse = new LoginResponse(); + loginResponse.setEmail(user.getEmail()); + loginResponse.setId(user.getId()); + List companyResponseBeans = companyDao.getCompanyByUserId(user.getId()); + loginResponse.setCompanies(companyResponseBeans); + loginResponse.setRole(roleResponseBean); + loginResponse.setStatus(user.getStatus()); + loginResponse.setLastLogin(user.getLastLogin()); loginResponse.setCreatedDate(user.getCreatedDate()); loginResponse.setUpdatedDate(user.getUpdatedDate()); + if (user.getBeneficiary() == null) { + loginResponse.setFirstName(user.getFirstName()); + loginResponse.setLastName(user.getLastName()); + loginResponse.setPhoneNumber(user.getPhoneNumber()); + loginResponse.setAddress(user.getAddress()); + loginResponse.setOrganization(user.getOrganization()); + loginResponse.setCountry(user.getCountry()); + loginResponse.setCity(user.getCity()); + loginResponse.setDateOfBirth(user.getDateOfBirth()); + }else { + loginResponse.setFirstName(user.getBeneficiary().getFirstName()); + loginResponse.setLastName(user.getBeneficiary().getLastName()); + loginResponse.setPhoneNumber(user.getBeneficiary().getPhoneNumber()); + loginResponse.setAddress(user.getBeneficiary().getAddress()); + loginResponse.setOrganization(user.getBeneficiary().getOrganization()); + loginResponse.setCountry(user.getBeneficiary().getCountry()); + loginResponse.setCity(user.getBeneficiary().getCity()); + loginResponse.setCodiceFiscale(user.getBeneficiary().getCodiceFiscale()); + loginResponse.setDateOfBirth(user.getBeneficiary().getDateOfBirth()); + loginResponse.setPrivacy(user.getBeneficiary().getPrivacy()); + loginResponse.setMarketing(user.getBeneficiary().getMarketing()); + loginResponse.setOffers(user.getBeneficiary().getOffers()); + loginResponse.setTerms(user.getBeneficiary().getTerms()); + loginResponse.setThirdParty(user.getBeneficiary().getThirdParty()); + loginResponse.setEmailPec(user.getBeneficiary().getEmailPec()); + } + return loginResponse; } - public void logout(HttpServletRequest request, HttpServletResponse response) - { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + public void logout(HttpServletRequest request, HttpServletResponse response) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { String token = tokenProvider.extractTokenFromRequest(request); tokenProvider.invalidateToken(token); @@ -102,6 +177,60 @@ public class AuthenticationService { } SecurityContextHolder.getContext().setAuthentication(null); SecurityContextHolder.clearContext(); -} + } + + public JWTToken validateExistingUserToken(String token) { + SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token); + if (samlResponseLogEntity == null) { + log.info("Invalid spid login token : {}", token); + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG)); + } + Map> userAttributes = Utils + .convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject()); + String cf = userAttributes.get("CodiceFiscale").get(0).toString(); + UserEntity userEntity = userRepository.findByBeneficiaryCodiceFiscale(cf) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + //samlResponseLogRepository.delete(samlResponseLogEntity); + + return getJWTTokenBean(userEntity, Boolean.TRUE); + } + + + public UserSamlResponse validateNewUserToken(String token) { + SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token); + if (samlResponseLogEntity == null) { + log.info("Invalid spid login token : {}", token); + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG)); + } + Map> userAttributes = Utils + .convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject()); + String cf = userAttributes.get("CodiceFiscale").get(0).toString(); + if (userRepository.existsByBeneficiaryCodiceFiscale(cf)) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.USER_ALREADY_EXIST_MSG)); + } + UserSamlResponse userSamlResponse = new UserSamlResponse(); + userSamlResponse.setCodiceFiscale(cf); + if (userAttributes.containsKey("nome") && userAttributes.get("nome") != null + && !userAttributes.get("nome").isEmpty()) { + userSamlResponse.setFirstName(userAttributes.get("nome").get(0).toString()); + } + if (userAttributes.containsKey("cognome") && userAttributes.get("cognome") != null + && !userAttributes.get("cognome").isEmpty()) { + userSamlResponse.setLastName(userAttributes.get("cognome").get(0).toString()); + } + if (userAttributes.containsKey("dataNascita") && userAttributes.get("dataNascita") != null + && !userAttributes.get("dataNascita").isEmpty()) { + String dateString =userAttributes.get("dataNascita").get(0).toString(); + LocalDate dateOfBirth = LocalDate.parse(dateString); + LocalDateTime dateOfBirthWithTime = dateOfBirth.atStartOfDay(); + userSamlResponse.setDateOfBirth(dateOfBirthWithTime); + } + userSamlResponse.setCodiceFiscale(cf); + return userSamlResponse; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/BeneficiaryPreferredCallServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/BeneficiaryPreferredCallServiceImpl.java new file mode 100644 index 00000000..4484027e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/BeneficiaryPreferredCallServiceImpl.java @@ -0,0 +1,90 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.BeneficiaryPreferredCallDao; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; + +import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; +import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.service.BeneficiaryPreferredCallService; +import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.Validator; +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.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +@Service +public class BeneficiaryPreferredCallServiceImpl implements BeneficiaryPreferredCallService { + + @Autowired + private BeneficiaryPreferredCallDao beneficiaryPreferredCallDao; + @Autowired + private Validator validator; + @Autowired + private UserRepository userRepository; + @Autowired + private UserService userService; + + + @Override + public BeneficiaryPreferredCallResponseBean createBeneficiaryPreferredCall(HttpServletRequest request, BeneficiaryPreferredCallReq beneficiaryPreferredCallRequest) { + UserEntity userEntity = validator.validateUser(request); + return beneficiaryPreferredCallDao.createBeneficiaryPreferredCall(beneficiaryPreferredCallRequest,userEntity); + } + + @Override + public BeneficiaryPreferredCallResponseBean getBeneficiaryPreferredCallById(HttpServletRequest request, Long id) { + return beneficiaryPreferredCallDao.getBeneficiaryPreferredCallById(id); + } + + @Override + public void deleteBeneficiaryPreferredCall(HttpServletRequest request, Long id) { + beneficiaryPreferredCallDao.deleteBeneficiaryPreferredCallById(id); + } + + @Override + public List getAllBeneficiaryPreferredCalls(HttpServletRequest request) { + return beneficiaryPreferredCallDao.getAllBeneficiaryPreferredCalls(); + } + +// @Override +// public BeneficiaryPreferredCallResponseBean updateBeneficiaryPreferredCall(HttpServletRequest request, Long id, +// BeneficiaryPreferredCallReq beneficiaryPreferredCallRequest) { +// UserEntity userEntity = validator.validateUser(request); +// return beneficiaryPreferredCallDao.updateBeneficiaryPreferredCall(id, beneficiaryPreferredCallRequest,userEntity); +// } + @Override + public void updateBeneficiaryPreferredCallStatus(HttpServletRequest request, Long id, BeneficiaryCallStatus status) { + beneficiaryPreferredCallDao.updateBeneficiaryPreferredCallStatus(id, status); + } + @Override + public List getBeneficiaryPreferredCallByUserId(HttpServletRequest request,Long userId,Long beneficiaryId,Long companyId) { + UserEntity userEntity =validateGetBeneficiaryPreferredCallrequest(request,userId,beneficiaryId); + return beneficiaryPreferredCallDao.getBeneficiaryPreferredCallByUserId(userEntity,companyId); + } + + private UserEntity validateGetBeneficiaryPreferredCallrequest(HttpServletRequest request, Long userId, Long beneficiaryId) { + if (userId == null && beneficiaryId == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.EITHER_USER_OR_BENEFICIARY_ID_REQUIRED)); + } + if(userId!=null&&beneficiaryId!=null){ + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.USER_ID_AND_BENEFICIARY_ID_ERROR)); + } + if(beneficiaryId!=null){ + UserEntity user = userService.getUserByBeneficiaryId(beneficiaryId); + return validator.validateUserId(request,user.getId()); + } + else{ + return validator.validateUserId(request, userId); + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java index a6a6a901..281b33b1 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java @@ -1,7 +1,6 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; -import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.dao.CallDao; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.UserEntity; @@ -12,12 +11,13 @@ import net.gepafin.tendermanagement.model.request.UpdateCallRequestStep1; import net.gepafin.tendermanagement.model.response.CallDetailsResponseBean; import net.gepafin.tendermanagement.model.response.CallResponse; import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.util.Validator; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Map; @Service @@ -27,59 +27,61 @@ public class CallServiceImpl implements CallService { private CallDao callDao; @Autowired - private TokenProvider tokenProvider; + private Validator validator; @Override @Transactional(rollbackFor = Exception.class) public CallResponse createCallStep1(HttpServletRequest request, CreateCallRequestStep1 createCallRequest) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - return callDao.createCallStep1(createCallRequest, Long.parseLong(userInfo.get("userId").toString())); + UserEntity user = validator.validateUser(request); + return callDao.createCallStep1(createCallRequest, user); } @Override @Transactional(rollbackFor = Exception.class) public CallResponse createCallStep2(HttpServletRequest request, Long callId, CreateCallRequestStep2 createCallRequest) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - return callDao.createCallStep2(callId, createCallRequest, Long.parseLong(userInfo.get("userId").toString())); + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return callDao.createCallStep2(call, createCallRequest, user); } @Override @Transactional(rollbackFor = Exception.class) public CallResponse updateCallStep1(HttpServletRequest request, Long callId, UpdateCallRequestStep1 updateCallRequest) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - return callDao.updateCallStep1(callId, updateCallRequest, Long.parseLong(userInfo.get("userId").toString())); + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return callDao.updateCallStep1(call, updateCallRequest, user); } @Override @Transactional(readOnly = true) - public CallResponse getCallById(Long callId) { - return callDao.getCallById(callId); + public CallResponse getCallById(HttpServletRequest request, Long callId) { + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return callDao.getCallById(call); } @Override @Transactional(readOnly = true) public List getAllCalls(HttpServletRequest request) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - UserEntity user=tokenProvider.validateUser(userInfo); + UserEntity user = validator.validateUser(request); return callDao.getAllCalls(user); } @Override @Transactional(rollbackFor = Exception.class) - public CallResponse validateCallData(Long callId) { - return callDao.validateCallData(callDao.validateCall(callId)); - } - - @Override - public CallEntity getCallEntityById(Long id){ - return callDao.getCallEntityById(id); + public CallResponse validateCallData(HttpServletRequest request, Long callId) { + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return callDao.validateCallData(call); } @Override @Transactional(rollbackFor = Exception.class) public CallResponse updateCallStatus(HttpServletRequest request, Long callId, CallStatusEnum statusReq) { - return callDao.updateCallStatus(callId, statusReq); + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return callDao.updateCallStatus(call, statusReq); } @@ -88,8 +90,15 @@ public class CallServiceImpl implements CallService { return callDao.validateCall(callId); } - @Override - public CallEntity validatePublishedCall(Long callId) { - return callDao.validatePublishedCall(callId); - } - } + @Override + public CallEntity validatePublishedCall(Long callId) { + return callDao.validatePublishedCall(callId); + } + + @Override + @Transactional(readOnly = true) + public byte[] downloadCallDocumentsAsZip(Long callId) { + return callDao.downloadCallDocumentsAsZip(callId); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CallValidatorServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CallValidatorServiceImpl.java index 715242f5..3c7091cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CallValidatorServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CallValidatorServiceImpl.java @@ -10,6 +10,7 @@ import net.gepafin.tendermanagement.model.response.CallResponse; import net.gepafin.tendermanagement.model.response.FlowResponseBean; import net.gepafin.tendermanagement.model.response.FormResponseBean; import net.gepafin.tendermanagement.util.FieldValidator; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -28,6 +29,10 @@ public class CallValidatorServiceImpl { .notNull(response.getAmount(), "amount") .notNull(response.getAmountMax(), "amountMax") .notNull(response.getThreshold(), "threshold") + .notNull(response.getEmail(),"email") + .notNull(response.getAmountMin(),"amountMin") + .notNull(response.getStartTime(),"startTime") + .notNull(response.getEndTime(),"endTime") .notNull(response.getDocumentationRequested(), "documentationRequested") .notEmpty(response.getAimedTo(), "aimedTo") .notEmpty(response.getCriteria(), "criteria") diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java new file mode 100644 index 00000000..34c8777f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -0,0 +1,127 @@ +package net.gepafin.tendermanagement.service.impl; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.CompanyDao; +import net.gepafin.tendermanagement.dao.DelegationDao; +import net.gepafin.tendermanagement.dao.VatCheckDao; +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; +import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; +import net.gepafin.tendermanagement.model.response.CompanyResponse; +import net.gepafin.tendermanagement.service.CompanyService; +import net.gepafin.tendermanagement.util.Validator; + +@Service +public class CompanyServiceImpl implements CompanyService { + + @Autowired + private Validator validator; + + @Autowired + private CompanyDao companyDao; + + @Autowired + private VatCheckDao vatCheckDao; + + @Autowired + private DelegationDao delegationDao; + + @Override + @Transactional(rollbackFor = Exception.class) + public CompanyResponse createCompany(HttpServletRequest request, CompanyRequest companyRequest) { + UserEntity userEntity =validator.validateUser(request); + return companyDao.createCompany(userEntity, companyRequest); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CompanyResponse updateCompany(HttpServletRequest request, Long companyId, CompanyRequest companyRequest) { + UserEntity userEntity =validator.validateUser(request); + return companyDao.updateCompany(userEntity, companyId, companyRequest); + } + + @Override + @Transactional(readOnly = true) + public CompanyResponse getCompany(HttpServletRequest request, Long companyId) { + UserEntity userEntity =validator.validateUser(request); + return companyDao.getCompany(userEntity, companyId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteCompany(HttpServletRequest request, Long companyId) { + UserEntity userEntity =validator.validateUser(request); + companyDao.deleteCompany(userEntity, companyId); + } + + @Override + @Transactional(readOnly = true) + public List getCompanyByUserId(HttpServletRequest request, Long userId) { + validator.validateUser(request); + return companyDao.getCompanyByUserId(userId); + } + + @Override + @Transactional(readOnly = true) + public Map checkVatNumber(HttpServletRequest request, String vatNumber) { + return vatCheckDao.checkVatNumber(vatNumber); + } + @Override + public CompanyEntity validateCompany(Long companyId) { + return companyDao.validateCompany(companyId); + } + + @Override + public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) { + return companyDao.validateUserWithCompny(userId, companyId); + } + + @Override + @Transactional(readOnly = true) + public ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { + UserEntity userEntity =validator.validateUser(request); + return delegationDao.downloadCompanyDelegation(userEntity, companyId, companyDelegationRequest); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file) { + UserEntity userEntity = validator.validateUser(request); + validator.validateUserWithCompany(request, companyId); + return delegationDao.uploadCompanyDelegation(userEntity, companyId, file); + } + + @Override + @Transactional(readOnly = true) + public CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId) { + UserEntity userEntity =validator.validateUser(request); + return delegationDao.getCompanyDelegation(userEntity, companyId); + } + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteCompanyDelegation(HttpServletRequest request, Long companyId) { + UserEntity userEntity =validator.validateUser(request); + delegationDao.deleteCompanyDelegation(userEntity, companyId); + } + public UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId){ + return companyDao.getUserWithCompany(userId,companyId); + } + @Override + @Transactional(rollbackFor = Exception.class) + public void removeCompanyFromList(HttpServletRequest request, Long companyId) { + UserEntity userEntity =validator.validateUser(request); + companyDao.removeCompanyFromList(userEntity, companyId); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java new file mode 100644 index 00000000..d0bd0217 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java @@ -0,0 +1,34 @@ +package net.gepafin.tendermanagement.service.impl; + +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.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; +import net.gepafin.tendermanagement.service.DashboardService; +import net.gepafin.tendermanagement.util.Validator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DashboardServiceImpl implements DashboardService { + + @Autowired + private DashboardDao dashboardDao; + + @Autowired + private Validator validator; + + @Override + public SuperAdminWidgetResponseBean getDashboardWidgetForSuperAdmin(HttpServletRequest request) { + return dashboardDao.getDashboardWidget(); + } + + @Override + public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId) { + UserEntity userEntity=validator.validateUser(request); + CompanyEntity company = validator.validateUserWithCompany(request, companyId); + return dashboardDao.getDashboardWidgetForBeneficiary(userEntity, company); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/FaqServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/FaqServiceImpl.java index 78a458f3..921b0ae7 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/FaqServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/FaqServiceImpl.java @@ -25,9 +25,9 @@ public class FaqServiceImpl implements FaqService { private Validator validator; @Override - public FaqResponseBean createFaq(HttpServletRequest request,Long callId, FaqReq faqRequest) { + public FaqResponseBean createFaq(HttpServletRequest request,Long callId, Long companyId, FaqReq faqRequest) { UserEntity userEntity = validator.validateUser(request); - return faqDao.createFaq(faqRequest, userEntity,callId); + return faqDao.createFaq(faqRequest, userEntity, callId, companyId); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java index 9d04dbc5..51199767 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java @@ -3,12 +3,15 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.FormDao; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.FormEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.FormRequest; import net.gepafin.tendermanagement.model.response.FormResponseBean; import net.gepafin.tendermanagement.service.FormService; +import net.gepafin.tendermanagement.util.Validator; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -19,26 +22,33 @@ public class FormServiceImpl implements FormService { @Autowired private FormDao formDao; + + @Autowired + private Validator validator; @Override public FormResponseBean createForm(HttpServletRequest request,Long callId, FormRequest formRequest) { - return formDao.createForm(callId,formRequest); + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return formDao.createForm(call,formRequest); } @Override public FormResponseBean updateForm(HttpServletRequest request, Long formId, FormRequest formRequest,Boolean forceDeleteFlow) { - return formDao.updateForm(formId,formRequest,forceDeleteFlow); + UserEntity user = validator.validateUser(request); + return formDao.updateForm(user, formId,formRequest,forceDeleteFlow); } @Override public FormResponseBean getFormById(HttpServletRequest request, Long formId) { - return formDao.getFormEntityById(formId); + UserEntity user = validator.validateUser(request); + return formDao.getFormEntityById(user, formId); } @Override public void deleteForm(HttpServletRequest request, Long formId) { - formDao.deleteFormById(formId); - return; + UserEntity user = validator.validateUser(request); + formDao.deleteFormById(user, formId); } @Override @@ -48,7 +58,9 @@ public class FormServiceImpl implements FormService { @Override public List getFormsByCallId(HttpServletRequest request, Long callId) { - return formDao.getFormsByCallId(callId); + UserEntity user = validator.validateUser(request); + CallEntity call = validator.validateUserWithCall(user, callId); + return formDao.getFormsByCallId(call); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/LoginAttemptServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/LoginAttemptServiceImpl.java new file mode 100644 index 00000000..1519273f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/LoginAttemptServiceImpl.java @@ -0,0 +1,40 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.LoginAttemptDao; +import net.gepafin.tendermanagement.entities.LoginAttemptEntity; +import net.gepafin.tendermanagement.enums.LoginAttemptResultEnum; +import net.gepafin.tendermanagement.enums.LoginAttemptTypeEnum; +import net.gepafin.tendermanagement.model.request.LoginAttemptReq; +import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; +import net.gepafin.tendermanagement.service.LoginAttemptService; +import net.gepafin.tendermanagement.util.Utils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class LoginAttemptServiceImpl implements LoginAttemptService { + + @Autowired + LoginAttemptDao loginAttemptDao; + + @Override + public LoginAttemptPageableResponseBean> getLoginAttemptsList(Integer pageNo, Integer pageLimit) { + return loginAttemptDao.getLoginAttemptsList(pageNo, pageLimit); + } + + @Override + public void createLoginAttempt(LoginAttemptReq loginAttemptReq, HttpServletRequest request) { + String ipAddress = Utils.getClientIpAddress(request); + String userAgent = request.getHeader("user-agent"); + LoginAttemptEntity loginAttemptEntity = new LoginAttemptEntity(); + loginAttemptEntity.setType(LoginAttemptTypeEnum.SWITCH.getValue()); + loginAttemptEntity.setIpAddress(ipAddress); + loginAttemptEntity.setUserAgent(userAgent); + loginAttemptEntity.setUsername(loginAttemptReq.getUserName()); + loginAttemptEntity.setResult(LoginAttemptResultEnum.SUCCESS.getValue()); + loginAttemptDao.createLoginAttempt(loginAttemptEntity); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/PdfServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/PdfServiceImpl.java new file mode 100644 index 00000000..b075584d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/PdfServiceImpl.java @@ -0,0 +1,24 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.PdfDao; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.service.PdfService; +import net.gepafin.tendermanagement.util.Validator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class PdfServiceImpl implements PdfService { + + @Autowired + private PdfDao pdfDao; + + @Autowired + private Validator validator; + + @Override + public byte[] generatePdf(HttpServletRequest request, Long applicationId) { + return pdfDao.generatePdf(request, applicationId); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java index 49fd86c4..697e0018 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.service.impl; import java.util.List; import net.gepafin.tendermanagement.dao.RoleDao; +import net.gepafin.tendermanagement.entities.RoleEntity; import net.gepafin.tendermanagement.model.request.RoleReq; import net.gepafin.tendermanagement.model.response.RoleResponseBean; import net.gepafin.tendermanagement.service.RoleService; @@ -46,4 +47,10 @@ public class RoleServiceImpl implements RoleService { return roleDao.getAllRoles(); } + @Override + @Transactional(readOnly = true) + public RoleEntity validateRole(Long roleId) { + return roleDao.validateRole(roleId); + + } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java new file mode 100644 index 00000000..802f2580 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.service.impl; + +import java.util.Locale; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import net.gepafin.tendermanagement.dao.SystemEmailTemplatesDao; +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; +import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; + +@Service +public class SystemEmailTemplatesServiceImpl implements SystemEmailTemplatesService { + + @Autowired + private SystemEmailTemplatesDao systemEmailTemplatesDao; + + + @Override + public SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) { + return systemEmailTemplatesDao.retrieveTemplate(type, call, language); + } + + +} 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 7b949008..51e92579 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java @@ -2,23 +2,26 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import net.gepafin.tendermanagement.config.jwt.TokenProvider; +import net.gepafin.tendermanagement.config.SamlSuccessHandler; import net.gepafin.tendermanagement.dao.UserDao; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.request.LoginReq; import net.gepafin.tendermanagement.model.request.UpdateUserReq; import net.gepafin.tendermanagement.model.request.UserReq; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.*; +import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.Validator; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Map; @Service @@ -26,12 +29,22 @@ public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; + @Autowired - private TokenProvider tokenProvider; + private Validator validator; + + @Autowired + private SamlSuccessHandler samlSuccessHandler; + @Override @Transactional(rollbackFor = Exception.class) - public UserResponseBean createUser(UserReq userReq) { - return userDao.createUser(userReq); + public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) { + if (tempToken == null) { + validator.validateRequest(request,RoleStatusEnum.ROLE_SUPER_ADMIN); + }else { + samlSuccessHandler.validateToken(tempToken, userReq.getCodiceFiscale()); + } + return userDao.createUser(request, tempToken, userReq); } @@ -54,8 +67,8 @@ public class UserServiceImpl implements UserService { } @Override - public JWTToken login(LoginReq loginReq) { - return userDao.login(loginReq); + public JWTToken login(LoginReq loginReq, HttpServletRequest request) { + return userDao.login(loginReq,request); } @@ -74,8 +87,8 @@ public class UserServiceImpl implements UserService { return userDao.resetPassword(resetPasswordReq); } @Override - public Boolean changePassword(ChangePasswordRequest request){ - return userDao.changePassword(request); + public Boolean changePassword(HttpServletRequest httpServletRequest, ChangePasswordRequest request){ + return userDao.changePassword(validator.validateUser(httpServletRequest), request); } @Override public void logoutUser(HttpServletRequest request, HttpServletResponse response) { @@ -90,19 +103,38 @@ public class UserServiceImpl implements UserService { @Override @Transactional(readOnly = true) public UserResponseBean getValidUser(HttpServletRequest request) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - UserEntity user=tokenProvider.validateUser(userInfo); + UserEntity user=validator.validateUser(request); return userDao.getUserById(user.getId()); } + @Override @Transactional(readOnly = true) public List getUserByHubId(String hubId) { return userDao.getUserByHubId(hubId); } + @Override @Transactional(rollbackFor = Exception.class) - public UserResponseBean createUserByHubId(String hubId, UserReq userReq) { - return userDao.createUserByHubId(hubId, userReq); + public JWTToken validateExistingUserToken(HttpServletRequest request, String token) { + return userDao.validateExistingUserToken(token); + } + @Override + public UserSamlResponse validateNewUserToken(HttpServletRequest request, String token) { + return userDao.validateNewUserToken(token); + } + @Override + public UserEntity getUserByBeneficiaryId(Long beneficiaryId) { + return userDao.getUserByBeneficiaryId(beneficiaryId); + } + @Override + public UserEntity getUserEntityById(Long userId) { + // Calling DAO Function + return userDao.validateUser(userId); + } + @Override + @Transactional(readOnly = true) + public List getAllUsers(Long roleId) { + // Calling DAO Function + return userDao.getAllUsers(roleId); } - } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java index ab67ccdd..1fdf6c1a 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java @@ -1,21 +1,30 @@ package net.gepafin.tendermanagement.util; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.Calendar; import java.util.Date; +import java.util.regex.Pattern; @Component public class DateTimeUtil { - + + private static final Pattern TIME_PATTERN = Pattern.compile( + "^((([01]?\\d|2[0-3]):([0-5]\\d)(:[0-5]\\d)?(\\s?[AP]M)?)|((0?[1-9]|1[0-2]):([0-5]\\d)(:[0-5]\\d)?\\s?[AP]M))$"); + public static LocalDateTime DateServerToUTC(LocalDateTime systemDate) { ZonedDateTime ldtZoned = systemDate.atZone(ZoneId.systemDefault()); - LocalDateTime localDatetime = ldtZoned.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(); + LocalDateTime localDatetime = ldtZoned.withZoneSameInstant(ZoneId.of("Europe/Rome")).toLocalDateTime(); return localDatetime; } @@ -50,4 +59,53 @@ public class DateTimeUtil { .from(localDateTime.atZone(ZoneId.systemDefault()) .toInstant()); } + + public static LocalTime parseTime(String timeString) throws DateTimeParseException { + DateTimeFormatter formatter; + if(timeString==null) { + return null; + } + if (!TIME_PATTERN.matcher(timeString).matches()) { + throw new CustomValidationException(Status.BAD_REQUEST,"Invalid time format: " + timeString); + } + // Try to parse using default formats if no format is provided + String[] defaultFormats = {"HH:mm:ss", "HH:mm", "HH:mm:ss a", "hh:mm a"}; + for (String defaultFormat : defaultFormats) { + formatter = DateTimeFormatter.ofPattern(defaultFormat); + try { + return LocalTime.parse(timeString, formatter); + } catch (DateTimeParseException e) { + // Continue to the next format + } + } + + // If all parsing attempts fail, throw an exception + throw new CustomValidationException(Status.BAD_REQUEST,"Failed to parse time: " + timeString); + } + + public static String formatLocalDateTime(LocalDateTime dateTime, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return dateTime.format(formatter); + } + + public static LocalDateTime parseStringToLocalDateTime(String dateTimeStr, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.parse(dateTimeStr, formatter); + } + + public static String parseLocalTimeToString(LocalTime time, String format) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + return time.format(formatter); + } + + // Method 2: Convert String and format to LocalTime + public static LocalTime parseStringToLocalTime(String timeString, String format) { + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + return LocalTime.parse(timeString, formatter); + } catch (DateTimeParseException e) { + System.out.println("Invalid time format: " + e.getMessage()); + return null; + } + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java index 71c76f1a..26edffff 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java @@ -27,16 +27,16 @@ public class FieldValidator { private VatCheckDao vatCheckDao; - public FieldValidator notNull(Object object, String fieldName) { + public FieldValidator notNull(Object object, String fieldLabel) { if (Objects.isNull(object)) { - errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_NULL), fieldName)); + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_NULL), fieldLabel)); } return this; } - public FieldValidator notEmpty(List list, String fieldName) { + public FieldValidator notEmpty(List list, String fieldLabel) { if (list == null || list.isEmpty()) { - errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_EMPTY), fieldName)); + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_EMPTY), fieldLabel)); } return this; } @@ -46,23 +46,23 @@ public class FieldValidator { throw new ValidationException(Status.VALIDATION_ERROR, errors, Translator.toLocale(GepafinConstant.VALIDATION_MESSAGE)); } } - public FieldValidator minLength(String value, Long minLength, String fieldName) { + public FieldValidator minLength(String value, Long minLength, String fieldLabel) { if (minLength != null && value != null && value.length() < minLength) { - errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MIN_LENGTH), fieldName, minLength)); + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MIN_LENGTH), fieldLabel, minLength)); } return this; } - public FieldValidator maxLength(String value, Long maxLength, String fieldName) { + public FieldValidator maxLength(String value, Long maxLength, String fieldLabel) { if (maxLength != null && value != null && value.length() > maxLength) { - errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MAX_LENGTH), fieldName, maxLength)); + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MAX_LENGTH), fieldLabel, maxLength)); } return this; } - public FieldValidator matchesPattern(String value, String pattern, String fieldName) { + public FieldValidator matchesPattern(String value, String pattern, String fieldLabel) { if (value != null && pattern != null && !value.matches(pattern)) { - errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_PATTERN), fieldName)); + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_PATTERN), fieldLabel)); } return this; } @@ -147,4 +147,7 @@ public class FieldValidator { } return this; } + public boolean hasErrors() { + return !errors.isEmpty(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/MailUtil.java b/src/main/java/net/gepafin/tendermanagement/util/MailUtil.java new file mode 100644 index 00000000..8b41ea3f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/MailUtil.java @@ -0,0 +1,78 @@ +package net.gepafin.tendermanagement.util; + +import java.util.Arrays; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import com.mailgun.api.v3.MailgunMessagesApi; +import com.mailgun.client.MailgunClient; + +@Component +public class MailUtil { + + @Value("${apiKey}") + private String apiKeyValue; + + @Value("${mailGun_user}") + private String mailGunUser; + + @Value("${mailGun_apiKey}") + private String mailGunApiKey; + + @Value("${mailGun_domainName}") + private String mailGunDomainName; + + @Value("${mailGun_base_url}") + private String mailGunBaseUrl; + + @Value("${isMailSendingEnabled}") + private String isEmailSendingEnabled; + + @Autowired + private Environment environment; + + public Boolean isTestProfileActivated() { + String[] activeProfiles = environment.getActiveProfiles(); + return Arrays.stream(activeProfiles).anyMatch("test"::equals); + } + + public void sendMailByMailGunAPI(List recipents, List CC, List BCC, String subject, + String body, String replyTo) { + if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) { + return; + } + + MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(mailGunBaseUrl, mailGunApiKey) + .createApi(MailgunMessagesApi.class); + + String mailFrom = mailGunUser; + + com.mailgun.model.message.Message.MessageBuilder temp = com.mailgun.model.message.Message.builder() + .replyTo(replyTo).from(mailFrom).to(recipents).subject(subject).html(body); + + if (Boolean.FALSE.equals(CollectionUtils.isEmpty(CC))) { + temp.cc(CC); + } + + if (Boolean.FALSE.equals(CollectionUtils.isEmpty(BCC))) { + temp.bcc(BCC); + } + + if (Boolean.FALSE.equals(isTestProfileActivated())) { + com.mailgun.model.message.Message message = temp.build(); + mailgunMessagesApi.sendMessage(mailGunDomainName, message); + } + + } + + public void sendByMailGun(String subject, String body, List receiverEmails, String replyTo) { + sendMailByMailGunAPI(receiverEmails, null, null, subject, body, replyTo); + + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 055fb8e8..767872ce 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -1,27 +1,36 @@ package net.gepafin.tendermanagement.util; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.json.JsonReadFeature; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import io.micrometer.common.util.StringUtils; -import org.apache.commons.collections4.MapUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.List; -import java.util.Map; +import java.security.SecureRandom; +import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.collections4.MapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.json.JsonReadFeature; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import feign.FeignException; +import io.micrometer.common.util.StringUtils; +import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientForbiddenException; +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; + public class Utils { @@ -161,4 +170,142 @@ public class Utils { } } } + + public static String encodeData(String data) { + return Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8)); + } + + public static String decodeData(String token) { + byte[] decodedBytes = Base64.getDecoder().decode(token); + return new String(decodedBytes, StandardCharsets.UTF_8); + } + + public static String generateSecureToken() { + SecureRandom secureRandom = new SecureRandom(); + byte[] tokenBytes = new byte[24]; + 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>>() { + }); + } catch (Exception e) { + log.error("Error converting object: " + e.getMessage(), e); + return null; + } + } + + public static void callException(Integer staus, FeignException ex) { + switch (staus) { + case 400: + throw new FeignClientValidationException(HttpStatus.valueOf(staus), ex.getMessage()); + + case 401: + throw new FeignClientUnauthorizedException(HttpStatus.valueOf(staus), ex.getMessage()); + + case 403: + throw new FeignClientForbiddenException(HttpStatus.valueOf(staus), ex.getMessage()); + + case 404: + throw new FeignClientNotFoundException(HttpStatus.valueOf(staus), ex.getMessage()); + default: + log.error("Exception occured :- {0}", ex); + throw ex; + } + } + + public static Boolean isValidEmail(String email) { + String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"; + if (email == null || email.isEmpty()) { + return false; + } + Pattern pattern = Pattern.compile(EMAIL_REGEX); + return pattern.matcher(email).matches(); + } + + public static String randomKey(Integer range) { + String data = String.valueOf(System.currentTimeMillis()); + return data.substring(data.length() - range); + } + + public static String convertObjectToJsonString(Object object) { + try { + // Check if the object is a string + if (object instanceof String) { + String str = (String) object; + // Return null if the string is null or empty + if (str != null && !str.trim().isEmpty()) { + return str; // Return the non-empty string + } else { + return null; // Return null for null or empty string + } + } else if (object != null) { + // Convert non-string objects (arrays, objects) to JSON strings + return mapper.writeValueAsString(object); + } + return null; // Return null if the object is null + } catch (JsonProcessingException e) { + log.error("Error while converting object to string: {}", e.getMessage(), e); + return null; // Return null in case of exception + } + } + + + public static Object getFieldValueAsObject(String fieldValue) { + ObjectMapper mapper = new ObjectMapper(); + try { + // Check if the string is a valid JSON object, array, or simple string + if (fieldValue.startsWith("{")) { + // Convert to a Map (representing an object) + return mapper.readValue(fieldValue, Map.class); + } else if (fieldValue.startsWith("[")) { + // Convert to a List (representing an array) + return mapper.readValue(fieldValue, List.class); + } else { + // Return the raw string (it's a simple value) + return fieldValue; + } + } catch (JsonProcessingException e) { + log.error("Error while converting string to object: {}", e.getMessage(), e); + return fieldValue; // If there's an error, return the raw string + } + } + + public static Map> parseJsonContent(String jsonContent) { + ObjectMapper objectMapper = new ObjectMapper(); + try { + return mapper.readValue(jsonContent, HashMap.class); + } catch (Exception exception) { + log.error(exception.getMessage()); + } + return new HashMap<>(); + } + + // Utility method to replace placeholders with their values, handling nulls + public static String replacePlaceholders(String text, Map placeholders) { + if (text == null) { + return ""; + } + for (Map.Entry entry : placeholders.entrySet()) { + text = replaceNull(text, entry.getKey(), entry.getValue()); + } + return text; + } + + // Method to safely replace nulls with an empty string or a default value + private static String replaceNull(String text, String target, String replacement) { + return text.replace(target, replacement != null ? replacement : ""); + } + public static String getClientIpAddress(HttpServletRequest request) { + String header = request.getHeader("X-Forwarded-For"); + if (org.apache.commons.lang3.StringUtils.isBlank(header)) { + return request.getRemoteAddr(); + } + + return new StringTokenizer(header, ",").nextToken().trim(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Validator.java b/src/main/java/net/gepafin/tendermanagement/util/Validator.java index a831c2dc..b4c36227 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Validator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Validator.java @@ -1,11 +1,25 @@ package net.gepafin.tendermanagement.util; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.config.jwt.TokenProvider; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.CallDao; +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.RoleStatusEnum; +import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.web.rest.api.errors.ForbiddenAccessException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import java.util.Map; @@ -18,14 +32,88 @@ public class Validator { @Autowired private UserService userService; + + @Autowired + private CompanyService companyService; + + @Autowired + private CallService callService; public Map getUserInfoFromToken(HttpServletRequest request) { return tokenProvider.getUserInfoAndUserIdFromToken(request); } public UserEntity validateUser(HttpServletRequest request) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - return userService.validateUser(Long.parseLong(userInfo.get("userId").toString())); + return userService.validateUser(getUserIdFromToken(request)); } + public Boolean checkIsSuperAdmin() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.isAuthenticated()) { + // Check if the user has the ROLE_SUPER_ADMIN authority + for (GrantedAuthority authority : authentication.getAuthorities()) { + if (RoleStatusEnum.ROLE_SUPER_ADMIN.getValue().equals(authority.getAuthority())) { + return true; + } + } + } + return false; + } + + public void validateRequest(HttpServletRequest request,RoleStatusEnum role) { + if (RoleStatusEnum.ROLE_SUPER_ADMIN.equals(role) && Boolean.FALSE.equals(checkIsSuperAdmin())) { + throw new UnauthorizedAccessException(Status.UNAUTHORIZED, Translator.toLocale(GepafinConstant.INVALID_REQUEST)); + } + } + + public CompanyEntity validateUserWithCompany(HttpServletRequest request, Long companyId) { + if (checkIsSuperAdmin()) { + return companyService.validateCompany(companyId); + } + Map userInfo = tokenProvider.getUserInfoAndUserIdFromToken(request); + companyService.validateUserWithCompny(getUserId(userInfo), companyId); + return companyService.validateCompany(companyId); + } + + private Long getUserId(Map userInfo) { + return Long.parseLong(userInfo.get("userId").toString()); + } + + public Boolean checkIsBeneficiary() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + // Check if the user has the ROLE_SUPER_ADMIN authority + for (GrantedAuthority authority : authentication.getAuthorities()) { + if (RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(authority.getAuthority())) { + return true; + } + } + } + return false; + } + + public UserEntity validateUserId(HttpServletRequest request, Long userId) { + UserEntity user = validateUser(request); + if(user.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue()) && Boolean.FALSE.equals(user.getId().equals(userId))) { + throw new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); + } + return userService.validateUser(userId); + } + + private Long getUserIdFromToken(HttpServletRequest request) { + Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); + return Long.parseLong(userInfo.get("userId").toString()); + } + + public CallEntity validateUserWithCall(UserEntity user, Long callId) { + CallEntity callEntity = callService.validateCall(callId); + if(user.getHub().getId().equals(callEntity.getHub().getId())) { + throw new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); + } + return callEntity; + } + + + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java index 9499bfe0..e3be06c7 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java @@ -6,6 +6,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -21,6 +22,8 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationResponse; import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; @@ -67,7 +70,8 @@ public interface ApplicationApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "", produces = "application/json") ResponseEntity>> getAllApplications(HttpServletRequest request, - @Parameter(description = "The call id", required = false) @RequestParam(value = "callId", required = false) Long callId); + @Parameter(description = "The call id", required = false) @RequestParam(value = "callId", required = false) Long callId, + @Parameter(description = "The company id", required = false) @RequestParam(value = "companyId", required = false) Long companyId); @Operation(summary = "Api to delete application", responses = { @@ -93,9 +97,10 @@ public interface ApplicationApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "/call/{callId}", produces = { "application/json" }) - ResponseEntity> createApplicationByCallId(HttpServletRequest request, - @Parameter(description = " Flow request object", required = true) @Valid @RequestBody ApplicationRequest applicationRequest, - @Parameter(description = "The call ID", required = true) @PathVariable("callId") Long callId); + ResponseEntity> createApplicationByCallId(HttpServletRequest request, + @Parameter(description = "The company ID", required = true) @RequestParam(value = "companyId", required = true) Long companyId, + @Parameter(description = " Flow request object", required = true) @Valid @RequestBody ApplicationRequest applicationRequest, + @Parameter(description = "The call ID", required = true) @PathVariable("callId") Long callId); @@ -125,9 +130,61 @@ public interface ApplicationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{applicationId}/status", produces = { "application/json" }) - ResponseEntity> updateApplicationStatus(HttpServletRequest request, + ResponseEntity> updateApplicationStatus(HttpServletRequest request, @Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId, @Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationStatusTypeEnum status); + + @Operation(summary = "API to generate PDF for an application", + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/pdf")), + @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 = "/{applicationId}/download-pdf", + produces = { "application/pdf" }) + public ResponseEntity generateApplicationPdf( + HttpServletRequest request, + @Parameter(description = "The application id", required = true) + @PathVariable(value = "applicationId", required = true) Long applicationId); + + @Operation(summary = "Api to upload signed document (only p7m file format is supported)", 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 = "{applicationId}/signedDocument/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + ResponseEntity> uploadSignedDocument(HttpServletRequest request, + @Parameter(description = "The applicationId id", required = true) @PathVariable("applicationId") Long applicationId, + @Parameter(description = "The signed document", required = true) @RequestParam("file") MultipartFile file); + + + @Operation(summary = "Api to get signed document", 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 = "{applicationId}/signedDocument", produces = "application/json") + ResponseEntity> getSignedDocument(HttpServletRequest request, + @Parameter(description = "The applicationId id", required = true) @PathVariable("applicationId") Long applicationId); + + @Operation(summary = "Api to delete signed document", 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 = "{applicationId}/signedDocument", produces = "application/json") + ResponseEntity> deleteSignedDocument(HttpServletRequest request, + @Parameter(description = "The applicationId id", required = true) @PathVariable("applicationId") Long applicationId); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/BeneficiaryPreferredCallApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/BeneficiaryPreferredCallApi.java new file mode 100644 index 00000000..a320b6c4 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/BeneficiaryPreferredCallApi.java @@ -0,0 +1,102 @@ +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.responses.ApiResponse; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.enums.CallStatusEnum; +import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; + +import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; +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.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Validated +@RequestMapping("/v1/beneficiaryPreferredCall") +public interface BeneficiaryPreferredCallApi { + + @Operation(summary = "Create a new beneficiary preferred call", + responses = { + @ApiResponse(responseCode = "201", description = "Created"), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)})), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE)})), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)}))}) + @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity> createBeneficiaryPreferredCall(HttpServletRequest request, + @Parameter(required = true) + @Valid @RequestBody BeneficiaryPreferredCallReq beneficiaryPreferredCallReq); + + /* @Operation(summary = "Update an existing beneficiary preferred call", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)})), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)}))}) + @PutMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity> updateBeneficiaryPreferredCall(HttpServletRequest request, + @Parameter( required = true) + @PathVariable("id") Long id, + @Valid @RequestBody BeneficiaryPreferredCallReq beneficiaryPreferredCallReq); +*/ + @Operation(summary = "Get a beneficiary preferred call 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)}))}) + @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity> getBeneficiaryPreferredCallById(HttpServletRequest request, + @Parameter( required = true) + @PathVariable("id") Long id); + + @Operation(summary = "Delete a beneficiary preferred call", + 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)}))}) + @DeleteMapping(value = "/{id}") + ResponseEntity> deleteBeneficiaryPreferredCall(HttpServletRequest request, + @Parameter(required = true) + @PathVariable("id") Long id); + + @Operation(summary = "Update status of a beneficiary preferred call", + 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)}))}) + @PutMapping(value = "/{id}/status", produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity> updateBeneficiaryPreferredCallStatus(HttpServletRequest request, + @Parameter( required = true) + @PathVariable("id") Long id, + @Parameter(description = "New status for the preferred call", required = true) + @RequestParam(value = "status", required = true) BeneficiaryCallStatus status); + + @Operation(summary = "Get all beneficiary preferred calls", + 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)}))}) + @GetMapping(value = "/user", produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity>> getBeneficiaryPreferredCallByUserId( + HttpServletRequest request, + @RequestParam(value = "userId",required = false) Long userId, + @RequestParam(value = "beneficiaryId",required = false) Long beneficiaryId, + @RequestParam(value = "companyId",required = false) Long companyId + ); + + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java index cc7f985a..3fcfad5d 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java @@ -85,7 +85,7 @@ public interface CallApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/{callId}", produces = { "application/json" }) - ResponseEntity> getCallById( + ResponseEntity> getCallById(HttpServletRequest request, @Parameter(description = "The call ID", required = true) @PathVariable("callId") Long callId); @@ -134,4 +134,19 @@ public interface CallApi { public ResponseEntity> updateCallStatus(HttpServletRequest request, @Parameter(description = "The call id", required = true) @PathVariable("callId") Long callId, @Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) CallStatusEnum status); + + @Operation(summary = "Api to download call documents as a ZIP file", + 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 = "/{callId}/documents/zip") + ResponseEntity downloadCallDocumentsAsZip(HttpServletRequest httpServletRequest, + @Parameter(description = "The call ID", required = true) @PathVariable("callId") Long callId); + } 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 new file mode 100644 index 00000000..bc016334 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java @@ -0,0 +1,156 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import java.util.List; +import java.util.Map; + +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 org.springframework.web.multipart.MultipartFile; + +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.CompanyDelegationRequest; +import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; +import net.gepafin.tendermanagement.model.response.CompanyResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; + +public interface CompanyApi { + + @Operation(summary = "Api to create company", 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 = "", produces = { "application/json" }) + ResponseEntity> createCompany(HttpServletRequest request, + @Parameter(description = "Company request object", required = true) @RequestBody CompanyRequest companyRequest); + + @Operation(summary = "Api to update company", 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 = "/{companyId}", produces = { "application/json" }) + ResponseEntity> updateCompany(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId, + @Parameter(description = "Company request object", required = true) @RequestBody CompanyRequest companyRequest); + + @Operation(summary = "Api to delete company", 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 = "/{companyId}", produces = { "application/json" }) + ResponseEntity> deleteCompany(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); + + @Operation(summary = "Api to get company", 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 = "/{companyId}", produces = { "application/json" }) + ResponseEntity> getCompany(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); + + @Operation(summary = "Api to get company 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>> getCompanyByUserId(HttpServletRequest request, + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId); + + @Operation(summary = "Api to check vatNumber", 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 = "/vatNumber", produces = { "application/json" }) + 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 = { + @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 = "{companyId}/delegation/download", produces = { "application/json" }) + ResponseEntity downloadCompanyDelegation(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId, + @Parameter(description = "Company delegation request object", required = true) @RequestBody CompanyDelegationRequest companyDelegationRequest); + + @Operation(summary = "Api to upload company delegation (only p7m file format is supported)", 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 = "{companyId}/delegation/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + ResponseEntity> uploadCompanyDelegation(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId, + @Parameter(description = "The company delegation", required = true) @RequestParam("file") MultipartFile file); + + @Operation(summary = "Api to get company delegation", 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 = "{companyId}/delegation", produces = { "application/json" }) + ResponseEntity> getCompanyDelegation(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); + + @Operation(summary = "Api to delete company delegation", 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 = "{companyId}/delegation", produces = { "application/json" }) + ResponseEntity> deleteCompanyDelegation(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); + @Operation(summary = "Api to remove a company from user ", 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 = "user/{companyId}", produces = { "application/json" }) + ResponseEntity> removeCompanyFromList(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); + +} 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 new file mode 100644 index 00000000..753473f2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java @@ -0,0 +1,52 @@ +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.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; +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.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + +public interface DashboardApi { + + @Operation(summary = "Api to get dashboard widget for super admin", + 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 = "", + produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + ResponseEntity> getDashboardWidgetForSuperAdmin(HttpServletRequest request); + + @Operation(summary = "Api to get dashboard widget for beneficiary", + 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 = "/beneficiary/company/{companyId}", + produces = { "application/json" }) + ResponseEntity> getDashboardWidgetForBeneficiary(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId); + + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DocumentApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DocumentApi.java index 9c2cedcc..45a16c8f 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DocumentApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DocumentApi.java @@ -31,9 +31,13 @@ public interface DocumentApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))}) @PostMapping(value = "/uploadFile/source/{sourceId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - default ResponseEntity>> uploadFile(HttpServletRequest httpServletRequest, @Parameter(description = "Source Id", required = true) @PathVariable("sourceId") Long sourceId, @RequestParam DocumentSourceTypeEnum sourceType, @RequestParam("file") List files, @RequestParam("documentType") DocumentTypeEnum documentTypeEnum) { - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - } + default ResponseEntity>> uploadFile(HttpServletRequest httpServletRequest, + @Parameter(description = "Source Id", required = true) @PathVariable("sourceId") Long sourceId, + @RequestParam("sourceType") DocumentSourceTypeEnum sourceType, + @RequestParam("file") List files, + @RequestParam("documentType") DocumentTypeEnum documentTypeEnum) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } @Operation(summary = "API to delete a file by document id", responses = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/FaqApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/FaqApi.java index f44491a8..8fad8c06 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/FaqApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/FaqApi.java @@ -24,7 +24,7 @@ public interface FaqApi { }) @PostMapping(value = "/call/{callId}", consumes = "application/json", produces = "application/json") ResponseEntity> createFaq(HttpServletRequest request, @Parameter(description = "call id", required = true) - @PathVariable("callId") Long callId, @Valid @RequestBody FaqReq faqRequest); + @PathVariable("callId") Long callId, @RequestParam(value = "companyId", required = false) Long companyId, @Valid @RequestBody FaqReq faqRequest); @Operation(summary = "API to get FAQ by id", responses = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormApi.java index 04417439..99eb8835 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormApi.java @@ -49,6 +49,7 @@ public interface FormApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{formId}", produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") ResponseEntity> updateForm(HttpServletRequest request, @Parameter(description = "The form ID", required = true) @PathVariable("formId") Long formId, @Parameter(description = "form request object", required = true) @Valid @RequestBody FormRequest formRequest,@Parameter(description = "force delete flow ",required = true)@RequestParam(value = "forceDeleteFlow",required = true)Boolean forceDeleteFlow); @@ -78,6 +79,7 @@ public interface FormApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @DeleteMapping(value = "/{formId}") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") ResponseEntity> deleteForm(HttpServletRequest request, @Parameter(description = "The form ID", required = true) @PathVariable("formId") Long formId); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormFieldApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormFieldApi.java index 341b3fed..0aeecf0f 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormFieldApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/FormFieldApi.java @@ -13,6 +13,7 @@ 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.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -30,6 +31,7 @@ public interface FormFieldApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") public ResponseEntity> createFormField(HttpServletRequest request, @Parameter(description = "form field request object", required = true) @Valid @RequestBody FormFieldRequest formFieldRequest); @@ -46,6 +48,7 @@ public interface FormFieldApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{formFieldId}", produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") ResponseEntity> updateFormField(HttpServletRequest request, @Parameter(description = "The form field ID", required = true) @PathVariable("formFieldId") Long formFieldId, @Parameter(description = "form field request object", required = true) @Valid @RequestBody FormFieldRequest formFieldRequest); @@ -61,6 +64,7 @@ public interface FormFieldApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/{formFieldId}", produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") ResponseEntity> getFormFieldById(HttpServletRequest request, @Parameter(description = "The form field ID", required = true) @PathVariable("formFieldId") Long formFieldId); @@ -75,6 +79,7 @@ public interface FormFieldApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @DeleteMapping(value = "/{formFieldId}") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") ResponseEntity> deleteForm(HttpServletRequest request, @Parameter(description = "The form field ID", required = true) @PathVariable("formFieldId") Long formFieldId); @@ -89,6 +94,7 @@ public interface FormFieldApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "", produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") ResponseEntity>> getAllFormField(HttpServletRequest request); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/LoginAttemptApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/LoginAttemptApi.java new file mode 100644 index 00000000..379a1d05 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/LoginAttemptApi.java @@ -0,0 +1,60 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import io.swagger.v3.oas.annotations.Operation; +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 jakarta.validation.Valid; +import io.swagger.annotations.ApiParam; +import net.gepafin.tendermanagement.entities.LoginAttemptEntity; +import net.gepafin.tendermanagement.model.request.LoginAttemptReq; +import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.context.request.NativeWebRequest; + +import java.util.List; +import java.util.Optional; + +@Validated +public interface LoginAttemptApi { + + default Optional getRequest() { + return Optional.empty(); + } + + @Operation(summary = "Api to get list of login attempts", responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @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 = "/login-attempt", produces = {"application/json"}) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + default ResponseEntity>> getLoginAttemptsList( + @ApiParam(value = "page number") @RequestParam(name = "pageNo", required = false) Integer pageNo, + @ApiParam(value = "page limit") @RequestParam(name = "pageLimit", required = false) Integer pageLimit) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + + @Operation(summary = "Api to create a login attempt", responses = { + @ApiResponse(responseCode = "201", description = "Created"), + @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 = "/login-attempt", consumes = {"application/json"}) + default ResponseEntity> createLoginAttempt(@ApiParam(value = "login attempt request", required = true) @Valid @RequestBody LoginAttemptReq loginAttemptReq, HttpServletRequest request) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } +} 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 f567752d..bbd5859f 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 @@ -10,6 +10,7 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.*; +import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.Response; @@ -39,10 +40,11 @@ public interface UserApi { @RequestMapping(value = "", produces = {"application/json"}, method = RequestMethod.POST) - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") - default ResponseEntity> createUser( +// @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + default ResponseEntity> createUser(HttpServletRequest request, + @Parameter(description = "temp spid Token", required = false) @RequestParam(value = "tempToken", required = false) String tempToken, @Parameter(description = "User request object", required = true) @Validated @RequestBody UserReq userReq) { - return new ResponseEntity>(HttpStatus.NOT_IMPLEMENTED); + return new ResponseEntity>(HttpStatus.NOT_IMPLEMENTED); } @Operation(summary = "Api to update user", @@ -104,7 +106,7 @@ public interface UserApi { @RequestMapping(value = "/login", produces = {"application/json"}, method = RequestMethod.POST) - ResponseEntity> login( + ResponseEntity> login(HttpServletRequest request, @Parameter(description = "Login request object", required = true) @Valid @RequestBody LoginReq loginReq); @Operation(summary = "Api to initiate password reset request", responses = { @@ -142,8 +144,10 @@ public interface UserApi { @RequestMapping(value = "/change-password", produces = {"application/json"}, method = RequestMethod.POST) - ResponseEntity> changePassword( - @Parameter(description = "Change password request object", required = true) @Valid @RequestBody ChangePasswordRequest changePasswordRequest); @Operation(summary = "Api to logout user", + ResponseEntity> changePassword(HttpServletRequest request, + @Parameter(description = "Change password request object", required = true) @Valid @RequestBody ChangePasswordRequest changePasswordRequest); + + @Operation(summary = "Api to logout user", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @@ -176,6 +180,7 @@ public interface UserApi { @Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) UserStatusEnum status) { return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } + @Operation(summary = "Api to get valid user from token", responses = { @ApiResponse(responseCode = "200", description = "OK"), @@ -188,21 +193,7 @@ public interface UserApi { @GetMapping(value = "/me", produces = { "application/json" }) ResponseEntity> getValidUser(HttpServletRequest request); - @Operation(summary = "API to create user by hubId", - responses = { - @ApiResponse(responseCode = "200", description = "User created successfully"), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)})), - @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { - @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})) - }) - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") - @RequestMapping(value = "/hub/{hubId}", - produces = {"application/json"}, - method = RequestMethod.POST) - ResponseEntity> createUserByHubId( - @Parameter(description = "The hubId", required = true) @PathVariable("hubId") String hubId, - @Parameter(description = "User request object for hubId", required = true) @Valid @RequestBody UserReq userReq); + @Operation(summary = "Api to get user by hubId", responses = { @@ -218,6 +209,57 @@ public interface UserApi { method = RequestMethod.GET) ResponseEntity>> getUserByHubId( @Parameter(description = "The hubId", required = true) @PathVariable("hubId") String hubId); + + @Operation(summary = "Api to validate existing user from saml token", + 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 = "/sso/validate/existing-user/{token}", + produces = { "application/json" }) + ResponseEntity> validateExistingUserToken(HttpServletRequest request, + @Parameter(description = "The spid token", required = true) @PathVariable("token") String token); + + + @Operation(summary = "Api to validate new user from saml token", + 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 = "/sso/validate/new-user/{token}", + produces = { "application/json" }) + ResponseEntity> validateNewUserToken(HttpServletRequest request, + @Parameter(description = "The spid token", required = true) @PathVariable("token") String token); + + @Operation(summary = "Api to get all users", + 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)}))}) + @RequestMapping(value = "", produces = {"application/json"}, method = RequestMethod.GET) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + ResponseEntity>> getAllUsers( + @Parameter( required = false)@RequestParam(value ="roleId", required = false) Long roleId); + + + @RequestMapping("favicon.ico") + @ResponseBody + void returnNoFavicon(); + + + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientForbiddenException.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientForbiddenException.java new file mode 100644 index 00000000..bfabad15 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientForbiddenException.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +import org.springframework.http.HttpStatus; + +import feign.FeignException; + +public class FeignClientForbiddenException extends FeignException{ + + private static final long serialVersionUID = 1L; + + private final HttpStatus status; + + public FeignClientForbiddenException(HttpStatus status,String message) { + super(403,message); + this.status = status; + } + + public HttpStatus getStatus() { + return status; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientNotFoundException.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientNotFoundException.java new file mode 100644 index 00000000..c5896f5e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientNotFoundException.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +import org.springframework.http.HttpStatus; + +import feign.FeignException; + +public class FeignClientNotFoundException extends FeignException{ + + private static final long serialVersionUID = 1L; + + private final HttpStatus status; + + public FeignClientNotFoundException(HttpStatus status,String message) { + super(404,message); + this.status = status; + } + + public HttpStatus getStatus() { + return status; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientUnauthorizedException.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientUnauthorizedException.java new file mode 100644 index 00000000..9fe1092b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientUnauthorizedException.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +import org.springframework.http.HttpStatus; + +import feign.FeignException; + +public class FeignClientUnauthorizedException extends FeignException{ + + private static final long serialVersionUID = 1L; + + private final HttpStatus status; + + public FeignClientUnauthorizedException(HttpStatus status,String message) { + super(401,message); + this.status = status; + } + + public HttpStatus getStatus() { + return status; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientValidationException.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientValidationException.java new file mode 100644 index 00000000..f623faab --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/FeignClientValidationException.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +import org.springframework.http.HttpStatus; + +import feign.FeignException; + +public class FeignClientValidationException extends FeignException{ + + private static final long serialVersionUID = 1L; + + private final HttpStatus status; + + public FeignClientValidationException(HttpStatus status,String message) { + super(400,message); + this.status = status; + } + + public HttpStatus getStatus() { + return status; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java index 1118da03..fd7ba455 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java @@ -2,9 +2,11 @@ package net.gepafin.tendermanagement.web.rest.api.errors; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.util.Utils; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +16,9 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; + +import feign.FeignException; + import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authorization.AuthorizationDeniedException; @@ -122,4 +127,54 @@ public class GlobalExceptionHandler { } + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ExceptionHandler(FeignClientValidationException.class) + @ResponseBody + public Map handleFeignClientBadRequestException(final Throwable ex) { + log.error(ex.getMessage()); + log.error(ex.getLocalizedMessage(), ex); + String exceptionString = ex.getMessage().substring(ex.getMessage().indexOf("]: [") + 4, ex.getMessage().length() - 1); + return Utils.convertIntoJson(exceptionString); + } + + @ResponseStatus(value = HttpStatus.FORBIDDEN) + @ExceptionHandler(FeignClientForbiddenException.class) + @ResponseBody + public Map handleFeignClientForbiddenException(final Throwable ex) { + log.error(ex.getMessage()); + log.error(ex.getLocalizedMessage(), ex); + String exceptionString = ex.getMessage().substring(ex.getMessage().indexOf("]: [") + 4, ex.getMessage().length() - 1); + return Utils.convertIntoJson(exceptionString); + } + + @ResponseStatus(value = HttpStatus.UNAUTHORIZED) + @ExceptionHandler(FeignClientUnauthorizedException.class) + @ResponseBody + public Map handleFeignClientUnauthorizedException(final Throwable ex) { + log.error(ex.getMessage()); + log.error(ex.getLocalizedMessage(), ex); + String exceptionString = ex.getMessage().substring(ex.getMessage().indexOf("]: [") + 4, ex.getMessage().length() - 1); + return Utils.convertIntoJson(exceptionString); + } + + @ResponseStatus(value = HttpStatus.NOT_FOUND) + @ExceptionHandler(FeignClientNotFoundException.class) + @ResponseBody + public Map handleFeignClientNotFoundException(final Throwable ex) { + log.error(ex.getMessage()); + log.error(ex.getLocalizedMessage(), ex); + String exceptionString = ex.getMessage().substring(ex.getMessage().indexOf("]: [") + 4, ex.getMessage().length() - 1); + return Utils.convertIntoJson(exceptionString); + } + + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(FeignException.class) + @ResponseBody + public Map handleFeignException(final Throwable ex) { + log.error(ex.getMessage()); + log.error(ex.getLocalizedMessage(), ex); + String exceptionString = ex.getMessage().substring(ex.getMessage().indexOf("]: [") + 4, ex.getMessage().length() - 1); + return Utils.convertIntoJson(exceptionString); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java index 1d8b205b..f6e6d1e5 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java @@ -10,17 +10,22 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationResponse; import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse; import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.service.PdfService; import net.gepafin.tendermanagement.web.rest.api.ApplicationApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import org.slf4j.Logger; import java.util.List; @@ -35,17 +40,21 @@ public class ApplicationApiController implements ApplicationApi { @Autowired private ApplicationService applicationService; + @Autowired + private PdfService pdfService; + @Override - public ResponseEntity> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean,Long applicationId, Long formId) { - ApplicationResponseBean applicationResponseBean= applicationService.createApplication(request,applicationRequestBean,applicationId,formId); + public ResponseEntity> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long applicationId, Long formId) { + ApplicationResponseBean applicationResponseBean = applicationService.createApplication(request, applicationRequestBean, applicationId, formId); return ResponseEntity.status(HttpStatus.CREATED) - .body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); } + .body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); + } @Override public ResponseEntity> getApplicationByFormId(HttpServletRequest request - , Long applicationId,Long formId) { + , Long applicationId, Long formId) { log.info("Get Application by ID - Application ID: {}", applicationId); - ApplicationGetResponseBean application = applicationService.getApplicationByFormId(request,applicationId,formId); + ApplicationGetResponseBean application = applicationService.getApplicationByFormId(request, applicationId, formId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(application, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); } @@ -54,39 +63,83 @@ public class ApplicationApiController implements ApplicationApi { public ResponseEntity> deleteApplication(HttpServletRequest request, Long applicationId) { log.info("Delete Application - Application ID: {}", applicationId); - applicationService.deleteApplication(request,applicationId); + applicationService.deleteApplication(request, applicationId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG))); } @Override - public ResponseEntity> createApplicationByCallId(HttpServletRequest request, ApplicationRequest applicationRequest, Long callId) { - ApplicationResponse applicationResponseBean=applicationService.createApplication(request,applicationRequest,callId); + public ResponseEntity> createApplicationByCallId(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId) { + ApplicationResponse applicationResponseBean = applicationService.createApplication(request, companyId, applicationRequest, callId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); } + @Override - public ResponseEntity>> getAllApplications(HttpServletRequest request,Long callId) { - List applications = applicationService.getAllApplications(request,callId); + public ResponseEntity>> getAllApplications(HttpServletRequest request, Long callId, Long companyId) { + List applications = applicationService.getAllApplications(request, callId, companyId); log.info("Get All Applications"); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); } - + @Override - public ResponseEntity> getNextOrPreviousForm(HttpServletRequest request,Long applicationId, - Long formId, FormActionEnum action) { - NextOrPreviousFormResponse data = applicationService.getNextOrPreviousForm(request, applicationId, formId, action); - log.info("Get Next Or Previous Form "); + public ResponseEntity> getNextOrPreviousForm(HttpServletRequest request, Long applicationId, + Long formId, FormActionEnum action) { + NextOrPreviousFormResponse data = applicationService.getNextOrPreviousForm(request, applicationId, formId, action); + log.info("Get Next Or Previous Form "); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); } + + @Override + public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, + ApplicationStatusTypeEnum status) { + ApplicationResponse applicationResponse = applicationService.updateApplicationStatus(request, applicationId, status); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY))); + } + + @Override + public ResponseEntity generateApplicationPdf(HttpServletRequest request, Long applicationId) { + byte[] pdfBytes = pdfService.generatePdf(request, applicationId); + + // Prepare headers for downloading the PDF + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Disposition", "attachment; filename=bando-preview.pdf"); + + // Return the PDF as a response + return ResponseEntity.ok() + .headers(headers) + .contentType(MediaType.APPLICATION_PDF) + .body(pdfBytes); + } @Override - public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, - ApplicationStatusTypeEnum status) { - applicationService.updateApplicationStatus(request, applicationId, status); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + public ResponseEntity> uploadSignedDocument(HttpServletRequest request, + Long applicationId, MultipartFile file) { + log.info("upload signed document applicationId: {}", applicationId); + ApplicationSignedDocumentResponse response = applicationService.uploadSignedDocument(request, applicationId, file); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.SIGNED_DOCUMENT_FILE_UPLOAD_SUCCESS))); + } + + @Override + public ResponseEntity> getSignedDocument(HttpServletRequest request, + Long applicationId) { + ApplicationSignedDocumentResponse response = applicationService.getSignedDocument(request, applicationId); + log.info("get signed document applicationId: {}", applicationId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_SIGNED_DOCUMENT_FILE_SUCCESS))); } + + @Override + public ResponseEntity> deleteSignedDocument(HttpServletRequest request, + Long applicationId) { + applicationService.deleteSignedDocument(request, applicationId); + log.info("delete signed document applicationId: {}", applicationId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_SIGNED_DOCUMENT_FILE_SUCCESS))); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java new file mode 100644 index 00000000..d4e5b574 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java @@ -0,0 +1,78 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; + +import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.BeneficiaryPreferredCallService; +import net.gepafin.tendermanagement.web.rest.api.BeneficiaryPreferredCallApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class BeneficiaryPreferredCallApiController implements BeneficiaryPreferredCallApi { + + private final Logger log = LoggerFactory.getLogger(BeneficiaryPreferredCallApiController.class); + + @Autowired + private BeneficiaryPreferredCallService beneficiaryPreferredCallService; + + @Override + public ResponseEntity> createBeneficiaryPreferredCall(HttpServletRequest request, BeneficiaryPreferredCallReq beneficiaryPreferredCallReq) { + log.info("Creating Beneficiary Preferred Call"); + BeneficiaryPreferredCallResponseBean responseBean = beneficiaryPreferredCallService.createBeneficiaryPreferredCall(request, beneficiaryPreferredCallReq); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(responseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.BENEFICIARY_PREFERRED_CALL_CREATED_SUCCESS_MSG))); + } + +// @Override +// public ResponseEntity> updateBeneficiaryPreferredCall(HttpServletRequest request, Long id, BeneficiaryPreferredCallReq beneficiaryPreferredCallReq) { +// log.info("Updating Beneficiary Preferred Call - ID: {}", id); +// BeneficiaryPreferredCallResponseBean response = beneficiaryPreferredCallService.updateBeneficiaryPreferredCall(request, id, beneficiaryPreferredCallReq); +// return ResponseEntity.status(HttpStatus.OK) +// .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.BENEFICIARY_PREFERRED_CALL_UPDATED_SUCCESS_MSG))); +// } + + @Override + public ResponseEntity> getBeneficiaryPreferredCallById(HttpServletRequest request, Long id) { + log.info("Fetching Beneficiary Preferred Call by ID - ID: {}", id); + BeneficiaryPreferredCallResponseBean response = beneficiaryPreferredCallService.getBeneficiaryPreferredCallById(request, id); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_BENEFICIARY_PREFERRED_CALL_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> deleteBeneficiaryPreferredCall(HttpServletRequest request, Long id) { + log.info("Deleting Beneficiary Preferred Call - ID: {}", id); + beneficiaryPreferredCallService.deleteBeneficiaryPreferredCall(request, id); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_BENEFICIARY_PREFERRED_CALL_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> updateBeneficiaryPreferredCallStatus(HttpServletRequest request, Long id, BeneficiaryCallStatus status) { + log.info("Updating status of Beneficiary Preferred Call - ID: {}, Status: {}", id, status); + beneficiaryPreferredCallService.updateBeneficiaryPreferredCallStatus(request, id, status); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.BENEFICIARY_PREFERRED_CALL_STATUS_UPDATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity>> getBeneficiaryPreferredCallByUserId(HttpServletRequest request,Long userId,Long beneficiaryId,Long companyId) { + log.info("Fetching all Beneficiary Preferred Calls for User ID"); + List response = beneficiaryPreferredCallService.getBeneficiaryPreferredCallByUserId(request, userId,beneficiaryId,companyId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_ALL_BENEFICIARY_PREFERRED_CALLS_SUCCESS_MSG))); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index e4680428..b06380e4 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -4,7 +4,9 @@ import java.util.List; import net.gepafin.tendermanagement.enums.CallStatusEnum; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestMapping; @@ -57,8 +59,8 @@ public class CallApiController implements CallApi { } @Override @Transactional(readOnly = true) - public ResponseEntity> getCallById(Long callId) { - CallResponse createCallResponseBean = callService.getCallById(callId); + public ResponseEntity> getCallById(HttpServletRequest request, Long callId) { + CallResponse createCallResponseBean = callService.getCallById(request, callId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_FETCH_SUCCESS_MSG))); } @@ -74,7 +76,7 @@ public class CallApiController implements CallApi { } @Override public ResponseEntity> validateCallData(HttpServletRequest request, Long callId) { - CallResponse call = callService.validateCallData(callId); + CallResponse call = callService.validateCallData(request, callId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(call, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_FETCH_SUCCESS_MSG))); @@ -84,4 +86,22 @@ public class CallApiController implements CallApi { CallResponse updateCall = callService.updateCallStatus(request, callId, status); return ResponseEntity.ok(new Response<>(updateCall, Status.SUCCESS, Translator.toLocale(GepafinConstant.UPDATE_CALL_STATUS_SUCCESS_MSG))); } + @Override + public ResponseEntity downloadCallDocumentsAsZip(HttpServletRequest request, Long callId) { + byte[] zipFile = callService.downloadCallDocumentsAsZip(callId); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentDispositionFormData("attachment", "documents.zip"); + + if (zipFile == null || zipFile.length == 0) { + String notFoundMessage = Translator.toLocale(GepafinConstant.CALL_DOCUMENTS_NOT_FOUND_MSG); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(notFoundMessage.getBytes()); + } + + return new ResponseEntity<>(zipFile, headers, HttpStatus.OK); + } + + } \ No newline at end of file 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 new file mode 100644 index 00000000..55fd6cef --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java @@ -0,0 +1,139 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; +import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; +import net.gepafin.tendermanagement.model.response.CompanyResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.CompanyService; +import net.gepafin.tendermanagement.web.rest.api.CompanyApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/company}") +public class CompanyApiController implements CompanyApi{ + + private final Logger log = LoggerFactory.getLogger(CompanyApiController.class); + + @Autowired + private CompanyService companyService; + + @Override + public ResponseEntity> createCompany(HttpServletRequest request, + CompanyRequest companyRequest) { + log.info("Create company with - Request Body: {}", companyRequest); + CompanyResponse data = companyService.createCompany(request, companyRequest); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_CREATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> updateCompany(HttpServletRequest request, Long companyId, + CompanyRequest companyRequest) { + log.info("Update company with - Request Body: {}", companyRequest); + CompanyResponse data = companyService.updateCompany(request, companyId, companyRequest); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_UPDATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> getCompany(HttpServletRequest request, Long companyId) { + + log.info("Get company with id: {}", companyId); + CompanyResponse data = companyService.getCompany(request, companyId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_GET_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> deleteCompany(HttpServletRequest request, Long companyId) { + log.info("Delete company with id: {}", companyId); + companyService.deleteCompany(request, companyId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_DELETE_SUCCESS_MSG))); + } + + @Override + public ResponseEntity>> getCompanyByUserId(HttpServletRequest request, Long userId) { + + log.info("Get company with userId: {}", userId); + List data = companyService.getCompanyByUserId(request, userId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_GET_SUCCESS_MSG))); + } + + @Override + public ResponseEntity>> checkVatNumber(HttpServletRequest request, String vatNumber) { + log.info("check VatNumber with: {}", vatNumber); + Map data = companyService.checkVatNumber(request, vatNumber); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.CHECK_VATNUMBER_SUCCESS_MSG))); + } + + @Override + public ResponseEntity downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { + log.info("download company delegation with companyId: {}", companyId); + ByteArrayOutputStream data = companyService.downloadCompanyDelegation(request, companyId, companyDelegationRequest); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentDispositionFormData("attachment", "delegation-template.docx"); + + return new ResponseEntity<>(data.toByteArray(), headers, HttpStatus.OK); + } + + @Override + public ResponseEntity> uploadCompanyDelegation(HttpServletRequest request, Long companyId, + MultipartFile file) { + log.info("upload company delegation with companyId: {}", companyId); + CompanyDelegationResponse companyDelegationResponse = companyService.uploadCompanyDelegation(request, companyId, file); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(companyDelegationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_FILE_UPLOAD_SUCCESS))); + } + + @Override + public ResponseEntity> getCompanyDelegation(HttpServletRequest request, + Long companyId) { + log.info("get company delegation with companyId: {}", companyId); + CompanyDelegationResponse companyDelegationResponse = companyService.getCompanyDelegation(request, companyId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(companyDelegationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_FETCH_SUCCESS))); + } + @Override + public ResponseEntity> deleteCompanyDelegation(HttpServletRequest request, + Long companyId) { + log.info("delete company delegation with companyId: {}", companyId); + companyService.deleteCompanyDelegation(request, companyId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_DELETE_SUCCESS))); + } + @Override + public ResponseEntity> removeCompanyFromList(HttpServletRequest request, Long companyId) { + log.info("Api to remove a company from user's list"); + companyService.removeCompanyFromList(request, companyId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_DELETE_SUCCESS_MSG))); + } +} 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 71f60387..a11157ac 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 @@ -29,10 +29,13 @@ public class CustomUserDetailsService implements UserDetailsService { @Override @Transactional - public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException { - log.debug("Authenticating {}", email); + public UserDetails loadUserByUsername(final String emailWithHudId) throws UsernameNotFoundException { + log.debug("Authenticating {}", emailWithHudId); + String[] loginParts = emailWithHudId.split(":"); + String email = loginParts[0]; + String hubId = loginParts[1]; - UserEntity user = userRepository.findByEmailIgnoreCase(email) + UserEntity user = userRepository.findByEmailIgnoreCaseAndhubUniqueUuid(email, hubId) .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/DashboardApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java new file mode 100644 index 00000000..c46258a2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java @@ -0,0 +1,38 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.DashboardService; +import net.gepafin.tendermanagement.web.rest.api.DashboardApi; +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/dashboard}") +public class DashboardApiController implements DashboardApi { + + @Autowired + private DashboardService dashboardService; + + @Override + public ResponseEntity> getDashboardWidgetForSuperAdmin(HttpServletRequest request) { + SuperAdminWidgetResponseBean widgetResponseBean= dashboardService.getDashboardWidgetForSuperAdmin(request); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); } + + @Override + public ResponseEntity> getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId) { + BeneficiaryWidgetResponseBean widgetResponseBean= dashboardService.getDashboardWidgetForBeneficiary(request, companyId); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java index 142e5614..d905e938 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java @@ -22,8 +22,8 @@ public class FaqApiController implements FaqApi { private FaqService faqService; @Override - public ResponseEntity> createFaq(HttpServletRequest request, Long callId,FaqReq faqRequest) { - FaqResponseBean response = faqService.createFaq(request,callId, faqRequest); + public ResponseEntity> createFaq(HttpServletRequest request, Long callId, Long companyId, FaqReq faqRequest) { + FaqResponseBean response = faqService.createFaq(request,callId, companyId, faqRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_CREATED_SUCCESSFULLY))); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java new file mode 100644 index 00000000..ed3a048b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java @@ -0,0 +1,56 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.LoginAttemptEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.LoginAttemptReq; +import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.LoginAttemptService; +import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.Validator; +import net.gepafin.tendermanagement.web.rest.api.LoginAttemptApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/loginAttempt}") +public class LoginAttemptApiController implements LoginAttemptApi { + + public final Logger log = LoggerFactory.getLogger(LoginAttemptApiController.class); + @Autowired + Validator validator; + + @Autowired + private LoginAttemptService loginAttemptService; + + @Autowired + private UserService userService; + + @Override + public ResponseEntity>> getLoginAttemptsList(Integer pageNo, Integer pageLimit) { + LoginAttemptPageableResponseBean> response = loginAttemptService.getLoginAttemptsList(pageNo, pageLimit); + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + @Override + public ResponseEntity> createLoginAttempt(LoginAttemptReq loginAttemptReq, HttpServletRequest request) { + Map userInfo = validator.getUserInfoFromToken(request); + String userIdString = (String) userInfo.get("userId"); + UserEntity currentUser = userService.getUserEntityById(Long.parseLong(userIdString)); + loginAttemptReq.setUserName(currentUser.getEmail()); + loginAttemptService.createLoginAttempt(loginAttemptReq, request); + return ResponseEntity.status(HttpStatus.CREATED).body(new Response(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOGIN_ATTEMPTED_CREATED_SUCCESSFULLY))); + } +} 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 872ebb2f..497967f3 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 @@ -7,6 +7,7 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.*; +import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.Response; @@ -35,9 +36,9 @@ public class UserApiController implements UserApi { private UserService userService; @Override - public ResponseEntity> createUser(@RequestBody UserReq userReq) { + public ResponseEntity> createUser(HttpServletRequest request, String tempToken, @RequestBody UserReq userReq) { log.info("Create User with - Request Body: {}", userReq); - UserResponseBean createdUser = userService.createUser(userReq); + JWTToken createdUser = userService.createUser(request, tempToken, userReq); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG))); } @@ -71,16 +72,16 @@ public class UserApiController implements UserApi { } @Override - public ResponseEntity> login( + public ResponseEntity> login(HttpServletRequest request, @Valid @RequestBody LoginReq loginReq) { log.info("User login attempt "); - JWTToken jwtToken = userService.login(loginReq); + JWTToken jwtToken = userService.login(loginReq,request); return ResponseEntity.ok(new Response<>(jwtToken, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOGIN_SUCCESS_MSG))); } @Override - public ResponseEntity> changePassword(@Valid @RequestBody ChangePasswordRequest request) { + public ResponseEntity> changePassword(HttpServletRequest httpServletRequest, @Valid @RequestBody ChangePasswordRequest request) { log.info("Change Password attempt for email: {}", request.getEmail()); - userService.changePassword(request); + userService.changePassword(httpServletRequest, request); return ResponseEntity.ok(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.SUCCESS_PASSWORD_CHANGED))); } @Override @@ -126,15 +127,7 @@ public class UserApiController implements UserApi { .body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); } - @Override - public ResponseEntity> createUserByHubId( - @PathVariable("hubId") String hubId, - @Valid @RequestBody UserReq userReq) { - log.info("Create User by Hub ID - Hub ID: {}, Request Body: {}", hubId, userReq); - UserResponseBean createdUser = userService.createUserByHubId(hubId, userReq); - return ResponseEntity.status(HttpStatus.CREATED) - .body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG))); - } + @Override public ResponseEntity>> getUserByHubId(String hubId) { log.info("Get User by Hub ID - Hub ID: {}", hubId); @@ -142,4 +135,32 @@ public class UserApiController implements UserApi { return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); } + + @Override + public ResponseEntity> validateExistingUserToken(HttpServletRequest request, String token) { + log.info("User login attempt via spid token"); + JWTToken data = userService.validateExistingUserToken(request, token); + return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSE))); + } + + @Override + public ResponseEntity> validateNewUserToken(HttpServletRequest request, String token) { + log.info("User validating spid token"); + UserSamlResponse data = userService.validateNewUserToken(request,token); + return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSE))); + } + @Override + public ResponseEntity>> getAllUsers( + Long roleId) { + log.info("Get all Users by Role ID - Role ID: {}", roleId); + List users = userService.getAllUsers(roleId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(users, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USERS_SUCCESS_MSG))); + } + + @Override + public void returnNoFavicon() { + // Do nothing + } + } \ No newline at end of file diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 930cbd9f..5b6ca7a9 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -6,6 +6,6 @@ spring.datasource.driver-class-name=org.postgresql.Driver # JPA Configuration spring.h2.console.enabled=true -base-url=https://api-dev-gepafin.memento.credit isVatCheckGloballyDisabled = false +isMailSendingEnabled = true diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties new file mode 100644 index 00000000..91fb1979 --- /dev/null +++ b/src/main/resources/application-production.properties @@ -0,0 +1,17 @@ +# DataSource Configuration +spring.datasource.url=jdbc:postgresql://bandidb.gepafin.it:21543/gepaDb +spring.datasource.username=usergepa +spring.datasource.password=nRHMi7esdgHJiIm3L5ctrSJ0 +spring.datasource.driver-class-name=org.postgresql.Driver + +# JPA Configuration +spring.h2.console.enabled=true +base-url=https://bandi-api.gepafin.it + +isVatCheckGloballyDisabled = false +#fe.base.url=http://gepafin-production-fe.s3-website.eu-central-1.amazonaws.com +fe.base.url=https://bandi.gepafin.it +#SPID configuration +spid.ipd.base.url=https://login.regione.umbria.it +active.profile.folder=production +isMailSendingEnabled = true diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1e41a2e9..ca5b8b20 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,8 +1,8 @@ spring.application.name=tendermanagement # Multipart Configuration -spring.servlet.multipart.max-file-size=50MB -spring.servlet.multipart.max-request-size=50MB +spring.servlet.multipart.max-file-size=15MB +spring.servlet.multipart.max-request-size=15MB spring.profiles.active=testing @@ -31,15 +31,38 @@ aws.s3.region=eu-west-1 aws.s3.bucket.name=mementoresources aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/ aws.s3.url.folder=gepafin +aws.s3.url.folder.delegation=gepafin/delegation +aws.s3.url.folder.signed.document=gepafin/signed-document # JWT configuration # Ensure these values match your expectations security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key security.authentication.jwt.token-validity-in-seconds=86400 -base-url=https://api-dev-gepafin.memento.credit +# Default system base URLs +base-url=https://api-dev-gepafin.memento.credit +fe.base.url=https://bandi-staging.memento.credit spring.main.allow-circular-references=true isVatCheckGloballyDisabled = true vatCheckNewToken: 66026bd891a51044e90e08c4 +#SPID configuration +spid.ipd.base.url=https://federatest.umbriadigitale.it +active.profile.folder=dev + +# MailGun API Key +mailGun_apiKey= 398e3dea1911fe941af261906ec99362-07e2c238-8094421f +mailGun_user=comunicazione@paghiamoci.ai +mailGun_domainName=paghiamoci.ai +mailGun_base_url=https://api.eu.mailgun.net/ +# SendinBlue API key +apiKey=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 +#senderEmail=mailer@bflows.net +isMailSendingEnabled = false +default_System_Receiver_Email=antonio.manca@bflows.net +gepafin_email=bandi@pec.gepafin.it +rinaldo_email=rinaldo.bonazzo@bflows.net +carlo_email=carlo.mancosu@bflows.net +default.hub.uuid=o2vf1aaz2MDrpMaHUTaUu + diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 00000000..1968a28e --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,6 @@ + ____ __ _ + / ___| ___ _ __ __ _ / _(_)_ __ + | | _ / _ \ '_ \ / _` | |_| | '_ \ + | |_| | __/ |_) | (_| | _| | | | | + \____|\___| .__/ \__,_|_| |_|_| |_| + |_| \ 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 14399deb..5b779bd7 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 @@ -539,7 +539,7 @@ - + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; @@ -696,7 +696,7 @@ path="classpath:db/dump/inserted_form_field_data_13_09_2024.sql" /> - + @@ -710,29 +710,43 @@ + + + + CREATE OR REPLACE FUNCTION gepafin_schema.clock_timestamp_updated_date_column() + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ + BEGIN + NEW.updated_date = clock_timestamp(); + RETURN NEW; + END; + $$; + + + + CREATE OR REPLACE FUNCTION gepafin_schema.clock_timestamp_created_date_column() + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ + BEGIN + IF NEW.created_date IS NULL THEN + NEW.created_date = clock_timestamp(); + END IF; + NEW.updated_date = NEW.created_date; + RETURN NEW; + END; + $$; + + - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -769,17 +783,241 @@ - - - - + + + + + id = 13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -788,5 +1026,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name='table' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.xml b/src/main/resources/db/changelog/db.changelog-master.xml index f44695c7..bf4c4536 100644 --- a/src/main/resources/db/changelog/db.changelog-master.xml +++ b/src/main/resources/db/changelog/db.changelog-master.xml @@ -5,4 +5,5 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.23.xsd"> + diff --git a/src/main/resources/db/changelog/dynamic-triggers.xml b/src/main/resources/db/changelog/dynamic-triggers.xml new file mode 100644 index 00000000..23f1101e --- /dev/null +++ b/src/main/resources/db/changelog/dynamic-triggers.xml @@ -0,0 +1,51 @@ + + + + + DO $$ + DECLARE + r RECORD; + BEGIN + -- Loop through all tables in the schema that have the 'updated_date' column + FOR r IN ( + SELECT table_name + FROM information_schema.columns + WHERE column_name = 'updated_date' + AND table_schema = 'gepafin_schema' + ) + LOOP + EXECUTE format( + 'CREATE OR REPLACE TRIGGER tg_gepafin_schema_updated_at_%I + BEFORE UPDATE ON gepafin_schema.%I + FOR EACH ROW + EXECUTE FUNCTION gepafin_schema.clock_timestamp_updated_date_column()', + r.table_name, r.table_name + ); + END LOOP; + + -- Loop through all tables in the schema that have the 'created_date' column + FOR r IN ( + SELECT table_name + FROM information_schema.columns + WHERE column_name = 'created_date' + AND table_schema = 'gepafin_schema' + ) + LOOP + EXECUTE format( + 'CREATE OR REPLACE TRIGGER tg_gepafin_schema_created_at_%I + BEFORE INSERT ON gepafin_schema.%I + FOR EACH ROW + EXECUTE FUNCTION gepafin_schema.clock_timestamp_created_date_column()', + r.table_name, r.table_name + ); + END LOOP; + END; + $$ LANGUAGE plpgsql; + + + diff --git a/src/main/resources/db/dump/insert_system_email_template_for_application_submission.sql b/src/main/resources/db/dump/insert_system_email_template_for_application_submission.sql new file mode 100644 index 00000000..acd205bd --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_for_application_submission.sql @@ -0,0 +1,34 @@ +INSERT INTO gepafin_schema.system_email_template (id, template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date) VALUES(1, 'Application submission template to beneficiary and company', 'APPLICATION_SUBMISSION_TO_USER_AND_COMPANY', ' + +
+

Buongiorno,

+

+ Si comunica che, in riferimento alla domanda di concessione di + Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all''oggetto, la stessa è stata + regolarmente acquisita ed è stata registrata con Protocollo n. + {{protocol_number}} del {{date}} alle + {{time}}. +

+

Distinti Saluti,

+

+ Gepafin S.p.a. +

+
+ +', 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', NULL, true, false, '2024-10-10 16:10:31.035', '2024-10-11 10:09:23.037'); +INSERT INTO gepafin_schema.system_email_template (id, template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date) VALUES(2, 'Application submission template to gepafin', 'APPLICATION_SUBMISSION_TO_GEPAFIN', ' + +
+

+ In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all’oggetto, la stessa è stata regolarmente acquisita ed è stata + registrata con Protocollo n. {{protocol_number}} del {{date}} e {{time}}. +

+

Distinti Saluti,

+

+ Gepafin S.p.a. +

+
+ +', 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', NULL, true, false, '2024-10-10 16:10:31.035', '2024-10-11 10:09:57.224'); \ No newline at end of file diff --git a/src/main/resources/db/dump/update_system_email_template_of_application_submission.sql b/src/main/resources/db/dump/update_system_email_template_of_application_submission.sql new file mode 100644 index 00000000..5379233a --- /dev/null +++ b/src/main/resources/db/dump/update_system_email_template_of_application_submission.sql @@ -0,0 +1,19 @@ + +UPDATE gepafin_schema.system_email_template +SET html_content = ' + +
+

+ In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all’oggetto, la stessa è stata regolarmente acquisita ed è stata + registrata con Protocollo n. {{protocol_number}} del {{date}} alle {{time}}. +

+

Distinti Saluti,

+

+ Gepafin S.p.a. +

+
+ +', +updated_date = '2024-10-14 10:00:00' +WHERE type = 'APPLICATION_SUBMISSION_TO_GEPAFIN'; diff --git a/src/main/resources/db/dump/updated_form_field_data_03-10-2024.sql b/src/main/resources/db/dump/updated_form_field_data_03-10-2024.sql new file mode 100644 index 00000000..21a5d11f --- /dev/null +++ b/src/main/resources/db/dump/updated_form_field_data_03-10-2024.sql @@ -0,0 +1,99 @@ +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, "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, "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, "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"}]', + '{"isRequired": false, "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,"custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(8, 'switch', 'Casella di Spunta', 'Per selezioni binarie, accettazioni, conferme', + '[{"name": "label", "value": "Casella di Spunta"}]', + '{"isRequired": false, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(9, 'datepicker', 'Data', 'Selezione di data', + '[{"name": "label", "value": "Data"}]', + '{"isRequired": false, "custom": null}', + 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, "custom": null}', + 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, 'numberinput', '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); diff --git a/src/main/resources/db/dump/updated_form_field_data_03-10-2024_1.sql b/src/main/resources/db/dump/updated_form_field_data_03-10-2024_1.sql new file mode 100644 index 00000000..697903cc --- /dev/null +++ b/src/main/resources/db/dump/updated_form_field_data_03-10-2024_1.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"}]', + '{"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); diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 78c02cbf..4d1f6a2b 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -8,6 +8,9 @@ delete_user_error_msg=An error occurred while deleting the user. get_user_success_msg=User retrieved successfully. get_user_error_msg=An error occurred while retrieving the user. user.not.active=User is not active. Please contact support. +user.already.exist.msg=User already exist for this codice fiscale. +validate.email=The email is mandatory and must be in the correct format. Please verify and try again. +validate.password=The password and confPassword are mandatory. Please verify and try again. # Role-related messages role.created.success=Role created successfully. role.updated.success=Role updated successfully. @@ -17,6 +20,7 @@ create.role.error=Error occurred while creating the role. update.role.error=Error occurred while updating the role. role.fetch.success=Role fetched successfully. delete.role.error=Error occurred while deleting the role. +role.id.mandatory=Role id is mandatory. # Region-related messages region.created.success=Region created successfully. @@ -184,6 +188,71 @@ valid.vat.number=The VAT number is not valid for field {0}. failed.retain.field=Failed to retain specific fields. application.is.incomplete = The application is incomplete. +token.validate.success=Token validated successfully. +invalid.request=Invalid Request. +codice.fiscale.exists=This codice fiscale is already associated with another user. +total.steps.not.zero=Total steps cannot be zero. +completed.steps.not.valid=Completed steps should be between 0 and total steps. +field.id.not.found=Field ID {0} does not exist in the form structure. +company.created.success=Company created successfully. +company.updated.success=Company updated successfully. +company.delete.success=Company deleted successfully. +company.get.success=Company retrieved successfully. +company.not.found=Company not found. +check.vatnumber.success=VAT number checked successfully. +invalid.vatnumber=Invalid VAT number. +vatnumber.mandatory=VatNumber is mandatory. +vatnumber.already.exists=VatNumber already exists. +invalid.email=Invalid email. +company.id.mandatory=Company id is mandatory. +user.already.connected.to.company=The user is already connected to this company. +validation.error.missing.firstName=First name is required. +validation.error.missing.lastName=Last name is required. +validation.error.missing.codiceFiscale=Codice Fiscale is required. +delegation.file.upload.success=Delegation file uploaded successfully. +delegation.fetch.success=Delegation fetched successfully. +delegation.template.generation.error=Something went wrong while generating the delegation template. +validation.error.file.empty=The uploaded file is empty. +validation.error.file.invalidType=Only .p7m files are accepted. +upload.error.s3=Failed to upload the file to S3. + +call.not.started.yet = The call has not started yet. Please wait until the specified start date and time. +call.already.ended = The call has already ended. You cannot submit the application after the deadline. +status.updated.successfully=Status updated successfully. +application.status.updated.successfully = Application status updated successfully. +application.already.in.provided.status=Application is already in provided status. +delegation.not.found=Delegation not found. +user.company.relation.not.found=User with the specified company relation not found. +delegation.delete.success=Delegation deleted successfully. +user.not.authorized.create.application=User must be a legal representative or have delegation. +application.submitted.cannot.change=The submitted application cannot be changed. +# Call Document Messages +call.documents.fetch.success=Documents fetched successfully. +call.documents.not.found=No documents found for the specified call. +# Beneficiary Preferred Call messages +beneficiary.preferred.call.status.updated.success=Beneficiary preferred call status updated successfully. +beneficiary.preferred.calls.get.all.success=All beneficiary preferred calls fetched successfully. +beneficiary.preferred.call.created.success=Beneficiary preferred call created successfully. +beneficiary.preferred.call.get.success=Beneficiary preferred call retrieved successfully. +beneficiary.preferred.call.delete.success=Beneficiary preferred call deleted successfully. +beneficiary.preferred.calls.get.success=All beneficiary preferred calls retrieved successfully. +beneficiary.preferred.call.updated.success=Beneficiary preferred call updated successfully. +beneficiary.preferred.call.not.found=Beneficiary preferred call not found. +either.user.or.beneficiary.id.required = User ID or Beneficiary ID not present. +userId.and.beneficiaryId.error = Both userId and beneficiaryId cannot be provided at the same time. +User.not.found.with.the.given.beneficiaryID=User not found with the given beneficiary ID. +permission.denied=You are not authorized to access this data. +signed.document.file.upload.success=Signed document file uploaded successfully. +get.signed.document.file.success=Signed document file retrieved successfully. +application.signed.document.not.found=Signed document for the application not found. +delete.signed.document.file.success=Signed document deleted successfully. + +dashboard.widget.fetched.successfully=Dasboard widget fetched sucessfully. +login_attempt_successfully_created = Login attempt successfully created. +get_login_attempt_se_msg=Login attempts fetched successfully. +application.in.submit.status.cannot.delete.company=The company cannot be deleted because there are active applications in the SUBMITTED status. +get.users.success.msg = Successfully fetched users. +cannot.create.beneficiary.user = Creation of a Beneficiary user is not allowed. Please assign the appropriate role. # Hub Messages hub_create_success=Hub created successfully @@ -193,3 +262,5 @@ hub_get_all_success=Hubs retrieved successfully hub_delete_success=Hub deleted successfully hub_not_found=Hub not found + + diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index b081ffaf..0e28be72 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -8,6 +8,9 @@ delete_user_error_msg=Si � verificato un errore durante l'eliminazione dell'ut get_user_success_msg=Utente recuperato con successo. get_user_error_msg=Si � verificato un errore durante il recupero dell'utente. user.not.active=Utente non attivo. Si prega di contattare il supporto. +user.already.exist.msg=L'utente esiste gi� per questo codice fiscale. +validate.email=L'email � obbligatoria e deve essere nel formato corretto. Si prega di verificare e riprovare. +validate.password=La password e confPassword sono obbligatorie. Verifica e riprova. # Role-related messages role.created.success=Ruolo creato con successo. role.updated.success=Ruolo aggiornato con successo. @@ -17,6 +20,7 @@ create.role.error=Errore durante la creazione del ruolo. update.role.error=Errore durante l'aggiornamento del ruolo. role.fetch.success=Ruolo recuperato con successo. delete.role.error=Errore durante l'eliminazione del ruolo. +role.id.mandatory=L'ID del ruolo � obbligatorio. # Region-related messages region.created.success=Regione creata con successo. @@ -176,10 +180,81 @@ validation.marca.da.bollo=Il campo {0} deve essere una Marca Da Bollo valida con validation.piva=Il numero di partita IVA per {0} deve essere lungo fino a 11 cifre. valid.vat.number=Il numero di partita IVA non � valido per il campo {0}. failed.retain.field=Impossibile conservare campi specifici. +token.validate.success=Token convalidato con successo. +invalid.request=Richiesta non valida. +codice.fiscale.exists=Questo codice fiscale � gi� associato ad un altro utente. + +total.steps.not.zero=Il totale dei passaggi non pu� essere zero. +completed.steps.not.valid=I passaggi completati devono essere compresi tra 0 e il totale dei passaggi. +field.id.not.found=L'ID campo {0} non esiste nella struttura del modulo. +company.created.success=Azienda creata con successo. +company.updated.success=Azienda aggiornata con successo. +company.delete.success=Azienda eliminata con successo. +company.get.success=Azienda recuperata con successo. +company.not.found=Azienda non trovata. +check.vatnumber.success=Numero di partita IVA verificato con successo. +invalid.vatnumber=Numero di partita IVA non valido. +vatnumber.mandatory=Il numero di partita IVA � obbligatorio. +vatnumber.already.exists=Il numero di partita IVA esiste gi�. +invalid.email=Email non valida. +company.id.mandatory=L'ID dell'azienda � obbligatorio. +user.already.connected.to.company=L'utente � gi� collegato a questa azienda. +validation.error.missing.firstName=Il nome � obbligatorio. +validation.error.missing.lastName=Il cognome � obbligatorio. +validation.error.missing.codiceFiscale=Il Codice Fiscale � obbligatorio. +delegation.file.upload.success=File di delega caricato con successo. +delegation.fetch.success=Delega recuperata con successo. +delegation.template.generation.error=Si � verificato un errore durante la generazione del modello di delega. +validation.error.file.empty=Il file caricato � vuoto. +validation.error.file.invalidType=Sono accettati solo file .p7m. +upload.error.s3=Impossibile caricare il file su S3. + +company.id.mandatory=L'ID dell'azienda � obbligatorio. +user.already.connected.to.company=L'utente � gi� collegato a questa azienda. +call.not.started.yet = La chiamata non � ancora iniziata. Attendere fino alla data e all'ora di inizio specificate. +call.already.ended = La chiamata � gi� terminata. Non � possibile inviare l'applicazione dopo la scadenza. +status.updated.successfully=Stato aggiornato con successo. +application.status.updated.successfully = Stato dell'applicazione aggiornato con successo. +application.already.in.provided.status=L'applicazione � gi� nello stato fornito. +delegation.not.found=Delega non trovata. +user.company.relation.not.found=Relazione utente con l'azienda specificata non trovata. +delegation.delete.success=Delega eliminata con successo. +user.not.authorized.create.application=L'utente deve essere un rappresentante legale o avere una delega. +application.submitted.cannot.change=La domanda inviata non pu� essere modificata. + +# Call Document Messages +call.documents.fetch.success=Documenti recuperati con successo. +call.documents.not.found=Nessun documento trovato per la chiamata specificata. +# Beneficiary Preferred Call messages +beneficiary.preferred.call.status.updated.success=Lo stato della chiamata preferita del beneficiario � stato aggiornato con successo. +beneficiary.preferred.calls.get.all.success=Tutte le chiamate preferite del beneficiario sono state recuperate con successo. +beneficiary.preferred.call.created.success=Chiamata preferita del beneficiario creata con successo. +beneficiary.preferred.call.get.success=Chiamata preferita del beneficiario recuperata con successo. +beneficiary.preferred.call.delete.success=Chiamata preferita del beneficiario eliminata con successo. +beneficiary.preferred.calls.get.success=Tutte le chiamate preferite del beneficiario recuperate con successo. +beneficiary.preferred.call.updated.success=Chiamata preferita del beneficiario aggiornata con successo. +beneficiary.preferred.call.not.found=Chiamata preferita del beneficiario non trovata. +either.user.or.beneficiary.id.required = ID utente o ID beneficiario non presente. +userId.and.beneficiaryId.error = Non � possibile fornire contemporaneamente sia userId che beneficiaryId. +User.not.found.with.the.given.beneficiaryID=Utente non trovato con l'ID beneficiario fornito. +permission.denied=Non sei autorizzato ad accedere a questi dati. +signed.document.file.upload.success=File del documento firmato caricato con successo. +get.signed.document.file.success=File del documento firmato recuperato con successo. +application.signed.document.not.found=Documento firmato per l'applicazione non trovato. +delete.signed.document.file.success=Documento firmato eliminato con successo. + +dashboard.widget.fetched.successfully=Widget dashboard recuperato correttamente. +login_attempt_successfully_created= Tentativo di login creato con successo. +get_login_attempt_se_msg=Lista dei tentativi di accesso recuperata correttamente. +application.in.submit.status.cannot.delete.company=Non � possibile eliminare l'azienda perch� ci sono domande attive con stato SUBMITTED. + +get.users.success.msg = Utenti recuperati con successo +cannot.create.beneficiary.user = La creazione di un utente beneficiario non � consentita. Si prega di assegnare il ruolo appropriato. + # Hub Messages hub_create_success=Hub creato con successo hub_update_success=Hub aggiornato con successo hub_get_success=Hub recuperato con successo hub_get_all_success=Hub recuperati con successo hub_delete_success=Hub eliminato con successo -hub_not_found=Hub non trovato +hub_not_found=Hub non trovato \ No newline at end of file diff --git a/src/main/resources/production/saml/idp-certificate.pem b/src/main/resources/production/saml/idp-certificate.pem new file mode 100644 index 00000000..dd9e7b96 --- /dev/null +++ b/src/main/resources/production/saml/idp-certificate.pem @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +MIIHBzCCBe+gAwIBAgIQBa/5uQoACfZc0a+0cFPKaDANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8w LQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFNlcnZlciBDQTAeFw0xNDAyMDMw MDAwMDBaFw0xNzAyMDcxMjAwMDBaMIGRMQswCQYDVQQGEwJJVDEOMAwGA1UECBMFSXRhbHkxEDAO BgNVBAcTB1BlcnVnaWExFzAVBgNVBAoTDlJlZ2lvbmUgVW1icmlhMSkwJwYDVQQLEyBTZXJ2aXpp byBJbmZyYXN0cnV0dHVyZSBEaWdpdGFsaTEcMBoGA1UEAwwTKi5yZWdpb25lLnVtYnJpYS5pdDCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALx+hg0/SsF+kpakHw24sO8LFawtMiILsEKS jLbqU8LjUcvDj50CVDa/jz21OwdBfCEB6SBVEKp0a61x5RZFKBUnL795y7Na56VWzqA0kyLg7QNn 73Tu0SJPRF0Hm+2ePLLypU+TkIFfC85GO5iXn82E5rb6XRA8blLj/GauQ0DSHkY3ZTQGGzN3La9a ZJ1Tl80cIATY10iuwQdVkLXRx8VriVrS4jVJOOl8vGJ4VWLVwGYUkhmwvoR/zfeNkSQe7USjHmdf Zm4lLMYZjLM0S2wJMRQbj3MscVBKaXMHc6POqMlKrgO1nRK4/1dRYtnJeMCK/uK/ms/MYpxIX2ZG G/MCAwEAAaOCA3kwggN1MB8GA1UdIwQYMBaAFFFo/5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQW BBShweIeUSOk3EJgXqB9164xrkURDDAxBgNVHREEKjAoghMqLnJlZ2lvbmUudW1icmlhLml0ghFy ZWdpb25lLnVtYnJpYS5pdDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG AQUFBwMCMHUGA1UdHwRuMGwwNKAyoDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWhh LXNlcnZlci1nMS5jcmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWhhLXNl cnZlci1nMS5jcmwwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwBATCCAaQwOgYIKwYBBQUH AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggr BgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABp AGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMA ZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAg AHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAA dwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBl ACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUA cgBlAG4AYwBlAC4wgYMGCCsGAQUFBwEBBHcwdTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlM aWNlcnQuY29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl cnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEB CwUAA4IBAQBPWrp7uoj9qX8h+7iGwyNOB7274/GDQZSqnk52FTQ3Qi8AzM7YV/tNDZG2j1Ran7vG /q214cqsv/gtyxSBfRR4/WgGCIylw5uZv35FsEC0lyAyPJGLKsZSMALqKkeBGQlzsmkNo7TyZgQV XMzoeuQz2mocC+ShpQjn4Uug/FptmbnYKCiKFShc0IAwAj5+U3kPmOhskml2tj+BTXDKpq4m9onY C8eN928I7tkJPvCYGDwdsBkf3EHyM/AUB4oZ/zcnT/8F7SoRfexmD9Eojslzs+hEMKkKg7M/UxJt ySAVQF/BznGvWiWfZtHrtvBCKgXsvUJ3h/7M/SqtRQnpNZ0C +-----END CERTIFICATE----- diff --git a/src/main/resources/production/saml/private-key.pem b/src/main/resources/production/saml/private-key.pem new file mode 100644 index 00000000..12869e56 --- /dev/null +++ b/src/main/resources/production/saml/private-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCKHE1L4E95N6jG +4bED1vd7c5ZMry6J0qIqojpHAzG1YIEtfL28twxBfN9voNhFL9TD6dGsfWDwYaa7 +LXyMAHLRi7pI+sH852d7sq3xRd1ynKDmt+cU+6kMlDtUPulkbzeU9Z0lGFuS9qJw +CdjYliCuwUxwJsU3tVHTHlV8nAz5RaXw31Gl6u11QpgxLPeFP5AUWHzfduTA2Wr0 +5ePtx5iuMj1oIMv0o50DJaqGmCKtQAtGZMGSKIrtXhLerUAfEteH6M+6POzoKg0F +ZyfLEiuqAE1Ymt16P5PLfTPjRHz4XRBCcd6a+iAAvIpG0yQE9dS7PfNtY1akk51J +La150Ef1AgMBAAECggEAIH3MCX+58rCPekp6VIbsLhThVSUZc78j+5ey0iYEOcF8 +YnEoSg9eSMHR5vcWKiC4k2act1G/zo2KphprZJxuZrHSn3yuyoq+I7HDjjF7iY0j +pWO6b4tNF/J/irBKRCCOGPM3hxSV5pszV9xZMYsQIUzEaNYWK6bymxJV1jz4KGRL +w3nPIpeu8MwMZwOzQwz980bZ2vbr67Ft3GmsflKzM5SesmsW8ZyaYbVfHExvfQxV +nsf9ya0PLQqE9Gi81xY1sVkL3V+niU+AXYZ3w/neuXPz6eaJrxlu4hFdJifWlrQV +vW7mgfOmUuR/bEXr/1c95nZQykobrMqHCRVPpfesQQKBgQDCBrlYKD1XJXfXENnG +32O3TksbxVtL0Eyw1lstp20j6txetHn3F/rx/SFy70J02r2jdFHeP/V1iLrEJ81/ +5QVpsA+Au5Oxwdfee/izUFqhXwSpgvtLoVypBUNcglw/qi2tCKrL10nb0i+bocoD +PGaTIECJ0MWUxTX3SrzqC8XX2QKBgQC2OWw7gGu12eutQBHujTbaZXhjwv2QEBup +UZcVYeVn8KrPrK5621aLgQXUq5Db7GoelB09SXOoqy04WZkYy5XeF+ULRtz0M5ZD +cNgAaQXuuZZdxKWFVXbK1iliGJjcMkd9PEpx5BjM49Gq2r5n3FS5KK9A44iSPMbB +IZoYWsIbfQKBgQCeME08itI4Etw6BAsKEWeDM9oYsjdVAGcGZj3AYxigiANTU2F9 +C5gVY4O56UgNbanfch6tTQga43ciJjFtbJOVL230TvqDmr8dLYX+7Cx4FLgAXEH1 +z4F0bE4XRlFftqe2w7I8rzIQfrVB9g51xPD8UvdLZWMxf/gXvl93klGjQQKBgQCw +JWv5TJdR73jBPZjX50up68JndRrUwq1qjAMm2T3/roX/QCZdfl73dV4kiT/7R1oB +ex2Um8cguW959Cpo7ItPZ/uxXevCZ4eOY6t5IgxpCp9OvwNdkxLE2iagu7Qvzq6K +Ydh4pYxPqr2HkfHSxgpj/e8DI69l5TgfgxLJDhpqpQKBgAgSgck834l8lNZwVPa8 ++Vi9nOtoWy7pyf8pv7sDEKcVkTmUU6+53eZoccW8AUu6ilL1PtrQ7cNPTJcUom80 +IVyJsVTQjDy17mj1DU8Fw15pjFWE4zRfQo9vondblJaxs9aIIG/6x9vDQVjN0hwe +jTOz1k3Du8fEEpKQMgn97J/+ +-----END PRIVATE KEY----- diff --git a/src/main/resources/production/saml/public-cert.pem b/src/main/resources/production/saml/public-cert.pem new file mode 100644 index 00000000..55254d2d --- /dev/null +++ b/src/main/resources/production/saml/public-cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7TCCAtWgAwIBAgIUQ2G093CKO3nbHlyw68f5998BIjkwDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIDAVJdGFseTEQMA4GA1UEBwwHUGVy +dWdpYTEQMA4GA1UECgwHR2VwYWZpbjELMAkGA1UECwwCSVQxEDAOBgNVBAMMB0dl +cGFmaW4xIzAhBgkqhkiG9w0BCQEWFGMubW9yZXR0aUBnZXBhZmluLml0MB4XDTI0 +MTAwMTA5MjIwMloXDTI1MTAwMTA5MjIwMlowgYUxCzAJBgNVBAYTAklUMQ4wDAYD +VQQIDAVJdGFseTEQMA4GA1UEBwwHUGVydWdpYTEQMA4GA1UECgwHR2VwYWZpbjEL +MAkGA1UECwwCSVQxEDAOBgNVBAMMB0dlcGFmaW4xIzAhBgkqhkiG9w0BCQEWFGMu +bW9yZXR0aUBnZXBhZmluLml0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAihxNS+BPeTeoxuGxA9b3e3OWTK8uidKiKqI6RwMxtWCBLXy9vLcMQXzfb6DY +RS/Uw+nRrH1g8GGmuy18jABy0Yu6SPrB/Odne7Kt8UXdcpyg5rfnFPupDJQ7VD7p +ZG83lPWdJRhbkvaicAnY2JYgrsFMcCbFN7VR0x5VfJwM+UWl8N9RpertdUKYMSz3 +hT+QFFh833bkwNlq9OXj7ceYrjI9aCDL9KOdAyWqhpgirUALRmTBkiiK7V4S3q1A +HxLXh+jPujzs6CoNBWcnyxIrqgBNWJrdej+Ty30z40R8+F0QQnHemvogALyKRtMk +BPXUuz3zbWNWpJOdSS2tedBH9QIDAQABo1MwUTAdBgNVHQ4EFgQUQ+GP6sby5ZQX +KTgq0/MsCWfdcHcwHwYDVR0jBBgwFoAUQ+GP6sby5ZQXKTgq0/MsCWfdcHcwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAWnzvIOhK4Z/GQA2H0jb+ +tkpPiwXucybEEOwQyb6+ErNGLjM7aj/HXJv70zibchmuPN5yd6C9dmrlajf/qLFz +T+Dfy6zl3r0mNErcT/bgaJzVA87u0z2/DRP77XqwV23zDGK56bp8G2C1nZGq6x2k +zswESJYBquXtBWNEJnreDKOLic9AucSyf8T0C9aeWhC8L0Hz4Bd825J2n54L4YZD +ShkCDSdCOZVdaZNikRv+KyD1SI6HM3KeUNNknW6z7g2jb5PG4dn5U9+lpzOsfoYD +QEBrNG8qFZ7k9DYzh8l1dTo9izSNmudaiyjhgFw+5DZ0pcrhti6h3hnPPysSA8q/ +Mg== +-----END CERTIFICATE-----