Skip to content

Commit

Permalink
Merge pull request #28 from bouanani-soufiane/PIG-30-gestion-des-resu…
Browse files Browse the repository at this point in the history
…ltats

Pig 30 gestion des resultats
  • Loading branch information
bouanani-soufiane authored Nov 15, 2024
2 parents 896f829 + 4e2e8f8 commit f7e080d
Show file tree
Hide file tree
Showing 18 changed files with 249 additions and 71 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,5 @@ For further questions or contributions, feel free to open an issue or submit a p

---

(link jira)[https://bouananisfn.atlassian.net/jira/software/projects/PIG/boards/39]

75 changes: 32 additions & 43 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,22 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.5</version>
<relativePath/> <!-- lookup parent from repository -->
<relativePath/>
</parent>
<groupId>ma.yc</groupId>
<artifactId>PigeonSkyRace</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>PigeonSkyRace</name>
<description>saas project foodeals</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
<spring-modulith.version>1.2.4</spring-modulith.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<!-- mapStruct -->
<org.mapstruct.version>1.6.2</org.mapstruct.version>
</properties>
<dependencies>
<!-- Spring Boot Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
Expand All @@ -47,15 +34,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter-mongodb</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
Expand All @@ -68,34 +46,36 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>

<!-- Spring Modulith Dependencies -->
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter-test</artifactId>
<scope>test</scope>
<artifactId>spring-modulith-starter-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- Mapping and Utility Dependencies -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mongodb</artifactId>
<scope>test</scope>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
Expand All @@ -107,6 +87,8 @@
<artifactId>spring-security-crypto</artifactId>
<version>6.3.4</version>
</dependency>

<!-- Documentation and PDF Dependencies -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
Expand All @@ -128,6 +110,17 @@
<version>1.76</version>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mongodb</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
Expand All @@ -140,7 +133,6 @@
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
Expand All @@ -155,7 +147,6 @@
</excludes>
</configuration>
</plugin>
<!-- mapstruct plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand All @@ -182,8 +173,6 @@
<artifactId>go-offline-maven-plugin</artifactId>
<version>1.2.8</version>
</plugin>

</plugins>
</build>

</project>
</project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ma.yc.PigeonSkyRace.common.infrastructure.web;

import ma.yc.PigeonSkyRace.common.domain.exception.NotFoundException;
import ma.yc.PigeonSkyRace.competition.domain.Exception.FailedToRegister;
import ma.yc.PigeonSkyRace.piegon.domain.exception.InvalidLoftException;
import ma.yc.PigeonSkyRace.piegon.domain.exception.InvalidLoftIdFormatException;
import ma.yc.PigeonSkyRace.user.domain.exception.InvalidCredentialsException;
Expand All @@ -17,6 +19,13 @@
@RestControllerAdvice
public class GlobalExceptionHandler {


@ExceptionHandler(NotFoundException.class)
public ResponseEntity<ErrorResponse>handleNotFoundException(NotFoundException e) {
ErrorResponse errorResponse = new ErrorResponse(LocalDateTime.now(),HttpStatus.BAD_REQUEST.value(), "Not Found",e.getMessage() );
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(InvalidLoftIdFormatException.class)
public ResponseEntity<String> handleInvalidLoftIdFormatException ( InvalidLoftIdFormatException ex ) {
return ResponseEntity
Expand All @@ -37,6 +46,7 @@ public ResponseEntity<ErrorResponse> handleUserRegistrationException ( UserRegis
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}


@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleValidationExceptions ( MethodArgumentNotValidException ex ) {
Expand All @@ -56,6 +66,12 @@ public ResponseEntity<ErrorResponse> handleInvalidCredentialsException ( Invalid
ErrorResponse error = new ErrorResponse(LocalDateTime.now(), HttpStatus.UNAUTHORIZED.value(), "Authentication Error", e.getMessage());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(error);
}
@ExceptionHandler(FailedToRegister.class)
public ResponseEntity<ErrorResponse> handleRegisterFailed ( FailedToRegister e ) {
ErrorResponse error = new ErrorResponse(LocalDateTime.now(), HttpStatus.UNAUTHORIZED.value(), "register Error", e.getMessage());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(error);
}

}

record ErrorResponse(LocalDateTime timestamp, int status, String error, String message) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package ma.yc.PigeonSkyRace.competition.application.dto.request;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import ma.yc.PigeonSkyRace.competition.domain.ValueObject.AdmissionPercentage;
import ma.yc.PigeonSkyRace.competition.domain.ValueObject.Coordinate;
import ma.yc.PigeonSkyRace.competition.domain.ValueObject.SeasonId;
import ma.yc.PigeonSkyRace.piegon.application.dto.request.CoordinateRequestDTO;

import java.time.LocalDateTime;

public record CompetitionRequestDto(
@NotBlank String name,
@NotBlank String description,
@Positive Integer maxPigeons,
@NotNull Coordinate coordinate,
@Valid
@NotNull(message = "coordinate cannot be null" )
CoordinateRequestDTO coordinate,
@Valid
@NotNull AdmissionPercentage admissionPercentage,
@NotNull LocalDateTime dateStart,
@NotNull LocalDateTime dateEnd,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import ma.yc.PigeonSkyRace.competition.domain.entity.SeasonPigeon;

import javax.swing.text.html.Option;
import java.util.List;
import java.util.Optional;

public interface CompetitionPigeonApplicationService {
CompetitionPigeon findBySeasonPigeonAndCompetition(SeasonPigeon seasonPigeon, Competition competition);
CompetitionPigeon findById(CompetitionPigeonId id);
List<CompetitionPigeon> findByCompetition(Competition competition);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

import jakarta.validation.constraints.NotNull;

public record Coordinate( Double latitude, Double longitude) {
import java.io.Serializable;

public record Coordinate(@NotNull Double latitude, @NotNull Double longitude) implements Serializable {
public Coordinate {
if (latitude < -90 || latitude > 90) {
throw new IllegalArgumentException("Latitude must be between -90 and 90 degrees.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,8 @@ public CompetitionPigeon findById(CompetitionPigeonId id){
return repository.findById(id).orElseThrow(() -> new NotFoundException("competitionPigeon", id));
}

@Override
public List<CompetitionPigeon> findByCompetition(Competition competition) {
return repository.findByCompetition(competition);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
import static ma.yc.PigeonSkyRace.common.application.service.Helper.calculateDistance;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Validated
@RequiredArgsConstructor
public class CompetitionServiceImpl implements CompetitionService, CompetitionApplicationService {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public SeasonPigeonResponseDto RegisterToSeason(SeasonPigeonRequestDto seasonPig
).ifPresent(existing -> {
throw new FailedToRegister("This pigeon is already registered in the season.");
});
if(!seasonPigeonRequestDto.season().getIsActive()){
throw new FailedToRegister("This pigeon is not active.");
}

SeasonPigeon savedSeasonPigeon = repository.save(mapper.toEntity(seasonPigeonRequestDto));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ma.yc.PigeonSkyRace.competition.domain.entity.Competition;
import ma.yc.PigeonSkyRace.competition.domain.entity.CompetitionPigeon;

import ma.yc.PigeonSkyRace.competition.domain.entity.Season;
import ma.yc.PigeonSkyRace.competition.domain.entity.SeasonPigeon;
import ma.yc.PigeonSkyRace.piegon.domain.model.aggregate.Pigeon;
import org.springframework.data.mongodb.repository.MongoRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public record LoftRequestDTO(
CoordinateRequestDTO coordinate,

@EntityExists(entity = User.class, message = "The specified breeder does not exist")
@NotNull String userId) {
@NotNull
String userId) {
}
27 changes: 18 additions & 9 deletions src/main/java/ma/yc/PigeonSkyRace/result/api/ResultController.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,37 @@ public class ResultController {


@PostMapping("/{competitionId}")
public ResponseEntity<ResponseApi<ResultResponseDto>> createResult ( @PathVariable String competitionId, @RequestBody ResultRequestDto resultRequestDto ) {
public ResponseEntity<ResponseApi<ResultResponseDto>> createResult(
@PathVariable String competitionId,
@RequestBody ResultRequestDto resultRequestDto) {

CompetitionResponseDto competitionResponseDto = competitionApplicationService.getCompetition(CompetitionId.fromString(competitionId));
ResultResponseDto responseDto = resultService.createResult(resultRequestDto, competitionResponseDto);
ResultResponseDto responseDto = resultService.createResult(resultRequestDto, competitionResponseDto);

ResponseApi<ResultResponseDto> response = new ResponseApi<>(responseDto, "The information stored with success for competition ", HttpStatus.CREATED);
ResponseApi<ResultResponseDto> response = new ResponseApi<>(
responseDto,
"The information stored with success for competition ",
HttpStatus.CREATED
);

return new ResponseEntity<>(response, HttpStatus.CREATED);

}

@GetMapping("/{id}")
public ResponseEntity<List<ResultResponseDto>> getResult ( @PathVariable String id ) {
List<ResultResponseDto> resultsResponseDto = resultService.calculatePoint(CompetitionPigeonId.fromString(id));
@GetMapping("/{competitionId}")
public ResponseEntity<List<ResultResponseDto>> getResult(@PathVariable String competitionId){
CompetitionResponseDto competitionResponseDto = competitionApplicationService.getCompetition(CompetitionId.fromString(competitionId));
List<ResultResponseDto> resultsResponseDto = resultService.calculatePoint(competitionResponseDto);

return new ResponseEntity<>(resultsResponseDto, HttpStatus.CREATED);
}

@GetMapping("/{id}/pdf")
public ResponseEntity<byte[]> downloadResultPdf ( @PathVariable String id ) {
@GetMapping("/{competitionId}/pdf")
public ResponseEntity<byte[]> downloadResultPdf ( @PathVariable String competitionId ) {
try {
List<ResultResponseDto> results = resultService.calculatePoint(CompetitionPigeonId.fromString(id));
CompetitionResponseDto competitionResponseDto = competitionApplicationService.getCompetition(CompetitionId.fromString(competitionId));

List<ResultResponseDto> results = resultService.calculatePoint(competitionResponseDto);

byte[] pdfBytes = pdfGenerationService.generateResultsPdf(results);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public abstract class ResultMapper {

@Mapping(target = "bandNumber", expression = "java(result.getCompetitionPigeon().getSeasonPigeon().getPigeon().getBandNumber())")
@Mapping(target = "loft", expression = "java(getLoftName(result.getCompetitionPigeon().getSeasonPigeon().getPigeon().getLoft()))")
@Mapping(target = "createdDate", expression = "java(java.time.LocalDateTime.now())")
public abstract ResultResponseDto toDto(Result result);

protected String getLoftName(LoftId loftId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

public interface ResultService {
ResultResponseDto createResult(ResultRequestDto requestDto, CompetitionResponseDto competition);
List<ResultResponseDto> calculatePoint(CompetitionPigeonId id);
List<ResultResponseDto> calculatePoint(CompetitionResponseDto competition);
}
Loading

0 comments on commit f7e080d

Please sign in to comment.