created: monorepo with front & back
This commit is contained in:
18
backend/TODO
Normal file
18
backend/TODO
Normal file
@@ -0,0 +1,18 @@
|
||||
POR HACER --------------------------------
|
||||
- implementar urlParams para filtros
|
||||
- documentación
|
||||
- mail wrapper
|
||||
|
||||
RESUELTO ---------------------------------
|
||||
- añadir colaborador desde perfil
|
||||
- apuntarse lista espera
|
||||
- aceptar solicitudes LE/Colab (sobre todo por crear preusers)
|
||||
- mejorar queries para no filtrar en memoria -> IMPOSIBLE CON ENDPOINTS INTERNOS DE CORE: RESUELTO CON CACHING
|
||||
- normalizar el uso de services y repositories desde otros services y repositories
|
||||
- sistema comun de errores en back & front
|
||||
- nombre del requester
|
||||
- cambiar contraseña (?)
|
||||
- todos los socios en dropdown ingresos
|
||||
- validacion LE/COlab
|
||||
- createdAt custom en ing,gastos
|
||||
- editar createdAt
|
||||
10
backend/build-upload.sh
Executable file
10
backend/build-upload.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd core/ || exit
|
||||
mvn clean package
|
||||
cd ..
|
||||
cd huertos/ || exit
|
||||
mvn clean package
|
||||
cd ..
|
||||
scp core/target/core-*.jar root@huertosbellavista.es:/root/transfer
|
||||
scp huertos/target/huertos-*.jar root@huertosbellavista.es:/root/transfer
|
||||
1
backend/core/.gitignore
vendored
Normal file
1
backend/core/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target/
|
||||
9
backend/core/core.iml
Normal file
9
backend/core/core.iml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="AdditionalModuleElements">
|
||||
<content url="file://$MODULE_DIR$" dumb="true">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
</content>
|
||||
</component>
|
||||
</module>
|
||||
107
backend/core/pom.xml
Normal file
107
backend/core/pom.xml
Normal file
@@ -0,0 +1,107 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>es.huertosbellavista</groupId>
|
||||
<artifactId>backend</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>25</maven.compiler.source>
|
||||
<maven.compiler.target>25</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gitea</id>
|
||||
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>3.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>8.0.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.42</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>0.11.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.miarma</groupId>
|
||||
<artifactId>backlib</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
package es.huertosbellavista.backend.core;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = {
|
||||
"es.huertosbellavista.backend.core",
|
||||
"net.miarma.backlib"
|
||||
})
|
||||
public class CoreApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CoreApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package es.huertosbellavista.backend.core.config;
|
||||
|
||||
import es.huertosbellavista.backend.core.security.JwtFilter;
|
||||
import net.miarma.backlib.http.RestAccessDeniedHandler;
|
||||
import net.miarma.backlib.http.RestAuthEntryPoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityConfig {
|
||||
private final JwtFilter jwtFilter;
|
||||
private final RestAuthEntryPoint authEntryPoint;
|
||||
private final RestAccessDeniedHandler accessDeniedHandler;
|
||||
private final CorsConfigurationSource corsConfigurationSource;
|
||||
|
||||
public SecurityConfig(
|
||||
JwtFilter jwtFilter,
|
||||
RestAuthEntryPoint authEntryPoint,
|
||||
RestAccessDeniedHandler accessDeniedHandler,
|
||||
Optional<CorsConfigurationSource> corsConfigurationSource
|
||||
) {
|
||||
this.jwtFilter = jwtFilter;
|
||||
this.authEntryPoint = authEntryPoint;
|
||||
this.accessDeniedHandler = accessDeniedHandler;
|
||||
this.corsConfigurationSource = corsConfigurationSource.orElse(null);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
if (corsConfigurationSource != null) {
|
||||
http.cors(Customizer.withDefaults());
|
||||
}
|
||||
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.exceptionHandling(ex -> ex
|
||||
.authenticationEntryPoint(authEntryPoint)
|
||||
.accessDeniedHandler(accessDeniedHandler)
|
||||
)
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/auth/login").permitAll()
|
||||
.requestMatchers("/auth/refresh").permitAll()
|
||||
.requestMatchers("/auth/change-password").permitAll()
|
||||
.requestMatchers("/auth/register").permitAll()
|
||||
.requestMatchers("/test").permitAll()
|
||||
.requestMatchers("/screenshot").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
);
|
||||
|
||||
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package es.huertosbellavista.backend.core.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@Configuration
|
||||
public class WebClientConfig {
|
||||
@Bean
|
||||
public WebClient.Builder webClientBuilder() {
|
||||
return WebClient.builder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package es.huertosbellavista.backend.core.controller;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.miarma.backlib.dto.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import es.huertosbellavista.backend.core.service.AuthService;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/auth")
|
||||
public class AuthController {
|
||||
|
||||
private final JwtService jwtService;
|
||||
private final AuthService authService;
|
||||
|
||||
public AuthController(JwtService jwtService, AuthService authService) {
|
||||
this.jwtService = jwtService;
|
||||
this.authService = authService;
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<LoginResponse> login(@Valid @RequestBody LoginRequest request) {
|
||||
LoginResponse response = authService.login(request);
|
||||
return ResponseEntity.ok(
|
||||
new LoginResponse(response.token(), response.user(), response.account())
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<LoginResponse> register(@RequestBody RegisterRequest request) {
|
||||
return ResponseEntity.ok(authService.register(request));
|
||||
}
|
||||
|
||||
@GetMapping("/refresh")
|
||||
public ResponseEntity<?> refreshToken(@RequestHeader("Authorization") String authHeader) {
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return ResponseEntity.status(401).body(
|
||||
new ApiErrorDto(
|
||||
401,
|
||||
"Unauthorized",
|
||||
"No hay token",
|
||||
"/v2/core/auth/change-password"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
if (!jwtService.validateToken(token)) {
|
||||
return ResponseEntity.status(401).body(
|
||||
new ApiErrorDto(
|
||||
401,
|
||||
"Unauthorized",
|
||||
"Invalid token",
|
||||
"/v2/core/auth/change-password"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
UUID userId = jwtService.getUserId(token);
|
||||
Byte serviceId = jwtService.getServiceId(token);
|
||||
|
||||
String newToken = jwtService.generateToken(userId, serviceId);
|
||||
|
||||
return ResponseEntity.ok(Map.of(
|
||||
"token", newToken,
|
||||
"userId", userId,
|
||||
"serviceId", serviceId
|
||||
));
|
||||
}
|
||||
|
||||
@PostMapping("/change-password")
|
||||
public ResponseEntity<?> changePassword(
|
||||
@RequestHeader("Authorization") String authHeader,
|
||||
@RequestBody ChangePasswordRequest request
|
||||
) {
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return ResponseEntity.status(401).body(
|
||||
new ApiErrorDto(
|
||||
401,
|
||||
"Unauthorized",
|
||||
"No hay token",
|
||||
"/v2/core/auth/change-password"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
if (!jwtService.validateToken(token)) {
|
||||
return ResponseEntity.status(401).body(
|
||||
new ApiErrorDto(
|
||||
401,
|
||||
"Unauthorized",
|
||||
"Invalid token",
|
||||
"/v2/core/auth/change-password"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
UUID userId = jwtService.getUserId(token);
|
||||
|
||||
authService.changePassword(userId, request);
|
||||
return ResponseEntity.ok(Map.of("message", "Contraseña cambiada correctamente"));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/validate")
|
||||
public ResponseEntity<Boolean> validate(@RequestHeader("Authorization") String authHeader) {
|
||||
String token = authHeader.substring(7);
|
||||
return ResponseEntity.ok(jwtService.validateToken(token));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package es.huertosbellavista.backend.core.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import es.huertosbellavista.backend.core.dto.UpdateCredentialDto;
|
||||
import es.huertosbellavista.backend.core.mapper.CredentialMapper;
|
||||
import es.huertosbellavista.backend.core.security.CorePrincipal;
|
||||
import net.miarma.backlib.dto.*;
|
||||
import net.miarma.backlib.exception.ForbiddenException;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.Credential;
|
||||
import es.huertosbellavista.backend.core.service.CredentialService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/credentials")
|
||||
public class CredentialController {
|
||||
|
||||
private final CredentialService credentialService;
|
||||
|
||||
public CredentialController(CredentialService credentialService) {
|
||||
this.credentialService = credentialService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<List<Credential>> getAll() {
|
||||
return ResponseEntity.ok(credentialService.getAll());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<CredentialDto> create(@RequestBody CreateCredentialDto dto) {
|
||||
return ResponseEntity.ok(
|
||||
CredentialMapper.toDto(
|
||||
credentialService.create(
|
||||
CredentialMapper.toEntity(dto)))
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/user/{userId}")
|
||||
public ResponseEntity<List<CredentialDto>> getByUserId(@PathVariable("userId") UUID userId) {
|
||||
CorePrincipal principal = (CorePrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
if (!principal.getRole().equals((byte)1) && !principal.getUserId().equals(userId)) {
|
||||
throw new ForbiddenException("No tienes permiso");
|
||||
}
|
||||
return ResponseEntity.ok(credentialService.getByUserId(userId).stream()
|
||||
.map(CredentialMapper::toDto)
|
||||
.toList());
|
||||
}
|
||||
|
||||
@GetMapping("/{credential_id}")
|
||||
public ResponseEntity<CredentialDto> getById(@PathVariable("credential_id") UUID credentialId) {
|
||||
CorePrincipal principal = (CorePrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
Credential cred = credentialService.getById(credentialId);
|
||||
if (!principal.getRole().equals((byte)1) && !cred.getUserId().equals(principal.getUserId())) {
|
||||
throw new ForbiddenException("No tienes permiso");
|
||||
}
|
||||
return ResponseEntity.ok(CredentialMapper.toDto(cred));
|
||||
}
|
||||
|
||||
@PutMapping("/{credential_id}")
|
||||
public ResponseEntity<CredentialDto> update(
|
||||
@PathVariable("credential_id") UUID credentialId,
|
||||
@RequestBody UpdateCredentialDto dto
|
||||
) {
|
||||
CorePrincipal principal = (CorePrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
Credential cred = credentialService.getById(credentialId);
|
||||
if (!principal.getRole().equals((byte)1) && !cred.getUserId().equals(principal.getUserId())) {
|
||||
throw new ForbiddenException("No tienes permiso");
|
||||
}
|
||||
return ResponseEntity.ok(
|
||||
CredentialMapper.toDto(
|
||||
credentialService.update(credentialId, CredentialMapper.toEntity(dto))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@PutMapping("/{credential_id}/full")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<CredentialDto> updateFull(
|
||||
@PathVariable("credential_id") UUID credentialId,
|
||||
@RequestBody CredentialDto dto
|
||||
) {
|
||||
return ResponseEntity.ok(
|
||||
CredentialMapper.toDto(
|
||||
credentialService.update(credentialId, CredentialMapper.toEntity(dto))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/{service_id}/{user_id}/status")
|
||||
public ResponseEntity<Byte> getStatus(@PathVariable("user_id") UUID userId, @PathVariable("service_id") Byte serviceId) {
|
||||
return ResponseEntity.ok(credentialService.getStatus(userId, serviceId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package es.huertosbellavista.backend.core.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import es.huertosbellavista.backend.core.mapper.FileMapper;
|
||||
import net.miarma.backlib.dto.FileDto;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.File;
|
||||
import es.huertosbellavista.backend.core.service.FileService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/files")
|
||||
public class FileController {
|
||||
|
||||
private final FileService fileService;
|
||||
|
||||
public FileController(FileService fileService) {
|
||||
this.fileService = fileService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<List<File>> getAll() {
|
||||
List<File> files = fileService.getAll();
|
||||
return ResponseEntity.ok(files);
|
||||
}
|
||||
|
||||
@GetMapping("/{file_id}")
|
||||
@PreAuthorize("hasRole('ADMIN') or @fileService.isOwner(#file_id, authentication.principal.userId)")
|
||||
public ResponseEntity<File> getById(@PathVariable("file_id") UUID fileId) {
|
||||
File file = fileService.getById(fileId);
|
||||
return ResponseEntity.ok(file);
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data")
|
||||
@PreAuthorize("hasRole('ADMIN') or #uploadedBy == authentication.principal.userId")
|
||||
public ResponseEntity<FileDto.Response> create(
|
||||
@RequestPart("file") MultipartFile file,
|
||||
@RequestPart("fileName") String fileName,
|
||||
@RequestPart("mimeType") String mimeType,
|
||||
@RequestPart("uploadedBy") UUID uploadedBy,
|
||||
@RequestPart("context") Integer context
|
||||
) throws IOException {
|
||||
|
||||
File entity = new File();
|
||||
entity.setFileName(fileName);
|
||||
entity.setMimeType(mimeType);
|
||||
entity.setUploadedBy(uploadedBy);
|
||||
entity.setContext(context.byteValue());
|
||||
|
||||
File created = fileService.create(entity, file.getBytes());
|
||||
return ResponseEntity.status(HttpStatus.CREATED)
|
||||
.body(FileMapper.toResponse(created));
|
||||
}
|
||||
|
||||
@PutMapping("/{file_id}")
|
||||
@PreAuthorize("hasRole('ADMIN') or @fileService.isOwner(#file_id, authentication.principal.userId)")
|
||||
public ResponseEntity<File> update(@PathVariable("file_id") UUID fileId, @RequestBody FileDto.Request request) {
|
||||
File updated = fileService.update(fileId, FileMapper.toEntity(request));
|
||||
return ResponseEntity.ok(updated);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{file_id}")
|
||||
@PreAuthorize("hasRole('ADMIN') or @fileService.isOwner(#file_id, authentication.principal.userId)")
|
||||
public ResponseEntity<Void> delete(@PathVariable("file_id") UUID fileId, @RequestBody Map<String,String> body) throws IOException {
|
||||
String filePath = body.get("file_path");
|
||||
Files.deleteIfExists(Paths.get(filePath));
|
||||
fileService.delete(fileId);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package es.huertosbellavista.backend.core.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import es.huertosbellavista.backend.core.mapper.CredentialMapper;
|
||||
import es.huertosbellavista.backend.core.model.Credential;
|
||||
import es.huertosbellavista.backend.core.service.CredentialService;
|
||||
import net.miarma.backlib.dto.*;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import es.huertosbellavista.backend.core.mapper.UserMapper;
|
||||
import es.huertosbellavista.backend.core.model.User;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
import es.huertosbellavista.backend.core.service.UserService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
public class UserController {
|
||||
private UserService userService;
|
||||
private CredentialService credentialService;
|
||||
private JwtService jwtService;
|
||||
|
||||
public UserController(UserService userService, CredentialService credentialService, JwtService jwtService) {
|
||||
this.userService = userService;
|
||||
this.credentialService = credentialService;
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<List<UserDto>> getAll() {
|
||||
return ResponseEntity.ok(
|
||||
userService.getAll()
|
||||
.stream()
|
||||
.map(UserMapper::toDto)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<UserDto> create(@RequestBody CreateUserDto dto) {
|
||||
return ResponseEntity.ok(
|
||||
UserMapper.toDto(
|
||||
userService.create(
|
||||
UserMapper.fromCreateDto(dto)))
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<UserDto> getById(@PathVariable("user_id") UUID userId) {
|
||||
User user = userService.getById(userId);
|
||||
return ResponseEntity.ok(UserMapper.toDto(user));
|
||||
}
|
||||
|
||||
@GetMapping("/service/{service_id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<List<UserWithCredentialDto>> getAllWithCredentials(
|
||||
@PathVariable("service_id") Byte serviceId
|
||||
) {
|
||||
List<Credential> credentials = credentialService.getByServiceIdFetchUser(serviceId);
|
||||
|
||||
List<UserWithCredentialDto> result = credentials.stream()
|
||||
.map(cred -> new UserWithCredentialDto(
|
||||
UserMapper.toDto(cred.getUser()),
|
||||
CredentialMapper.toDto(cred)
|
||||
))
|
||||
.toList();
|
||||
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id}/service/{service_id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<UserWithCredentialDto> getByIdWithCredentials(
|
||||
@PathVariable("user_id") UUID userId,
|
||||
@PathVariable("service_id") Byte serviceId
|
||||
) {
|
||||
User user = userService.getById(userId);
|
||||
Credential credential = credentialService.getByUserIdAndService(userId, serviceId);
|
||||
return ResponseEntity.ok(
|
||||
UserMapper.toDtoWithCredentials(
|
||||
UserMapper.toDto(user),
|
||||
CredentialMapper.toDto(credential)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@PutMapping("/{user_id}")
|
||||
@PreAuthorize("hasRole('ADMIN') or #userId == principal.userId")
|
||||
public ResponseEntity<UserDto> update(
|
||||
@PathVariable("user_id") UUID userId,
|
||||
@RequestBody UserDto dto
|
||||
) {
|
||||
User updated = userService.update(userId, UserMapper.fromDto(dto));
|
||||
return ResponseEntity.ok(UserMapper.toDto(updated));
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id}/avatar")
|
||||
public ResponseEntity<String> getAvatar(@PathVariable("user_id") UUID userId) {
|
||||
return ResponseEntity.ok(userService.getById(userId).getAvatar());
|
||||
}
|
||||
|
||||
@PutMapping("/{user_id}/avatar")
|
||||
public ResponseEntity<UserDto> updateAvatar(@PathVariable("user_id") UUID userId, @RequestBody ChangeAvatarRequest avatar) {
|
||||
return ResponseEntity.ok(userService.updateAvatar(userId, avatar));
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id}/status")
|
||||
public ResponseEntity<Byte> getStatus(@PathVariable("user_id") UUID userId) {
|
||||
return ResponseEntity.ok(userService.getStatus(userId));
|
||||
}
|
||||
|
||||
@PutMapping("/{user_id}/status")
|
||||
public ResponseEntity<Void> updateStatus(
|
||||
@PathVariable("user_id") UUID userId,
|
||||
@RequestBody ChangeStatusRequest req
|
||||
) {
|
||||
userService.updateStatus(userId, req.status());
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id}/role")
|
||||
public ResponseEntity<Byte> getRole(@PathVariable("user_id") UUID userId) {
|
||||
return ResponseEntity.ok(userService.getRole(userId));
|
||||
}
|
||||
|
||||
@PutMapping("/{user_id}/role")
|
||||
public ResponseEntity<Void> updateRole(
|
||||
@PathVariable("user_id") UUID userid,
|
||||
@RequestBody ChangeRoleRequest req
|
||||
) {
|
||||
userService.updateRole(userid, req.role());
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id}/exists")
|
||||
public ResponseEntity<UserExistsResponse> exists(@PathVariable("user_id") UUID userId) {
|
||||
boolean exists = userService.exists(userId);
|
||||
return ResponseEntity.ok(new UserExistsResponse(exists));
|
||||
}
|
||||
|
||||
@GetMapping("/me")
|
||||
public ResponseEntity<UserDto> getMe(@RequestHeader("Authorization") String authHeader) {
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
|
||||
UUID userId;
|
||||
try {
|
||||
userId = jwtService.getUserId(token);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
User user = userService.getById(userId);
|
||||
return ResponseEntity.ok(UserMapper.toDto(user));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{user_id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<Void> delete(@PathVariable("user_id") UUID userId) {
|
||||
userService.delete(userId);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package es.huertosbellavista.backend.core.dto;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UpdateCredentialDto {
|
||||
private String email;
|
||||
private String username;
|
||||
private Byte status;
|
||||
|
||||
public UpdateCredentialDto() { }
|
||||
|
||||
public UpdateCredentialDto(String email, String username, Byte status) {
|
||||
this.email = email;
|
||||
this.username = username;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public Byte getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Byte status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package es.huertosbellavista.backend.core.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.core.dto.UpdateCredentialDto;
|
||||
import es.huertosbellavista.backend.core.model.Credential;
|
||||
import net.miarma.backlib.dto.CreateCredentialDto;
|
||||
import net.miarma.backlib.dto.CredentialDto;
|
||||
|
||||
public class CredentialMapper {
|
||||
|
||||
public static CredentialDto toDto(Credential c) {
|
||||
if (c == null) return null;
|
||||
|
||||
return new CredentialDto(
|
||||
c.getCredentialId(),
|
||||
c.getUserId(),
|
||||
c.getServiceId(),
|
||||
c.getUsername(),
|
||||
c.getEmail(),
|
||||
c.getStatus(),
|
||||
c.getCreatedAt(),
|
||||
c.getUpdatedAt()
|
||||
);
|
||||
}
|
||||
|
||||
public static CreateCredentialDto toCreateDto(Credential c) {
|
||||
if (c == null) return null;
|
||||
|
||||
return new CreateCredentialDto(
|
||||
c.getUserId(),
|
||||
c.getServiceId(),
|
||||
c.getUsername(),
|
||||
c.getEmail(),
|
||||
c.getPassword(),
|
||||
c.getStatus()
|
||||
);
|
||||
}
|
||||
|
||||
public static Credential toEntity(CredentialDto dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Credential c = new Credential();
|
||||
c.setCredentialId(dto.getCredentialId());
|
||||
c.setUserId(dto.getUserId());
|
||||
c.setServiceId(dto.getServiceId());
|
||||
c.setUsername(dto.getUsername());
|
||||
c.setEmail(dto.getEmail());
|
||||
c.setStatus(dto.getStatus());
|
||||
c.setCreatedAt(dto.getCreatedAt());
|
||||
c.setUpdatedAt(dto.getUpdatedAt());
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Credential toEntity(CreateCredentialDto dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Credential c = new Credential();
|
||||
c.setUserId(dto.getUserId());
|
||||
c.setServiceId(dto.getServiceId());
|
||||
c.setUsername(dto.getUsername());
|
||||
c.setEmail(dto.getEmail());
|
||||
c.setPassword(dto.getPassword());
|
||||
c.setStatus(dto.getStatus());
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Credential toEntity(UpdateCredentialDto dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Credential c = new Credential();
|
||||
c.setEmail(dto.getEmail());
|
||||
c.setUsername(dto.getUsername());
|
||||
c.setStatus(dto.getStatus());
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package es.huertosbellavista.backend.core.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.File;
|
||||
import net.miarma.backlib.dto.FileDto;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileMapper {
|
||||
|
||||
private FileMapper() {}
|
||||
|
||||
public static FileDto.Response toResponse(File file) {
|
||||
FileDto.Response res = new FileDto.Response();
|
||||
|
||||
res.setFileId(file.getFileId());
|
||||
res.setFileName(file.getFileName());
|
||||
res.setFilePath(file.getFilePath());
|
||||
res.setMimeType(file.getMimeType());
|
||||
res.setUploadedBy(file.getUploadedBy());
|
||||
res.setUploadedAt(file.getUploadedAt());
|
||||
res.setContext(file.getContext());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static File toEntity(FileDto.Request req) {
|
||||
File file = new File();
|
||||
|
||||
file.setFileId(UUID.randomUUID());
|
||||
file.setFileName(req.getFileName());
|
||||
file.setFilePath(req.getFilePath());
|
||||
file.setMimeType(req.getMimeType());
|
||||
file.setUploadedBy(req.getUploadedBy());
|
||||
file.setContext(req.getContext());
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package es.huertosbellavista.backend.core.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.User;
|
||||
import net.miarma.backlib.dto.CreateUserDto;
|
||||
import net.miarma.backlib.dto.CredentialDto;
|
||||
import net.miarma.backlib.dto.UserDto;
|
||||
import net.miarma.backlib.dto.UserWithCredentialDto;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserMapper {
|
||||
public static User fromDto(UserDto dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
User user = new User();
|
||||
user.setDisplayName(dto.getDisplayName());
|
||||
user.setAvatar(dto.getAvatar());
|
||||
user.setGlobalRole(dto.getGlobalRole());
|
||||
user.setGlobalStatus(dto.getGlobalStatus());
|
||||
return user;
|
||||
}
|
||||
|
||||
public static User fromCreateDto(CreateUserDto dto) {
|
||||
User user = new User();
|
||||
user.setUserId(UUID.randomUUID());
|
||||
user.setDisplayName(dto.displayName());
|
||||
user.setAvatar(dto.avatar() != null ? dto.avatar() : null);
|
||||
user.setGlobalRole((byte)0);
|
||||
user.setGlobalStatus((byte)1);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static UserDto toDto(User u) {
|
||||
if (u == null) return null;
|
||||
|
||||
return new UserDto(
|
||||
u.getUserId(),
|
||||
u.getDisplayName(),
|
||||
u.getAvatar(),
|
||||
u.getGlobalStatus(),
|
||||
u.getGlobalRole(),
|
||||
u.getCreatedAt(),
|
||||
u.getUpdatedAt()
|
||||
);
|
||||
}
|
||||
|
||||
public static UserWithCredentialDto toDtoWithCredentials(UserDto user, CredentialDto account){
|
||||
if (user == null || account == null) return null;
|
||||
|
||||
return new UserWithCredentialDto(user, account);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package es.huertosbellavista.backend.core.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "credentials",
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(columnNames = { "service_id", "username" }),
|
||||
@UniqueConstraint(columnNames = { "service_id", "email" })
|
||||
})
|
||||
|
||||
public class Credential {
|
||||
|
||||
@Id
|
||||
@Column(name = "credential_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] credentialIdBin;
|
||||
|
||||
@Column(name = "user_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] userIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID credentialId;
|
||||
|
||||
@Transient
|
||||
private UUID userId;
|
||||
|
||||
@Column(name = "service_id")
|
||||
private Byte serviceId;
|
||||
|
||||
private String username;
|
||||
private String email;
|
||||
private String password;
|
||||
private Byte status;
|
||||
|
||||
@CreationTimestamp
|
||||
private Instant createdAt;
|
||||
|
||||
@UpdateTimestamp
|
||||
private Instant updatedAt;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "user_id", insertable = false, updatable = false)
|
||||
private User user;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (credentialId != null) {
|
||||
credentialIdBin = UuidUtil.uuidToBin(credentialId);
|
||||
}
|
||||
if (userId != null) {
|
||||
userIdBin = UuidUtil.uuidToBin(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (credentialIdBin != null) {
|
||||
credentialId = UuidUtil.binToUUID(credentialIdBin);
|
||||
}
|
||||
if (userIdBin != null) {
|
||||
userId = UuidUtil.binToUUID(userIdBin);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getCredentialId() {
|
||||
return credentialId;
|
||||
}
|
||||
|
||||
public void setCredentialId(UUID credentialId) {
|
||||
this.credentialId = credentialId;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Byte getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
public void setServiceId(Byte serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Byte getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Byte status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Instant getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(Instant updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package es.huertosbellavista.backend.core.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "files")
|
||||
public class File {
|
||||
|
||||
@Id
|
||||
@Column(name = "file_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] fileIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID fileId;
|
||||
|
||||
@Column(name = "file_name", nullable = false, length = 128)
|
||||
private String fileName;
|
||||
|
||||
@Column(name = "file_path", nullable = false, length = 256)
|
||||
private String filePath;
|
||||
|
||||
@Column(name = "mime_type", nullable = false, length = 64)
|
||||
private String mimeType;
|
||||
|
||||
@Column(name = "uploaded_by", columnDefinition = "BINARY(16)", nullable = false)
|
||||
private byte[] uploadedByBin;
|
||||
|
||||
@Transient
|
||||
private UUID uploadedBy;
|
||||
|
||||
@Column(name = "uploaded_at", nullable = false, updatable = false)
|
||||
private Instant uploadedAt;
|
||||
|
||||
@Column(name = "context", nullable = false)
|
||||
private Byte context;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (fileId != null) {
|
||||
fileIdBin = UuidUtil.uuidToBin(fileId);
|
||||
}
|
||||
|
||||
if (uploadedBy != null) {
|
||||
uploadedByBin = UuidUtil.uuidToBin(uploadedBy);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (fileIdBin != null) {
|
||||
fileId = UuidUtil.binToUUID(fileIdBin);
|
||||
}
|
||||
|
||||
if (uploadedByBin != null) {
|
||||
uploadedBy = UuidUtil.binToUUID(uploadedByBin);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getFileId() {
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public void setFileId(UUID fileId) {
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public void setMimeType(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public UUID getUploadedBy() {
|
||||
return uploadedBy;
|
||||
}
|
||||
|
||||
public void setUploadedBy(UUID uploadedBy) {
|
||||
this.uploadedBy = uploadedBy;
|
||||
}
|
||||
|
||||
public Instant getUploadedAt() {
|
||||
return uploadedAt;
|
||||
}
|
||||
|
||||
public Byte getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(Byte context) {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package es.huertosbellavista.backend.core.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@Column(name = "user_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] userIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID userId;
|
||||
|
||||
@Column(name = "display_name", nullable = false)
|
||||
private String displayName;
|
||||
|
||||
private String avatar;
|
||||
|
||||
@Column(name = "global_status")
|
||||
private Byte globalStatus;
|
||||
|
||||
@Column(name = "global_role")
|
||||
private Byte globalRole;
|
||||
|
||||
@CreationTimestamp
|
||||
private Instant createdAt;
|
||||
|
||||
@UpdateTimestamp
|
||||
private Instant updatedAt;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (userId != null) {
|
||||
userIdBin = UuidUtil.uuidToBin(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (userIdBin != null) {
|
||||
userId = UuidUtil.binToUUID(userIdBin);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public Byte getGlobalStatus() {
|
||||
return globalStatus;
|
||||
}
|
||||
|
||||
public void setGlobalStatus(Byte globalStatus) {
|
||||
this.globalStatus = globalStatus;
|
||||
}
|
||||
|
||||
public Byte getGlobalRole() {
|
||||
return globalRole;
|
||||
}
|
||||
|
||||
public void setGlobalRole(Byte globalRole) {
|
||||
this.globalRole = globalRole;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Instant getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(Instant updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package es.huertosbellavista.backend.core.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.Credential;
|
||||
|
||||
public interface CredentialRepository extends JpaRepository<Credential, byte[]> {
|
||||
|
||||
@Query("""
|
||||
SELECT c FROM Credential c
|
||||
JOIN FETCH c.user
|
||||
WHERE c.serviceId = :serviceId
|
||||
AND c.username = :username
|
||||
""")
|
||||
Optional<Credential> findByServiceIdAndUsername(@Param("serviceId") Byte serviceId,
|
||||
@Param("username") String username);
|
||||
|
||||
List<Credential> findAllByServiceId(Byte serviceId);
|
||||
|
||||
@Query("SELECT c FROM Credential c JOIN FETCH c.user WHERE c.serviceId = :serviceId")
|
||||
List<Credential> getByServiceIdFetchUser(@Param("serviceId") Byte serviceId);
|
||||
|
||||
Optional<Credential> findByServiceIdAndEmail(Byte serviceId, String email);
|
||||
|
||||
@Query("SELECT c FROM Credential c WHERE c.userIdBin = :userIdBin AND c.serviceId = :serviceId")
|
||||
Optional<Credential> findByUserIdAndServiceId(@Param("userIdBin") byte[] userIdBin, @Param("serviceId") Byte serviceId);
|
||||
|
||||
Optional<Credential> findByUsernameAndServiceId(String username, Byte serviceId);
|
||||
|
||||
@Query("SELECT c FROM Credential c WHERE c.userIdBin = :userIdBin")
|
||||
List<Credential> findByUserId(@Param("userIdBin") byte[] userIdBin);
|
||||
|
||||
@Query("SELECT c FROM Credential c WHERE c.email = :email")
|
||||
List<Credential> findByEmail(@Param("email") String email);
|
||||
|
||||
boolean existsByUsernameAndServiceId(String username, Byte serviceId);
|
||||
|
||||
boolean existsByEmailAndServiceId(String email, Byte serviceId);
|
||||
|
||||
@Modifying
|
||||
@Query("""
|
||||
UPDATE Credential c
|
||||
SET c.username = :username,
|
||||
c.email = :email,
|
||||
c.status = :status
|
||||
WHERE c.credentialIdBin = :credentialIdBin
|
||||
""")
|
||||
int update(@Param("credentialIdBin") byte[] credentialIdBin,
|
||||
@Param("username") String username,
|
||||
@Param("email") String email,
|
||||
@Param("status") Byte status);
|
||||
|
||||
List<Credential> findByUsername(@NotBlank String username);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package es.huertosbellavista.backend.core.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.File;
|
||||
|
||||
public interface FileRepository extends JpaRepository<File, byte[]> {
|
||||
List<File> findByUploadedBy(UUID uploadedBy);
|
||||
|
||||
List<File> findByContext(Byte context);
|
||||
|
||||
List<File> findByUploadedByAndContext(UUID uploadedBy, Byte context);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package es.huertosbellavista.backend.core.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.User;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, byte[]> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package es.huertosbellavista.backend.core.security;
|
||||
|
||||
import net.miarma.backlib.security.CoreAuthTokenHolder;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CorePrincipal implements UserDetails {
|
||||
private final UUID userId;
|
||||
private final Byte role;
|
||||
|
||||
public CorePrincipal(UUID userId, Byte role) {
|
||||
this.userId = userId;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public UUID getUserId() { return userId; }
|
||||
public Byte getRole() { return role; }
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
List<GrantedAuthority> auth = new ArrayList<>();
|
||||
|
||||
String roleName = switch(role) {
|
||||
case 0 -> "USER";
|
||||
case 1 -> "ADMIN";
|
||||
default -> "GUEST";
|
||||
};
|
||||
|
||||
auth.add(new SimpleGrantedAuthority("ROLE_" + roleName));
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
@Override public String getPassword() { return ""; }
|
||||
@Override public String getUsername() { return userId.toString(); }
|
||||
@Override public boolean isAccountNonExpired() { return true; }
|
||||
@Override public boolean isAccountNonLocked() { return true; }
|
||||
@Override public boolean isCredentialsNonExpired() { return true; }
|
||||
@Override public boolean isEnabled() { return true; }
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package es.huertosbellavista.backend.core.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import es.huertosbellavista.backend.core.model.User;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
import es.huertosbellavista.backend.core.service.UserService;
|
||||
|
||||
@Component
|
||||
public class JwtFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtService jwtService;
|
||||
private final UserService userService;
|
||||
private final long refreshThreshold = 300_000;
|
||||
|
||||
public JwtFilter(JwtService jwtService, UserService userService) {
|
||||
this.jwtService = jwtService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||
String token = authHeader.substring(7);
|
||||
|
||||
try {
|
||||
if (jwtService.validateToken(token)) {
|
||||
UUID userId = jwtService.getUserId(token);
|
||||
Byte serviceId = jwtService.getServiceId(token);
|
||||
|
||||
User user = userService.getById(userId);
|
||||
CorePrincipal principal = new CorePrincipal(userId, user.getGlobalRole());
|
||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(principal, null, principal.getAuthorities());
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
long timeLeft = jwtService.getExpiration(token).getTime() - System.currentTimeMillis();
|
||||
if (timeLeft < refreshThreshold) {
|
||||
String newToken = jwtService.generateToken(userId, serviceId);
|
||||
response.setHeader("X-Refresh-Token", newToken);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid or expired token");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package es.huertosbellavista.backend.core.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.miarma.backlib.dto.*;
|
||||
import net.miarma.backlib.exception.*;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import es.huertosbellavista.backend.core.mapper.CredentialMapper;
|
||||
import es.huertosbellavista.backend.core.mapper.UserMapper;
|
||||
import es.huertosbellavista.backend.core.model.Credential;
|
||||
import es.huertosbellavista.backend.core.model.User;
|
||||
|
||||
@Service
|
||||
public class AuthService {
|
||||
|
||||
private final CredentialService credentialService;
|
||||
private final UserService userService;
|
||||
private final net.miarma.backlib.security.JwtService jwtService;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
public AuthService(CredentialService credentialService, UserService userService,
|
||||
net.miarma.backlib.security.JwtService jwtService, PasswordEncoder passwordEncoder) {
|
||||
this.credentialService = credentialService;
|
||||
this.userService = userService;
|
||||
this.jwtService = jwtService;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
public LoginResponse login(LoginRequest request) {
|
||||
Credential cred = credentialService.getForLogin(request.serviceId(), request.username());
|
||||
|
||||
if (!passwordEncoder.matches(request.password(), cred.getPassword())) {
|
||||
throw new UnauthorizedException("Credenciales no válidas");
|
||||
}
|
||||
|
||||
if (cred.getStatus() == 0) {
|
||||
throw new ForbiddenException("Esa cuenta está desactivada");
|
||||
}
|
||||
|
||||
String token = jwtService.generateToken(cred.getUserId(), request.serviceId());
|
||||
UserDto userDto = UserMapper.toDto(cred.getUser());
|
||||
CredentialDto credentialDto = CredentialMapper.toDto(cred);
|
||||
|
||||
return new LoginResponse(token, userDto, credentialDto);
|
||||
}
|
||||
|
||||
public LoginResponse register(RegisterRequest request) {
|
||||
UUID userIdByUsername = null;
|
||||
UUID userIdByEmail = null;
|
||||
|
||||
Optional<Credential> credByUsername = credentialService.getByUsername(request.username()).stream().findFirst();
|
||||
if(credByUsername.isPresent()) {
|
||||
userIdByUsername = credByUsername.get().getUserId();
|
||||
}
|
||||
|
||||
List<Credential> accountsByEmail = credentialService.getByEmail(request.email());
|
||||
if (!accountsByEmail.isEmpty()) {
|
||||
userIdByEmail = accountsByEmail.getFirst().getUserId();
|
||||
}
|
||||
|
||||
User user;
|
||||
if (userIdByUsername != null && userIdByEmail != null) {
|
||||
if (!userIdByUsername.equals(userIdByEmail)) {
|
||||
throw new ConflictException("Username y email ya existen pero pertenecen a usuarios distintos");
|
||||
}
|
||||
user = userService.getById(userIdByUsername);
|
||||
} else if (userIdByUsername != null) {
|
||||
user = userService.getById(userIdByUsername);
|
||||
} else if (userIdByEmail != null) {
|
||||
user = userService.getById(userIdByEmail);
|
||||
} else {
|
||||
CreateUserDto dto = new CreateUserDto(request.displayName(), null);
|
||||
user = userService.create(UserMapper.fromCreateDto(dto));
|
||||
}
|
||||
|
||||
Credential cred = new Credential();
|
||||
cred.setCredentialId(UUID.randomUUID());
|
||||
cred.setUserId(user.getUserId());
|
||||
cred.setUser(user);
|
||||
cred.setServiceId(request.serviceId());
|
||||
cred.setUsername(request.username());
|
||||
cred.setEmail(request.email());
|
||||
cred.setPassword(request.password());
|
||||
cred.setStatus((byte)1);
|
||||
credentialService.create(cred);
|
||||
|
||||
String token = jwtService.generateToken(user.getUserId(), request.serviceId());
|
||||
|
||||
return new LoginResponse(token, UserMapper.toDto(user), CredentialMapper.toDto(cred));
|
||||
}
|
||||
|
||||
public void changePassword(UUID userId, ChangePasswordRequest request) {
|
||||
Credential cred = credentialService.getByUserId(userId)
|
||||
.stream()
|
||||
.filter(c -> c.getServiceId().equals(request.serviceId()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
|
||||
|
||||
if (!passwordEncoder.matches(request.oldPassword(), cred.getPassword())) {
|
||||
throw new ValidationException("oldPassword", "La contraseña actual es incorrecta");
|
||||
}
|
||||
|
||||
if (request.newPassword().length() < 8) {
|
||||
throw new ValidationException("newPassword", "La nueva contraseña debe tener al menos 8 caracteres");
|
||||
}
|
||||
|
||||
credentialService.updatePassword(cred.getCredentialId(), request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package es.huertosbellavista.backend.core.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import net.miarma.backlib.exception.*;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.Credential;
|
||||
import es.huertosbellavista.backend.core.repository.CredentialRepository;
|
||||
import net.miarma.backlib.dto.ChangePasswordRequest;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class CredentialService {
|
||||
|
||||
private final CredentialRepository credentialRepository;
|
||||
private final UserService userService;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
public CredentialService(CredentialRepository credentialRepository, UserService userService, PasswordEncoder passwordEncoder) {
|
||||
this.credentialRepository = credentialRepository;
|
||||
this.userService = userService;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
public Credential getById(UUID credentialId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
|
||||
return credentialRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
|
||||
}
|
||||
|
||||
public Credential create(Credential credential) {
|
||||
if (credential.getUsername() == null || credential.getUsername().isBlank()) {
|
||||
throw new ValidationException("userName", "El usuario no puede estar vacío");
|
||||
}
|
||||
if (credential.getEmail() == null || !credential.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) {
|
||||
throw new ValidationException("email", "Formato de email no válido");
|
||||
}
|
||||
if (credential.getPassword() == null || credential.getPassword().length() < 6) {
|
||||
throw new ValidationException("password", "La contraseña tiene que tener al menos 6 caracteres");
|
||||
}
|
||||
if (credential.getServiceId() == null || credential.getServiceId() < 0) {
|
||||
throw new ValidationException("serviceId", "El identificador de servicio debe ser positivo");
|
||||
}
|
||||
|
||||
boolean existsUsername = credentialRepository.existsByUsernameAndServiceId(
|
||||
credential.getUsername(), credential.getServiceId());
|
||||
if (existsUsername) throw new ConflictException("El usuario ya existe para este servicio");
|
||||
|
||||
boolean existsEmail = credentialRepository.existsByEmailAndServiceId(
|
||||
credential.getEmail(), credential.getServiceId());
|
||||
if (existsEmail) throw new ConflictException("El email ya existe para este servicio");
|
||||
|
||||
credential.setCredentialId(UUID.randomUUID());
|
||||
credential.setPassword(passwordEncoder.encode(credential.getPassword()));
|
||||
return credentialRepository.save(credential);
|
||||
}
|
||||
|
||||
public List<Credential> getAll() {
|
||||
return credentialRepository.findAll();
|
||||
}
|
||||
|
||||
public List<Credential> getByServiceId(Byte serviceId) {
|
||||
return credentialRepository.findAllByServiceId(serviceId);
|
||||
}
|
||||
|
||||
public List<Credential> getByServiceIdFetchUser(Byte serviceId) {
|
||||
return credentialRepository.getByServiceIdFetchUser(serviceId);
|
||||
}
|
||||
|
||||
public List<Credential> getByUserId(UUID userId) {
|
||||
List<Credential> creds = credentialRepository.findByUserId(UuidUtil.uuidToBin(userId));
|
||||
if (creds.isEmpty()) {
|
||||
throw new NotFoundException("El usuario no tiene cuenta");
|
||||
}
|
||||
return creds;
|
||||
}
|
||||
|
||||
public List<Credential> getByUsername(@NotBlank String username) {
|
||||
return credentialRepository.findByUsername(username);
|
||||
}
|
||||
|
||||
public List<Credential> getByEmail(String email) {
|
||||
return credentialRepository.findByEmail(email);
|
||||
}
|
||||
|
||||
public Credential getByUserIdAndService(UUID userId, Byte serviceId) {
|
||||
return credentialRepository.findByUserIdAndServiceId(UuidUtil.uuidToBin(userId), serviceId)
|
||||
.orElseThrow(() -> new NotFoundException("El usuario no tiene cuenta en este sitio"));
|
||||
}
|
||||
|
||||
public Credential getForLogin(Byte serviceId, String username) {
|
||||
return credentialRepository.findByServiceIdAndUsername(serviceId, username)
|
||||
.orElseThrow(() -> new BadRequestException("Credenciales no válidas"));
|
||||
}
|
||||
|
||||
public boolean existsByUsernameAndService(String username, Byte serviceId) {
|
||||
return credentialRepository.findByUsernameAndServiceId(username, serviceId).isPresent();
|
||||
}
|
||||
|
||||
public boolean isOwner(UUID credentialId, UUID userId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
|
||||
|
||||
return credentialRepository.findById(idBytes)
|
||||
.map(c -> c.getUserId().equals(userId))
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
public Credential update(UUID credentialId, Credential changes) {
|
||||
Credential cred = getById(credentialId);
|
||||
|
||||
if (cred.getStatus() == (byte)0) {
|
||||
throw new ForbiddenException("La cuenta está inactiva, contacta con un administrador");
|
||||
}
|
||||
|
||||
if (changes.getUsername() != null) cred.setUsername(changes.getUsername());
|
||||
if (changes.getEmail() != null) cred.setEmail(changes.getEmail());
|
||||
if (changes.getStatus() != null) cred.setStatus(changes.getStatus());
|
||||
|
||||
int updated = credentialRepository.update(
|
||||
UuidUtil.uuidToBin(cred.getCredentialId()),
|
||||
cred.getUsername(),
|
||||
cred.getEmail(),
|
||||
cred.getStatus()
|
||||
);
|
||||
|
||||
if (updated == 0)
|
||||
throw new RuntimeException("No se pudo actualizar la cuenta");
|
||||
|
||||
return getById(credentialId);
|
||||
}
|
||||
|
||||
public Credential updatePassword(UUID credentialId, ChangePasswordRequest request) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
|
||||
|
||||
Credential cred = credentialRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
|
||||
|
||||
if (!passwordEncoder.matches(request.oldPassword(), cred.getPassword())) {
|
||||
throw new ValidationException("oldPassword", "La contraseña actual es incorrecta");
|
||||
}
|
||||
|
||||
cred.setPassword(passwordEncoder.encode(request.newPassword()));
|
||||
return credentialRepository.save(cred);
|
||||
}
|
||||
|
||||
public void delete(UUID credentialId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
|
||||
if(!credentialRepository.existsById(idBytes))
|
||||
throw new NotFoundException("Cuenta no encontrada");
|
||||
credentialRepository.deleteById(idBytes);
|
||||
}
|
||||
|
||||
public Byte getStatus(UUID userId, Byte serviceId) {
|
||||
Credential credential = getByUserIdAndService(userId, serviceId);
|
||||
return credential.getStatus();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package es.huertosbellavista.backend.core.service;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.miarma.backlib.exception.NotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import es.huertosbellavista.backend.core.model.File;
|
||||
import es.huertosbellavista.backend.core.repository.FileRepository;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class FileService {
|
||||
|
||||
private final FileRepository fileRepository;
|
||||
|
||||
@Value("${filesDir}")
|
||||
private String filesDir;
|
||||
|
||||
public FileService(FileRepository fileRepository) {
|
||||
this.fileRepository = fileRepository;
|
||||
}
|
||||
|
||||
public File getById(UUID fileId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(fileId);
|
||||
return fileRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Archivo no encontrado"));
|
||||
}
|
||||
|
||||
public List<File> getAll() {
|
||||
return fileRepository.findAll();
|
||||
}
|
||||
|
||||
public List<File> getByUserId(UUID userId) {
|
||||
return fileRepository.findByUploadedBy(userId);
|
||||
}
|
||||
|
||||
public File create(File file, byte[] fileBinary) throws IOException {
|
||||
Path dirPath = Paths.get(filesDir, String.valueOf(file.getContext()));
|
||||
if (!Files.exists(dirPath)) {
|
||||
Files.createDirectories(dirPath);
|
||||
}
|
||||
|
||||
Path filePath = dirPath.resolve(file.getFileName());
|
||||
try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) {
|
||||
fos.write(fileBinary);
|
||||
}
|
||||
|
||||
file.setFilePath(filePath.toString());
|
||||
|
||||
return fileRepository.save(file);
|
||||
}
|
||||
|
||||
public File update(UUID fileId, File file) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(fileId);
|
||||
if (!fileRepository.existsById(idBytes)) {
|
||||
throw new NotFoundException("Archivo no encontrado");
|
||||
}
|
||||
return fileRepository.save(file);
|
||||
}
|
||||
|
||||
public void delete(UUID fileId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(fileId);
|
||||
if (!fileRepository.existsById(idBytes)) {
|
||||
throw new NotFoundException("Archivo no encontrado");
|
||||
}
|
||||
fileRepository.deleteById(idBytes);
|
||||
}
|
||||
|
||||
public boolean isOwner(UUID fileId, UUID userId) {
|
||||
byte[] fileBytes = UuidUtil.uuidToBin(fileId);
|
||||
return fileRepository.findById(fileBytes)
|
||||
.map(f -> f.getUploadedBy().equals(userId))
|
||||
.orElse(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package es.huertosbellavista.backend.core.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import es.huertosbellavista.backend.core.mapper.UserMapper;
|
||||
import net.miarma.backlib.dto.ChangeAvatarRequest;
|
||||
import net.miarma.backlib.exception.NotFoundException;
|
||||
import net.miarma.backlib.exception.ValidationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import es.huertosbellavista.backend.core.model.User;
|
||||
import es.huertosbellavista.backend.core.repository.UserRepository;
|
||||
import net.miarma.backlib.dto.UserDto;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class UserService {
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public UserService(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
public List<User> getAll() {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
|
||||
public User getById(UUID userId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(userId);
|
||||
return userRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
|
||||
}
|
||||
|
||||
public User create(User user) {
|
||||
if(user.getDisplayName() == null || user.getDisplayName().isBlank()) {
|
||||
throw new ValidationException("displayName", "El nombre a mostrar es necesario");
|
||||
}
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
public User update(UUID userId, User changes) {
|
||||
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
|
||||
|
||||
if (changes.getDisplayName() != null) {
|
||||
String dn = changes.getDisplayName().trim();
|
||||
if (dn.isEmpty()) throw new ValidationException("displayName", "No puede estar vacío");
|
||||
if (dn.length() > 50) throw new ValidationException("displayName", "Máx 50 caracteres");
|
||||
user.setDisplayName(dn);
|
||||
}
|
||||
|
||||
if (changes.getAvatar() != null)
|
||||
user.setAvatar(changes.getAvatar());
|
||||
|
||||
if (changes.getGlobalRole() != null)
|
||||
user.setGlobalRole(changes.getGlobalRole());
|
||||
|
||||
if (changes.getGlobalStatus() != null)
|
||||
user.setGlobalStatus(changes.getGlobalStatus());
|
||||
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
public void delete(UUID userId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(userId);
|
||||
if(!userRepository.existsById(idBytes))
|
||||
throw new NotFoundException("Usuario no encontrado");
|
||||
userRepository.deleteById(idBytes);
|
||||
}
|
||||
|
||||
public UserDto updateAvatar(UUID userId, ChangeAvatarRequest req) {
|
||||
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
|
||||
user.setAvatar(req.avatar());
|
||||
userRepository.save(user);
|
||||
return UserMapper.toDto(user);
|
||||
}
|
||||
|
||||
public Byte getStatus(UUID userId) {
|
||||
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
|
||||
return user.getGlobalStatus();
|
||||
}
|
||||
|
||||
public void updateStatus(UUID userId, Byte status) {
|
||||
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
|
||||
user.setGlobalStatus(status);
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
||||
public Byte getRole(UUID userId) {
|
||||
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
|
||||
return user.getGlobalRole();
|
||||
}
|
||||
|
||||
public void updateRole(UUID userId, Byte role) {
|
||||
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
|
||||
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
|
||||
user.setGlobalRole(role);
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
||||
public boolean exists(UUID userId) {
|
||||
return userRepository.existsById(UuidUtil.uuidToBin(userId));
|
||||
}
|
||||
}
|
||||
23
backend/core/src/main/resources/application-dev.yml
Normal file
23
backend/core/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /v2/core
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mariadb://localhost:3306/huertos
|
||||
username: admin
|
||||
password: ${DB_PASS}
|
||||
driver-class-name: org.mariadb.jdbc.Driver
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.hibernate.SQL: DEBUG
|
||||
org.hibernate.orm.jdbc.bind: TRACE
|
||||
org.springframework.security: DEBUG
|
||||
|
||||
filesDir: "/home/jomaa/.config/miarma-backend/files"
|
||||
|
||||
jwt:
|
||||
private-key-path: /home/jomaa/.config/miarma-backend/private.pem
|
||||
public-key-path: /home/jomaa/.config/miarma-backend/public.pem
|
||||
22
backend/core/src/main/resources/application-prod.yml
Normal file
22
backend/core/src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /v2/core
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mariadb://mariadb:3306/huertos
|
||||
username: ${DB_USER}
|
||||
password: ${DB_PASS}
|
||||
driver-class-name: org.mariadb.jdbc.Driver
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.springframework.security: INFO
|
||||
org.hibernate.SQL: WARN
|
||||
|
||||
filesDir: "/files"
|
||||
|
||||
jwt:
|
||||
private-key-path: ${JWT_PRIVATE_KEY}
|
||||
public-key-path: ${JWT_PUBLIC_KEY}
|
||||
25
backend/core/src/main/resources/application.yml
Normal file
25
backend/core/src/main/resources/application.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
spring:
|
||||
application:
|
||||
name: core-service
|
||||
|
||||
jpa:
|
||||
open-in-view: false
|
||||
hibernate:
|
||||
ddl-auto: validate
|
||||
properties:
|
||||
hibernate:
|
||||
jdbc:
|
||||
time_zone: UTC
|
||||
|
||||
jackson:
|
||||
default-property-inclusion: non_null
|
||||
time-zone: Europe/Madrid
|
||||
|
||||
jwt:
|
||||
expiration-ms: 3600000
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info
|
||||
1
backend/huertos/.gitignore
vendored
Normal file
1
backend/huertos/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target/
|
||||
9
backend/huertos/huertos.iml
Normal file
9
backend/huertos/huertos.iml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="AdditionalModuleElements">
|
||||
<content url="file://$MODULE_DIR$" dumb="true">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
</content>
|
||||
</component>
|
||||
</module>
|
||||
102
backend/huertos/pom.xml
Normal file
102
backend/huertos/pom.xml
Normal file
@@ -0,0 +1,102 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>es.huertosbellavista</groupId>
|
||||
<artifactId>backend</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>huertos</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>25</maven.compiler.source>
|
||||
<maven.compiler.target>25</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gitea</id>
|
||||
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-http-client</artifactId>
|
||||
<version>4.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- CACHE -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-cache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
</dependency>
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>0.11.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.miarma</groupId>
|
||||
<artifactId>backlib</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,16 @@
|
||||
package es.huertosbellavista.backend.huertos;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
|
||||
@EnableCaching
|
||||
@SpringBootApplication(scanBasePackages = {
|
||||
"es.huertosbellavista.backend.huertos",
|
||||
"net.miarma.backlib"
|
||||
})
|
||||
public class HuertosApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(HuertosApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package es.huertosbellavista.backend.huertos.client;
|
||||
|
||||
import net.miarma.backlib.dto.ApiErrorDto;
|
||||
import net.miarma.backlib.dto.LoginRequest;
|
||||
import net.miarma.backlib.dto.LoginResponse;
|
||||
import net.miarma.backlib.exception.*;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
public class CoreAuthClient {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final String coreUrl;
|
||||
|
||||
public CoreAuthClient(
|
||||
@Qualifier("authRestTemplate") RestTemplate restTemplate,
|
||||
@Value("${core.url}") String coreUrl
|
||||
) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.coreUrl = coreUrl;
|
||||
}
|
||||
|
||||
|
||||
public LoginResponse login(LoginRequest req) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
HttpEntity<LoginRequest> requestEntity = new HttpEntity<>(req, headers);
|
||||
|
||||
ResponseEntity<LoginResponse> response = restTemplate.exchange(
|
||||
coreUrl + "/auth/login",
|
||||
HttpMethod.POST,
|
||||
requestEntity,
|
||||
LoginResponse.class
|
||||
);
|
||||
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(response);
|
||||
}
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
private void handleError(ResponseEntity<?> response) {
|
||||
HttpStatusCode statusCode = response.getStatusCode();
|
||||
|
||||
if (statusCode.equals(HttpStatus.UNAUTHORIZED)) {
|
||||
throw new UnauthorizedException("Credenciales no válidas");
|
||||
} else if (statusCode.equals(HttpStatus.FORBIDDEN)) {
|
||||
throw new ForbiddenException("Esa cuenta está desactivada");
|
||||
} else if (statusCode.equals(HttpStatus.NOT_FOUND)) {
|
||||
throw new NotFoundException("No encontrado");
|
||||
} else if (statusCode.equals(HttpStatus.BAD_REQUEST)) {
|
||||
throw new BadRequestException("Datos de solicitud faltantes");
|
||||
} else if (statusCode.equals(HttpStatus.CONFLICT)) {
|
||||
throw new ConflictException("Ya existe");
|
||||
} else if (statusCode.equals(HttpStatus.UNPROCESSABLE_CONTENT)) {
|
||||
throw new ValidationException("general", "Los datos no tienen formato válido");
|
||||
} else {
|
||||
if (statusCode.is4xxClientError()) {
|
||||
throw new BadRequestException(response.getBody().toString());
|
||||
} else {
|
||||
throw new RuntimeException("Error desconocido");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package es.huertosbellavista.backend.huertos.client;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestMetadataDto;
|
||||
import es.huertosbellavista.backend.huertos.util.UsernameGenerator;
|
||||
import net.miarma.backlib.dto.*;
|
||||
import net.miarma.backlib.exception.*;
|
||||
import net.miarma.backlib.security.PasswordGenerator;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import tools.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class HuertosWebClient {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final String coreUrl;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public HuertosWebClient(@Qualifier("secureRestTemplate") RestTemplate restTemplate,
|
||||
@Value("${core.url}") String coreUrl,
|
||||
ObjectMapper objectMapper) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.coreUrl = coreUrl;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
public UserWithCredentialDto getUserWithCredential(UUID userId, Byte serviceId) {
|
||||
ResponseEntity<UserWithCredentialDto> response = restTemplate.exchange(
|
||||
coreUrl + "/users/{user_id}/service/{service_id}",
|
||||
HttpMethod.GET,
|
||||
null,
|
||||
UserWithCredentialDto.class,
|
||||
userId, serviceId
|
||||
);
|
||||
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(response);
|
||||
}
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
public List<UserWithCredentialDto> getAllUsersWithCredentials(Byte serviceId) {
|
||||
ResponseEntity<UserWithCredentialDto[]> response = restTemplate.exchange(
|
||||
coreUrl + "/users/service/{service_id}",
|
||||
HttpMethod.GET,
|
||||
null,
|
||||
UserWithCredentialDto[].class,
|
||||
serviceId
|
||||
);
|
||||
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(response);
|
||||
}
|
||||
|
||||
UserWithCredentialDto[] arr = response.getBody();
|
||||
return arr == null ? List.of() : Arrays.asList(arr);
|
||||
}
|
||||
|
||||
public UserWithCredentialDto createUser(RequestMetadataDto metadataDto) {
|
||||
CreateUserDto userDto = new CreateUserDto(metadataDto.displayName(), null);
|
||||
HttpEntity<CreateUserDto> userRequestEntity = new HttpEntity<>(userDto);
|
||||
|
||||
ResponseEntity<UserDto> userResponse = restTemplate.exchange(
|
||||
coreUrl + "/users",
|
||||
HttpMethod.POST,
|
||||
userRequestEntity,
|
||||
UserDto.class
|
||||
);
|
||||
|
||||
if (!userResponse.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(userResponse);
|
||||
}
|
||||
|
||||
UserDto createdUser = userResponse.getBody();
|
||||
if (createdUser == null) {
|
||||
throw new RuntimeException("No se pudo crear al usuario");
|
||||
}
|
||||
|
||||
CreateCredentialDto credDto = new CreateCredentialDto(
|
||||
createdUser.getUserId(),
|
||||
(byte) 1,
|
||||
UsernameGenerator.generate(metadataDto.displayName(), metadataDto.memberNumber()),
|
||||
metadataDto.email(),
|
||||
PasswordGenerator.generate(8),
|
||||
(byte) 1
|
||||
);
|
||||
|
||||
HttpEntity<CreateCredentialDto> credRequestEntity = new HttpEntity<>(credDto);
|
||||
|
||||
ResponseEntity<CredentialDto> credResponse = restTemplate.exchange(
|
||||
coreUrl + "/credentials",
|
||||
HttpMethod.POST,
|
||||
credRequestEntity,
|
||||
CredentialDto.class
|
||||
);
|
||||
|
||||
if (!credResponse.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(credResponse);
|
||||
}
|
||||
|
||||
CredentialDto createdCred = credResponse.getBody();
|
||||
if (createdCred == null) {
|
||||
throw new RuntimeException("No se pudo crear la cuenta del usuario");
|
||||
}
|
||||
|
||||
return new UserWithCredentialDto(createdUser, createdCred);
|
||||
}
|
||||
|
||||
public void updateUser(UUID userId, UserWithCredentialDto dto) {
|
||||
HttpEntity<UserDto> userRequestEntity = new HttpEntity<>(dto.user());
|
||||
ResponseEntity<Void> userResponse = restTemplate.exchange(
|
||||
coreUrl + "/users/{user_id}",
|
||||
HttpMethod.PUT,
|
||||
userRequestEntity,
|
||||
Void.class,
|
||||
userId
|
||||
);
|
||||
|
||||
if (!userResponse.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(userResponse);
|
||||
}
|
||||
|
||||
HttpEntity<CredentialDto> credRequestEntity = new HttpEntity<>(dto.account());
|
||||
ResponseEntity<Void> credResponse = restTemplate.exchange(
|
||||
coreUrl + "/credentials/{credential_id}/full",
|
||||
HttpMethod.PUT,
|
||||
credRequestEntity,
|
||||
Void.class,
|
||||
dto.account().getCredentialId()
|
||||
);
|
||||
|
||||
if (!credResponse.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(credResponse);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteUser(UUID userId) {
|
||||
ResponseEntity<Void> response = restTemplate.exchange(
|
||||
coreUrl + "/users/{user_id}",
|
||||
HttpMethod.DELETE,
|
||||
null,
|
||||
Void.class,
|
||||
userId
|
||||
);
|
||||
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
if (response.getStatusCode() != HttpStatus.NOT_FOUND) {
|
||||
handleError(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Byte getCredentialStatus(UUID userId, Byte serviceId) {
|
||||
ResponseEntity<Byte> response = restTemplate.exchange(
|
||||
coreUrl + "/credentials/{service_id}/{user_id}/status",
|
||||
HttpMethod.GET,
|
||||
null,
|
||||
Byte.class,
|
||||
serviceId, userId
|
||||
);
|
||||
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(response);
|
||||
}
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
public void updateCredentialStatus(UUID userId, Byte serviceId, Byte newStatus) {
|
||||
ChangeStatusRequest req = new ChangeStatusRequest(newStatus);
|
||||
HttpEntity<ChangeStatusRequest> requestEntity = new HttpEntity<>(req);
|
||||
|
||||
ResponseEntity<Void> response = restTemplate.exchange(
|
||||
coreUrl + "/credentials/{service_id}/{user_id}/status",
|
||||
HttpMethod.PUT,
|
||||
requestEntity,
|
||||
Void.class,
|
||||
serviceId, userId
|
||||
);
|
||||
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
handleError(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleError(ResponseEntity<?> response) {
|
||||
HttpStatusCode statusCode = response.getStatusCode();
|
||||
|
||||
if (statusCode.equals(HttpStatus.UNAUTHORIZED)) {
|
||||
throw new UnauthorizedException("Credenciales no válidas");
|
||||
} else if (statusCode.equals(HttpStatus.FORBIDDEN)) {
|
||||
throw new ForbiddenException("Esa cuenta está desactivada");
|
||||
} else if (statusCode.equals(HttpStatus.NOT_FOUND)) {
|
||||
throw new NotFoundException("No encontrado");
|
||||
} else if (statusCode.equals(HttpStatus.BAD_REQUEST)) {
|
||||
throw new BadRequestException("Datos de solicitud faltantes");
|
||||
} else if (statusCode.equals(HttpStatus.CONFLICT)) {
|
||||
throw new ConflictException("Ya existe");
|
||||
} else if (statusCode.equals(HttpStatus.UNPROCESSABLE_CONTENT)) {
|
||||
throw new ValidationException("general", "Los datos no tienen formato válido");
|
||||
} else {
|
||||
if (statusCode.is4xxClientError()) {
|
||||
throw new BadRequestException(response.getBody().toString());
|
||||
} else {
|
||||
throw new RuntimeException("Error desconocido");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package es.huertosbellavista.backend.huertos.config;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
public class CacheConfig {
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
CaffeineCacheManager manager = new CaffeineCacheManager(
|
||||
"members", "memberById", "waitlist",
|
||||
"metadataByUserId", "metadataByMemberNumber", "metadataExists");
|
||||
manager.setCaffeine(
|
||||
Caffeine.newBuilder()
|
||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||
.maximumSize(10_000)
|
||||
);
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package es.huertosbellavista.backend.huertos.config;
|
||||
|
||||
import io.jsonwebtoken.io.IOException;
|
||||
import es.huertosbellavista.backend.huertos.service.CoreAuthService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
|
||||
@Bean
|
||||
public RestTemplate authRestTemplate() {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.setErrorHandler(new NoOpResponseErrorHandler());
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate secureRestTemplate(CoreAuthService coreAuthService) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
restTemplate.getInterceptors().add((request, body, execution) -> {
|
||||
String token = coreAuthService.getToken();
|
||||
request.getHeaders().setBearerAuth(token);
|
||||
return execution.execute(request, body);
|
||||
});
|
||||
|
||||
restTemplate.setErrorHandler(new NoOpResponseErrorHandler());
|
||||
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
public static class NoOpResponseErrorHandler implements ResponseErrorHandler {
|
||||
@Override
|
||||
public boolean hasError(ClientHttpResponse response) throws IOException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package es.huertosbellavista.backend.huertos.config;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.security.HuertosJwtFilter;
|
||||
import net.miarma.backlib.http.RestAccessDeniedHandler;
|
||||
import net.miarma.backlib.http.RestAuthEntryPoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityConfig {
|
||||
|
||||
private final HuertosJwtFilter jwtFilter;
|
||||
private final RestAuthEntryPoint authEntryPoint;
|
||||
private final RestAccessDeniedHandler accessDeniedHandler;
|
||||
private final CorsConfigurationSource corsConfigurationSource;
|
||||
|
||||
public SecurityConfig(
|
||||
HuertosJwtFilter jwtFilter,
|
||||
RestAuthEntryPoint authEntryPoint,
|
||||
RestAccessDeniedHandler accessDeniedHandler,
|
||||
Optional<CorsConfigurationSource> corsConfigurationSource
|
||||
) {
|
||||
this.jwtFilter = jwtFilter;
|
||||
this.authEntryPoint = authEntryPoint;
|
||||
this.accessDeniedHandler = accessDeniedHandler;
|
||||
this.corsConfigurationSource = corsConfigurationSource.orElse(null);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
if (corsConfigurationSource != null) {
|
||||
http.cors(Customizer.withDefaults());
|
||||
}
|
||||
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.exceptionHandling(ex -> ex
|
||||
.authenticationEntryPoint(authEntryPoint)
|
||||
.accessDeniedHandler(accessDeniedHandler)
|
||||
)
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
// PUBLICAS
|
||||
.requestMatchers("/auth/login").permitAll()
|
||||
.requestMatchers("/users/waitlist/limited").permitAll()
|
||||
.requestMatchers("/requests").permitAll()
|
||||
.requestMatchers("/users/latest-number").permitAll()
|
||||
// PRIVADAS
|
||||
.anyRequest().authenticated()
|
||||
);
|
||||
|
||||
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.AnnouncementDto;
|
||||
import es.huertosbellavista.backend.huertos.mapper.AnnouncementMapper;
|
||||
import es.huertosbellavista.backend.huertos.model.Announcement;
|
||||
import es.huertosbellavista.backend.huertos.service.AnnouncementService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/announcements")
|
||||
public class AnnouncementController {
|
||||
|
||||
private final AnnouncementService announcementService;
|
||||
|
||||
public AnnouncementController(AnnouncementService announcementService) {
|
||||
this.announcementService = announcementService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<AnnouncementDto.Response>> getAll() {
|
||||
return ResponseEntity.ok(
|
||||
announcementService.getAll()
|
||||
.stream()
|
||||
.map(AnnouncementMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/{announce_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<AnnouncementDto.Response> getById(@PathVariable("announce_id") UUID announcementId) {
|
||||
Announcement announcement = announcementService.getById(announcementId);
|
||||
return ResponseEntity.ok(AnnouncementMapper.toResponse(announcement));
|
||||
}
|
||||
|
||||
@PutMapping("/{announce_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<AnnouncementDto.Response> update(
|
||||
@PathVariable("announce_id") UUID announcementId,
|
||||
@RequestBody AnnouncementDto.Request dto
|
||||
) {
|
||||
return ResponseEntity.ok(
|
||||
AnnouncementMapper.toResponse(announcementService.update(announcementId, AnnouncementMapper.toEntity(dto)))
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<AnnouncementDto.Response> create(@RequestBody AnnouncementDto.Request dto) {
|
||||
return ResponseEntity.ok(
|
||||
AnnouncementMapper.toResponse(
|
||||
announcementService.create(
|
||||
AnnouncementMapper.toEntity(dto)
|
||||
)));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{announce_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<Map<String, String>> delete(@PathVariable("announce_id") UUID announcementId) {
|
||||
announcementService.delete(announcementId);
|
||||
return ResponseEntity.ok(Map.of("message", "Deleted announcement: " + announcementId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.BalanceDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.view.VBalanceWithTotalsDto;
|
||||
import es.huertosbellavista.backend.huertos.mapper.BalanceMapper;
|
||||
import es.huertosbellavista.backend.huertos.mapper.view.VBalanceWithTotalsMapper;
|
||||
import es.huertosbellavista.backend.huertos.model.Balance;
|
||||
import es.huertosbellavista.backend.huertos.service.BalanceService;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/balance")
|
||||
public class BalanceController {
|
||||
private final BalanceService balanceService;
|
||||
|
||||
public BalanceController(BalanceService balanceService) {
|
||||
this.balanceService = balanceService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<BalanceDto> getBalance() {
|
||||
Balance balance = balanceService.get();
|
||||
return ResponseEntity.ok(BalanceMapper.toDto(balance));
|
||||
}
|
||||
|
||||
@GetMapping("/with-totals")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<VBalanceWithTotalsDto> getWithTotals() {
|
||||
return ResponseEntity.ok(VBalanceWithTotalsMapper.toDto(balanceService.getWithTotals()));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<BalanceDto> setBalance(BalanceDto dto) {
|
||||
return ResponseEntity.ok(
|
||||
BalanceMapper.toDto(
|
||||
balanceService.create(BalanceMapper.toEntity(dto))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.ExpenseDto;
|
||||
import es.huertosbellavista.backend.huertos.mapper.ExpenseMapper;
|
||||
import es.huertosbellavista.backend.huertos.model.Expense;
|
||||
import es.huertosbellavista.backend.huertos.service.ExpenseService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/expenses")
|
||||
public class ExpenseController {
|
||||
private ExpenseService expenseService;
|
||||
|
||||
public ExpenseController(ExpenseService expenseService) {
|
||||
this.expenseService = expenseService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<ExpenseDto.Response>> getAll() {
|
||||
return ResponseEntity.ok(
|
||||
expenseService.getAll()
|
||||
.stream()
|
||||
.map(ExpenseMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<ExpenseDto.Response> create(@RequestBody ExpenseDto.Request dto) {
|
||||
return ResponseEntity.ok(
|
||||
ExpenseMapper.toResponse(
|
||||
expenseService.create(
|
||||
ExpenseMapper.toEntity(dto)
|
||||
)));
|
||||
}
|
||||
|
||||
@GetMapping("/{expense_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<ExpenseDto.Response> getById(@PathVariable("expense_id") UUID expenseId) {
|
||||
Expense expense = expenseService.getById(expenseId);
|
||||
return ResponseEntity.ok(ExpenseMapper.toResponse(expense));
|
||||
}
|
||||
|
||||
@PutMapping("/{expense_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<ExpenseDto.Response> update(
|
||||
@PathVariable("expense_id") UUID expenseId,
|
||||
@RequestBody ExpenseDto.Request dto
|
||||
) {
|
||||
Expense updated = expenseService.update(
|
||||
expenseId,
|
||||
ExpenseMapper.toEntity(dto)
|
||||
);
|
||||
|
||||
return ResponseEntity.ok(
|
||||
ExpenseMapper.toResponse(updated)
|
||||
);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{expense_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<Map<String,String>> delete(@PathVariable("expense_id") UUID expenseId) {
|
||||
expenseService.delete(expenseId);
|
||||
return ResponseEntity.ok(Map.of("message", "Deleted expense: " + expenseId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.client.CoreAuthClient;
|
||||
import es.huertosbellavista.backend.huertos.dto.HuertosLoginResponse;
|
||||
import es.huertosbellavista.backend.huertos.mapper.UserMetadataMapper;
|
||||
import es.huertosbellavista.backend.huertos.model.UserMetadata;
|
||||
import es.huertosbellavista.backend.huertos.service.UserMetadataService;
|
||||
import net.miarma.backlib.dto.LoginRequest;
|
||||
import net.miarma.backlib.dto.LoginResponse;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/auth")
|
||||
public class HuertosAuthController {
|
||||
private final UserMetadataService metadataService;
|
||||
private final CoreAuthClient authClient;
|
||||
|
||||
public HuertosAuthController(UserMetadataService metadataService,
|
||||
CoreAuthClient authClient) {
|
||||
this.metadataService = metadataService;
|
||||
this.authClient = authClient;
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<HuertosLoginResponse> login(@RequestBody LoginRequest req) {
|
||||
LoginResponse coreResponse = authClient.login(req);
|
||||
UserMetadata metadata = metadataService.getById(coreResponse.user().getUserId());
|
||||
return ResponseEntity.ok(
|
||||
new HuertosLoginResponse(
|
||||
coreResponse.token(),
|
||||
coreResponse.user(),
|
||||
coreResponse.account(),
|
||||
UserMetadataMapper.toDto(metadata)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.IncomeDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.view.VIncomesWithInfoDto;
|
||||
import es.huertosbellavista.backend.huertos.mapper.IncomeMapper;
|
||||
import es.huertosbellavista.backend.huertos.mapper.view.VIncomesWithInfoMapper;
|
||||
import es.huertosbellavista.backend.huertos.model.Income;
|
||||
import es.huertosbellavista.backend.huertos.service.IncomeService;
|
||||
import es.huertosbellavista.backend.huertos.service.view.VIncomesWithInfoService;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/incomes")
|
||||
public class IncomeController {
|
||||
private IncomeService incomeService;
|
||||
private VIncomesWithInfoService vIncomesWithInfoService;
|
||||
private JwtService jwtService;
|
||||
|
||||
public IncomeController(IncomeService incomeService, VIncomesWithInfoService vIncomesWithInfoService, JwtService jwtService) {
|
||||
this.incomeService = incomeService;
|
||||
this.vIncomesWithInfoService = vIncomesWithInfoService;
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<IncomeDto.Response>> getAll() {
|
||||
return ResponseEntity.ok(
|
||||
incomeService.getAll()
|
||||
.stream()
|
||||
.map(IncomeMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/with-info")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<VIncomesWithInfoDto>> getAllWithInfo() {
|
||||
return ResponseEntity.ok(
|
||||
vIncomesWithInfoService.getAll()
|
||||
.stream()
|
||||
.map(VIncomesWithInfoMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/mine")
|
||||
public ResponseEntity<List<IncomeDto.Response>> getMine(@RequestHeader("Authorization") String authHeader) {
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
|
||||
UUID userId;
|
||||
try {
|
||||
userId = jwtService.getUserId(token);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(
|
||||
incomeService.getByUserId(userId)
|
||||
.stream()
|
||||
.map(IncomeMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<IncomeDto.Response> create(@RequestBody IncomeDto.Request dto) {
|
||||
return ResponseEntity.ok(
|
||||
IncomeMapper.toResponse(
|
||||
incomeService.create(
|
||||
IncomeMapper.toEntity(dto)
|
||||
)));
|
||||
}
|
||||
|
||||
@GetMapping("/{income_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<IncomeDto.Response> getById(@PathVariable("income_id") UUID incomeId) {
|
||||
Income income = incomeService.getById(incomeId);
|
||||
return ResponseEntity.ok(IncomeMapper.toResponse(income));
|
||||
}
|
||||
|
||||
@PutMapping("/{income_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<IncomeDto.Response> update(
|
||||
@PathVariable("income_id") UUID incomeId,
|
||||
@RequestBody IncomeDto.Request dto
|
||||
) {
|
||||
IO.println(dto.getCreatedAt());
|
||||
return ResponseEntity.ok(
|
||||
IncomeMapper.toResponse(
|
||||
incomeService.update(
|
||||
incomeId, IncomeMapper.toEntity(dto))));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{income_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<Map<String,String>> delete(@PathVariable("income_id") UUID incomeId) {
|
||||
incomeService.delete(incomeId);
|
||||
return ResponseEntity.ok(Map.of("message", "Deleted income: " + incomeId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.DropdownDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.MemberDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.MemberProfileDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.WaitlistCensoredDto;
|
||||
import net.miarma.backend.huertos.dto.*;
|
||||
import es.huertosbellavista.backend.huertos.dto.view.VIncomesWithInfoDto;
|
||||
import es.huertosbellavista.backend.huertos.security.HuertosPrincipal;
|
||||
import es.huertosbellavista.backend.huertos.service.MemberService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
public class MemberController {
|
||||
|
||||
private final MemberService memberService;
|
||||
|
||||
public MemberController(MemberService memberService) {
|
||||
this.memberService = memberService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<MemberDto>> getAll() {
|
||||
return ResponseEntity.ok(memberService.getAll());
|
||||
}
|
||||
|
||||
@GetMapping("/me")
|
||||
public ResponseEntity<MemberProfileDto> getMe(Authentication authentication) {
|
||||
if (!(authentication.getPrincipal() instanceof HuertosPrincipal principal)) {
|
||||
throw new IllegalStateException("Tipo de autenticación inválida");
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(
|
||||
memberService.getMyProfile(principal.getUserId())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/dropdown")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<DropdownDto>> getDropdown() {
|
||||
return ResponseEntity.ok(memberService.getDropdown());
|
||||
}
|
||||
|
||||
@GetMapping("/{user_id:[0-9a-fA-F\\-]{36}}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<MemberDto> getById(@PathVariable("user_id") UUID userId) {
|
||||
return ResponseEntity.ok(memberService.getById(userId));
|
||||
}
|
||||
|
||||
@GetMapping("/latest-number")
|
||||
public ResponseEntity<Integer> getLatestNumber() {
|
||||
return ResponseEntity.ok(memberService.getLatestMemberNumber());
|
||||
}
|
||||
|
||||
@GetMapping("/waitlist")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<MemberDto>> getWaitlist() {
|
||||
return ResponseEntity.ok(memberService.getWaitlist());
|
||||
}
|
||||
|
||||
@GetMapping("/waitlist/limited")
|
||||
public ResponseEntity<List<WaitlistCensoredDto>> getWaitlistLimited() {
|
||||
return ResponseEntity.ok(memberService.getWaitlistLimited());
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<MemberDto> getByMemberNumber(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.getByMemberNumber(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}/incomes")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<VIncomesWithInfoDto>> getMemberIncomes(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.getIncomes(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}/has-paid")
|
||||
public ResponseEntity<Boolean> getMemberHasPaid(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.hasPaid(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}/has-collaborator")
|
||||
public ResponseEntity<Boolean> getMemberHasCollaborator(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.hasCollaborator(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}/has-greenhouse")
|
||||
public ResponseEntity<Boolean> getMemberHasGreenhouse(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.hasGreenhouse(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}/has-collaborator-request")
|
||||
public ResponseEntity<Boolean> getMemberHasCollaboratorRequest(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.hasCollaboratorRequest(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/number/{member_number}/has-greenhouse-request")
|
||||
public ResponseEntity<Boolean> getMemberHasGreenhouseRequest(@PathVariable("member_number") Integer memberNumber) {
|
||||
return ResponseEntity.ok(memberService.hasGreenhouseRequest(memberNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/plot/{plot_number}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<MemberDto> getByPlotNumber(@PathVariable("plot_number") Integer plotNumber) {
|
||||
return ResponseEntity.ok(memberService.getByPlotNumber(plotNumber));
|
||||
}
|
||||
|
||||
@GetMapping("/dni/{dni}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<MemberDto> getByDni(@PathVariable("dni") String dni) {
|
||||
return ResponseEntity.ok(memberService.getByDni(dni));
|
||||
}
|
||||
|
||||
@PutMapping("/{user_id:[0-9a-fA-F\\-]{36}}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<MemberDto> update(
|
||||
@PathVariable("user_id") UUID userId,
|
||||
@RequestBody MemberDto changes
|
||||
) {
|
||||
return ResponseEntity.ok(memberService.update(userId, changes));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package es.huertosbellavista.backend.huertos.controller;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestCountDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestWithMetadataDto;
|
||||
import net.miarma.backend.huertos.dto.*;
|
||||
import es.huertosbellavista.backend.huertos.mapper.RequestMapper;
|
||||
import es.huertosbellavista.backend.huertos.mapper.RequestWithMetadataMapper;
|
||||
import es.huertosbellavista.backend.huertos.model.Request;
|
||||
import es.huertosbellavista.backend.huertos.service.RequestAcceptanceService;
|
||||
import es.huertosbellavista.backend.huertos.service.RequestService;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/requests")
|
||||
public class RequestController {
|
||||
|
||||
private final RequestService requestService;
|
||||
private final RequestAcceptanceService requestAcceptanceService;
|
||||
private final JwtService jwtService;
|
||||
|
||||
public RequestController(RequestService requestService,
|
||||
RequestAcceptanceService requestAcceptanceService,
|
||||
JwtService jwtService) {
|
||||
this.requestService = requestService;
|
||||
this.requestAcceptanceService = requestAcceptanceService;
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<RequestDto.Response>> getAll() {
|
||||
return ResponseEntity.ok(
|
||||
requestService.getAll()
|
||||
.stream()
|
||||
.map(RequestMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<RequestDto.Response> create(@RequestBody RequestDto.Request dto) {
|
||||
return ResponseEntity.ok(
|
||||
RequestMapper.toResponse(
|
||||
requestService.create(
|
||||
RequestMapper.toEntity(dto)
|
||||
)));
|
||||
}
|
||||
|
||||
@GetMapping("/count")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<RequestCountDto> getRequestCount() {
|
||||
return ResponseEntity.ok(
|
||||
requestService.getAll()
|
||||
.stream()
|
||||
.map(RequestMapper::toResponse)
|
||||
.collect(Collectors.collectingAndThen(
|
||||
Collectors.counting(),
|
||||
RequestCountDto::new
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/mine")
|
||||
public ResponseEntity<List<RequestDto.Response>> getMine(@RequestHeader("Authorization") String authHeader) {
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
|
||||
UUID userId;
|
||||
try {
|
||||
userId = jwtService.getUserId(token);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(
|
||||
requestService.getByUserId(userId)
|
||||
.stream()
|
||||
.map(RequestMapper::toResponse)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/full")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<List<RequestWithMetadataDto>> getAllWithMetadata() {
|
||||
return ResponseEntity.ok(
|
||||
requestService.getAll()
|
||||
.stream()
|
||||
.map(RequestWithMetadataMapper::toDto)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/full/{request_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<RequestWithMetadataDto> getByIdWithMetadata(
|
||||
@PathVariable("request_id") UUID requestId) {
|
||||
Request request = requestService.getById(requestId);
|
||||
return ResponseEntity.ok(RequestWithMetadataMapper.toDto(request));
|
||||
}
|
||||
|
||||
@GetMapping("/{request_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<RequestDto.Response> getById(@PathVariable("request_id") UUID requestId) {
|
||||
Request request = requestService.getById(requestId);
|
||||
return ResponseEntity.ok(RequestMapper.toResponse(request));
|
||||
}
|
||||
|
||||
@PutMapping("/{request_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<RequestDto.Response> update(
|
||||
@PathVariable("request_id") UUID requestId,
|
||||
@RequestBody RequestDto.Request dto
|
||||
) {
|
||||
return ResponseEntity.ok(
|
||||
RequestMapper.toResponse(requestService.update(requestId, RequestMapper.toEntity(dto)))
|
||||
);
|
||||
}
|
||||
|
||||
@PutMapping("/{request_id}/accept")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<Map<String, String>> acceptRequest(@PathVariable("request_id") UUID requestId) {
|
||||
Request r = requestAcceptanceService.acceptRequest(requestId);
|
||||
requestAcceptanceService.handleSideEffects(r);
|
||||
return ResponseEntity.ok(Map.of("message", "Accepted request: " + r.getRequestId()));
|
||||
}
|
||||
|
||||
@PutMapping("/{request_id}/reject")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<Map<String, String>> rejectRequest(@PathVariable("request_id") UUID requestId) {
|
||||
Request r = requestService.reject(requestId);
|
||||
return ResponseEntity.ok(Map.of("message", "Denied request: " + r.getRequestId()));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{request_id}")
|
||||
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
|
||||
public ResponseEntity<Map<String, String>> delete(@PathVariable("request_id") UUID requestId) {
|
||||
requestService.delete(requestId);
|
||||
return ResponseEntity.ok(Map.of("message", "Deleted request: " + requestId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AnnouncementDto {
|
||||
public static class Request {
|
||||
private String body;
|
||||
private Byte priority;
|
||||
private UUID publishedBy;
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Byte getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void setPriority(Byte priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public UUID getPublishedBy() {
|
||||
return publishedBy;
|
||||
}
|
||||
|
||||
public void setPublishedBy(UUID publishedBy) {
|
||||
this.publishedBy = publishedBy;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Response {
|
||||
private UUID announceId;
|
||||
private String body;
|
||||
private Byte priority;
|
||||
private UUID publishedBy;
|
||||
private String publishedByName;
|
||||
private Instant createdAt;
|
||||
|
||||
public UUID getAnnounceId() {
|
||||
return announceId;
|
||||
}
|
||||
|
||||
public void setAnnounceId(UUID announceId) {
|
||||
this.announceId = announceId;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Byte getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void setPriority(Byte priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public UUID getPublishedBy() {
|
||||
return publishedBy;
|
||||
}
|
||||
|
||||
public void setPublishedBy(UUID publishedBy) {
|
||||
this.publishedBy = publishedBy;
|
||||
}
|
||||
|
||||
public String getPublishedByName() { return publishedByName; }
|
||||
|
||||
public void setPublishedByName(String publishedByName) { this.publishedByName = publishedByName; }
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
||||
public class BalanceDto {
|
||||
private Byte id;
|
||||
private BigDecimal initialBank;
|
||||
private BigDecimal initialCash;
|
||||
private Instant createdAt;
|
||||
|
||||
public Byte getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialBank() {
|
||||
return initialBank;
|
||||
}
|
||||
|
||||
public void setInitialBank(BigDecimal initialBank) {
|
||||
this.initialBank = initialBank;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialCash() {
|
||||
return initialCash;
|
||||
}
|
||||
|
||||
public void setInitialCash(BigDecimal initialCash) {
|
||||
this.initialCash = initialCash;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record DropdownDto(UUID userId, Integer memberNumber, String displayName) {
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ExpenseDto {
|
||||
public static class Request {
|
||||
private String concept;
|
||||
private BigDecimal amount;
|
||||
private String supplier;
|
||||
private String invoice;
|
||||
private Byte type;
|
||||
private Instant createdAt;
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getSupplier() {
|
||||
return supplier;
|
||||
}
|
||||
|
||||
public void setSupplier(String supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public String getInvoice() {
|
||||
return invoice;
|
||||
}
|
||||
|
||||
public void setInvoice(String invoice) {
|
||||
this.invoice = invoice;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Response {
|
||||
private UUID expenseId;
|
||||
private String concept;
|
||||
private BigDecimal amount;
|
||||
private String supplier;
|
||||
private String invoice;
|
||||
private Byte type;
|
||||
private Instant createdAt;
|
||||
|
||||
public UUID getExpenseId() {
|
||||
return expenseId;
|
||||
}
|
||||
|
||||
public void setExpenseId(UUID expenseId) {
|
||||
this.expenseId = expenseId;
|
||||
}
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getSupplier() {
|
||||
return supplier;
|
||||
}
|
||||
|
||||
public void setSupplier(String supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public String getInvoice() {
|
||||
return invoice;
|
||||
}
|
||||
|
||||
public void setInvoice(String invoice) {
|
||||
this.invoice = invoice;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import net.miarma.backlib.dto.CredentialDto;
|
||||
import net.miarma.backlib.dto.UserDto;
|
||||
|
||||
public record HuertosLoginResponse(
|
||||
String token,
|
||||
UserDto user,
|
||||
CredentialDto account,
|
||||
UserMetadataDto metadata
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class IncomeDto {
|
||||
public static class Request {
|
||||
private UUID userId;
|
||||
private Integer memberNumber;
|
||||
private String concept;
|
||||
private BigDecimal amount;
|
||||
private Byte type;
|
||||
private Byte frequency;
|
||||
private Instant createdAt;
|
||||
|
||||
public Integer getMemberNumber() {
|
||||
return memberNumber;
|
||||
}
|
||||
|
||||
public void setMemberNumber(Integer memberNumber) {
|
||||
this.memberNumber = memberNumber;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(Byte frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Response {
|
||||
private UUID incomeId;
|
||||
private UUID userId;
|
||||
private String concept;
|
||||
private BigDecimal amount;
|
||||
private Byte type;
|
||||
private Byte frequency;
|
||||
private Instant createdAt;
|
||||
|
||||
public UUID getIncomeId() {
|
||||
return incomeId;
|
||||
}
|
||||
|
||||
public void setIncomeId(UUID incomeId) {
|
||||
this.incomeId = incomeId;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(Byte frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import net.miarma.backlib.dto.CredentialDto;
|
||||
import net.miarma.backlib.dto.UserDto;
|
||||
|
||||
public record MemberDto(UserDto user,
|
||||
CredentialDto account,
|
||||
UserMetadataDto metadata) {}
|
||||
@@ -0,0 +1,20 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.view.VIncomesWithInfoDto;
|
||||
import net.miarma.backlib.dto.CredentialDto;
|
||||
import net.miarma.backlib.dto.UserDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record MemberProfileDto(
|
||||
UserDto user,
|
||||
CredentialDto account,
|
||||
UserMetadataDto metadata,
|
||||
List<RequestDto.Response> requests,
|
||||
List<VIncomesWithInfoDto> payments,
|
||||
boolean hasCollaborator,
|
||||
boolean hasGreenhouse,
|
||||
boolean hasCollaboratorRequest,
|
||||
boolean hasGreenhouseRequest
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
public record RequestCountDto(Long count) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RequestDto {
|
||||
public static class Request {
|
||||
private Byte type;
|
||||
private UUID userId;
|
||||
private String name;
|
||||
private RequestMetadataDto metadata;
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public RequestMetadataDto getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public void setMetadata(RequestMetadataDto metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Response {
|
||||
private UUID requestId;
|
||||
private Byte type;
|
||||
private Byte status;
|
||||
private UUID userId;
|
||||
private String name;
|
||||
private RequestMetadataDto metadata;
|
||||
private Instant createdAt;
|
||||
|
||||
public UUID getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
public void setRequestId(UUID requestId) {
|
||||
this.requestId = requestId;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Byte status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public RequestMetadataDto getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public void setMetadata(RequestMetadataDto metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public record RequestMetadataDto(
|
||||
Long id,
|
||||
String displayName,
|
||||
String dni,
|
||||
String phone,
|
||||
String email,
|
||||
String username,
|
||||
String address,
|
||||
String zipCode,
|
||||
String city,
|
||||
Integer memberNumber,
|
||||
Integer plotNumber,
|
||||
Byte type,
|
||||
Instant createdAt
|
||||
) {}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public record RequestWithMetadataDto(
|
||||
UUID requestId,
|
||||
UUID userId,
|
||||
String name,
|
||||
Byte type,
|
||||
Byte status,
|
||||
Instant createdAt,
|
||||
RequestMetadataDto metadata
|
||||
) {}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserMetadataDto {
|
||||
private UUID userId;
|
||||
private Integer memberNumber;
|
||||
private Integer plotNumber;
|
||||
private String dni;
|
||||
private String phone;
|
||||
private Byte type;
|
||||
private Byte role;
|
||||
private String notes;
|
||||
private Instant createdAt;
|
||||
private Instant assignedAt;
|
||||
private Instant deactivatedAt;
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getMemberNumber() {
|
||||
return memberNumber;
|
||||
}
|
||||
|
||||
public void setMemberNumber(Integer memberNumber) {
|
||||
this.memberNumber = memberNumber;
|
||||
}
|
||||
|
||||
public Integer getPlotNumber() {
|
||||
return plotNumber;
|
||||
}
|
||||
|
||||
public void setPlotNumber(Integer plotNumber) {
|
||||
this.plotNumber = plotNumber;
|
||||
}
|
||||
|
||||
public String getDni() {
|
||||
return dni;
|
||||
}
|
||||
|
||||
public void setDni(String dni) {
|
||||
this.dni = dni;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(Byte role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(String notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Instant getAssignedAt() {
|
||||
return assignedAt;
|
||||
}
|
||||
|
||||
public void setAssignedAt(Instant assignedAt) {
|
||||
this.assignedAt = assignedAt;
|
||||
}
|
||||
|
||||
public Instant getDeactivatedAt() {
|
||||
return deactivatedAt;
|
||||
}
|
||||
|
||||
public void setDeactivatedAt(Instant deactivatedAt) {
|
||||
this.deactivatedAt = deactivatedAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package es.huertosbellavista.backend.huertos.dto;
|
||||
|
||||
public class WaitlistCensoredDto {
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package es.huertosbellavista.backend.huertos.dto.view;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
||||
public class VBalanceWithTotalsDto {
|
||||
private Byte id;
|
||||
private BigDecimal initialBank;
|
||||
private BigDecimal initialCash;
|
||||
private BigDecimal totalBankExpenses;
|
||||
private BigDecimal totalCashExpenses;
|
||||
private BigDecimal totalBankIncomes;
|
||||
private BigDecimal totalCashIncomes;
|
||||
private Instant createdAt;
|
||||
|
||||
public Byte getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialBank() {
|
||||
return initialBank;
|
||||
}
|
||||
|
||||
public void setInitialBank(BigDecimal initialBank) {
|
||||
this.initialBank = initialBank;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialCash() {
|
||||
return initialCash;
|
||||
}
|
||||
|
||||
public void setInitialCash(BigDecimal initialCash) {
|
||||
this.initialCash = initialCash;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalBankExpenses() {
|
||||
return totalBankExpenses;
|
||||
}
|
||||
|
||||
public void setTotalBankExpenses(BigDecimal totalBankExpenses) {
|
||||
this.totalBankExpenses = totalBankExpenses;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalCashExpenses() {
|
||||
return totalCashExpenses;
|
||||
}
|
||||
|
||||
public void setTotalCashExpenses(BigDecimal totalCashExpenses) {
|
||||
this.totalCashExpenses = totalCashExpenses;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalBankIncomes() {
|
||||
return totalBankIncomes;
|
||||
}
|
||||
|
||||
public void setTotalBankIncomes(BigDecimal totalBankIncomes) {
|
||||
this.totalBankIncomes = totalBankIncomes;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalCashIncomes() {
|
||||
return totalCashIncomes;
|
||||
}
|
||||
|
||||
public void setTotalCashIncomes(BigDecimal totalCashIncomes) {
|
||||
this.totalCashIncomes = totalCashIncomes;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package es.huertosbellavista.backend.huertos.dto.view;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VIncomesWithInfoDto {
|
||||
private UUID incomeId;
|
||||
private UUID userId;
|
||||
private String displayName;
|
||||
private Integer memberNumber;
|
||||
private String concept;
|
||||
private BigDecimal amount;
|
||||
private Byte type;
|
||||
private Byte frequency;
|
||||
private Instant createdAt;
|
||||
|
||||
public UUID getIncomeId() {
|
||||
return incomeId;
|
||||
}
|
||||
|
||||
public void setIncomeId(UUID incomeId) {
|
||||
this.incomeId = incomeId;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public Integer getMemberNumber() {
|
||||
return memberNumber;
|
||||
}
|
||||
|
||||
public void setMemberNumber(Integer memberNumber) {
|
||||
this.memberNumber = memberNumber;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(Byte frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.AnnouncementDto;
|
||||
import es.huertosbellavista.backend.huertos.model.Announcement;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AnnouncementMapper {
|
||||
|
||||
public static AnnouncementDto.Response toResponse(Announcement entity) {
|
||||
AnnouncementDto.Response dto = new AnnouncementDto.Response();
|
||||
dto.setAnnounceId(entity.getAnnounceId());
|
||||
dto.setBody(entity.getBody());
|
||||
dto.setPriority(entity.getPriority());
|
||||
dto.setPublishedBy(entity.getPublishedBy());
|
||||
dto.setPublishedByName(entity.getPublishedByName());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static Announcement toEntity(AnnouncementDto.Request dto) {
|
||||
Announcement entity = new Announcement();
|
||||
entity.setAnnounceId(UUID.randomUUID());
|
||||
entity.setBody(dto.getBody());
|
||||
entity.setPriority(dto.getPriority());
|
||||
entity.setPublishedBy(dto.getPublishedBy());
|
||||
entity.setCreatedAt(Instant.now());
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.BalanceDto;
|
||||
import es.huertosbellavista.backend.huertos.model.Balance;
|
||||
|
||||
public class BalanceMapper {
|
||||
|
||||
public static BalanceDto toDto(Balance balance) {
|
||||
if (balance == null) return null;
|
||||
|
||||
BalanceDto dto = new BalanceDto();
|
||||
dto.setId(balance.getId());
|
||||
dto.setInitialBank(balance.getInitialBank());
|
||||
dto.setInitialCash(balance.getInitialCash());
|
||||
dto.setCreatedAt(balance.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static Balance toEntity(BalanceDto dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Balance balance = new Balance();
|
||||
balance.setId(dto.getId());
|
||||
balance.setInitialBank(dto.getInitialBank());
|
||||
balance.setInitialCash(dto.getInitialCash());
|
||||
balance.setCreatedAt(dto.getCreatedAt());
|
||||
return balance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.DropdownDto;
|
||||
import es.huertosbellavista.backend.huertos.dto.MemberDto;
|
||||
|
||||
public class DropdownDtoMapper {
|
||||
public static DropdownDto toDto(MemberDto dto) {
|
||||
return new DropdownDto(dto.user().getUserId(), dto.metadata().getMemberNumber(), dto.user().getDisplayName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.ExpenseDto;
|
||||
import es.huertosbellavista.backend.huertos.model.Expense;
|
||||
|
||||
public class ExpenseMapper {
|
||||
|
||||
public static ExpenseDto.Response toResponse(Expense entity) {
|
||||
if (entity == null) return null;
|
||||
|
||||
ExpenseDto.Response dto = new ExpenseDto.Response();
|
||||
dto.setExpenseId(entity.getExpenseId());
|
||||
dto.setConcept(entity.getConcept());
|
||||
dto.setAmount(entity.getAmount());
|
||||
dto.setSupplier(entity.getSupplier());
|
||||
dto.setInvoice(entity.getInvoice());
|
||||
dto.setType(entity.getType());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static Expense toEntity(ExpenseDto.Request dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Expense entity = new Expense();
|
||||
entity.setConcept(dto.getConcept());
|
||||
entity.setAmount(dto.getAmount());
|
||||
entity.setSupplier(dto.getSupplier());
|
||||
entity.setInvoice(dto.getInvoice());
|
||||
entity.setType(dto.getType());
|
||||
entity.setCreatedAt(dto.getCreatedAt());
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.IncomeDto;
|
||||
import es.huertosbellavista.backend.huertos.model.Income;
|
||||
|
||||
public class IncomeMapper {
|
||||
|
||||
public static IncomeDto.Response toResponse(Income entity) {
|
||||
if (entity == null) return null;
|
||||
|
||||
IncomeDto.Response dto = new IncomeDto.Response();
|
||||
dto.setIncomeId(entity.getIncomeId());
|
||||
dto.setUserId(entity.getUserId());
|
||||
dto.setConcept(entity.getConcept());
|
||||
dto.setAmount(entity.getAmount());
|
||||
dto.setType(entity.getType());
|
||||
dto.setFrequency(entity.getFrequency());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static Income toEntity(IncomeDto.Request dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Income entity = new Income();
|
||||
entity.setUserId(dto.getUserId());
|
||||
entity.setConcept(dto.getConcept());
|
||||
entity.setAmount(dto.getAmount());
|
||||
entity.setType(dto.getType());
|
||||
entity.setFrequency(dto.getFrequency());
|
||||
entity.setCreatedAt(dto.getCreatedAt());
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestDto;
|
||||
import es.huertosbellavista.backend.huertos.model.Request;
|
||||
|
||||
public class RequestMapper {
|
||||
|
||||
public static RequestDto.Response toResponse(Request entity) {
|
||||
if (entity == null) return null;
|
||||
|
||||
RequestDto.Response dto = new RequestDto.Response();
|
||||
dto.setRequestId(entity.getRequestId());
|
||||
dto.setType(entity.getType());
|
||||
dto.setStatus(entity.getStatus());
|
||||
dto.setUserId(entity.getUserId());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
|
||||
if (entity.getMetadata() != null) {
|
||||
dto.setMetadata(
|
||||
RequestMetadataMapper.toDto(entity.getMetadata())
|
||||
);
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static Request toEntity(RequestDto.Request dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
Request entity = new Request();
|
||||
entity.setType(dto.getType());
|
||||
entity.setUserId(dto.getUserId());
|
||||
entity.setName(dto.getName());
|
||||
entity.setStatus((byte) 0);
|
||||
|
||||
if (dto.getMetadata() != null) {
|
||||
entity.setMetadata(
|
||||
RequestMetadataMapper.fromDto(dto.getMetadata())
|
||||
);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestMetadataDto;
|
||||
import es.huertosbellavista.backend.huertos.model.RequestMetadata;
|
||||
|
||||
public class RequestMetadataMapper {
|
||||
|
||||
public static RequestMetadata fromDto(RequestMetadataDto dto) {
|
||||
if (dto == null) return null;
|
||||
|
||||
RequestMetadata metadata = new RequestMetadata();
|
||||
|
||||
metadata.setDisplayName(dto.displayName());
|
||||
metadata.setDni(dto.dni());
|
||||
metadata.setPhone(dto.phone());
|
||||
metadata.setEmail(dto.email());
|
||||
|
||||
metadata.setUsername(dto.username());
|
||||
metadata.setAddress(dto.address());
|
||||
metadata.setZipCode(dto.zipCode());
|
||||
metadata.setCity(dto.city());
|
||||
|
||||
metadata.setMemberNumber(dto.memberNumber());
|
||||
metadata.setPlotNumber(dto.plotNumber());
|
||||
|
||||
metadata.setType(dto.type());
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public static RequestMetadataDto toDto(RequestMetadata entity) {
|
||||
if (entity == null) return null;
|
||||
|
||||
return new RequestMetadataDto(
|
||||
entity.getId(),
|
||||
entity.getDisplayName(),
|
||||
entity.getDni(),
|
||||
entity.getPhone(),
|
||||
entity.getEmail(),
|
||||
entity.getUsername(),
|
||||
entity.getAddress(),
|
||||
entity.getZipCode(),
|
||||
entity.getCity(),
|
||||
entity.getMemberNumber(),
|
||||
entity.getPlotNumber(),
|
||||
entity.getType(),
|
||||
entity.getCreatedAt()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.RequestWithMetadataDto;
|
||||
import es.huertosbellavista.backend.huertos.model.Request;
|
||||
|
||||
public class RequestWithMetadataMapper {
|
||||
public static RequestWithMetadataDto toDto(Request r) {
|
||||
if (r == null) return null;
|
||||
return new RequestWithMetadataDto(
|
||||
r.getRequestId(),
|
||||
r.getUserId(),
|
||||
r.getName(),
|
||||
r.getType(),
|
||||
r.getStatus(),
|
||||
r.getCreatedAt(),
|
||||
RequestMetadataMapper.toDto(r.getMetadata())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.UserMetadataDto;
|
||||
import es.huertosbellavista.backend.huertos.model.UserMetadata;
|
||||
|
||||
public class UserMetadataMapper {
|
||||
|
||||
public static UserMetadataDto toDto(UserMetadata entity) {
|
||||
UserMetadataDto dto = new UserMetadataDto();
|
||||
dto.setUserId(entity.getUserId());
|
||||
dto.setMemberNumber(entity.getMemberNumber());
|
||||
dto.setPlotNumber(entity.getPlotNumber());
|
||||
dto.setDni(entity.getDni());
|
||||
dto.setPhone(entity.getPhone());
|
||||
dto.setType(entity.getType());
|
||||
dto.setRole(entity.getRole());
|
||||
dto.setNotes(entity.getNotes());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
dto.setAssignedAt(entity.getAssignedAt());
|
||||
dto.setDeactivatedAt(entity.getDeactivatedAt());
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static UserMetadata fromDto(UserMetadataDto dto) {
|
||||
UserMetadata entity = new UserMetadata();
|
||||
entity.setUserId(dto.getUserId());
|
||||
entity.setMemberNumber(dto.getMemberNumber());
|
||||
entity.setPlotNumber(dto.getPlotNumber());
|
||||
entity.setDni(dto.getDni());
|
||||
entity.setPhone(dto.getPhone());
|
||||
entity.setType(dto.getType());
|
||||
entity.setRole(dto.getRole());
|
||||
entity.setNotes(dto.getNotes());
|
||||
entity.setCreatedAt(dto.getCreatedAt());
|
||||
entity.setAssignedAt(dto.getAssignedAt());
|
||||
entity.setDeactivatedAt(dto.getDeactivatedAt());
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper.view;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.view.VBalanceWithTotalsDto;
|
||||
import es.huertosbellavista.backend.huertos.model.view.VBalanceWithTotals;
|
||||
|
||||
public class VBalanceWithTotalsMapper {
|
||||
|
||||
public static VBalanceWithTotalsDto toDto(VBalanceWithTotals entity) {
|
||||
VBalanceWithTotalsDto dto = new VBalanceWithTotalsDto();
|
||||
dto.setId(entity.getId());
|
||||
dto.setInitialBank(entity.getInitialBank());
|
||||
dto.setInitialCash(entity.getInitialCash());
|
||||
dto.setTotalBankExpenses(entity.getTotalBankExpenses());
|
||||
dto.setTotalCashExpenses(entity.getTotalCashExpenses());
|
||||
dto.setTotalBankIncomes(entity.getTotalBankIncomes());
|
||||
dto.setTotalCashIncomes(entity.getTotalCashIncomes());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package es.huertosbellavista.backend.huertos.mapper.view;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.dto.view.VIncomesWithInfoDto;
|
||||
import es.huertosbellavista.backend.huertos.model.view.VIncomesWithInfo;
|
||||
|
||||
public class VIncomesWithInfoMapper {
|
||||
|
||||
public static VIncomesWithInfoDto toResponse(VIncomesWithInfo entity) {
|
||||
VIncomesWithInfoDto dto = new VIncomesWithInfoDto();
|
||||
dto.setIncomeId(entity.getIncomeId());
|
||||
dto.setUserId(entity.getUserId());
|
||||
dto.setDisplayName(entity.getDisplayName());
|
||||
dto.setMemberNumber(entity.getMemberNumber());
|
||||
dto.setConcept(entity.getConcept());
|
||||
dto.setAmount(entity.getAmount());
|
||||
dto.setType(entity.getType());
|
||||
dto.setFrequency(entity.getFrequency());
|
||||
dto.setCreatedAt(entity.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_announces")
|
||||
public class Announcement {
|
||||
|
||||
@Id
|
||||
@Column(name = "announce_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] announceIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID announceId;
|
||||
|
||||
@Column(name = "body", nullable = false, columnDefinition = "TEXT")
|
||||
private String body;
|
||||
|
||||
@Column(name = "priority", nullable = false)
|
||||
private Byte priority;
|
||||
|
||||
@Column(name = "published_by", columnDefinition = "BINARY(16)", nullable = false)
|
||||
private byte[] publishedByBin;
|
||||
|
||||
@Transient
|
||||
private UUID publishedBy;
|
||||
|
||||
@Column(name = "published_by_name", nullable = false)
|
||||
private String publishedByName;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (announceId != null) {
|
||||
announceIdBin = UuidUtil.uuidToBin(announceId);
|
||||
}
|
||||
|
||||
if (publishedBy != null) {
|
||||
publishedByBin = UuidUtil.uuidToBin(publishedBy);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (announceIdBin != null) {
|
||||
announceId = UuidUtil.binToUUID(announceIdBin);
|
||||
}
|
||||
|
||||
if (publishedByBin != null) {
|
||||
publishedBy = UuidUtil.binToUUID(publishedByBin);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getAnnounceId() {
|
||||
return announceId;
|
||||
}
|
||||
|
||||
public void setAnnounceId(UUID announceId) {
|
||||
this.announceId = announceId;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Byte getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void setPriority(Byte priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public UUID getPublishedBy() {
|
||||
return publishedBy;
|
||||
}
|
||||
|
||||
public void setPublishedBy(UUID publishedBy) {
|
||||
this.publishedBy = publishedBy;
|
||||
}
|
||||
|
||||
public String getPublishedByName() {
|
||||
return publishedByName;
|
||||
}
|
||||
|
||||
public void setPublishedByName(String publishedByName) {
|
||||
this.publishedByName = publishedByName;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_balance")
|
||||
public class Balance {
|
||||
|
||||
@Id
|
||||
private Byte id = 1;
|
||||
|
||||
@Column(name = "initial_bank", nullable = false)
|
||||
private BigDecimal initialBank;
|
||||
|
||||
@Column(name = "initial_cash", nullable = false)
|
||||
private BigDecimal initialCash;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
public Byte getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialBank() {
|
||||
return initialBank;
|
||||
}
|
||||
|
||||
public void setInitialBank(BigDecimal initialBank) {
|
||||
this.initialBank = initialBank;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialCash() {
|
||||
return initialCash;
|
||||
}
|
||||
|
||||
public void setInitialCash(BigDecimal initialCash) {
|
||||
this.initialCash = initialCash;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_expenses")
|
||||
public class Expense {
|
||||
|
||||
@Id
|
||||
@Column(name = "expense_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] expenseIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID expenseId;
|
||||
|
||||
@Column(name = "concept", nullable = false, length = 128)
|
||||
private String concept;
|
||||
|
||||
@Column(name = "amount", nullable = false)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Column(name = "supplier", nullable = false, length = 128)
|
||||
private String supplier;
|
||||
|
||||
@Column(name = "invoice", nullable = false, length = 32)
|
||||
private String invoice;
|
||||
|
||||
@Column(name = "type")
|
||||
private Byte type;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (expenseId != null) {
|
||||
expenseIdBin = UuidUtil.uuidToBin(expenseId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (expenseIdBin != null) {
|
||||
expenseId = UuidUtil.binToUUID(expenseIdBin);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getExpenseId() {
|
||||
return expenseId;
|
||||
}
|
||||
|
||||
public void setExpenseId(UUID expenseId) {
|
||||
this.expenseId = expenseId;
|
||||
}
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getSupplier() {
|
||||
return supplier;
|
||||
}
|
||||
|
||||
public void setSupplier(String supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public String getInvoice() {
|
||||
return invoice;
|
||||
}
|
||||
|
||||
public void setInvoice(String invoice) {
|
||||
this.invoice = invoice;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_incomes")
|
||||
public class Income {
|
||||
|
||||
@Id
|
||||
@Column(name = "income_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] incomeIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID incomeId;
|
||||
|
||||
@Column(name = "user_id", columnDefinition = "BINARY(16)", nullable = false)
|
||||
private byte[] userIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID userId;
|
||||
|
||||
@Column(name = "concept", nullable = false, length = 128)
|
||||
private String concept;
|
||||
|
||||
@Column(name = "amount", nullable = false)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Column(name = "type")
|
||||
private Byte type;
|
||||
|
||||
@Column(name = "frequency")
|
||||
private Byte frequency;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = true)
|
||||
private Instant createdAt;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (userId != null) {
|
||||
userIdBin = UuidUtil.uuidToBin(userId);
|
||||
}
|
||||
|
||||
if (incomeId != null) {
|
||||
incomeIdBin = UuidUtil.uuidToBin(incomeId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (userIdBin != null) {
|
||||
userId = UuidUtil.binToUUID(userIdBin);
|
||||
}
|
||||
|
||||
if (incomeIdBin != null) {
|
||||
incomeId = UuidUtil.binToUUID(incomeIdBin);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
Instant now = Instant.now();
|
||||
if (frequency == 0) { // BIYEARLY
|
||||
return Duration.between(createdAt, now).toDays() <= 6L * 30;
|
||||
} else if (frequency == 1) { // YEARLY
|
||||
return Duration.between(createdAt, now).toDays() <= 12L * 30;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getIncomeId() {
|
||||
return incomeId;
|
||||
}
|
||||
|
||||
public void setIncomeId(UUID incomeId) {
|
||||
this.incomeId = incomeId;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public void setConcept(String concept) {
|
||||
this.concept = concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(Byte frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_requests")
|
||||
public class Request {
|
||||
|
||||
@Id
|
||||
@Column(name = "request_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] requestIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID requestId;
|
||||
|
||||
@Column(name = "user_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] userIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID userId;
|
||||
|
||||
private String name;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Byte type;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Byte status;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
@OneToOne(mappedBy = "request", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = true)
|
||||
private RequestMetadata metadata;
|
||||
|
||||
@PrePersist
|
||||
private void prePersist() {
|
||||
if (requestId != null) requestIdBin = UuidUtil.uuidToBin(requestId);
|
||||
if (userId != null) userIdBin = UuidUtil.uuidToBin(userId);
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (requestIdBin != null) requestId = UuidUtil.binToUUID(requestIdBin);
|
||||
if (userIdBin != null) userId = UuidUtil.binToUUID(userIdBin);
|
||||
}
|
||||
|
||||
public UUID getRequestId() { return requestId; }
|
||||
public void setRequestId(UUID requestId) { this.requestId = requestId; }
|
||||
|
||||
public UUID getUserId() { return userId; }
|
||||
public void setUserId(UUID userId) { this.userId = userId; }
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Byte getType() { return type; }
|
||||
public void setType(Byte type) { this.type = type; }
|
||||
|
||||
public Byte getStatus() { return status; }
|
||||
public void setStatus(Byte status) { this.status = status; }
|
||||
|
||||
public Instant getCreatedAt() { return createdAt; }
|
||||
public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; }
|
||||
|
||||
public RequestMetadata getMetadata() { return metadata; }
|
||||
public void setMetadata(RequestMetadata metadata) { this.metadata = metadata; }
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_request_metadata")
|
||||
public class RequestMetadata {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "request_id", columnDefinition = "BINARY(16)", nullable = false, unique = true)
|
||||
private byte[] requestIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID requestId;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "request_id", referencedColumnName = "request_id", insertable = false, updatable = false)
|
||||
private Request request;
|
||||
|
||||
@Column(name = "display_name", nullable = false, length = 150)
|
||||
private String displayName;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String dni;
|
||||
|
||||
@Column(length = 30)
|
||||
private String phone;
|
||||
|
||||
@Column(nullable = false, length = 150)
|
||||
private String email;
|
||||
|
||||
@Column(length = 255)
|
||||
private String address;
|
||||
|
||||
@Column(name = "zip_code", length = 10)
|
||||
private String zipCode;
|
||||
|
||||
@Column(length = 100)
|
||||
private String city;
|
||||
|
||||
@Column(name = "member_number")
|
||||
private Integer memberNumber;
|
||||
|
||||
@Column(name = "plot_number")
|
||||
private Integer plotNumber;
|
||||
|
||||
@Column(nullable = false, length = 100)
|
||||
private String username;
|
||||
|
||||
private Byte type;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
@PrePersist
|
||||
private void prePersist() {
|
||||
if (requestId != null) requestIdBin = UuidUtil.uuidToBin(requestId);
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (requestIdBin != null) requestId = UuidUtil.binToUUID(requestIdBin);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public byte[] getRequestIdBin() {
|
||||
return requestIdBin;
|
||||
}
|
||||
|
||||
public void setRequestIdBin(byte[] requestIdBin) {
|
||||
this.requestIdBin = requestIdBin;
|
||||
}
|
||||
|
||||
public UUID getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
public void setRequestId(UUID requestId) {
|
||||
this.requestId = requestId;
|
||||
}
|
||||
|
||||
public Request getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public void setRequest(Request request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDni() {
|
||||
return dni;
|
||||
}
|
||||
|
||||
public void setDni(String dni) {
|
||||
this.dni = dni;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getZipCode() {
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode) {
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public Integer getMemberNumber() {
|
||||
return memberNumber;
|
||||
}
|
||||
|
||||
public void setMemberNumber(Integer memberNumber) {
|
||||
this.memberNumber = memberNumber;
|
||||
}
|
||||
|
||||
public Integer getPlotNumber() {
|
||||
return plotNumber;
|
||||
}
|
||||
|
||||
public void setPlotNumber(Integer plotNumber) {
|
||||
this.plotNumber = plotNumber;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package es.huertosbellavista.backend.huertos.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "huertos_user_metadata")
|
||||
public class UserMetadata {
|
||||
|
||||
@Id
|
||||
@Column(name = "user_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] userIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID userId;
|
||||
|
||||
@Column(name = "member_number", nullable = false, unique = true)
|
||||
private Integer memberNumber;
|
||||
|
||||
@Column(name = "plot_number", nullable = false)
|
||||
private Integer plotNumber;
|
||||
|
||||
@Column(name = "dni", nullable = false, unique = true, length = 9)
|
||||
private String dni;
|
||||
|
||||
@Column(name = "phone", nullable = false, length = 20)
|
||||
private String phone;
|
||||
|
||||
@Column(name = "type", nullable = false)
|
||||
private Byte type;
|
||||
|
||||
@Column(name = "role", nullable = false)
|
||||
private Byte role;
|
||||
|
||||
@Column(name = "notes")
|
||||
private String notes;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
@Column(name = "assigned_at")
|
||||
private Instant assignedAt;
|
||||
|
||||
@Column(name = "deactivated_at")
|
||||
private Instant deactivatedAt;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void prePersist() {
|
||||
if (userId != null) {
|
||||
userIdBin = UuidUtil.uuidToBin(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (userIdBin != null) {
|
||||
userId = UuidUtil.binToUUID(userIdBin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getMemberNumber() {
|
||||
return memberNumber;
|
||||
}
|
||||
|
||||
public void setMemberNumber(Integer memberNumber) {
|
||||
this.memberNumber = memberNumber;
|
||||
}
|
||||
|
||||
public Integer getPlotNumber() {
|
||||
return plotNumber;
|
||||
}
|
||||
|
||||
public void setPlotNumber(Integer plotNumber) {
|
||||
this.plotNumber = plotNumber;
|
||||
}
|
||||
|
||||
public String getDni() {
|
||||
return dni;
|
||||
}
|
||||
|
||||
public void setDni(String dni) {
|
||||
this.dni = dni;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Byte getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(Byte role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(String notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Instant getAssignedAt() {
|
||||
return assignedAt;
|
||||
}
|
||||
|
||||
public void setAssignedAt(Instant assignedAt) {
|
||||
this.assignedAt = assignedAt;
|
||||
}
|
||||
|
||||
public Instant getDeactivatedAt() {
|
||||
return deactivatedAt;
|
||||
}
|
||||
|
||||
public void setDeactivatedAt(Instant deactivatedAt) {
|
||||
this.deactivatedAt = deactivatedAt;
|
||||
}
|
||||
|
||||
public void setUserIdBin(byte[] userIdBin) {
|
||||
this.userIdBin = userIdBin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package es.huertosbellavista.backend.huertos.model.view;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.annotations.Immutable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
||||
@Entity
|
||||
@Immutable
|
||||
@Table(name = "v_balance_with_totals")
|
||||
public class VBalanceWithTotals {
|
||||
|
||||
@Id
|
||||
private Byte id;
|
||||
|
||||
@Column(name = "initial_bank")
|
||||
private BigDecimal initialBank;
|
||||
|
||||
@Column(name = "initial_cash")
|
||||
private BigDecimal initialCash;
|
||||
|
||||
@Column(name = "total_bank_expenses")
|
||||
private BigDecimal totalBankExpenses;
|
||||
|
||||
@Column(name = "total_cash_expenses")
|
||||
private BigDecimal totalCashExpenses;
|
||||
|
||||
@Column(name = "total_bank_incomes")
|
||||
private BigDecimal totalBankIncomes;
|
||||
|
||||
@Column(name = "total_cash_incomes")
|
||||
private BigDecimal totalCashIncomes;
|
||||
|
||||
@Column(name = "created_at")
|
||||
private Instant createdAt;
|
||||
|
||||
public Byte getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialBank() {
|
||||
return initialBank;
|
||||
}
|
||||
|
||||
public BigDecimal getInitialCash() {
|
||||
return initialCash;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalBankExpenses() {
|
||||
return totalBankExpenses;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalCashExpenses() {
|
||||
return totalCashExpenses;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalBankIncomes() {
|
||||
return totalBankIncomes;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalCashIncomes() {
|
||||
return totalCashIncomes;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package es.huertosbellavista.backend.huertos.model.view;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
import org.hibernate.annotations.Immutable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Immutable
|
||||
@Table(name = "v_incomes_with_info")
|
||||
public class VIncomesWithInfo {
|
||||
|
||||
@Id
|
||||
@Column(name = "income_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] incomeIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID incomeId;
|
||||
|
||||
@Column(name = "user_id", columnDefinition = "BINARY(16)")
|
||||
private byte[] userIdBin;
|
||||
|
||||
@Transient
|
||||
private UUID userId;
|
||||
|
||||
@Column(name = "display_name")
|
||||
private String displayName;
|
||||
|
||||
@Column(name = "member_number")
|
||||
private Integer memberNumber;
|
||||
|
||||
private String concept;
|
||||
private BigDecimal amount;
|
||||
private Byte type;
|
||||
private Byte frequency;
|
||||
|
||||
@Column(name = "created_at")
|
||||
private Instant createdAt;
|
||||
|
||||
@PostLoad
|
||||
private void postLoad() {
|
||||
if (userIdBin != null) {
|
||||
userId = UuidUtil.binToUUID(userIdBin);
|
||||
}
|
||||
|
||||
if (incomeIdBin != null) {
|
||||
incomeId = UuidUtil.binToUUID(incomeIdBin);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getIncomeId() {
|
||||
return incomeId;
|
||||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public Integer getMemberNumber() { return memberNumber; }
|
||||
|
||||
public String getConcept() {
|
||||
return concept;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public Byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Byte getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.Announcement;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface AnnouncementRepository extends JpaRepository<Announcement, byte[]> {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.Balance;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface BalanceRepository extends JpaRepository<Balance, Byte> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.Expense;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface ExpenseRepository extends JpaRepository<Expense, byte[]> {}
|
||||
@@ -0,0 +1,7 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.Income;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface IncomeRepository extends JpaRepository<Income, byte[]> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.RequestMetadata;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface RequestMetadataRepository extends JpaRepository<RequestMetadata, Long> {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.Request;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface RequestRepository extends JpaRepository<Request, byte[]> {
|
||||
@Query("""
|
||||
SELECT r FROM Request r
|
||||
LEFT JOIN FETCH r.metadata
|
||||
WHERE r.requestIdBin = :id
|
||||
""")
|
||||
Optional<Request> findByIdWithMetadata(@Param("id") byte[] id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package es.huertosbellavista.backend.huertos.repository;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.UserMetadata;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface UserMetadataRepository extends JpaRepository<UserMetadata, byte[]> {
|
||||
Optional<UserMetadata> findByMemberNumber(Integer memberNumber);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package es.huertosbellavista.backend.huertos.repository.view;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.view.VBalanceWithTotals;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface VBalanceWithTotalsRepository extends Repository<VBalanceWithTotals, Byte> {
|
||||
List<VBalanceWithTotals> findAll();
|
||||
Optional<VBalanceWithTotals> findById(Byte id);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package es.huertosbellavista.backend.huertos.repository.view;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.view.VIncomesWithInfo;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface VIncomesWithInfoRepository extends Repository<VIncomesWithInfo, byte[]> {
|
||||
List<VIncomesWithInfo> findAll();
|
||||
Optional<VIncomesWithInfo> findById(byte[] incomeId);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package es.huertosbellavista.backend.huertos.security;
|
||||
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import es.huertosbellavista.backend.huertos.model.UserMetadata;
|
||||
import es.huertosbellavista.backend.huertos.service.UserMetadataService;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class HuertosJwtFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtService jwtService;
|
||||
private final UserMetadataService metadataService;
|
||||
|
||||
public HuertosJwtFilter(JwtService jwtService, UserMetadataService metadataService) {
|
||||
this.jwtService = jwtService;
|
||||
this.metadataService = metadataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||
String token = authHeader.substring(7);
|
||||
|
||||
if (jwtService.validateToken(token)) {
|
||||
UUID userId = jwtService.getUserId(token);
|
||||
Byte serviceId = jwtService.getServiceId(token);
|
||||
|
||||
UserMetadata metadata = metadataService.getById(userId);
|
||||
|
||||
if (metadata != null) {
|
||||
var principal = new HuertosPrincipal(
|
||||
userId,
|
||||
metadata.getRole(),
|
||||
metadata.getType(),
|
||||
serviceId
|
||||
);
|
||||
|
||||
var auth = new UsernamePasswordAuthenticationToken(
|
||||
principal, null, principal.getAuthorities()
|
||||
);
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package es.huertosbellavista.backend.huertos.security;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class HuertosPrincipal implements UserDetails {
|
||||
|
||||
private final UUID userId;
|
||||
private final Byte role;
|
||||
private final Byte type;
|
||||
private final Byte serviceId;
|
||||
|
||||
public HuertosPrincipal(UUID userId, Byte role, Byte type, Byte serviceId) {
|
||||
this.userId = userId;
|
||||
this.role = role;
|
||||
this.type = type;
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
public UUID getUserId() { return userId; }
|
||||
public Byte getHuertosRole() { return role; }
|
||||
public Byte getHuertosType() { return type; }
|
||||
public Byte getServiceId() { return serviceId; }
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
List<GrantedAuthority> auth = new ArrayList<>();
|
||||
|
||||
String roleName = switch(role) {
|
||||
case 0 -> "USER";
|
||||
case 1 -> "ADMIN";
|
||||
case 2 -> "DEV";
|
||||
default -> "USER";
|
||||
};
|
||||
|
||||
String typeName = switch(type) {
|
||||
case 0 -> "WAIT_LIST";
|
||||
case 1 -> "MEMBER";
|
||||
case 2 -> "WITH_GREENHOUSE";
|
||||
case 3 -> "COLLABORATOR";
|
||||
case 4 -> "SUBSIDY";
|
||||
case 5 -> "DEVELOPER";
|
||||
default -> "WAIT_LIST";
|
||||
};
|
||||
|
||||
auth.add(new SimpleGrantedAuthority("ROLE_HUERTOS_ROLE_" + roleName));
|
||||
auth.add(new SimpleGrantedAuthority("ROLE_HUERTOS_TYPE_" + typeName));
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
@Override public String getPassword() { return ""; }
|
||||
@Override public String getUsername() { return userId.toString(); }
|
||||
@Override public boolean isAccountNonExpired() { return true; }
|
||||
@Override public boolean isAccountNonLocked() { return true; }
|
||||
@Override public boolean isCredentialsNonExpired() { return true; }
|
||||
@Override public boolean isEnabled() { return true; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package es.huertosbellavista.backend.huertos.security;
|
||||
|
||||
|
||||
/**
|
||||
* Clase de utilidad para censurar nombres.
|
||||
* Censura los nombres dejando las primeras 3 letras visibles y el resto con asteriscos.
|
||||
* Si el nombre es muy largo, lo acorta a 16 caracteres y añade "..." al final.
|
||||
* @author José Manuel Amador Gallardo
|
||||
*/
|
||||
public class NameCensorer {
|
||||
|
||||
public static String censor(String name) {
|
||||
if (name == null || name.isBlank()) return "";
|
||||
|
||||
String[] words = name.trim().split("\\s+");
|
||||
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
String word = words[i];
|
||||
int len = word.length();
|
||||
|
||||
if (len > 3) {
|
||||
words[i] = word.substring(0, 3) + "*".repeat(len - 3);
|
||||
} else if (len > 0) {
|
||||
words[i] = word.charAt(0) + "*".repeat(len - 1);
|
||||
}
|
||||
}
|
||||
|
||||
String censored = String.join(" ", words);
|
||||
|
||||
if (censored.length() > 16) {
|
||||
censored = censored.substring(0, 16) + "...";
|
||||
}
|
||||
|
||||
return censored;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package es.huertosbellavista.backend.huertos.service;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import es.huertosbellavista.backend.huertos.model.Announcement;
|
||||
import es.huertosbellavista.backend.huertos.repository.AnnouncementRepository;
|
||||
import net.miarma.backlib.exception.NotFoundException;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class AnnouncementService {
|
||||
|
||||
private final AnnouncementRepository announcementRepository;
|
||||
private final MemberService memberService;
|
||||
|
||||
public AnnouncementService(AnnouncementRepository announcementRepository, MemberService memberService) {
|
||||
this.announcementRepository = announcementRepository;
|
||||
this.memberService = memberService;
|
||||
}
|
||||
|
||||
public List<Announcement> getAll() {
|
||||
return announcementRepository.findAll().stream()
|
||||
.sorted(Comparator.comparing(Announcement::getCreatedAt).reversed())
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Announcement getById(UUID announceId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(announceId);
|
||||
return announcementRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Anuncio no encontrado"));
|
||||
}
|
||||
|
||||
public Announcement create(Announcement announcement) {
|
||||
if (announcement.getAnnounceId() == null) {
|
||||
announcement.setAnnounceId(UUID.randomUUID());
|
||||
}
|
||||
announcement.setPublishedByName(memberService.getById(announcement.getPublishedBy()).user().getDisplayName());
|
||||
announcement.setCreatedAt(Instant.now());
|
||||
return announcementRepository.save(announcement);
|
||||
}
|
||||
|
||||
public Announcement update(UUID announceId, Announcement changes) {
|
||||
Announcement announcement = getById(announceId);
|
||||
|
||||
if (changes.getBody() != null)
|
||||
announcement.setBody(changes.getBody());
|
||||
|
||||
if (changes.getPriority() != null)
|
||||
announcement.setPriority(changes.getPriority());
|
||||
|
||||
if (changes.getPublishedBy() != null)
|
||||
announcement.setPublishedBy(changes.getPublishedBy());
|
||||
|
||||
return announcementRepository.save(announcement);
|
||||
}
|
||||
|
||||
public void delete(UUID announceId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(announceId);
|
||||
if (!announcementRepository.existsById(idBytes))
|
||||
throw new NotFoundException("Anuncio no encontrado");
|
||||
announcementRepository.deleteById(idBytes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package es.huertosbellavista.backend.huertos.service;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.view.VBalanceWithTotals;
|
||||
import es.huertosbellavista.backend.huertos.repository.view.VBalanceWithTotalsRepository;
|
||||
import net.miarma.backlib.exception.ConflictException;
|
||||
import net.miarma.backlib.exception.NotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import es.huertosbellavista.backend.huertos.model.Balance;
|
||||
import es.huertosbellavista.backend.huertos.repository.BalanceRepository;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class BalanceService {
|
||||
|
||||
private final BalanceRepository balanceRepository;
|
||||
private final VBalanceWithTotalsRepository vBalanceWithTotalsRepository;
|
||||
|
||||
public BalanceService(BalanceRepository balanceRepository, VBalanceWithTotalsRepository vBalanceWithTotalsRepository) {
|
||||
this.balanceRepository = balanceRepository;
|
||||
this.vBalanceWithTotalsRepository = vBalanceWithTotalsRepository;
|
||||
}
|
||||
|
||||
public Balance get() {
|
||||
return balanceRepository.findById((byte) 1)
|
||||
.orElseThrow(() -> new NotFoundException("Balance no encontrado"));
|
||||
}
|
||||
|
||||
public VBalanceWithTotals getWithTotals() {
|
||||
return vBalanceWithTotalsRepository.findById((byte) 1)
|
||||
.orElseThrow(() -> new NotFoundException("Balance no encontrado"));
|
||||
}
|
||||
|
||||
public Balance create(Balance balance) {
|
||||
if (balanceRepository.existsById((byte) 1)) {
|
||||
throw new ConflictException("Ya hay un valor de balance en la base de datos");
|
||||
}
|
||||
balance.setId((byte) 1);
|
||||
balance.setCreatedAt(Instant.now());
|
||||
return balanceRepository.save(balance);
|
||||
}
|
||||
|
||||
public Balance update(Balance dto) {
|
||||
Balance balance = balanceRepository.findById((byte) 1)
|
||||
.orElseThrow(() -> new NotFoundException("Balance no encontrado"));
|
||||
|
||||
if (dto.getInitialBank() != null) balance.setInitialBank(dto.getInitialBank());
|
||||
if (dto.getInitialCash() != null) balance.setInitialCash(dto.getInitialCash());
|
||||
|
||||
return balanceRepository.save(balance);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (!balanceRepository.existsById((byte) 1)) {
|
||||
throw new NotFoundException("Balance no encontrado");
|
||||
}
|
||||
balanceRepository.deleteById((byte) 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package es.huertosbellavista.backend.huertos.service;
|
||||
|
||||
import net.miarma.backlib.dto.LoginRequest;
|
||||
import net.miarma.backlib.dto.LoginResponse;
|
||||
import net.miarma.backlib.security.CoreAuthTokenHolder;
|
||||
import net.miarma.backlib.security.JwtService;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Service
|
||||
public class CoreAuthService {
|
||||
|
||||
private final RestTemplate authRestTemplate;
|
||||
private final CoreAuthTokenHolder tokenHolder;
|
||||
private final JwtService jwtService;
|
||||
|
||||
@Value("${huertos.user}")
|
||||
private String username;
|
||||
|
||||
@Value("${huertos.password}")
|
||||
private String password;
|
||||
|
||||
@Value("${core.url}")
|
||||
private String coreUrl;
|
||||
|
||||
public CoreAuthService(@Qualifier("authRestTemplate") RestTemplate authRestTemplate,
|
||||
CoreAuthTokenHolder tokenHolder,
|
||||
JwtService jwtService) {
|
||||
this.authRestTemplate = authRestTemplate;
|
||||
this.tokenHolder = tokenHolder;
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
public synchronized String getToken() {
|
||||
if (tokenHolder.getToken() == null || tokenHolder.isExpired()) {
|
||||
refreshToken();
|
||||
}
|
||||
return tokenHolder.getToken();
|
||||
}
|
||||
|
||||
private void refreshToken() {
|
||||
var req = new LoginRequest(username, password, (byte) 1);
|
||||
|
||||
LoginResponse resp = authRestTemplate.postForObject(
|
||||
coreUrl + "/auth/login",
|
||||
req,
|
||||
LoginResponse.class
|
||||
);
|
||||
|
||||
String token = resp.token();
|
||||
Instant exp = jwtService.getExpiration(token).toInstant();
|
||||
tokenHolder.setToken(token, exp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package es.huertosbellavista.backend.huertos.service;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import es.huertosbellavista.backend.huertos.model.Expense;
|
||||
import es.huertosbellavista.backend.huertos.repository.ExpenseRepository;
|
||||
import net.miarma.backlib.exception.NotFoundException;
|
||||
import net.miarma.backlib.exception.ValidationException;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class ExpenseService {
|
||||
|
||||
private final ExpenseRepository expenseRepository;
|
||||
|
||||
public ExpenseService(ExpenseRepository expenseRepository) {
|
||||
this.expenseRepository = expenseRepository;
|
||||
}
|
||||
|
||||
public List<Expense> getAll() {
|
||||
return expenseRepository.findAll().stream()
|
||||
.sorted(Comparator.comparing(Expense::getCreatedAt).reversed())
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Expense getById(UUID expenseId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(expenseId);
|
||||
return expenseRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Gasto no encontrado"));
|
||||
}
|
||||
|
||||
public Expense create(Expense expense) {
|
||||
if (expense.getConcept() == null || expense.getConcept().isBlank()) {
|
||||
throw new ValidationException("concept", "El concepto es obligatorio");
|
||||
}
|
||||
if (expense.getAmount() == null) {
|
||||
throw new ValidationException("amount", "La cantidad es obligatoria");
|
||||
}
|
||||
if (expense.getSupplier() == null || expense.getSupplier().isBlank()) {
|
||||
throw new ValidationException("supplier", "El proveedor es obligatorio");
|
||||
}
|
||||
if (expense.getInvoice() == null || expense.getInvoice().isBlank()) {
|
||||
throw new ValidationException("invoice", "La factura es obligatoria");
|
||||
}
|
||||
if (expense.getCreatedAt() == null) {
|
||||
expense.setCreatedAt(Instant.now());
|
||||
}
|
||||
|
||||
expense.setExpenseId(UUID.randomUUID());
|
||||
|
||||
return expenseRepository.save(expense);
|
||||
}
|
||||
|
||||
public Expense update(UUID expenseId, Expense changes) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(expenseId);
|
||||
|
||||
Expense expense = expenseRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Gasto no encontrado"));
|
||||
|
||||
if (changes.getConcept() != null)
|
||||
expense.setConcept(changes.getConcept());
|
||||
|
||||
if (changes.getAmount() != null)
|
||||
expense.setAmount(changes.getAmount());
|
||||
|
||||
if (changes.getSupplier() != null)
|
||||
expense.setSupplier(changes.getSupplier());
|
||||
|
||||
if (changes.getInvoice() != null)
|
||||
expense.setInvoice(changes.getInvoice());
|
||||
|
||||
if (changes.getType() != null)
|
||||
expense.setType(changes.getType());
|
||||
|
||||
if (changes.getCreatedAt() != null)
|
||||
expense.setCreatedAt(changes.getCreatedAt());
|
||||
|
||||
return expenseRepository.save(expense);
|
||||
}
|
||||
|
||||
public void delete(UUID expenseId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(expenseId);
|
||||
if (!expenseRepository.existsById(idBytes)) {
|
||||
throw new NotFoundException("Gasto no encontrado");
|
||||
}
|
||||
expenseRepository.deleteById(idBytes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package es.huertosbellavista.backend.huertos.service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import es.huertosbellavista.backend.huertos.model.view.VIncomesWithInfo;
|
||||
import es.huertosbellavista.backend.huertos.service.view.VIncomesWithInfoService;
|
||||
import net.miarma.backlib.exception.BadRequestException;
|
||||
import net.miarma.backlib.exception.NotFoundException;
|
||||
import net.miarma.backlib.exception.ValidationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import es.huertosbellavista.backend.huertos.model.Income;
|
||||
import es.huertosbellavista.backend.huertos.repository.IncomeRepository;
|
||||
import net.miarma.backlib.util.UuidUtil;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class IncomeService {
|
||||
|
||||
private final IncomeRepository incomeRepository;
|
||||
private final VIncomesWithInfoService incomesWithInfoService;
|
||||
private final UserMetadataService metadataService;
|
||||
|
||||
public IncomeService(IncomeRepository incomeRepository,
|
||||
VIncomesWithInfoService incomesWithInfoService,
|
||||
UserMetadataService metadataService) {
|
||||
this.incomeRepository = incomeRepository;
|
||||
this.incomesWithInfoService = incomesWithInfoService;
|
||||
this.metadataService = metadataService;
|
||||
}
|
||||
|
||||
public List<Income> getAll() {
|
||||
return incomeRepository.findAll().stream()
|
||||
.sorted(Comparator.comparing(Income::getCreatedAt).reversed())
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Income getById(UUID incomeId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
|
||||
return incomeRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
|
||||
}
|
||||
|
||||
public List<Income> getByUserId(UUID userId) {
|
||||
return incomeRepository.findAll().stream()
|
||||
.filter(i -> i.getUserId().equals(userId))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Income create(Income income) {
|
||||
if (income.getUserId() == null) {
|
||||
throw new BadRequestException("El identificador de usuario es obligatorio");
|
||||
}
|
||||
if (income.getConcept() == null) {
|
||||
throw new BadRequestException("El concepto es obligatorio");
|
||||
}
|
||||
if (income.getConcept().isBlank() || income.getConcept().isEmpty()) {
|
||||
throw new ValidationException("concept", "El concepto no puede ir vacío");
|
||||
}
|
||||
if (income.getAmount() == null || income.getAmount().signum() <= 0) {
|
||||
throw new ValidationException("amount", "La cantidad debe ser positiva");
|
||||
}
|
||||
if (income.getCreatedAt() == null) {
|
||||
income.setCreatedAt(Instant.now());
|
||||
}
|
||||
|
||||
income.setIncomeId(UUID.randomUUID());
|
||||
|
||||
return incomeRepository.save(income);
|
||||
}
|
||||
|
||||
public Income update(UUID incomeId, Income changes) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
|
||||
|
||||
Income income = incomeRepository.findById(idBytes)
|
||||
.orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
|
||||
|
||||
if (changes.getConcept() != null) income.setConcept(changes.getConcept());
|
||||
if (changes.getAmount() != null) {
|
||||
if (changes.getAmount().signum() <= 0) {
|
||||
throw new ValidationException("amount", "La cantidad debe ser positiva");
|
||||
}
|
||||
income.setAmount(changes.getAmount());
|
||||
}
|
||||
if (changes.getType() != null) income.setType(changes.getType());
|
||||
if (changes.getFrequency() != null) income.setFrequency(changes.getFrequency());
|
||||
if (changes.getCreatedAt() != null && !changes.getCreatedAt().equals(income.getCreatedAt())) {
|
||||
income.setCreatedAt(changes.getCreatedAt());
|
||||
}
|
||||
|
||||
return incomeRepository.save(income);
|
||||
}
|
||||
|
||||
public void delete(UUID incomeId) {
|
||||
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
|
||||
|
||||
if (!incomeRepository.existsById(idBytes)) {
|
||||
throw new NotFoundException("Ingreso no encontrado");
|
||||
}
|
||||
|
||||
incomeRepository.deleteById(idBytes);
|
||||
}
|
||||
|
||||
public Boolean existsByMemberNumber(Integer memberNumber) {
|
||||
try {
|
||||
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
|
||||
return !getByUserId(userId).isEmpty();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean hasPaid(Integer memberNumber) {
|
||||
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
|
||||
List<Income> incomes = getByUserId(userId);
|
||||
return !incomes.isEmpty() && incomes.stream().allMatch(Income::isPaid);
|
||||
}
|
||||
|
||||
public List<VIncomesWithInfo> getByMemberNumber(Integer memberNumber) {
|
||||
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
|
||||
return incomesWithInfoService.getByUserId(userId);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user