Skip to content

Commit

Permalink
Merge pull request #175 from bounswe/issue#171-implement-joining-trai…
Browse files Browse the repository at this point in the history
…ning-program

Join Training Program Endpoint
  • Loading branch information
m1u1s1 authored Oct 21, 2024
2 parents fc0491a + 0d0effc commit ac9002d
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,30 @@ public ResponseEntity<Void> deleteTrainingProgram(@PathVariable Long id, HttpSer
}
}


@PostMapping("/{programId}/join")
public ResponseEntity<String> joinTrainingProgram(@RequestParam Long userId, @PathVariable Long programId , HttpServletRequest request) {
trainingProgramService.joinTrainingProgram(userId, programId ,request);
return ResponseEntity.ok("User has successfully joined the training program.");
}

@DeleteMapping("/leave")
public ResponseEntity<String> leaveProgram(@RequestParam Long programId, HttpServletRequest request) {
trainingProgramService.leaveTrainingProgram(programId, request);
return ResponseEntity.ok("Successfully left the training program.");
}

@GetMapping("/{programId}/participants")
public ResponseEntity<List<String>> getRegisteredUsernames(@PathVariable Long programId) {
List<String> usernames = trainingProgramService.getRegisteredUsernames(programId);
return ResponseEntity.ok(usernames);
}


@GetMapping("/trainer/{username}")
public ResponseEntity<List<TrainingProgramResponse>> getTrainingProgramsByTrainer(@PathVariable String username) {
List<TrainingProgramResponse> trainingPrograms = trainingProgramService.getTrainingProgramByTrainer(username);
return ResponseEntity.ok(trainingPrograms);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,7 @@ public ResponseEntity<Set<String>> getFollowing(@PathVariable String username) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
}


}

Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package com.group7.demo.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.group7.demo.models.enums.LocationType;
import com.group7.demo.models.enums.ProgramType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EqualsAndHashCode( exclude = {"trainer", "exercises", "participants"})
public class TrainingProgram {

@Id
Expand All @@ -38,7 +39,13 @@ public class TrainingProgram {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
@JsonIgnoreProperties("trainingPrograms")
private User trainer;

private String description; // Optional description of the program
private String description;

@OneToMany(mappedBy = "trainingProgram", cascade = CascadeType.ALL)
@JsonIgnoreProperties("trainingProgram")
private Set<UserTrainingProgram> participants = new HashSet<>();

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.group7.demo.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
Expand Down Expand Up @@ -63,6 +64,11 @@ public class User {
private Set<Post> posts = new HashSet<>();

@OneToMany(mappedBy = "trainer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonIgnoreProperties("trainer")
private List<TrainingProgram> trainingPrograms;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnoreProperties("user")
private Set<UserTrainingProgram> joinedPrograms = new HashSet<>();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.group7.demo.models;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Entity
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserTrainingProgram {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "training_program_id", nullable = false)
private TrainingProgram trainingProgram;

private LocalDateTime joinedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.group7.demo.repository;

import com.group7.demo.models.TrainingProgram;
import com.group7.demo.models.User;
import com.group7.demo.models.UserTrainingProgram;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserTrainingProgramRepository extends JpaRepository<UserTrainingProgram, Long> {
boolean existsByUserAndTrainingProgram(User user, TrainingProgram trainingProgram);
Optional<UserTrainingProgram> findByUserIdAndTrainingProgramId(Long userId, Long programId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
import com.group7.demo.dtos.ExerciseResponse;
import com.group7.demo.dtos.TrainingProgramRequest;
import com.group7.demo.dtos.TrainingProgramResponse;
import com.group7.demo.models.Exercise;
import com.group7.demo.models.ExerciseDetail;
import com.group7.demo.models.TrainingProgram;
import com.group7.demo.models.User;
import com.group7.demo.models.*;
import com.group7.demo.repository.TrainingProgramRepository;
import com.group7.demo.repository.UserTrainingProgramRepository;
import com.group7.demo.repository.UserRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

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

Expand All @@ -27,7 +26,10 @@ public class TrainingProgramService {

private final AuthenticationService authenticationService;

private final UserTrainingProgramRepository userTrainingProgramRepository;

private final UserRepository userRepository;

@Transactional
public TrainingProgramResponse createTrainingProgram(TrainingProgramRequest trainingProgramRequest, HttpServletRequest request) throws IllegalAccessException {
User user = authenticationService.getAuthenticatedUserInternal(request);
Expand Down Expand Up @@ -145,5 +147,56 @@ public void deleteTrainingProgram(Long id, HttpServletRequest request) throws Ex
trainingProgramRepository.delete(trainingProgram);
}

@Transactional
public void joinTrainingProgram(Long userId, Long trainingProgramId , HttpServletRequest request) {
User user = authenticationService.getAuthenticatedUserInternal(request);

TrainingProgram trainingProgram = trainingProgramRepository.findById(trainingProgramId)
.orElseThrow(() -> new EntityNotFoundException("Training Program not found with id: " + trainingProgramId));

boolean alreadyJoined = userTrainingProgramRepository.existsByUserAndTrainingProgram(user, trainingProgram);
if (alreadyJoined) {
throw new IllegalStateException("User has already joined the training program.");
}

// Create a new UserTrainingProgram entity
UserTrainingProgram userTrainingProgram = UserTrainingProgram.builder()
.user(user)
.trainingProgram(trainingProgram)
.joinedAt(LocalDateTime.now())
.build();

// Save the UserTrainingProgram entity
userTrainingProgramRepository.save(userTrainingProgram);
}

@Transactional
public void leaveTrainingProgram(Long trainingProgramId, HttpServletRequest request) {
// Fetch the authenticated user from the request
User user = authenticationService.getAuthenticatedUserInternal(request);

// Fetch the training program by its ID
TrainingProgram trainingProgram = trainingProgramRepository.findById(trainingProgramId)
.orElseThrow(() -> new EntityNotFoundException("Training program not found with id: " + trainingProgramId));

// Check if the user is participating in the program
UserTrainingProgram userTrainingProgram = userTrainingProgramRepository.findByUserIdAndTrainingProgramId(user.getId(), trainingProgram.getId())
.orElseThrow(() -> new IllegalStateException("User is not participating in this program."));

// Remove the user from the program
userTrainingProgramRepository.delete(userTrainingProgram);
}

public List<String> getRegisteredUsernames(Long trainingProgramId) {
// Fetch the training program by its ID
TrainingProgram trainingProgram = trainingProgramRepository.findById(trainingProgramId)
.orElseThrow(() -> new EntityNotFoundException("Training program not found with id: " + trainingProgramId));

// Fetch the list of participants' usernames
return trainingProgram.getParticipants().stream()
.map(userTrainingProgram -> userTrainingProgram.getUser().getUsername())
.collect(Collectors.toList());
}


}
4 changes: 2 additions & 2 deletions backend/demo-group7/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update

# Enable SQL query logging - optional
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=false

0 comments on commit ac9002d

Please sign in to comment.