From e39d5f5db717b3826506c421d2e511888f46a960 Mon Sep 17 00:00:00 2001 From: Wilmer Winkler Date: Wed, 29 Jan 2025 10:57:15 +0100 Subject: [PATCH] Core and extension complete! --- build.gradle | 14 ++- .../java/com/booleanuk/api/cinema/.gitkeep | 0 .../java/com/booleanuk/api/cinema/Main.java | 11 +++ .../api/cinema/customers/Customer.java | 61 ++++++++++++ .../cinema/customers/CustomerController.java | 85 +++++++++++++++++ .../cinema/customers/CustomerRepository.java | 7 ++ .../booleanuk/api/cinema/movies/Movie.java | 65 +++++++++++++ .../api/cinema/movies/MovieController.java | 93 +++++++++++++++++++ .../api/cinema/movies/MovieRepository.java | 7 ++ .../responses/CustomerListResponse.java | 8 ++ .../cinema/responses/CustomerResponse.java | 7 ++ .../api/cinema/responses/ErrorResponse.java | 19 ++++ .../cinema/responses/MovieListResponse.java | 8 ++ .../api/cinema/responses/MovieResponse.java | 6 ++ .../api/cinema/responses/Response.java | 14 +++ .../responses/ScreeningListResponse.java | 8 ++ .../cinema/responses/ScreeningResponse.java | 6 ++ .../cinema/responses/TicketListResponse.java | 8 ++ .../api/cinema/responses/TicketResponse.java | 6 ++ .../api/cinema/screenings/Screening.java | 67 +++++++++++++ .../screenings/ScreeningController.java | 52 +++++++++++ .../screenings/ScreeningRepository.java | 14 +++ .../booleanuk/api/cinema/tickets/Ticket.java | 59 ++++++++++++ .../api/cinema/tickets/TicketController.java | 68 ++++++++++++++ .../api/cinema/tickets/TicketRepository.java | 12 +++ 25 files changed, 703 insertions(+), 2 deletions(-) delete mode 100644 src/main/java/com/booleanuk/api/cinema/.gitkeep create mode 100644 src/main/java/com/booleanuk/api/cinema/Main.java create mode 100644 src/main/java/com/booleanuk/api/cinema/customers/Customer.java create mode 100644 src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/customers/CustomerRepository.java create mode 100644 src/main/java/com/booleanuk/api/cinema/movies/Movie.java create mode 100644 src/main/java/com/booleanuk/api/cinema/movies/MovieController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/movies/MovieRepository.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/CustomerListResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/CustomerResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/MovieListResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/MovieResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/Response.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/ScreeningListResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/ScreeningResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/TicketListResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/TicketResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/screenings/Screening.java create mode 100644 src/main/java/com/booleanuk/api/cinema/screenings/ScreeningController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/screenings/ScreeningRepository.java create mode 100644 src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java create mode 100644 src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/tickets/TicketRepository.java diff --git a/build.gradle b/build.gradle index 3d7f7607..836c7ade 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.3.1' - id 'io.spring.dependency-management' version '1.1.5' + id 'org.springframework.boot' version '3.4.1' + id 'io.spring.dependency-management' version '1.1.7' } group = 'com.booleanuk' @@ -13,6 +13,12 @@ java { } } +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + repositories { mavenCentral() } @@ -20,10 +26,14 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' + compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' + annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + // https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.3' } tasks.named('test') { diff --git a/src/main/java/com/booleanuk/api/cinema/.gitkeep b/src/main/java/com/booleanuk/api/cinema/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/com/booleanuk/api/cinema/Main.java b/src/main/java/com/booleanuk/api/cinema/Main.java new file mode 100644 index 00000000..57047dbf --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/Main.java @@ -0,0 +1,11 @@ +package com.booleanuk.api.cinema; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/customers/Customer.java b/src/main/java/com/booleanuk/api/cinema/customers/Customer.java new file mode 100644 index 00000000..7f06efa5 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/Customer.java @@ -0,0 +1,61 @@ +package com.booleanuk.api.cinema.customers; + +import com.booleanuk.api.cinema.tickets.Ticket; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@Entity +@Table(name = "customers") +@JsonIgnoreProperties({"tickets"}) +public class Customer { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private String name; + + @Column + private String email; + + @Column + private String phone; + + @Column + private LocalDate createdAt; + + @Column + private LocalDate updatedAt; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", orphanRemoval = true) + private List tickets; + + + public Customer(String name, String email, String phone) { + this.name = name; + this.email = email; + this.phone = phone; + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + + } + + public Customer(int id) { + this.id = id; + } + + public Customer() { + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java new file mode 100644 index 00000000..2715c84c --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java @@ -0,0 +1,85 @@ +package com.booleanuk.api.cinema.customers; + +import com.booleanuk.api.cinema.responses.CustomerListResponse; +import com.booleanuk.api.cinema.responses.CustomerResponse; +import com.booleanuk.api.cinema.responses.ErrorResponse; +import com.booleanuk.api.cinema.responses.Response; +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.time.LocalDate; + +@RestController +@RequestMapping("customers") + +public class CustomerController { + + @Autowired + private final CustomerRepository repository; + + public CustomerController(CustomerRepository repository) { + this.repository = repository; + } + + @GetMapping + public ResponseEntity getAll() { + CustomerListResponse customerListResponse = new CustomerListResponse(); + customerListResponse.set(this.repository.findAll()); + return ResponseEntity.ok(customerListResponse); + } + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping + public ResponseEntity> create(@RequestBody Customer customer) { + CustomerResponse customerResponse = new CustomerResponse(); + try { + customerResponse.set(this.repository.save(customer)); + } catch (Exception e) { + ErrorResponse error = new ErrorResponse(); + error.set("Bad request - cannot create customer"); + return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); + } + return new ResponseEntity<>(customerResponse, HttpStatus.CREATED); + } + + @PutMapping("{id}") + public ResponseEntity> updateCustomer(@PathVariable int id, @RequestBody Customer customer) { + Customer customerToUpdate = null; + try { + customerToUpdate = this.repository.findById(id).orElse(null); + } catch (Exception e) { + ErrorResponse error = new ErrorResponse(); + error.set("Bad request - could not successfully find customer"); + return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); + } + if (customerToUpdate == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Customer not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + customerToUpdate.setName(customer.getName()); + customerToUpdate.setEmail(customer.getEmail()); + customerToUpdate.setPhone(customer.getPhone()); + customerToUpdate.setUpdatedAt(LocalDate.now()); + customerToUpdate= this.repository.save(customerToUpdate); + CustomerResponse customerResponse = new CustomerResponse(); + customerResponse.set(customerToUpdate); + return new ResponseEntity<>(customerResponse, HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity> deleteACustomer(@PathVariable int id) { + Customer customerToDelete = this.repository.findById(id).orElse(null); + if (customerToDelete == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Customer not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + this.repository.delete(customerToDelete); + CustomerResponse customerResponse = new CustomerResponse(); + customerResponse.set(customerToDelete); + return ResponseEntity.ok(customerResponse); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/customers/CustomerRepository.java b/src/main/java/com/booleanuk/api/cinema/customers/CustomerRepository.java new file mode 100644 index 00000000..3e9eb01f --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.cinema.customers; + +import com.booleanuk.api.cinema.customers.Customer; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CustomerRepository extends JpaRepository{ +} diff --git a/src/main/java/com/booleanuk/api/cinema/movies/Movie.java b/src/main/java/com/booleanuk/api/cinema/movies/Movie.java new file mode 100644 index 00000000..23872273 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/Movie.java @@ -0,0 +1,65 @@ +package com.booleanuk.api.cinema.movies; + +import com.booleanuk.api.cinema.screenings.Screening; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@Entity +@Table(name = "movies") +@JsonIgnoreProperties({"screenings"}) +public class Movie { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private String title; + + @Column + private String rating; + + @Column + private String description; + + @Column + private int runtimeMins; + + @Column + private LocalDate createdAt; + + @Column + private LocalDate updatedAt; + + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "movie", orphanRemoval = true) + 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; + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + + } + + public Movie(int id) { + this.id = id; + } + + public Movie() { + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/movies/MovieController.java b/src/main/java/com/booleanuk/api/cinema/movies/MovieController.java new file mode 100644 index 00000000..e5c1e986 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/MovieController.java @@ -0,0 +1,93 @@ +package com.booleanuk.api.cinema.movies; + +import com.booleanuk.api.cinema.responses.*; +import com.booleanuk.api.cinema.screenings.Screening; +import com.booleanuk.api.cinema.screenings.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.time.LocalDate; + +@RestController +@RequestMapping("movies") + +public class MovieController { + + @Autowired + private final MovieRepository repository; + @Autowired + private final ScreeningRepository screeningRepository; + + public MovieController(MovieRepository repository, ScreeningRepository screeningRepository) { + this.repository = repository; + this.screeningRepository = screeningRepository; + } + + @GetMapping + public ResponseEntity getAll() { + MovieListResponse movieListResponse = new MovieListResponse(); + movieListResponse.set(this.repository.findAll()); + return ResponseEntity.ok(movieListResponse); + } + + @PostMapping + public ResponseEntity> createAMovie(@RequestBody Movie movie) { + MovieResponse movieResponse = new MovieResponse(); + ScreeningResponse screeningResponse = new ScreeningResponse(); + try { + movieResponse.set(this.repository.save(movie)); + for(Screening screening : movie.getScreenings()){ + screening = new Screening(movie, screening.getScreenNumber(), screening.getStartsAt(), screening.getCapacity()); + screeningResponse.set(this.screeningRepository.save(screening)); + } + + } catch (Exception e) { + ErrorResponse error = new ErrorResponse(); + error.set("Bad request - cannot create movie and/or screening(s)"); + return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); + } + return new ResponseEntity<>(movieResponse, HttpStatus.CREATED); + } + + @PutMapping("{id}") + public ResponseEntity> updateAMovie(@PathVariable int id, @RequestBody Movie movie) { + Movie movieToUpdate = null; + try { + movieToUpdate = this.repository.findById(id).orElse(null); + } catch (Exception e) { + ErrorResponse error = new ErrorResponse(); + error.set("Bad request - could not successfully find movie"); + return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); + } + if (movieToUpdate == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Artist not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + movieToUpdate.setTitle(movie.getTitle()); + movieToUpdate.setRating(movie.getRating()); + movieToUpdate.setDescription(movie.getDescription()); + movieToUpdate.setRuntimeMins(movie.getRuntimeMins()); + movieToUpdate.setUpdatedAt(LocalDate.now()); + movieToUpdate = this.repository.save(movieToUpdate); + MovieResponse movieResponse = new MovieResponse(); + movieResponse.set(movieToUpdate); + return new ResponseEntity<>(movieResponse, HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity> deleteAMovie(@PathVariable int id) { + Movie movieToDelete = this.repository.findById(id).orElse(null); + if (movieToDelete == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Movie not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + this.repository.delete(movieToDelete); + MovieResponse movieResponse = new MovieResponse(); + movieResponse.set(movieToDelete); + return ResponseEntity.ok(movieResponse); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/movies/MovieRepository.java b/src/main/java/com/booleanuk/api/cinema/movies/MovieRepository.java new file mode 100644 index 00000000..e98d3781 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/MovieRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.cinema.movies; + +import com.booleanuk.api.cinema.movies.Movie; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MovieRepository extends JpaRepository{ +} diff --git a/src/main/java/com/booleanuk/api/cinema/responses/CustomerListResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/CustomerListResponse.java new file mode 100644 index 00000000..46736002 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/CustomerListResponse.java @@ -0,0 +1,8 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.customers.Customer; + +import java.util.List; + +public class CustomerListResponse extends Response>{ +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/responses/CustomerResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/CustomerResponse.java new file mode 100644 index 00000000..31b59d3d --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/CustomerResponse.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.customers.Customer; + +public class CustomerResponse extends Response{ +} + diff --git a/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java new file mode 100644 index 00000000..06d97d38 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java @@ -0,0 +1,19 @@ +package com.booleanuk.api.cinema.responses; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@NoArgsConstructor +public class ErrorResponse extends Response>{ + + public void set(String message) { + this.status = "error"; + Map reply = new HashMap<>(); + reply.put("message", message); + this.data = reply; + } +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/responses/MovieListResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/MovieListResponse.java new file mode 100644 index 00000000..3416a2fa --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/MovieListResponse.java @@ -0,0 +1,8 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.movies.Movie; + +import java.util.List; + +public class MovieListResponse extends Response>{ +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/responses/MovieResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/MovieResponse.java new file mode 100644 index 00000000..9fb75dfe --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/MovieResponse.java @@ -0,0 +1,6 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.movies.Movie; + +public class MovieResponse extends Response{ +} diff --git a/src/main/java/com/booleanuk/api/cinema/responses/Response.java b/src/main/java/com/booleanuk/api/cinema/responses/Response.java new file mode 100644 index 00000000..a54fb392 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/Response.java @@ -0,0 +1,14 @@ +package com.booleanuk.api.cinema.responses; + +import lombok.Getter; + +@Getter +public class Response { + protected String status; + protected T data; + + public void set(T data) { + this.status = "success"; + this.data = data; + } +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/responses/ScreeningListResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/ScreeningListResponse.java new file mode 100644 index 00000000..edfdf917 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/ScreeningListResponse.java @@ -0,0 +1,8 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.screenings.Screening; + +import java.util.List; + +public class ScreeningListResponse extends Response>{ +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/responses/ScreeningResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/ScreeningResponse.java new file mode 100644 index 00000000..e8eb47a0 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/ScreeningResponse.java @@ -0,0 +1,6 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.screenings.Screening; + +public class ScreeningResponse extends Response{ +} diff --git a/src/main/java/com/booleanuk/api/cinema/responses/TicketListResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/TicketListResponse.java new file mode 100644 index 00000000..6cee42e2 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/TicketListResponse.java @@ -0,0 +1,8 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.tickets.Ticket; + +import java.util.List; + +public class TicketListResponse extends Response>{ +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/responses/TicketResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/TicketResponse.java new file mode 100644 index 00000000..20fb7d43 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/TicketResponse.java @@ -0,0 +1,6 @@ +package com.booleanuk.api.cinema.responses; + +import com.booleanuk.api.cinema.tickets.Ticket; + +public class TicketResponse extends Response{ +} diff --git a/src/main/java/com/booleanuk/api/cinema/screenings/Screening.java b/src/main/java/com/booleanuk/api/cinema/screenings/Screening.java new file mode 100644 index 00000000..919cfa7a --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screenings/Screening.java @@ -0,0 +1,67 @@ +package com.booleanuk.api.cinema.screenings; + +import com.booleanuk.api.cinema.movies.Movie; +import com.booleanuk.api.cinema.tickets.Ticket; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@Entity +@Table(name = "screenings") +@JsonIgnoreProperties({"tickets", "movie"}) +public class Screening { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private int screenNumber; + + @Column + private LocalDate startsAt; + + @Column + private int capacity; + + @Column + private LocalDate createdAt; + + @Column + private LocalDate updatedAt; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "screening", orphanRemoval = true) + private List tickets; + + @ManyToOne + @JoinColumn(name="movie") + private Movie movie; + + + public Screening(Movie movie, int screenNumber, LocalDate startsAt, int capacity) { + this.movie = movie; + this.screenNumber = screenNumber; + this.startsAt = startsAt; + this.capacity = capacity; + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + + } + + public Screening(int id) { + this.id = id; + } + + public Screening() { + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningController.java b/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningController.java new file mode 100644 index 00000000..82bbe916 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningController.java @@ -0,0 +1,52 @@ +package com.booleanuk.api.cinema.screenings; + +import com.booleanuk.api.cinema.movies.MovieRepository; +import com.booleanuk.api.cinema.responses.*; +import com.booleanuk.api.cinema.movies.Movie; +import com.booleanuk.api.cinema.tickets.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 org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("movie/{id}/screenings") +public class ScreeningController { + + @Autowired + private ScreeningRepository screeningRepository; + @Autowired + private MovieRepository movieRepository; + @Autowired + private TicketRepository ticketRepository; + + @GetMapping + public ResponseEntitygetById(@PathVariable("id") int id) { + ScreeningListResponse screeningListResponse = new ScreeningListResponse(); + + Movie movie = this.movieRepository.findById(id).orElse(null); + screeningListResponse.set(screeningRepository.getScreeningByMovie(movie)); + return ResponseEntity.ok(screeningListResponse); + } + + @PostMapping + public ResponseEntity> create(@RequestBody Screening screening, @PathVariable("id") int id) { + Movie theMovie = this.movieRepository.findById(id).orElse(null); + if (theMovie == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Movie not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + screening.setMovie(theMovie); + ScreeningResponse screeningResponse = new ScreeningResponse(); + try { + screeningResponse.set(this.screeningRepository.save(screening)); + } catch (Exception e) { + ErrorResponse error = new ErrorResponse(); + error.set("Bad request"); + return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); + } + return new ResponseEntity<>(screeningResponse, HttpStatus.CREATED); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningRepository.java b/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningRepository.java new file mode 100644 index 00000000..10b36ecf --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningRepository.java @@ -0,0 +1,14 @@ +package com.booleanuk.api.cinema.screenings; + +import com.booleanuk.api.cinema.customers.Customer; +import com.booleanuk.api.cinema.movies.Movie; +import com.booleanuk.api.cinema.screenings.Screening; +import com.booleanuk.api.cinema.tickets.Ticket; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ScreeningRepository extends JpaRepository{ + + List getScreeningByMovie(Movie movie); +} diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java b/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java new file mode 100644 index 00000000..dfb07ec8 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java @@ -0,0 +1,59 @@ +package com.booleanuk.api.cinema.tickets; + +import com.booleanuk.api.cinema.customers.Customer; +import com.booleanuk.api.cinema.screenings.Screening; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDate; + +@Getter +@Setter +@AllArgsConstructor +@Entity +@Table(name = "tickets") +@JsonIgnoreProperties({"screening", "customer"}) +public class Ticket { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private int numSeats; + + @Column + private LocalDate createdAt; + + @Column + private LocalDate updatedAt; + + @ManyToOne + @JoinColumn(name="screening") + private Screening screening; + + @ManyToOne + @JoinColumn(name="customer") + private Customer customer; + + + public Ticket(Customer customer, Screening screening, int numSeats) { + this.customer = customer; + this.screening = screening; + this.numSeats = numSeats; + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + } + + public Ticket(int id) { + this.id = id; + } + + public Ticket() { + createdAt = LocalDate.now(); + updatedAt = LocalDate.now(); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java new file mode 100644 index 00000000..9177e454 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java @@ -0,0 +1,68 @@ +package com.booleanuk.api.cinema.tickets; + +import com.booleanuk.api.cinema.customers.Customer; +import com.booleanuk.api.cinema.customers.CustomerRepository; +import com.booleanuk.api.cinema.responses.ErrorResponse; +import com.booleanuk.api.cinema.responses.Response; +import com.booleanuk.api.cinema.responses.TicketListResponse; +import com.booleanuk.api.cinema.responses.TicketResponse; +import com.booleanuk.api.cinema.screenings.Screening; +import com.booleanuk.api.cinema.screenings.ScreeningRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("customer/{cId}/screenings/{sId}") +public class TicketController { + + @Autowired + private CustomerRepository customerRepository; + @Autowired + private ScreeningRepository screeningRepository; + @Autowired + private TicketRepository ticketRepository; + + @GetMapping + public ResponseEntity getAllByCustomerAndScreening(@PathVariable("cId") int cId, @PathVariable("sId") int sId) { + TicketListResponse ticketListResponse = new TicketListResponse(); + Customer customer = this.customerRepository.findById(cId).orElse(null); + Screening screening = this.screeningRepository.findById(sId).orElse(null); + + if (customer == null || screening == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Customer or screening not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + ticketListResponse.set(this.ticketRepository.findAllTicketsByScreeningAndCustomer(screening, customer)); + return ResponseEntity.ok(ticketListResponse); + } + + @PostMapping + public ResponseEntity> book(@RequestBody Ticket ticket, @PathVariable("cId") int cId, @PathVariable("sId") int sId) { + Customer theCustomer = this.customerRepository.findById(cId).orElse(null); + if (theCustomer == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Customer not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + ticket.setCustomer(theCustomer); + Screening theScreening = this.screeningRepository.findById(sId).orElse(null); + if (theScreening == null) { + ErrorResponse error = new ErrorResponse(); + error.set("Screening not found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + ticket.setScreening(theScreening); + TicketResponse ticketResponse = new TicketResponse(); + try { + ticketResponse.set(this.ticketRepository.save(ticket)); + } catch (Exception e) { + ErrorResponse error = new ErrorResponse(); + error.set("Bad request"); + return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); + } + return new ResponseEntity<>(ticketResponse, HttpStatus.CREATED); + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/TicketRepository.java b/src/main/java/com/booleanuk/api/cinema/tickets/TicketRepository.java new file mode 100644 index 00000000..35ca9c38 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketRepository.java @@ -0,0 +1,12 @@ +package com.booleanuk.api.cinema.tickets; + +import com.booleanuk.api.cinema.customers.Customer; +import com.booleanuk.api.cinema.screenings.Screening; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface TicketRepository extends JpaRepository{ + + List findAllTicketsByScreeningAndCustomer(Screening screening, Customer customer); +}