From ccb9ce66f79ccda0226bc219faeea01c1dd16e65 Mon Sep 17 00:00:00 2001 From: Jostein Ruen Date: Fri, 13 Sep 2024 13:58:22 +0200 Subject: [PATCH 1/3] Core done and almost extensions --- build.gradle | 1 + src/main/java/com/booleanuk/api/Main.java | 11 ++ .../com/booleanuk/api/cinema/Customer.java | 126 ++++++++++++++++++ .../api/cinema/DTO/BadRequestException.java | 10 ++ .../booleanuk/api/cinema/DTO/ErrorData.java | 19 +++ .../api/cinema/DTO/ErrorResponse.java | 32 +++++ .../cinema/DTO/GlobalExceptionHandler.java | 22 +++ .../api/cinema/DTO/NotFoundException.java | 10 ++ .../booleanuk/api/cinema/DTO/TicketDTO.java | 82 ++++++++++++ .../java/com/booleanuk/api/cinema/Movie.java | 119 +++++++++++++++++ .../com/booleanuk/api/cinema/Screening.java | 114 ++++++++++++++++ .../java/com/booleanuk/api/cinema/Ticket.java | 103 ++++++++++++++ .../cinema/controller/CustomerController.java | 115 ++++++++++++++++ .../cinema/controller/MovieController.java | 55 ++++++++ .../controller/ScreeningController.java | 67 ++++++++++ .../cinema/controller/TicketController.java | 74 ++++++++++ .../cinema/repository/CustomerRepository.java | 10 ++ .../cinema/repository/MovieRepository.java | 7 + .../repository/ScreeningRepository.java | 7 + .../cinema/repository/TicketRepository.java | 10 ++ src/main/resources/application.yml.example | 23 ---- 21 files changed, 994 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/booleanuk/api/Main.java create mode 100644 src/main/java/com/booleanuk/api/cinema/Customer.java create mode 100644 src/main/java/com/booleanuk/api/cinema/DTO/BadRequestException.java create mode 100644 src/main/java/com/booleanuk/api/cinema/DTO/ErrorData.java create mode 100644 src/main/java/com/booleanuk/api/cinema/DTO/ErrorResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/DTO/GlobalExceptionHandler.java create mode 100644 src/main/java/com/booleanuk/api/cinema/DTO/NotFoundException.java create mode 100644 src/main/java/com/booleanuk/api/cinema/DTO/TicketDTO.java create mode 100644 src/main/java/com/booleanuk/api/cinema/Movie.java create mode 100644 src/main/java/com/booleanuk/api/cinema/Screening.java create mode 100644 src/main/java/com/booleanuk/api/cinema/Ticket.java create mode 100644 src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/controller/MovieController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/controller/TicketController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/repository/CustomerRepository.java create mode 100644 src/main/java/com/booleanuk/api/cinema/repository/MovieRepository.java create mode 100644 src/main/java/com/booleanuk/api/cinema/repository/ScreeningRepository.java create mode 100644 src/main/java/com/booleanuk/api/cinema/repository/TicketRepository.java delete mode 100644 src/main/resources/application.yml.example diff --git a/build.gradle b/build.gradle index 3d7f7607..1c6ff408 100644 --- a/build.gradle +++ b/build.gradle @@ -24,6 +24,7 @@ dependencies { runtimeOnly 'org.postgresql:postgresql' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'org.springframework.boot:spring-boot-starter-validation' } tasks.named('test') { diff --git a/src/main/java/com/booleanuk/api/Main.java b/src/main/java/com/booleanuk/api/Main.java new file mode 100644 index 00000000..289a5189 --- /dev/null +++ b/src/main/java/com/booleanuk/api/Main.java @@ -0,0 +1,11 @@ +package com.booleanuk.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = {"com.booleanuk.api"}) +public class Main { + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/Customer.java b/src/main/java/com/booleanuk/api/cinema/Customer.java new file mode 100644 index 00000000..3c2ff431 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/Customer.java @@ -0,0 +1,126 @@ +package com.booleanuk.api.cinema; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + + +@Entity +@Table(name = "customers") +public class Customer { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @NotBlank + @Column + private String name; + @NotBlank + @Column + private String email; + @NotBlank + @Column + private String phone; + @Column(name = "created_at") + private LocalDateTime createdAt; + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonManagedReference(value = "customer-tickets") + private List tickets; + + + + + + + public Customer(String name, String email, String phone) { + this.name = name; + this.email = email; + this.phone = phone; + this.tickets = new ArrayList<>(); + } + + public Customer() { + } + + @PrePersist + protected void onCreate() { + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + @PreUpdate + protected void onUpdate() { + this.updatedAt = LocalDateTime.now(); + } + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + + public List getTickets() { + return tickets; + } + + public void setTickets(List tickets) { + this.tickets = tickets; + } + + + + +} + + diff --git a/src/main/java/com/booleanuk/api/cinema/DTO/BadRequestException.java b/src/main/java/com/booleanuk/api/cinema/DTO/BadRequestException.java new file mode 100644 index 00000000..7214697f --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/DTO/BadRequestException.java @@ -0,0 +1,10 @@ +package com.booleanuk.api.cinema.DTO; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +public class BadRequestException extends RuntimeException { + public BadRequestException(String message) { + super(message); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/DTO/ErrorData.java b/src/main/java/com/booleanuk/api/cinema/DTO/ErrorData.java new file mode 100644 index 00000000..d0d43547 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/DTO/ErrorData.java @@ -0,0 +1,19 @@ +package com.booleanuk.api.cinema.DTO; + + +public class ErrorData { + private String message; + + // Constructor, getters, and setters + public ErrorData(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/DTO/ErrorResponse.java b/src/main/java/com/booleanuk/api/cinema/DTO/ErrorResponse.java new file mode 100644 index 00000000..f4fcea20 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/DTO/ErrorResponse.java @@ -0,0 +1,32 @@ +package com.booleanuk.api.cinema.DTO; + +public class ErrorResponse { + private String status; + private ErrorData data; + + // No-argument constructor + public ErrorResponse() {} + + // Parameterized constructor + public ErrorResponse(String status, ErrorData data) { + this.status = status; + this.data = data; + } + + // Getters and setters + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public ErrorData getData() { + return data; + } + + public void setData(ErrorData data) { + this.data = data; + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/DTO/GlobalExceptionHandler.java b/src/main/java/com/booleanuk/api/cinema/DTO/GlobalExceptionHandler.java new file mode 100644 index 00000000..7cd00ffa --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/DTO/GlobalExceptionHandler.java @@ -0,0 +1,22 @@ +package com.booleanuk.api.cinema.DTO; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(NotFoundException.class) + public ResponseEntity handleNotFoundException(NotFoundException ex) { + ErrorResponse errorResponse = new ErrorResponse("error", new ErrorData(ex.getMessage())); + return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND); + } + + @ExceptionHandler(BadRequestException.class) + public ResponseEntity handleBadRequestException(BadRequestException ex) { + ErrorResponse errorResponse = new ErrorResponse("error", new ErrorData(ex.getMessage())); + return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); + } + +} diff --git a/src/main/java/com/booleanuk/api/cinema/DTO/NotFoundException.java b/src/main/java/com/booleanuk/api/cinema/DTO/NotFoundException.java new file mode 100644 index 00000000..4f811318 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/DTO/NotFoundException.java @@ -0,0 +1,10 @@ +package com.booleanuk.api.cinema.DTO; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/DTO/TicketDTO.java b/src/main/java/com/booleanuk/api/cinema/DTO/TicketDTO.java new file mode 100644 index 00000000..f0323299 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/DTO/TicketDTO.java @@ -0,0 +1,82 @@ +package com.booleanuk.api.cinema.DTO; + +import java.time.LocalDateTime; + +public class TicketDTO { + private Integer id; + private int numSeats; + private LocalDateTime startsAt; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + private Integer customerId; + private Integer screeningId; + + public TicketDTO() { + } + + public TicketDTO(Integer id, int numSeats, LocalDateTime startsAt, LocalDateTime createdAt, LocalDateTime updatedAt, Integer customerId, Integer screeningId) { + this.id = id; + this.numSeats = numSeats; + this.startsAt = startsAt; + this.createdAt = createdAt; + this.updatedAt = updatedAt; + this.customerId = customerId; + this.screeningId = screeningId; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public int getNumSeats() { + return numSeats; + } + + public void setNumSeats(int numSeats) { + this.numSeats = numSeats; + } + + public LocalDateTime getStartsAt() { + return startsAt; + } + + public void setStartsAt(LocalDateTime startsAt) { + this.startsAt = startsAt; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public Integer getCustomerId() { + return customerId; + } + + public void setCustomerId(Integer customerId) { + this.customerId = customerId; + } + + public Integer getScreeningId() { + return screeningId; + } + + public void setScreeningId(Integer screeningId) { + this.screeningId = screeningId; + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/Movie.java b/src/main/java/com/booleanuk/api/cinema/Movie.java new file mode 100644 index 00000000..4fca03a7 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/Movie.java @@ -0,0 +1,119 @@ +package com.booleanuk.api.cinema; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "Movies") +public class Movie { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column + private String title; + @Column + private String rating; + @Column + private String description; + @Column + private int runtimeMins; + @Column(name = "created_at") + private LocalDateTime createdAt; + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonManagedReference(value = "movie-screenings") + private List screenings; + + public Movie(String title, String rating, String description, int runtimeMins) { + this.title = title; + this.rating = rating; + this.description = description; + this.runtimeMins = runtimeMins; + this.screenings = new ArrayList<>(); + } + + public Movie() { + } + + @PrePersist + protected void onCreate() { + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + @PreUpdate + protected void onUpdate() { + this.updatedAt = LocalDateTime.now(); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getRating() { + return rating; + } + + public void setRating(String rating) { + this.rating = rating; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getRuntimeMins() { + return runtimeMins; + } + + public void setRuntimeMins(int runtimeMins) { + this.runtimeMins = runtimeMins; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public List getScreenings() { + return screenings; + } + + public void setScreenings(List screenings) { + this.screenings = screenings; + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/Screening.java b/src/main/java/com/booleanuk/api/cinema/Screening.java new file mode 100644 index 00000000..5a69d06d --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/Screening.java @@ -0,0 +1,114 @@ +package com.booleanuk.api.cinema; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.*; + +import java.time.LocalDateTime; +import java.util.List; + +@Entity +@Table(name = "Screenings") +public class Screening { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column + private int screenNumber; + @Column + private int capacity; + @ManyToOne + @JoinColumn(name = "movie_id") + @JsonBackReference(value = "movie-screenings") + private Movie movie; + @Column + private LocalDateTime startsAt; + @Column(name = "created_at") + private LocalDateTime createdAt; + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @OneToMany(mappedBy = "screening", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonManagedReference(value = "screening-ticket") + private List tickets; + + + + public Screening(int screenNumber, int capacity, LocalDateTime startsAt) { + this.screenNumber = screenNumber; + this.capacity = capacity; + this.startsAt = startsAt; + } + + public Screening() { + } + + @PrePersist + protected void onCreate() { + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + @PreUpdate + protected void onUpdate() { + this.updatedAt = LocalDateTime.now(); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public int getScreenNumber() { + return screenNumber; + } + + public void setScreenNumber(int screenNumber) { + this.screenNumber = screenNumber; + } + + public int getCapacity() { + return capacity; + } + + public void setCapacity(int capacity) { + this.capacity = capacity; + } + + + public LocalDateTime getStartsAt() { + return startsAt; + } + + public void setStartsAt(LocalDateTime startsAt) { + this.startsAt = startsAt; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public Movie getMovie() { + return movie; + } + + public void setMovie(Movie movie) { + this.movie = movie; + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/Ticket.java b/src/main/java/com/booleanuk/api/cinema/Ticket.java new file mode 100644 index 00000000..0cc15c39 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/Ticket.java @@ -0,0 +1,103 @@ +package com.booleanuk.api.cinema; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.*; +import org.springframework.cglib.core.Local; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Entity +@Table(name = "tickets") +public class Ticket { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column + private int numSeats; + @Column + private LocalDateTime startsAt; + @Column(name = "created_at") + private LocalDateTime createdAt; + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @ManyToOne + @JoinColumn(name = "customer_id") + @JsonBackReference(value = "customer-tickets") + private Customer customer; + + @ManyToOne + @JoinColumn(name = "screening_id") + @JsonBackReference(value = "screening-ticket") + private Screening screening; + + public Ticket(int numSeats) { + this.numSeats = numSeats; + } + + public Ticket() { + } + + @PrePersist + protected void onCreate() { + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + @PreUpdate + protected void onUpdate() { + this.updatedAt = LocalDateTime.now(); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public int getNumSeats() { + return numSeats; + } + + public void setNumSeats(int numSeats) { + this.numSeats = numSeats; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + public Screening getScreening() { + return screening; + } + + public void setScreening(Screening screening) { + this.screening = screening; + } +} + + diff --git a/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java b/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java new file mode 100644 index 00000000..e54d5b0d --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java @@ -0,0 +1,115 @@ + +package com.booleanuk.api.cinema.controller; + +import com.booleanuk.api.cinema.Customer; +import com.booleanuk.api.cinema.DTO.BadRequestException; +import com.booleanuk.api.cinema.DTO.NotFoundException; +//import com.booleanuk.api.cinema.DTO.ErrorResponse; +import com.booleanuk.api.cinema.repository.CustomerRepository; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +@RestController +@RequestMapping("customers") +public class CustomerController { + @Autowired + private final CustomerRepository customerRepository; + + public CustomerController(CustomerRepository customerRepository) { + this.customerRepository = customerRepository; + } + + @GetMapping + public List getAllMovies() { + return this.customerRepository.findAll(); + } + + + + + @PostMapping + public ResponseEntity createCustomer (@Valid @RequestBody Customer customer){ + return new ResponseEntity<>(this.customerRepository.save(customer), HttpStatus.CREATED); + } + + + @PutMapping("{id}") + public ResponseEntity updateCustomer(@PathVariable int id, @Valid @RequestBody Customer customer) { + if(customer.getName() == null || customer.getName().length() < 2) { + System.out.println("TEST"); + throw new BadRequestException("Name must be at least 2 characters long"); + } + + Customer customerToUpdate = this.customerRepository.findById(id).orElseThrow( + () -> new NotFoundException("No customer with that ID found") + ); + // Only update the fields that are being changed + customerToUpdate.setName(customer.getName()); + customerToUpdate.setEmail(customer.getEmail()); + customerToUpdate.setPhone(customer.getPhone()); + + return new ResponseEntity<>(this.customerRepository.save(customerToUpdate), HttpStatus.OK); + } + + /* + // Exception handler for 404 Not Found + @ExceptionHandler(RuntimeException.class) + public ResponseEntity handleNotFound(RuntimeException ex) { + ErrorResponse errorResponse = new ErrorResponse("error", "not found"); + return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND); + } + + */ + + + + + /* + @PutMapping("{id}") + public ResponseEntity updateCustomer(@PathVariable int id, @RequestBody Customer customer){ + Customer customerToUpdate = this.customerRepository.findById(id).orElseThrow( + () -> new RuntimeException("No customer with that ID found") + ); + // Only update the fields that are being changed + customerToUpdate.setName(customer.getName()); + customerToUpdate.setEmail(customer.getEmail()); + customerToUpdate.setPhone(customer.getPhone()); + + + return new ResponseEntity<>(this.customerRepository.save(customerToUpdate), HttpStatus.OK); + } + + */ + + + + /* + @DeleteMapping("{id}") + public ResponseEntity deleteCustomer(@PathVariable int id){ + Customer customerToDelete = this.customerRepository.findById(id).orElseThrow( + () -> new RuntimeException("No customer with that ID found") + ); + this.customerRepository.delete(customerToDelete); + return ResponseEntity.ok(customerToDelete); + } + */ + + @DeleteMapping("{id}") + public ResponseEntity deleteCustomer(@PathVariable int id) { + Customer customerToDelete = this.customerRepository.findById(id).orElseThrow( + () -> new RuntimeException("No customer with that ID found") + ); + this.customerRepository.delete(customerToDelete); + return ResponseEntity.ok(customerToDelete); + } + + +} + diff --git a/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java b/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java new file mode 100644 index 00000000..a07247ba --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java @@ -0,0 +1,55 @@ +package com.booleanuk.api.cinema.controller; + +import com.booleanuk.api.cinema.Movie; +import com.booleanuk.api.cinema.repository.MovieRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("movies") +public class MovieController { + @Autowired + private final MovieRepository movieRepository; + + public MovieController(MovieRepository movieRepository) { + this.movieRepository = movieRepository; + } + + @GetMapping + public List getAllMovies() { + return this.movieRepository.findAll(); + } + + @PostMapping + public ResponseEntity createMovie(@RequestBody Movie movie) { + return new ResponseEntity<>(this.movieRepository.save(movie), HttpStatus.CREATED); + } + + @PutMapping("{id}") + public ResponseEntity updateMovie(@PathVariable int id, @RequestBody Movie movie) { + Movie movieToUpdate = this.movieRepository.findById(id).orElseThrow( + () -> new RuntimeException("No movie with that ID found") + ); + movieToUpdate.setDescription(movie.getDescription()); + movieToUpdate.setRating(movie.getRating()); + movieToUpdate.setTitle(movie.getTitle()); + movieToUpdate.setRuntimeMins(movie.getRuntimeMins()); + + movie.setId(movieToUpdate.getId()); + return new ResponseEntity<>(this.movieRepository.save(movieToUpdate), HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity deleteMovie(@PathVariable int id) { + Movie movieToDelete = this.movieRepository.findById(id).orElseThrow( + () -> new RuntimeException("No movie with that ID found") + ); + this.movieRepository.delete(movieToDelete); + return ResponseEntity.ok(movieToDelete); + } + +} diff --git a/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java b/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java new file mode 100644 index 00000000..27d4e281 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java @@ -0,0 +1,67 @@ +package com.booleanuk.api.cinema.controller; + +import com.booleanuk.api.cinema.Movie; +import com.booleanuk.api.cinema.Screening; +import com.booleanuk.api.cinema.repository.MovieRepository; +import com.booleanuk.api.cinema.repository.ScreeningRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/movies/{movieId}/screenings") +public class ScreeningController { + @Autowired + private final ScreeningRepository screeningRepository; + private final MovieRepository movieRepository; + + public ScreeningController(ScreeningRepository screeningRepository, MovieRepository movieRepository) { + this.screeningRepository = screeningRepository; + this.movieRepository = movieRepository; + } + + @GetMapping + public List getAllScreenings() { + return this.screeningRepository.findAll(); + } + + @PostMapping + public ResponseEntity createScreening(@PathVariable int movieId, @RequestBody Screening screening) { + + Movie movie = this.movieRepository.findById(movieId).orElseThrow( + () -> new RuntimeException("No movie with that ID found") + ); + screening.setMovie(movie); + return new ResponseEntity<>(this.screeningRepository.save(screening), HttpStatus.CREATED); + } + + @GetMapping("{id}") + public ResponseEntity getScreeningById(@PathVariable int id) { + Screening screening = null; + screening = this.screeningRepository.findById(id).orElseThrow( + () -> new RuntimeException("No screening with that ID found") + ); + return ResponseEntity.ok(screening); + } + + @PutMapping() + public ResponseEntity updateScreening(@PathVariable int id, @RequestBody Screening screening) { + Screening screeningToUpdate = this.screeningRepository.findById(id).orElseThrow( + () -> new RuntimeException("No screening with that ID found") + ); + screening.setId(screeningToUpdate.getId()); + return new ResponseEntity<>(this.screeningRepository.save(screening), HttpStatus.CREATED); + } + + @DeleteMapping() + public ResponseEntity deleteScreening(@RequestBody int id) { + Screening screeningToDelete = this.screeningRepository.findById(id).orElseThrow( + () -> new RuntimeException("No screening with that ID found") + ); + this.screeningRepository.delete(screeningToDelete); + return ResponseEntity.ok(screeningToDelete); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java b/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java new file mode 100644 index 00000000..279d2db4 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java @@ -0,0 +1,74 @@ +package com.booleanuk.api.cinema.controller; + +import com.booleanuk.api.cinema.Customer; +import com.booleanuk.api.cinema.DTO.TicketDTO; +import com.booleanuk.api.cinema.Screening; +import com.booleanuk.api.cinema.Ticket; +import com.booleanuk.api.cinema.repository.CustomerRepository; +import com.booleanuk.api.cinema.repository.ScreeningRepository; +import com.booleanuk.api.cinema.repository.TicketRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/customers/{customerId}/screenings/{screeningId}") +public class TicketController { + + private final TicketRepository ticketRepository; + private final CustomerRepository customerRepository; + private final ScreeningRepository screeningRepository; + + @Autowired + public TicketController(ScreeningRepository screeningRepository, TicketRepository ticketRepository, CustomerRepository customerRepository){ + this.ticketRepository = ticketRepository; + this.customerRepository = customerRepository; + this.screeningRepository = screeningRepository; + } + + @GetMapping + public List getAllTickets(){ + return this.ticketRepository.findAll(); + } + + /* + @PostMapping + public ResponseEntity createTicket(@PathVariable int customerId, int screeningId, @RequestBody Ticket ticket){ + Customer customer = this.customerRepository.findById(customerId).orElseThrow( + () -> new RuntimeException("No customer with that ID found") + ); + Screening screening = this.screeningRepository.findById(screeningId).orElseThrow( + () -> new RuntimeException("No screening with that ID found") + ); + + Ticket newTicket = new Ticket(); + newTicket.setNumSeats(ticket.getNumSeats()); + newTicket.setScreening(screening); + newTicket.setCustomer(customer); + return new ResponseEntity<>(this.ticketRepository.save(newTicket), HttpStatus.CREATED); + } + + */ + @PostMapping + public ResponseEntity createTicket(@PathVariable int customerId, @PathVariable int screeningId, @RequestBody TicketDTO ticketDTO) { + Customer customer = this.customerRepository.findById(customerId).orElseThrow( + () -> new RuntimeException("No customer with that ID found") + ); + Screening screening = this.screeningRepository.findById(screeningId).orElseThrow( + () -> new RuntimeException("No screening with that ID found") + ); + + Ticket newTicket = new Ticket(); + newTicket.setNumSeats(ticketDTO.getNumSeats()); + newTicket.setScreening(screening); + newTicket.setCustomer(customer); + return new ResponseEntity<>(this.ticketRepository.save(newTicket), HttpStatus.CREATED); + } +} + + + + diff --git a/src/main/java/com/booleanuk/api/cinema/repository/CustomerRepository.java b/src/main/java/com/booleanuk/api/cinema/repository/CustomerRepository.java new file mode 100644 index 00000000..4801007b --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/repository/CustomerRepository.java @@ -0,0 +1,10 @@ + +package com.booleanuk.api.cinema.repository; + +import com.booleanuk.api.cinema.Customer; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CustomerRepository extends JpaRepository { +} + + diff --git a/src/main/java/com/booleanuk/api/cinema/repository/MovieRepository.java b/src/main/java/com/booleanuk/api/cinema/repository/MovieRepository.java new file mode 100644 index 00000000..f92987ec --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/repository/MovieRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.cinema.repository; + +import com.booleanuk.api.cinema.Movie; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MovieRepository extends JpaRepository { +} diff --git a/src/main/java/com/booleanuk/api/cinema/repository/ScreeningRepository.java b/src/main/java/com/booleanuk/api/cinema/repository/ScreeningRepository.java new file mode 100644 index 00000000..3a182f3c --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/repository/ScreeningRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.cinema.repository; + +import com.booleanuk.api.cinema.Screening; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ScreeningRepository extends JpaRepository { +} diff --git a/src/main/java/com/booleanuk/api/cinema/repository/TicketRepository.java b/src/main/java/com/booleanuk/api/cinema/repository/TicketRepository.java new file mode 100644 index 00000000..acbd217d --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/repository/TicketRepository.java @@ -0,0 +1,10 @@ + +package com.booleanuk.api.cinema.repository; + +import com.booleanuk.api.cinema.Ticket; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TicketRepository extends JpaRepository { +} + + diff --git a/src/main/resources/application.yml.example b/src/main/resources/application.yml.example deleted file mode 100644 index 275ec30f..00000000 --- a/src/main/resources/application.yml.example +++ /dev/null @@ -1,23 +0,0 @@ -server: - port: 4000 - error: - include-message: always - include-binding-errors: always - include-stacktrace: never - include-exception: false - -spring: - datasource: - url: jdbc:postgresql://DATABASE_URL:5432/DATABASE_NAME - username: DATABASE_USERNAME - password: DATABASE_PASSWORD - max-active: 3 - max-idle: 3 - jpa: - hibernate: - ddl-auto: update - properties: - hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect - format_sql: true - show-sql: true From 17b017e7bc94f70e810798d47cf2cb461c6eab3f Mon Sep 17 00:00:00 2001 From: Jostein Ruen Date: Fri, 13 Sep 2024 15:03:34 +0200 Subject: [PATCH 2/3] Extension almost done (Json return format not exactly as specs demand) --- .../cinema/controller/CustomerController.java | 47 +------------------ .../cinema/controller/MovieController.java | 9 +++- .../controller/ScreeningController.java | 14 ++++-- .../cinema/controller/TicketController.java | 23 ++------- 4 files changed, 22 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java b/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java index e54d5b0d..f03af6f2 100644 --- a/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java +++ b/src/main/java/com/booleanuk/api/cinema/controller/CustomerController.java @@ -43,7 +43,6 @@ public ResponseEntity createCustomer (@Valid @RequestBody Customer cus @PutMapping("{id}") public ResponseEntity updateCustomer(@PathVariable int id, @Valid @RequestBody Customer customer) { if(customer.getName() == null || customer.getName().length() < 2) { - System.out.println("TEST"); throw new BadRequestException("Name must be at least 2 characters long"); } @@ -55,56 +54,14 @@ public ResponseEntity updateCustomer(@PathVariable int id, @Valid @Req customerToUpdate.setEmail(customer.getEmail()); customerToUpdate.setPhone(customer.getPhone()); - return new ResponseEntity<>(this.customerRepository.save(customerToUpdate), HttpStatus.OK); + return new ResponseEntity<>(this.customerRepository.save(customerToUpdate), HttpStatus.CREATED); } - /* - // Exception handler for 404 Not Found - @ExceptionHandler(RuntimeException.class) - public ResponseEntity handleNotFound(RuntimeException ex) { - ErrorResponse errorResponse = new ErrorResponse("error", "not found"); - return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND); - } - - */ - - - - - /* - @PutMapping("{id}") - public ResponseEntity updateCustomer(@PathVariable int id, @RequestBody Customer customer){ - Customer customerToUpdate = this.customerRepository.findById(id).orElseThrow( - () -> new RuntimeException("No customer with that ID found") - ); - // Only update the fields that are being changed - customerToUpdate.setName(customer.getName()); - customerToUpdate.setEmail(customer.getEmail()); - customerToUpdate.setPhone(customer.getPhone()); - - - return new ResponseEntity<>(this.customerRepository.save(customerToUpdate), HttpStatus.OK); - } - - */ - - - - /* - @DeleteMapping("{id}") - public ResponseEntity deleteCustomer(@PathVariable int id){ - Customer customerToDelete = this.customerRepository.findById(id).orElseThrow( - () -> new RuntimeException("No customer with that ID found") - ); - this.customerRepository.delete(customerToDelete); - return ResponseEntity.ok(customerToDelete); - } - */ @DeleteMapping("{id}") public ResponseEntity deleteCustomer(@PathVariable int id) { Customer customerToDelete = this.customerRepository.findById(id).orElseThrow( - () -> new RuntimeException("No customer with that ID found") + () -> new NotFoundException("No customer with that ID found") ); this.customerRepository.delete(customerToDelete); return ResponseEntity.ok(customerToDelete); diff --git a/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java b/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java index a07247ba..645c7f2a 100644 --- a/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java +++ b/src/main/java/com/booleanuk/api/cinema/controller/MovieController.java @@ -1,5 +1,7 @@ package com.booleanuk.api.cinema.controller; +import com.booleanuk.api.cinema.DTO.BadRequestException; +import com.booleanuk.api.cinema.DTO.NotFoundException; import com.booleanuk.api.cinema.Movie; import com.booleanuk.api.cinema.repository.MovieRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -31,8 +33,11 @@ public ResponseEntity createMovie(@RequestBody Movie movie) { @PutMapping("{id}") public ResponseEntity updateMovie(@PathVariable int id, @RequestBody Movie movie) { + if(movie.getTitle() == null || movie.getDescription().length() < 2) { + throw new BadRequestException("bad request"); + } Movie movieToUpdate = this.movieRepository.findById(id).orElseThrow( - () -> new RuntimeException("No movie with that ID found") + () -> new NotFoundException("No movie with that ID found") ); movieToUpdate.setDescription(movie.getDescription()); movieToUpdate.setRating(movie.getRating()); @@ -46,7 +51,7 @@ public ResponseEntity updateMovie(@PathVariable int id, @RequestBody Movi @DeleteMapping("{id}") public ResponseEntity deleteMovie(@PathVariable int id) { Movie movieToDelete = this.movieRepository.findById(id).orElseThrow( - () -> new RuntimeException("No movie with that ID found") + () -> new NotFoundException("No movie with that ID found") ); this.movieRepository.delete(movieToDelete); return ResponseEntity.ok(movieToDelete); diff --git a/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java b/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java index 27d4e281..a4e87fae 100644 --- a/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java +++ b/src/main/java/com/booleanuk/api/cinema/controller/ScreeningController.java @@ -1,5 +1,7 @@ package com.booleanuk.api.cinema.controller; +import com.booleanuk.api.cinema.DTO.BadRequestException; +import com.booleanuk.api.cinema.DTO.NotFoundException; import com.booleanuk.api.cinema.Movie; import com.booleanuk.api.cinema.Screening; import com.booleanuk.api.cinema.repository.MovieRepository; @@ -31,8 +33,9 @@ public List getAllScreenings() { @PostMapping public ResponseEntity createScreening(@PathVariable int movieId, @RequestBody Screening screening) { + Movie movie = this.movieRepository.findById(movieId).orElseThrow( - () -> new RuntimeException("No movie with that ID found") + () -> new NotFoundException("No movie with that ID found") ); screening.setMovie(movie); return new ResponseEntity<>(this.screeningRepository.save(screening), HttpStatus.CREATED); @@ -42,15 +45,18 @@ public ResponseEntity createScreening(@PathVariable int movieId, @Req public ResponseEntity getScreeningById(@PathVariable int id) { Screening screening = null; screening = this.screeningRepository.findById(id).orElseThrow( - () -> new RuntimeException("No screening with that ID found") + () -> new NotFoundException("No screening with that ID found") ); return ResponseEntity.ok(screening); } @PutMapping() public ResponseEntity updateScreening(@PathVariable int id, @RequestBody Screening screening) { + if(screening.getMovie() == null) { + throw new BadRequestException("Movie must be provided"); + } Screening screeningToUpdate = this.screeningRepository.findById(id).orElseThrow( - () -> new RuntimeException("No screening with that ID found") + () -> new NotFoundException("No screening with that ID found") ); screening.setId(screeningToUpdate.getId()); return new ResponseEntity<>(this.screeningRepository.save(screening), HttpStatus.CREATED); @@ -59,7 +65,7 @@ public ResponseEntity updateScreening(@PathVariable int id, @RequestB @DeleteMapping() public ResponseEntity deleteScreening(@RequestBody int id) { Screening screeningToDelete = this.screeningRepository.findById(id).orElseThrow( - () -> new RuntimeException("No screening with that ID found") + () -> new NotFoundException("No screening with that ID found") ); this.screeningRepository.delete(screeningToDelete); return ResponseEntity.ok(screeningToDelete); diff --git a/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java b/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java index 279d2db4..b76198e3 100644 --- a/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java +++ b/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java @@ -1,6 +1,7 @@ package com.booleanuk.api.cinema.controller; import com.booleanuk.api.cinema.Customer; +import com.booleanuk.api.cinema.DTO.NotFoundException; import com.booleanuk.api.cinema.DTO.TicketDTO; import com.booleanuk.api.cinema.Screening; import com.booleanuk.api.cinema.Ticket; @@ -34,31 +35,13 @@ public List getAllTickets(){ return this.ticketRepository.findAll(); } - /* - @PostMapping - public ResponseEntity createTicket(@PathVariable int customerId, int screeningId, @RequestBody Ticket ticket){ - Customer customer = this.customerRepository.findById(customerId).orElseThrow( - () -> new RuntimeException("No customer with that ID found") - ); - Screening screening = this.screeningRepository.findById(screeningId).orElseThrow( - () -> new RuntimeException("No screening with that ID found") - ); - - Ticket newTicket = new Ticket(); - newTicket.setNumSeats(ticket.getNumSeats()); - newTicket.setScreening(screening); - newTicket.setCustomer(customer); - return new ResponseEntity<>(this.ticketRepository.save(newTicket), HttpStatus.CREATED); - } - - */ @PostMapping public ResponseEntity createTicket(@PathVariable int customerId, @PathVariable int screeningId, @RequestBody TicketDTO ticketDTO) { Customer customer = this.customerRepository.findById(customerId).orElseThrow( - () -> new RuntimeException("No customer with that ID found") + () -> new NotFoundException("No customer with that ID found") ); Screening screening = this.screeningRepository.findById(screeningId).orElseThrow( - () -> new RuntimeException("No screening with that ID found") + () -> new NotFoundException("No screening with that ID found") ); Ticket newTicket = new Ticket(); From 0ea1f933577df87d09747fad93adbb195cdeeef3 Mon Sep 17 00:00:00 2001 From: Jostein Ruen Date: Fri, 13 Sep 2024 15:20:47 +0200 Subject: [PATCH 3/3] Extension done (i think) --- src/main/java/com/booleanuk/api/cinema/Customer.java | 2 ++ src/main/java/com/booleanuk/api/cinema/Movie.java | 2 ++ src/main/java/com/booleanuk/api/cinema/Screening.java | 4 ++-- src/main/java/com/booleanuk/api/cinema/Ticket.java | 8 ++++++++ .../booleanuk/api/cinema/controller/TicketController.java | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/booleanuk/api/cinema/Customer.java b/src/main/java/com/booleanuk/api/cinema/Customer.java index 3c2ff431..3c242652 100644 --- a/src/main/java/com/booleanuk/api/cinema/Customer.java +++ b/src/main/java/com/booleanuk/api/cinema/Customer.java @@ -1,5 +1,6 @@ package com.booleanuk.api.cinema; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; @@ -32,6 +33,7 @@ public class Customer { @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference(value = "customer-tickets") + @JsonIgnore private List tickets; diff --git a/src/main/java/com/booleanuk/api/cinema/Movie.java b/src/main/java/com/booleanuk/api/cinema/Movie.java index 4fca03a7..fc1253b4 100644 --- a/src/main/java/com/booleanuk/api/cinema/Movie.java +++ b/src/main/java/com/booleanuk/api/cinema/Movie.java @@ -1,5 +1,6 @@ package com.booleanuk.api.cinema; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; @@ -29,6 +30,7 @@ public class Movie { @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference(value = "movie-screenings") + @JsonIgnore private List screenings; public Movie(String title, String rating, String description, int runtimeMins) { diff --git a/src/main/java/com/booleanuk/api/cinema/Screening.java b/src/main/java/com/booleanuk/api/cinema/Screening.java index 5a69d06d..0dc1254a 100644 --- a/src/main/java/com/booleanuk/api/cinema/Screening.java +++ b/src/main/java/com/booleanuk/api/cinema/Screening.java @@ -1,6 +1,7 @@ package com.booleanuk.api.cinema; import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; @@ -31,10 +32,9 @@ public class Screening { @OneToMany(mappedBy = "screening", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference(value = "screening-ticket") + @JsonIgnore private List tickets; - - public Screening(int screenNumber, int capacity, LocalDateTime startsAt) { this.screenNumber = screenNumber; this.capacity = capacity; diff --git a/src/main/java/com/booleanuk/api/cinema/Ticket.java b/src/main/java/com/booleanuk/api/cinema/Ticket.java index 0cc15c39..d412210f 100644 --- a/src/main/java/com/booleanuk/api/cinema/Ticket.java +++ b/src/main/java/com/booleanuk/api/cinema/Ticket.java @@ -98,6 +98,14 @@ public Screening getScreening() { public void setScreening(Screening screening) { this.screening = screening; } + + public LocalDateTime getStartsAt() { + return startsAt; + } + + public void setStartsAt(LocalDateTime startsAt) { + this.startsAt = startsAt; + } } diff --git a/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java b/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java index b76198e3..a8189ccc 100644 --- a/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java +++ b/src/main/java/com/booleanuk/api/cinema/controller/TicketController.java @@ -48,6 +48,7 @@ public ResponseEntity createTicket(@PathVariable int customerId, @PathVa newTicket.setNumSeats(ticketDTO.getNumSeats()); newTicket.setScreening(screening); newTicket.setCustomer(customer); + newTicket.setStartsAt(screening.getStartsAt()); return new ResponseEntity<>(this.ticketRepository.save(newTicket), HttpStatus.CREATED); } }