From f02c2a18c37337123670570e1b117bb1d722cdc4 Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sat, 19 Apr 2025 17:31:27 -0300 Subject: [PATCH 1/8] feat(Accommodation): add the price-per-person endpoint --- .../unipampa/crud/dto/AccommodationDTO.java | 3 +- .../unipampa/crud/entities/Accommodation.java | 1 + .../crud/resources/AccommodationResource.java | 48 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java index d4ec7ac2..ece50347 100644 --- a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java +++ b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java @@ -18,5 +18,6 @@ public record AccommodationDTO( @NotBlank BigDecimal price, int number, @NotNull int imageQuantity, - @NotNull AccommodationType accommodationType + @NotNull AccommodationType accommodationType, + @NotNull int maxOccupancy ) {} diff --git a/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java b/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java index c3d5ddfb..dee97b19 100644 --- a/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java +++ b/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java @@ -33,5 +33,6 @@ public class Accommodation { private String address; private String state; private int imageQuantity; + private int maxOccupancy; } diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index 55f57494..4e26e8f5 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -13,7 +13,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; @RestController @@ -109,4 +113,48 @@ public ResponseEntity updateAccommodation( return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Erro ao atualizar a acomodação. Verifique os dados fornecidos."); } } + + @GetMapping("{id}/price-per-person") + @Operation(summary = "Shows the price each person will pay for the shared accommodation") + public ResponseEntity getPricePerPerson ( + @PathVariable("id") String id, + @RequestParam(value = "people", required = false) Integer numberOfPeople + ) { + Optional accommodationOpt = accommodationService.findById(id); + + if (accommodationOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Accomodations not found for this ID!"); + } + + Accommodation accommodation = accommodationOpt.get(); + int maxOccupancy = accommodation.getMaxOccupancy(); + + if (maxOccupancy <= 0) { + return ResponseEntity.badRequest().body("Max occupancy must be greater than 0"); + } + + if (numberOfPeople == null) { + numberOfPeople = maxOccupancy; + } + + if (numberOfPeople <= 0) { + return ResponseEntity.badRequest().body("Number of people must be greater than 0"); + } + + if (numberOfPeople > maxOccupancy) { + return ResponseEntity.badRequest().body("Number of people exceeds the maximum occupancy"); + } + + BigDecimal totalPrice = accommodation.getPrice(); + + BigDecimal pricePerPerson = totalPrice.divide(BigDecimal.valueOf(numberOfPeople), 2, RoundingMode.HALF_UP); + + Map response = new HashMap<>(); + response.put("totalPrice", totalPrice); + response.put("numberOfPeople", numberOfPeople); + response.put("pricePerPerson", pricePerPerson); + response.put("maxOccupancy", maxOccupancy); + + return ResponseEntity.ok(response); + } } From be149c554c3e95e45a4728dc5c1dd059c660631f Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sat, 19 Apr 2025 18:43:09 -0300 Subject: [PATCH 2/8] chore(Accommodation): remove endpoint that can be delegated to the frontend --- .../crud/resources/AccommodationResource.java | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index 4e26e8f5..55f57494 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -13,11 +13,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; @RestController @@ -113,48 +109,4 @@ public ResponseEntity updateAccommodation( return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Erro ao atualizar a acomodação. Verifique os dados fornecidos."); } } - - @GetMapping("{id}/price-per-person") - @Operation(summary = "Shows the price each person will pay for the shared accommodation") - public ResponseEntity getPricePerPerson ( - @PathVariable("id") String id, - @RequestParam(value = "people", required = false) Integer numberOfPeople - ) { - Optional accommodationOpt = accommodationService.findById(id); - - if (accommodationOpt.isEmpty()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Accomodations not found for this ID!"); - } - - Accommodation accommodation = accommodationOpt.get(); - int maxOccupancy = accommodation.getMaxOccupancy(); - - if (maxOccupancy <= 0) { - return ResponseEntity.badRequest().body("Max occupancy must be greater than 0"); - } - - if (numberOfPeople == null) { - numberOfPeople = maxOccupancy; - } - - if (numberOfPeople <= 0) { - return ResponseEntity.badRequest().body("Number of people must be greater than 0"); - } - - if (numberOfPeople > maxOccupancy) { - return ResponseEntity.badRequest().body("Number of people exceeds the maximum occupancy"); - } - - BigDecimal totalPrice = accommodation.getPrice(); - - BigDecimal pricePerPerson = totalPrice.divide(BigDecimal.valueOf(numberOfPeople), 2, RoundingMode.HALF_UP); - - Map response = new HashMap<>(); - response.put("totalPrice", totalPrice); - response.put("numberOfPeople", numberOfPeople); - response.put("pricePerPerson", pricePerPerson); - response.put("maxOccupancy", maxOccupancy); - - return ResponseEntity.ok(response); - } } From 9c1d36dcebe6fb25e1b4106f7295bd608f8be4d3 Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sat, 19 Apr 2025 19:03:34 -0300 Subject: [PATCH 3/8] feat(Accommodation): improve property names --- .../unipampa/crud/dto/AccommodationDTO.java | 7 ++++--- .../unipampa/crud/entities/Accommodation.java | 21 ++++++++++--------- .../repository/AccommodationRepository.java | 2 +- .../impl/AccommodationServiceImpl.java | 2 +- .../impl/ValidateAccommodationRegistered.java | 2 +- .../impl/AccommodationServiceImplTest.java | 20 +++++++++--------- .../ValidateAccommodationRegisteredTest.java | 8 +++---- 7 files changed, 32 insertions(+), 30 deletions(-) diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java index ece50347..e97b34b4 100644 --- a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java +++ b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java @@ -1,11 +1,11 @@ package com.unipampa.crud.dto; import com.unipampa.crud.enums.AccommodationType; -import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.math.BigDecimal; +import java.util.List; public record AccommodationDTO( @NotBlank String title, @@ -16,8 +16,9 @@ public record AccommodationDTO( String adress, @NotBlank String state, @NotBlank BigDecimal price, - int number, + int streetNumber, @NotNull int imageQuantity, @NotNull AccommodationType accommodationType, - @NotNull int maxOccupancy + @NotNull int maxOccupancy, + List imagesUrls ) {} diff --git a/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java b/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java index dee97b19..7120c821 100644 --- a/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java +++ b/cadastral/src/main/java/com/unipampa/crud/entities/Accommodation.java @@ -7,6 +7,7 @@ import org.springframework.data.annotation.Id; import java.math.BigDecimal; +import java.util.List; @Builder @Document @@ -18,21 +19,21 @@ public class Accommodation { private String title; private String description; private BigDecimal price; - private String imagesUrl; - private int numberRoooms; - private int numberBathrooms; - private boolean acceptsAnimals; - private boolean acceptsChildren; - private boolean sharedHosting; - private boolean authorizedAnnouncement; - private AccommodationType accommodationType; + private List imagesUrls; + private int roomCount; + private int bathroomCount; + private boolean allowsPets; + private boolean allowsChildren; + private boolean isSharedHosting; + private boolean isAuthorizedAnnouncement; + private AccommodationType type; private String city; private String neighborhood; - private int number; + private int streetNumber; private String zipCode; private String address; private String state; - private int imageQuantity; + private int imageCount; private int maxOccupancy; } diff --git a/cadastral/src/main/java/com/unipampa/crud/repository/AccommodationRepository.java b/cadastral/src/main/java/com/unipampa/crud/repository/AccommodationRepository.java index 9056a44c..b8477338 100644 --- a/cadastral/src/main/java/com/unipampa/crud/repository/AccommodationRepository.java +++ b/cadastral/src/main/java/com/unipampa/crud/repository/AccommodationRepository.java @@ -5,7 +5,7 @@ public interface AccommodationRepository extends MongoRepository { - boolean existsByZipCodeAndNumber(String codeAddress, int number); + boolean existsByZipCodeAndStreetNumber(String codeAddress, int streetNumber); } diff --git a/cadastral/src/main/java/com/unipampa/crud/service/impl/AccommodationServiceImpl.java b/cadastral/src/main/java/com/unipampa/crud/service/impl/AccommodationServiceImpl.java index b47e82d7..1f197e85 100644 --- a/cadastral/src/main/java/com/unipampa/crud/service/impl/AccommodationServiceImpl.java +++ b/cadastral/src/main/java/com/unipampa/crud/service/impl/AccommodationServiceImpl.java @@ -44,7 +44,7 @@ public void delete(String id) { @Override public boolean existsByCodAddressAndNumber(String codeAddress, int number) { - return propertyRepository.existsByZipCodeAndNumber(codeAddress, number); + return propertyRepository.existsByZipCodeAndStreetNumber(codeAddress, number); } @Override diff --git a/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java b/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java index 8b86616e..cfb8eefa 100644 --- a/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java +++ b/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java @@ -19,7 +19,7 @@ public class ValidateAccommodationRegistered implements ValidationsRegisterAccom @Override public void validate(AccommodationDTO entity) { if (entity.accommodationType().equals(AccommodationType.HOUSE) - && service.existsByCodAddressAndNumber(entity.codAddress(), entity.number())) { + && service.existsByCodAddressAndNumber(entity.codAddress(), entity.streetNumber())) { log.error("HOUSE {} is already registered!", entity.description()); throw new ValidateRegisterException("HOUSE is already registered!"); } diff --git a/cadastral/src/test/java/com/unipampa/crud/service/impl/AccommodationServiceImplTest.java b/cadastral/src/test/java/com/unipampa/crud/service/impl/AccommodationServiceImplTest.java index 26ee2dbe..4e74f1ab 100644 --- a/cadastral/src/test/java/com/unipampa/crud/service/impl/AccommodationServiceImplTest.java +++ b/cadastral/src/test/java/com/unipampa/crud/service/impl/AccommodationServiceImplTest.java @@ -36,8 +36,8 @@ class AccommodationServiceImplTest { void setUp() { accommodation = Accommodation.builder() .id("1") - .number(101) - .zipCode("ADDR123") + .addressNumber(101) + .postalCode("ADDR123") .build(); } @@ -113,26 +113,26 @@ void testDeleteWhenExceptionThrown() { @Test void testExistsByCodAddressAndNumberReturnsTrue() { - String codeAddress = accommodation.getZipCode(); - int number = accommodation.getNumber(); - when(propertyRepository.existsByZipCodeAndNumber(codeAddress, number)).thenReturn(true); + String codeAddress = accommodation.getPostalCode(); + int number = accommodation.getAddressNumber(); + when(propertyRepository.existsByZipCodeAndStreetNumber(codeAddress, number)).thenReturn(true); boolean result = accommodationService.existsByCodAddressAndNumber(codeAddress, number); assertTrue(result); - verify(propertyRepository, times(1)).existsByZipCodeAndNumber(codeAddress, number); + verify(propertyRepository, times(1)).existsByZipCodeAndStreetNumber(codeAddress, number); } @Test void testExistsByCodAddressAndNumberReturnsFalse() { - String codeAddress = accommodation.getZipCode(); - int number = accommodation.getNumber(); - when(propertyRepository.existsByZipCodeAndNumber(codeAddress, number)).thenReturn(false); + String codeAddress = accommodation.getPostalCode(); + int number = accommodation.getAddressNumber(); + when(propertyRepository.existsByZipCodeAndStreetNumber(codeAddress, number)).thenReturn(false); boolean result = accommodationService.existsByCodAddressAndNumber(codeAddress, number); assertFalse(result); - verify(propertyRepository, times(1)).existsByZipCodeAndNumber(codeAddress, number); + verify(propertyRepository, times(1)).existsByZipCodeAndStreetNumber(codeAddress, number); } @Test diff --git a/cadastral/src/test/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegisteredTest.java b/cadastral/src/test/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegisteredTest.java index d83a645d..1d930b89 100644 --- a/cadastral/src/test/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegisteredTest.java +++ b/cadastral/src/test/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegisteredTest.java @@ -46,23 +46,23 @@ void setUp() { @Test void shouldValidateSuccessWhenHouseNotRegistered() { - when(service.existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.number())).thenReturn(false); + when(service.existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.streetNumber())).thenReturn(false); assertDoesNotThrow(() -> validateAccommodation.validate(dtoHouse)); - verify(service).existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.number()); + verify(service).existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.streetNumber()); } @Test void testValidateFailureWhenHouseAlreadyRegistered() { - when(service.existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.number())).thenReturn(true); + when(service.existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.streetNumber())).thenReturn(true); ValidateRegisterException exception = assertThrows(ValidateRegisterException.class, () -> { validateAccommodation.validate(dtoHouse); }); assertEquals("HOUSE is already registered!", exception.getMessage()); - verify(service).existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.number()); + verify(service).existsByCodAddressAndNumber(dtoHouse.codAddress(), dtoHouse.streetNumber()); } } \ No newline at end of file From 2f76dfe8cd4fca4674d863086c871e215a06dfbe Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sat, 19 Apr 2025 19:27:01 -0300 Subject: [PATCH 4/8] feat(Accommodation): improve save response --- .../crud/resources/AccommodationResource.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index 55f57494..d2aa1eb5 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -13,6 +13,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.net.URI; import java.util.List; import java.util.Optional; @@ -30,9 +31,11 @@ public class AccommodationResource { private List validations; @PostMapping - @Operation(summary = "Salva uma acomodação)") + @Operation(summary = "Cria uma nova acomodação", + description = "Valida e salva uma nova acomodação no sistema.") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Recurso salvo com sucesso!" ) + @ApiResponse(responseCode = "201", description = "Acomodação criada com sucesso"), + @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos") }) public ResponseEntity save(@RequestBody AccommodationDTO accommodationDTO) { @@ -40,7 +43,10 @@ public ResponseEntity save(@RequestBody AccommodationDTO accommod var accommodation = mapper.convertValue(accommodationDTO, Accommodation.class); accommodationService.save(accommodation); - return ResponseEntity.status(HttpStatus.OK).body(accommodation); + + URI location = URI.create("/accommodations/" + accommodation.getId()); + + return ResponseEntity.created(location).body(accommodation); } @GetMapping From 0cb5d5ad8911be8cf8485618f4cb58dc73aa66e3 Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sat, 19 Apr 2025 23:17:31 -0300 Subject: [PATCH 5/8] feat(Accommodation): return DTOs on the findAll --- .../crud/resources/AccommodationResource.java | 13 +++++++++---- .../crud/resources/AccommodationResourceTest.java | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index d2aa1eb5..c5485bfd 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -16,6 +16,7 @@ import java.net.URI; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @RestController @RequestMapping("/accommodations") @@ -48,12 +49,16 @@ public ResponseEntity save(@RequestBody AccommodationDTO accommod return ResponseEntity.created(location).body(accommodation); } - + @GetMapping @Operation(summary = "Retorna uma lista com todas as acomodações") - public ResponseEntity> findAll() { - List accommodations = accommodationService.findAll(); - return ResponseEntity.status(HttpStatus.OK).body(accommodations); + public ResponseEntity> findAll() { + List accommodationDtos = accommodationService.findAll() + .stream() + .map(accommodation -> mapper.convertValue(accommodation, AccommodationDTO.class)) + .collect(Collectors.toList()); + + return ResponseEntity.ok(accommodationDtos); } @GetMapping("{id}") diff --git a/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java b/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java index 8716d95c..64d5f65a 100644 --- a/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java +++ b/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java @@ -111,7 +111,7 @@ void shouldFindAllSuccess() { List mockAccommodations = Arrays.asList(accommodation, accommodation2); when(accommodationService.findAll()).thenReturn(mockAccommodations); - ResponseEntity> response = accommodationResource.findAll(); + ResponseEntity> response = accommodationResource.findAll(); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); From 2e8c6020a4100e8b2e5b4437306281c0db2a974e Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sat, 19 Apr 2025 23:49:31 -0300 Subject: [PATCH 6/8] feat(Accommodation): use errorResponse and DTOs --- .../unipampa/crud/dto/AccommodationDTO.java | 2 +- .../com/unipampa/crud/dto/ErrorResponse.java | 5 ++ .../crud/resources/AccommodationResource.java | 53 ++++++++++++------- 3 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 cadastral/src/main/java/com/unipampa/crud/dto/ErrorResponse.java diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java index e97b34b4..670ef9da 100644 --- a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java +++ b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java @@ -13,7 +13,7 @@ public record AccommodationDTO( String codAddress, @NotNull String city, @NotBlank String description, - String adress, + String address, @NotBlank String state, @NotBlank BigDecimal price, int streetNumber, diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/ErrorResponse.java b/cadastral/src/main/java/com/unipampa/crud/dto/ErrorResponse.java new file mode 100644 index 00000000..c64cb003 --- /dev/null +++ b/cadastral/src/main/java/com/unipampa/crud/dto/ErrorResponse.java @@ -0,0 +1,5 @@ +package com.unipampa.crud.dto; + +import java.time.LocalDateTime; + +public record ErrorResponse(String message, LocalDateTime timestamp) { } diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index c5485bfd..e8735013 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.unipampa.crud.dto.AccommodationDTO; +import com.unipampa.crud.dto.ErrorResponse; import com.unipampa.crud.entities.Accommodation; import com.unipampa.crud.service.AccommodationService; import com.unipampa.crud.validations.ValidationsRegisterAccommodation; @@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.*; import java.net.URI; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -68,24 +70,35 @@ public ResponseEntity> findAll() { @ApiResponse(responseCode = "404", description = "Recurso não encontrado") }) public ResponseEntity getById(@PathVariable("id") String id) { - Optional accomodation = accommodationService.findById(id); - return accomodation.>map(accommodation -> new ResponseEntity<>(accommodation, HttpStatus.OK)) - .orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).body("Acomodação não encontrada para esse id")); + Optional accommodation = accommodationService.findById(id); + + if (accommodation.isPresent()) { + AccommodationDTO dto = mapper.convertValue(accommodation.get(), AccommodationDTO.class); + return ResponseEntity.ok(dto); + } + + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para esse id", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } - + + @DeleteMapping("{id}") - @Operation(summary = "Deleta uma acomodação através do id") + @Operation(summary = "Deleta uma Acomodação através do id") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Recurso deletado com sucesso"), - @ApiResponse(responseCode = "404", description = "Recurso não encontrado") + @ApiResponse(responseCode = "204", description = "Acomodação deletada com sucesso"), + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada") }) public ResponseEntity deleteAccommodation(@PathVariable("id") String id) { Optional accommodation = accommodationService.findById(id); - if(accommodation.isEmpty()){ - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Acomodação não encontrada para esse id, portanto não pode ser deletada!"); + + if (accommodation.isEmpty()) { + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para esse id, portanto não pode ser deletada!", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } + accommodationService.delete(id); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); + + return ResponseEntity.noContent().build(); } @PutMapping("{id}") @@ -97,27 +110,31 @@ public ResponseEntity deleteAccommodation(@PathVariable("id") String id) }) public ResponseEntity updateAccommodation( @PathVariable("id") String id, - @RequestBody AccommodationDTO accommodationDTO) { - + @RequestBody AccommodationDTO accommodationDTO + ) { Optional existingAccommodation = accommodationService.findById(id); if (existingAccommodation.isEmpty()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Acomodação não encontrada para esse id, portanto não pode ser atualizada!"); + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para esse id, portanto não pode ser atualizada!", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } try { - validations.forEach(e -> e.validate(accommodationDTO)); + validations.forEach(e -> e.validate(accommodationDTO)); // Custom validation logic Accommodation accommodation = existingAccommodation.get(); - accommodation.setTitle(accommodationDTO.title()); - accommodation.setAddress(accommodationDTO.adress()); + accommodation.setAddress(accommodationDTO.address()); accommodation.setPrice(accommodationDTO.price()); accommodationService.save(accommodation); - return ResponseEntity.ok(accommodation); + AccommodationDTO updatedDTO = mapper.convertValue(accommodation, AccommodationDTO.class); + + return ResponseEntity.ok(updatedDTO); } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Erro ao atualizar a acomodação. Verifique os dados fornecidos."); + ErrorResponse errorResponse = new ErrorResponse("Erro ao atualizar a acomodação. Verifique os dados fornecidos.", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); } } + } From 5c35bc75971359e8ea71ec6497783f88b87f0e0b Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sun, 20 Apr 2025 00:03:53 -0300 Subject: [PATCH 7/8] fix(Swagger): fix swagger and improve messages --- cadastral/pom.xml | 4 ++ .../unipampa/crud/dto/AccommodationDTO.java | 4 +- .../java/com/unipampa/crud/dto/UserDTO.java | 2 +- .../crud/resources/AccommodationResource.java | 56 ++++++++++++------- .../resources/AccommodationResourceTest.java | 2 +- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/cadastral/pom.xml b/cadastral/pom.xml index 3a09d9fd..b85a67f9 100644 --- a/cadastral/pom.xml +++ b/cadastral/pom.xml @@ -89,6 +89,10 @@ org.springframework.boot spring-boot-starter-data-mongodb + + jakarta.validation + jakarta.validation-api + diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java index 670ef9da..2bd93e17 100644 --- a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java +++ b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java @@ -2,8 +2,8 @@ import com.unipampa.crud.enums.AccommodationType; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.math.BigDecimal; import java.util.List; diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/UserDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/UserDTO.java index b9f19a7c..5d68849b 100644 --- a/cadastral/src/main/java/com/unipampa/crud/dto/UserDTO.java +++ b/cadastral/src/main/java/com/unipampa/crud/dto/UserDTO.java @@ -3,7 +3,7 @@ import com.unipampa.crud.enums.UserType; import lombok.Data; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; public record UserDTO( @NotBlank String email, diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index e8735013..904e9dea 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -7,6 +7,8 @@ import com.unipampa.crud.service.AccommodationService; import com.unipampa.crud.validations.ValidationsRegisterAccommodation; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.springframework.beans.factory.annotation.Autowired; @@ -34,11 +36,13 @@ public class AccommodationResource { private List validations; @PostMapping - @Operation(summary = "Cria uma nova acomodação", + @Operation(summary = "Criar uma nova acomodação", description = "Valida e salva uma nova acomodação no sistema.") @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Acomodação criada com sucesso"), - @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos") + @ApiResponse(responseCode = "201", description = "Acomodação criada com sucesso", + content = @Content(schema = @Schema(implementation = Accommodation.class))), + @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity save(@RequestBody AccommodationDTO accommodationDTO) { @@ -53,7 +57,12 @@ public ResponseEntity save(@RequestBody AccommodationDTO accommod } @GetMapping - @Operation(summary = "Retorna uma lista com todas as acomodações") + @Operation(summary = "Listar todas as acomodações", + description = "Retorna uma lista contendo todas as acomodações cadastradas.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Lista retornada com sucesso", + content = @Content(schema = @Schema(implementation = AccommodationDTO.class))) + }) public ResponseEntity> findAll() { List accommodationDtos = accommodationService.findAll() .stream() @@ -64,10 +73,13 @@ public ResponseEntity> findAll() { } @GetMapping("{id}") - @Operation(summary = "Encontra uma acomodação através do id") + @Operation(summary = "Buscar acomodação por ID", + description = "Retorna os dados de uma acomodação específica a partir do seu ID.") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Recurso encontrado com sucesso"), - @ApiResponse(responseCode = "404", description = "Recurso não encontrado") + @ApiResponse(responseCode = "200", description = "Acomodação encontrada", + content = @Content(schema = @Schema(implementation = AccommodationDTO.class))), + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity getById(@PathVariable("id") String id) { Optional accommodation = accommodationService.findById(id); @@ -77,36 +89,40 @@ public ResponseEntity getById(@PathVariable("id") String id) { return ResponseEntity.ok(dto); } - ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para esse id", LocalDateTime.now()); + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido.", LocalDateTime.now()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } - @DeleteMapping("{id}") - @Operation(summary = "Deleta uma Acomodação através do id") + @Operation(summary = "Deletar acomodação por ID", + description = "Remove uma acomodação existente a partir do seu ID.") @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Acomodação deletada com sucesso"), - @ApiResponse(responseCode = "404", description = "Acomodação não encontrada") + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity deleteAccommodation(@PathVariable("id") String id) { Optional accommodation = accommodationService.findById(id); if (accommodation.isEmpty()) { - ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para esse id, portanto não pode ser deletada!", LocalDateTime.now()); + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido. Exclusão não realizada.", LocalDateTime.now()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } accommodationService.delete(id); - return ResponseEntity.noContent().build(); } @PutMapping("{id}") - @Operation(summary = "Atualiza uma acomodação através do id") + @Operation(summary = "Atualizar acomodação por ID", + description = "Atualiza os dados de uma acomodação existente.") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Acomodação atualizada com sucesso"), - @ApiResponse(responseCode = "404", description = "Acomodação não encontrada"), - @ApiResponse(responseCode = "400", description = "Dados de acomodação inválidos") + @ApiResponse(responseCode = "200", description = "Acomodação atualizada com sucesso", + content = @Content(schema = @Schema(implementation = AccommodationDTO.class))), + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity updateAccommodation( @PathVariable("id") String id, @@ -114,12 +130,12 @@ public ResponseEntity updateAccommodation( ) { Optional existingAccommodation = accommodationService.findById(id); if (existingAccommodation.isEmpty()) { - ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para esse id, portanto não pode ser atualizada!", LocalDateTime.now()); + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido. Atualização não realizada.", LocalDateTime.now()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } try { - validations.forEach(e -> e.validate(accommodationDTO)); // Custom validation logic + validations.forEach(e -> e.validate(accommodationDTO)); Accommodation accommodation = existingAccommodation.get(); accommodation.setTitle(accommodationDTO.title()); @@ -129,8 +145,8 @@ public ResponseEntity updateAccommodation( accommodationService.save(accommodation); AccommodationDTO updatedDTO = mapper.convertValue(accommodation, AccommodationDTO.class); - return ResponseEntity.ok(updatedDTO); + } catch (Exception e) { ErrorResponse errorResponse = new ErrorResponse("Erro ao atualizar a acomodação. Verifique os dados fornecidos.", LocalDateTime.now()); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); diff --git a/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java b/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java index 64d5f65a..e1665cdc 100644 --- a/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java +++ b/cadastral/src/test/java/com/unipampa/crud/resources/AccommodationResourceTest.java @@ -21,7 +21,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import javax.validation.Validation; +import jakarta.validation.Validation; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; From 2b656f2ad3828eed4d08b46ab38adde8bcce45a1 Mon Sep 17 00:00:00 2001 From: Auri Gabriel Date: Sun, 20 Apr 2025 09:40:29 -0300 Subject: [PATCH 8/8] feat(Accommodation): add mapper and request DTO --- .../unipampa/crud/dto/AccommodationDTO.java | 8 +- .../crud/dto/AccommodationRequestDTO.java | 24 ++ .../crud/mappers/AccommodationMapper.java | 29 ++ .../crud/resources/AccommodationResource.java | 255 +++++++++--------- .../ValidationsRegisterAccommodation.java | 4 +- .../impl/ValidateAccommodationRegistered.java | 3 +- 6 files changed, 189 insertions(+), 134 deletions(-) create mode 100644 cadastral/src/main/java/com/unipampa/crud/dto/AccommodationRequestDTO.java create mode 100644 cadastral/src/main/java/com/unipampa/crud/mappers/AccommodationMapper.java diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java index 2bd93e17..fc4f98f4 100644 --- a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java +++ b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationDTO.java @@ -1,13 +1,13 @@ package com.unipampa.crud.dto; import com.unipampa.crud.enums.AccommodationType; - import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.math.BigDecimal; import java.util.List; public record AccommodationDTO( + String id, @NotBlank String title, String neighborhood, String codAddress, @@ -15,10 +15,10 @@ public record AccommodationDTO( @NotBlank String description, String address, @NotBlank String state, - @NotBlank BigDecimal price, + @NotNull BigDecimal price, int streetNumber, - @NotNull int imageQuantity, + @NotNull Integer imageQuantity, @NotNull AccommodationType accommodationType, - @NotNull int maxOccupancy, + @NotNull Integer maxOccupancy, List imagesUrls ) {} diff --git a/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationRequestDTO.java b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationRequestDTO.java new file mode 100644 index 00000000..4c714479 --- /dev/null +++ b/cadastral/src/main/java/com/unipampa/crud/dto/AccommodationRequestDTO.java @@ -0,0 +1,24 @@ +package com.unipampa.crud.dto; + +import com.unipampa.crud.enums.AccommodationType; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.math.BigDecimal; +import java.util.List; + +public record AccommodationRequestDTO( + @NotBlank String title, + String neighborhood, + String codAddress, + @NotNull String city, + @NotBlank String description, + String address, + @NotBlank String state, + @NotNull BigDecimal price, + int streetNumber, + @NotNull Integer imageQuantity, + @NotNull AccommodationType accommodationType, + @NotNull Integer maxOccupancy, + List imagesUrls +) {} diff --git a/cadastral/src/main/java/com/unipampa/crud/mappers/AccommodationMapper.java b/cadastral/src/main/java/com/unipampa/crud/mappers/AccommodationMapper.java new file mode 100644 index 00000000..dc3d39f5 --- /dev/null +++ b/cadastral/src/main/java/com/unipampa/crud/mappers/AccommodationMapper.java @@ -0,0 +1,29 @@ +package com.unipampa.crud.mappers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.unipampa.crud.dto.AccommodationDTO; +import com.unipampa.crud.dto.AccommodationRequestDTO; +import com.unipampa.crud.entities.Accommodation; +import org.springframework.stereotype.Component; + +@Component +public class AccommodationMapper { + + private final ObjectMapper objectMapper; + + public AccommodationMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public Accommodation toEntity(AccommodationDTO dto) { + return objectMapper.convertValue(dto, Accommodation.class); + } + + public Accommodation toEntity(AccommodationRequestDTO requestDTO) { + return objectMapper.convertValue(requestDTO, Accommodation.class); + } + + public AccommodationDTO toDTO(Accommodation entity) { + return objectMapper.convertValue(entity, AccommodationDTO.class); + } +} diff --git a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java index 904e9dea..b6b919c2 100644 --- a/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java +++ b/cadastral/src/main/java/com/unipampa/crud/resources/AccommodationResource.java @@ -1,9 +1,10 @@ package com.unipampa.crud.resources; -import com.fasterxml.jackson.databind.ObjectMapper; import com.unipampa.crud.dto.AccommodationDTO; +import com.unipampa.crud.dto.AccommodationRequestDTO; import com.unipampa.crud.dto.ErrorResponse; import com.unipampa.crud.entities.Accommodation; +import com.unipampa.crud.mappers.AccommodationMapper; import com.unipampa.crud.service.AccommodationService; import com.unipampa.crud.validations.ValidationsRegisterAccommodation; import io.swagger.v3.oas.annotations.Operation; @@ -26,131 +27,131 @@ @RequestMapping("/accommodations") public class AccommodationResource { - @Autowired - private AccommodationService accommodationService; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private List validations; - - @PostMapping - @Operation(summary = "Criar uma nova acomodação", - description = "Valida e salva uma nova acomodação no sistema.") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Acomodação criada com sucesso", - content = @Content(schema = @Schema(implementation = Accommodation.class))), - @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - public ResponseEntity save(@RequestBody AccommodationDTO accommodationDTO) { - - validations.forEach(e -> e.validate(accommodationDTO)); - - var accommodation = mapper.convertValue(accommodationDTO, Accommodation.class); - accommodationService.save(accommodation); - - URI location = URI.create("/accommodations/" + accommodation.getId()); - - return ResponseEntity.created(location).body(accommodation); - } - - @GetMapping - @Operation(summary = "Listar todas as acomodações", - description = "Retorna uma lista contendo todas as acomodações cadastradas.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Lista retornada com sucesso", - content = @Content(schema = @Schema(implementation = AccommodationDTO.class))) - }) - public ResponseEntity> findAll() { - List accommodationDtos = accommodationService.findAll() - .stream() - .map(accommodation -> mapper.convertValue(accommodation, AccommodationDTO.class)) - .collect(Collectors.toList()); - - return ResponseEntity.ok(accommodationDtos); - } - - @GetMapping("{id}") - @Operation(summary = "Buscar acomodação por ID", - description = "Retorna os dados de uma acomodação específica a partir do seu ID.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Acomodação encontrada", - content = @Content(schema = @Schema(implementation = AccommodationDTO.class))), - @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - public ResponseEntity getById(@PathVariable("id") String id) { - Optional accommodation = accommodationService.findById(id); - - if (accommodation.isPresent()) { - AccommodationDTO dto = mapper.convertValue(accommodation.get(), AccommodationDTO.class); - return ResponseEntity.ok(dto); - } - - ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido.", LocalDateTime.now()); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); - } - - @DeleteMapping("{id}") - @Operation(summary = "Deletar acomodação por ID", - description = "Remove uma acomodação existente a partir do seu ID.") - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Acomodação deletada com sucesso"), - @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - public ResponseEntity deleteAccommodation(@PathVariable("id") String id) { - Optional accommodation = accommodationService.findById(id); - - if (accommodation.isEmpty()) { - ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido. Exclusão não realizada.", LocalDateTime.now()); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); - } - - accommodationService.delete(id); - return ResponseEntity.noContent().build(); - } - - @PutMapping("{id}") - @Operation(summary = "Atualizar acomodação por ID", - description = "Atualiza os dados de uma acomodação existente.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Acomodação atualizada com sucesso", - content = @Content(schema = @Schema(implementation = AccommodationDTO.class))), - @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - public ResponseEntity updateAccommodation( - @PathVariable("id") String id, - @RequestBody AccommodationDTO accommodationDTO - ) { - Optional existingAccommodation = accommodationService.findById(id); - if (existingAccommodation.isEmpty()) { - ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido. Atualização não realizada.", LocalDateTime.now()); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); - } - - try { - validations.forEach(e -> e.validate(accommodationDTO)); - - Accommodation accommodation = existingAccommodation.get(); - accommodation.setTitle(accommodationDTO.title()); - accommodation.setAddress(accommodationDTO.address()); - accommodation.setPrice(accommodationDTO.price()); - - accommodationService.save(accommodation); - - AccommodationDTO updatedDTO = mapper.convertValue(accommodation, AccommodationDTO.class); - return ResponseEntity.ok(updatedDTO); - - } catch (Exception e) { - ErrorResponse errorResponse = new ErrorResponse("Erro ao atualizar a acomodação. Verifique os dados fornecidos.", LocalDateTime.now()); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); - } - } + @Autowired + private AccommodationService accommodationService; + + @Autowired + private AccommodationMapper accommodationMapper; + + @Autowired + private List validations; + + @PostMapping + @Operation(summary = "Criar uma nova acomodação", + description = "Valida e salva uma nova acomodação no sistema.") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Acomodação criada com sucesso", + content = @Content(schema = @Schema(implementation = Accommodation.class))), + @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + public ResponseEntity save(@RequestBody AccommodationRequestDTO accommodationDTO) { + + validations.forEach(e -> e.validate(accommodationDTO)); + + var accommodation = accommodationMapper.toEntity(accommodationDTO); + accommodationService.save(accommodation); + + URI location = URI.create("/accommodations/" + accommodation.getId()); + + return ResponseEntity.created(location).body(accommodation); + } + + @GetMapping + @Operation(summary = "Listar todas as acomodações", + description = "Retorna uma lista contendo todas as acomodações cadastradas.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Lista retornada com sucesso", + content = @Content(schema = @Schema(implementation = AccommodationDTO.class))) + }) + public ResponseEntity> findAll() { + List accommodationDtos = accommodationService.findAll() + .stream() + .map(accommodation -> accommodationMapper.toDTO(accommodation)) + .collect(Collectors.toList()); + + return ResponseEntity.ok(accommodationDtos); + } + + @GetMapping("{id}") + @Operation(summary = "Buscar acomodação por ID", + description = "Retorna os dados de uma acomodação específica a partir do seu ID.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Acomodação encontrada", + content = @Content(schema = @Schema(implementation = AccommodationDTO.class))), + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + public ResponseEntity getById(@PathVariable("id") String id) { + Optional accommodationOptional = accommodationService.findById(id); + + if (accommodationOptional.isPresent()) { + AccommodationDTO dto = accommodationMapper.toDTO(accommodationOptional.get()); + return ResponseEntity.ok(dto); + } + + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido.", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); + } + + @DeleteMapping("{id}") + @Operation(summary = "Deletar acomodação por ID", + description = "Remove uma acomodação existente a partir do seu ID.") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Acomodação deletada com sucesso"), + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + public ResponseEntity deleteAccommodation(@PathVariable("id") String id) { + Optional accommodation = accommodationService.findById(id); + + if (accommodation.isEmpty()) { + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido. Exclusão não realizada.", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); + } + + accommodationService.delete(id); + return ResponseEntity.noContent().build(); + } + + @PutMapping("{id}") + @Operation(summary = "Atualizar acomodação por ID", + description = "Atualiza os dados de uma acomodação existente.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Acomodação atualizada com sucesso", + content = @Content(schema = @Schema(implementation = AccommodationDTO.class))), + @ApiResponse(responseCode = "404", description = "Acomodação não encontrada", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + public ResponseEntity updateAccommodation( + @PathVariable("id") String id, + @RequestBody AccommodationRequestDTO accommodationDTO + ) { + Optional existingAccommodation = accommodationService.findById(id); + if (existingAccommodation.isEmpty()) { + ErrorResponse errorResponse = new ErrorResponse("Acomodação não encontrada para o ID fornecido. Atualização não realizada.", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); + } + + try { + validations.forEach(e -> e.validate(accommodationDTO)); + + Accommodation accommodation = existingAccommodation.get(); + accommodation.setTitle(accommodationDTO.title()); + accommodation.setAddress(accommodationDTO.address()); + accommodation.setPrice(accommodationDTO.price()); + + accommodationService.save(accommodation); + + AccommodationDTO updatedDTO = accommodationMapper.toDTO(accommodation); + return ResponseEntity.ok(updatedDTO); + + } catch (Exception e) { + ErrorResponse errorResponse = new ErrorResponse("Erro ao atualizar a acomodação. Verifique os dados fornecidos.", LocalDateTime.now()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); + } + } } diff --git a/cadastral/src/main/java/com/unipampa/crud/validations/ValidationsRegisterAccommodation.java b/cadastral/src/main/java/com/unipampa/crud/validations/ValidationsRegisterAccommodation.java index 58dd7438..cf986670 100644 --- a/cadastral/src/main/java/com/unipampa/crud/validations/ValidationsRegisterAccommodation.java +++ b/cadastral/src/main/java/com/unipampa/crud/validations/ValidationsRegisterAccommodation.java @@ -1,8 +1,8 @@ package com.unipampa.crud.validations; -import com.unipampa.crud.dto.AccommodationDTO; +import com.unipampa.crud.dto.AccommodationRequestDTO; public interface ValidationsRegisterAccommodation { - void validate(AccommodationDTO accommodationDTO); + void validate(AccommodationRequestDTO accommodationDTO); } diff --git a/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java b/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java index cfb8eefa..62844b39 100644 --- a/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java +++ b/cadastral/src/main/java/com/unipampa/crud/validations/impl/ValidateAccommodationRegistered.java @@ -1,6 +1,7 @@ package com.unipampa.crud.validations.impl; import com.unipampa.crud.dto.AccommodationDTO; +import com.unipampa.crud.dto.AccommodationRequestDTO; import com.unipampa.crud.enums.AccommodationType; import com.unipampa.crud.exceptions.ValidateRegisterException; import com.unipampa.crud.service.AccommodationService; @@ -17,7 +18,7 @@ public class ValidateAccommodationRegistered implements ValidationsRegisterAccom private AccommodationService service; @Override - public void validate(AccommodationDTO entity) { + public void validate(AccommodationRequestDTO entity) { if (entity.accommodationType().equals(AccommodationType.HOUSE) && service.existsByCodAddressAndNumber(entity.codAddress(), entity.streetNumber())) { log.error("HOUSE {} is already registered!", entity.description());