From 25246b2c6ab08903afd74b277236bbff4898869a Mon Sep 17 00:00:00 2001 From: Magnus-droid Date: Tue, 28 Jan 2025 11:28:38 +0100 Subject: [PATCH 1/4] Finished minimal core (more to come) --- .gitignore | 1 + build.gradle | 15 +++- .../java/com/booleanuk/api/cinema/Main.java | 11 +++ .../api/cinema/customers/Customer.java | 51 +++++++++++++ .../cinema/customers/CustomerController.java | 50 +++++++++++++ .../cinema/customers/CustomerRepository.java | 5 ++ .../booleanuk/api/cinema/movies/Movie.java | 51 +++++++++++++ .../api/cinema/movies/MovieController.java | 59 +++++++++++++++ .../api/cinema/movies/MovieRepository.java | 5 ++ .../booleanuk/api/cinema/screens/Screen.java | 56 +++++++++++++++ .../api/cinema/screens/ScreenController.java | 72 +++++++++++++++++++ .../api/cinema/screens/ScreenRepository.java | 6 ++ .../booleanuk/api/cinema/tickets/Ticket.java | 43 +++++++++++ .../api/cinema/tickets/TicketController.java | 11 +++ .../api/cinema/tickets/TicketRepository.java | 6 ++ src/main/resources/application.yml.example | 23 ------ 16 files changed, 440 insertions(+), 25 deletions(-) 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/screens/Screen.java create mode 100644 src/main/java/com/booleanuk/api/cinema/screens/ScreenController.java create mode 100644 src/main/java/com/booleanuk/api/cinema/screens/ScreenRepository.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 delete mode 100644 src/main/resources/application.yml.example diff --git a/.gitignore b/.gitignore index dc01f204..efdafb17 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ out/ ### VS Code ### .vscode/ + diff --git a/build.gradle b/build.gradle index 3d7f7607..ae1807dc 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.2' + 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,15 @@ 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/Main.java b/src/main/java/com/booleanuk/api/cinema/Main.java new file mode 100644 index 00000000..c4fb60ea --- /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); + } +} 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..d0aba323 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/Customer.java @@ -0,0 +1,51 @@ +package com.booleanuk.api.cinema.customers; + + +import com.booleanuk.api.cinema.screens.Screen; +import com.booleanuk.api.cinema.tickets.Ticket; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.List; + + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "customers") +public class Customer { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column(name = "name") + private String name; + + @Column(name = "email") + private String email; + + @Column(name = "phone") + private String phone; + + @Column(name = "date_created") + private String date_created; + + @Column(name = "date_updated") + private String date_updated; + + @OneToMany(mappedBy = "customer") + @JsonIgnoreProperties({"id", "customer"}) + private List tickets; + + public Customer(int id) { + this.id = id; + } +} 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..ee54cb12 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java @@ -0,0 +1,50 @@ +package com.booleanuk.api.cinema.customers; + + +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; +import java.time.LocalDateTime; +import java.util.List; + +@RestController +@RequestMapping("customers") +public class CustomerController { + + @Autowired + CustomerRepository customerRepository; + + @GetMapping + public ResponseEntity> getAllCustomers() { + return ResponseEntity.ok(customerRepository.findAll()); + } + + @PostMapping + public ResponseEntity createCustomer(@RequestBody Customer customer) { + customer.setDate_created(String.valueOf(LocalDateTime.now())); + return new ResponseEntity<>(this.customerRepository.save(customer), HttpStatus.CREATED); + } + + @PutMapping("/{id}") + public ResponseEntity updateCustomer(@PathVariable(name = "id") int id, @RequestBody Customer customer) { + Customer customerToUpdate = this.customerRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such customer.")); + customerToUpdate.setName(customer.getName()); + customerToUpdate.setEmail(customer.getEmail()); + customerToUpdate.setPhone(customer.getPhone()); + customerToUpdate.setDate_updated(String.valueOf(LocalDateTime.now())); + return new ResponseEntity<>(this.customerRepository.save(customerToUpdate), HttpStatus.OK); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteCustomer(@PathVariable(name = "id") int id) { + Customer toDelete = this.customerRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such customer found")); + this.customerRepository.delete(toDelete); + return ResponseEntity.ok(toDelete); + + } + +} 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..f644212f --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerRepository.java @@ -0,0 +1,5 @@ +package com.booleanuk.api.cinema.customers; + +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..167b1a1e --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/Movie.java @@ -0,0 +1,51 @@ +package com.booleanuk.api.cinema.movies; + +import com.booleanuk.api.cinema.screens.Screen; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import java.util.List; + + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "movies") +public class Movie { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column(name = "title") + private String title; + + @Column(name = "rating") + private String rating; + + @Column(name = "description") + private String description; + + @Column(name = "runtime_mins") + private int runtime_mins; + + @Column(name = "created_at") + private String created_at; + + @Column(name = "updated_at") + private String updated_at; + + @OneToMany(mappedBy = "movie") + @JsonIgnoreProperties({"id", "movie"}) + private List screens; + + public Movie(int id) { + this.id = id; + } + +} \ No newline at end of file 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..c99be3f9 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/MovieController.java @@ -0,0 +1,59 @@ +package com.booleanuk.api.cinema.movies; + + +import com.booleanuk.api.cinema.screens.Screen; +import com.booleanuk.api.cinema.screens.ScreenRepository; +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; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("movies") +public class MovieController { + + @Autowired + MovieRepository movieRepository; + + @Autowired + ScreenRepository screenRepository; + + @GetMapping + public ResponseEntity> getAllMovies() { + return ResponseEntity.ok(movieRepository.findAll()); + } + + @PostMapping + public ResponseEntity createMovie(@RequestBody Movie movie) { + List screenList = new ArrayList<>(); + movie.setScreens(screenList); + movie.setCreated_at(String.valueOf(LocalDateTime.now())); + return new ResponseEntity<>(this.movieRepository.save(movie), HttpStatus.CREATED); + } + + @PutMapping("/{id}") + public ResponseEntity updateMovie(@PathVariable(name = "id") int id, @RequestBody Movie movie) { + Movie movieToUpdate = this.movieRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such movie.")); + movieToUpdate.setTitle(movie.getTitle()); + movieToUpdate.setDescription(movie.getDescription()); + movieToUpdate.setRating(movie.getRating()); + movieToUpdate.setRuntime_mins(movie.getRuntime_mins()); + movieToUpdate.setUpdated_at(String.valueOf(LocalDateTime.now())); + return new ResponseEntity<>(this.movieRepository.save(movieToUpdate), HttpStatus.OK); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteMovie(@PathVariable(name = "id") int id) { + Movie toDelete = this.movieRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such movie found")); + this.screenRepository.deleteAll(toDelete.getScreens()); + this.movieRepository.delete(toDelete); + return ResponseEntity.ok(toDelete); + + } +} 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..e13298f6 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/MovieRepository.java @@ -0,0 +1,5 @@ +package com.booleanuk.api.cinema.movies; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MovieRepository extends JpaRepository {} diff --git a/src/main/java/com/booleanuk/api/cinema/screens/Screen.java b/src/main/java/com/booleanuk/api/cinema/screens/Screen.java new file mode 100644 index 00000000..d8a71b63 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screens/Screen.java @@ -0,0 +1,56 @@ +package com.booleanuk.api.cinema.screens; + +import com.booleanuk.api.cinema.movies.Movie; +import com.booleanuk.api.cinema.tickets.Ticket; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "screens") +public class Screen { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column(name = "screen_number") + private int screen_number; + + @Column(name = "starts_at") + private String starts_at; + + @Column(name = "capacity") + private int capacity; + + @Column(name = "created_at") + private String created_at; + + @Column(name = "updated_at") + private String updated_at; + + @ManyToOne + @JoinColumn(name = "movie_id") + @JsonIgnore + private Movie movie; + + @OneToMany(mappedBy = "screen") + @JsonIgnoreProperties({"id", "screen"}) + private List tickets; + + public Screen(int id) { + this.id = id; + } + +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/cinema/screens/ScreenController.java b/src/main/java/com/booleanuk/api/cinema/screens/ScreenController.java new file mode 100644 index 00000000..6cf90a9d --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screens/ScreenController.java @@ -0,0 +1,72 @@ +package com.booleanuk.api.cinema.screens; + + + +import com.booleanuk.api.cinema.customers.Customer; +import com.booleanuk.api.cinema.movies.MovieRepository; +import com.booleanuk.api.cinema.movies.Movie; +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; + +import java.time.LocalDateTime; +import java.util.List; + +@RestController +@RequestMapping("movies") +public class ScreenController { + + @Autowired + ScreenRepository screenRepository; + + @Autowired + MovieRepository movieRepository; + + @GetMapping("{id}/screenings") + public ResponseEntity> getAllScreens(@PathVariable(name = "id") int id) { + Movie movie = this.movieRepository.findById(id) + .orElseThrow(()-> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such movie!")); + + return ResponseEntity.ok(movie.getScreens()); + } + + @PostMapping("{id}/screenings") + public ResponseEntity createScreen(@PathVariable(name = "id") int id, @RequestBody Screen screen) { + Movie movie = this.movieRepository.findById(id) + .orElseThrow(()-> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such movie!")); + screen.setMovie(movie); + screen.setCreated_at(String.valueOf(LocalDateTime.now())); + return new ResponseEntity<>(this.screenRepository.save(screen), HttpStatus.CREATED); + } + +/* NOT DONE!! CONTAINS ERRORS! + @PutMapping("/{id}") + public ResponseEntity updateScreen(@PathVariable(name = "id") int id, @RequestBody Screen screen) { + Screen screenToUpdate = this.screenRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such screen.")); + + Movie movie = this.movieRepository.findById(screen.getMovie().getId()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such movie")); + + screenToUpdate.setMovie(movie); + screenToUpdate.setScreen_number(screen.getScreen_number()); + screenToUpdate.setStarts_at(screen.getStarts_at()); + screenToUpdate.setCapacity(screen.getCapacity()); + screenToUpdate.setUpdated_at(LocalDateTime.now()); + return new ResponseEntity<>(this.screenRepository.save(screenToUpdate), HttpStatus.OK); + } + + + @DeleteMapping("/{id}") + public ResponseEntity deleteScreen(@PathVariable(name = "id") int id) { + Screen toDelete = this.screenRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No such customer found")); + this.screenRepository.delete(toDelete); + return ResponseEntity.ok(toDelete); + + } + + */ +} diff --git a/src/main/java/com/booleanuk/api/cinema/screens/ScreenRepository.java b/src/main/java/com/booleanuk/api/cinema/screens/ScreenRepository.java new file mode 100644 index 00000000..df32c974 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screens/ScreenRepository.java @@ -0,0 +1,6 @@ +package com.booleanuk.api.cinema.screens; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ScreenRepository extends JpaRepository { +} 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..fe479b57 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java @@ -0,0 +1,43 @@ +package com.booleanuk.api.cinema.tickets; + +import com.booleanuk.api.cinema.customers.Customer; +import com.booleanuk.api.cinema.screens.Screen; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "tickets") +public class Ticket { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private int num_seats; + + @ManyToOne + @JoinColumn(name = "customer_id") + @JsonIgnoreProperties("tickets") + private Customer customer; + + @ManyToOne + @JoinColumn(name = "screening_id") + @JsonIgnoreProperties("tickets") + private Screen screen; + + @Column(name = "created_at") + private String created_at; + + @Column(name = "updated_at") + private String updated_at; +} 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..6dc4c47b --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java @@ -0,0 +1,11 @@ +package com.booleanuk.api.cinema.tickets; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("tickets") +public class TicketController { + +} 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..6448b7eb --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketRepository.java @@ -0,0 +1,6 @@ +package com.booleanuk.api.cinema.tickets; + +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 9c1e1d6c3e7c73222fc624a4d5491b11ac2bd5d1 Mon Sep 17 00:00:00 2001 From: Magnus-droid Date: Thu, 30 Jan 2025 08:54:18 +0100 Subject: [PATCH 2/4] Added ticket get and post requests as specified in the docs --- .../java/com/booleanuk/api/cinema/Main.java | 2 +- .../api/cinema/responses/ErrorResponse.java | 23 +++++ .../api/cinema/responses/Response.java | 14 ++++ .../booleanuk/api/cinema/tickets/Ticket.java | 5 +- .../api/cinema/tickets/TicketController.java | 83 ++++++++++++++++++- 5 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java create mode 100644 src/main/java/com/booleanuk/api/cinema/responses/Response.java diff --git a/src/main/java/com/booleanuk/api/cinema/Main.java b/src/main/java/com/booleanuk/api/cinema/Main.java index c4fb60ea..57047dbf 100644 --- a/src/main/java/com/booleanuk/api/cinema/Main.java +++ b/src/main/java/com/booleanuk/api/cinema/Main.java @@ -8,4 +8,4 @@ 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/responses/ErrorResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java new file mode 100644 index 00000000..52016522 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java @@ -0,0 +1,23 @@ +package com.booleanuk.api.cinema.responses; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +@Getter + +public class ErrorResponse extends Response>{ + + public ErrorResponse(String status, Map data) { + super(status, data); + + } + + public void set(String message) { + 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/Response.java b/src/main/java/com/booleanuk/api/cinema/responses/Response.java new file mode 100644 index 00000000..3f3b3696 --- /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 Response(String status, T data) { + this.status = status; + this.data = data; + } +} diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java b/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java index fe479b57..62cf1c7b 100644 --- a/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java +++ b/src/main/java/com/booleanuk/api/cinema/tickets/Ticket.java @@ -2,6 +2,7 @@ import com.booleanuk.api.cinema.customers.Customer; import com.booleanuk.api.cinema.screens.Screen; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -27,12 +28,12 @@ public class Ticket { @ManyToOne @JoinColumn(name = "customer_id") - @JsonIgnoreProperties("tickets") + @JsonIgnore private Customer customer; @ManyToOne @JoinColumn(name = "screening_id") - @JsonIgnoreProperties("tickets") + @JsonIgnore private Screen screen; @Column(name = "created_at") diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java index 6dc4c47b..c09f65f9 100644 --- a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java @@ -1,11 +1,88 @@ package com.booleanuk.api.cinema.tickets; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +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.screens.Screen; +import com.booleanuk.api.cinema.screens.ScreenRepository; +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.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @RestController -@RequestMapping("tickets") +@RequestMapping("customers") public class TicketController { + @Autowired + TicketRepository ticketRepository; + + @Autowired + CustomerRepository customerRepository; + + @Autowired + ScreenRepository screenRepository; + + @GetMapping("/{customerId}/screenings/{screeningId}") + public ResponseEntity> getAllTickets(@PathVariable(name = "customerId") int customerId, @PathVariable(name = "screeningId") int screeningId) { + + Customer customer = this.customerRepository.findById(customerId).orElse(null); + if (customer == null) { + ErrorResponse error = new ErrorResponse("Error", null); + error.set("No such customer found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + // Check if the tickets belonging to the customer ID match the screenID + List tickets = new ArrayList<>(); + for(Ticket customerTicket : customer.getTickets()) { + if (customerTicket.getScreen().getId() == screeningId) { + tickets.add(customerTicket); + } + } + + if (tickets.isEmpty()) { + ErrorResponse noMatchingTicketsError = new ErrorResponse("Error", null); + noMatchingTicketsError.set("The customer exists but does not have any tickets with that screening ID"); + return new ResponseEntity<>(noMatchingTicketsError, HttpStatus.NOT_FOUND); + } + + return new ResponseEntity<>(new Response<>("Success", tickets), HttpStatus.OK); + + } + + @PostMapping("/{customerId}/screenings/{screeningId}") + public ResponseEntity> bookNewTicket(@PathVariable(name = "customerId") int customerId, + @PathVariable(name = "screeningId") int screeningId, + @RequestBody Ticket ticket) + { + + Customer customer = this.customerRepository.findById(customerId).orElse(null); + if (customer == null) { + ErrorResponse error = new ErrorResponse("Error", null); + error.set("No such customer found"); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + Screen screen = this.screenRepository.findById(customerId).orElse(null); + if (screen == null) { + ErrorResponse error = new ErrorResponse("Error", null); + error.set("Customer exists but no such screen found."); + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + ticket.setCustomer(customer); + ticket.setScreen(screen); + ticket.setCreated_at(String.valueOf(LocalDateTime.now())); + return new ResponseEntity<>(new Response<>("Success", this.ticketRepository.save(ticket)), HttpStatus.CREATED); + + + + + } } From ddf2f484ebcdad05d0bfebf11304eb40c3a1ed9b Mon Sep 17 00:00:00 2001 From: Magnus-droid Date: Thu, 30 Jan 2025 17:03:20 +0100 Subject: [PATCH 3/4] Added most extension criteria (missing for customer PUT and DEL methods) --- .../cinema/customers/CustomerController.java | 14 +++++++++---- .../api/cinema/responses/ErrorResponse.java | 13 ++++-------- .../api/cinema/responses/Response.java | 5 +++-- .../api/cinema/tickets/TicketController.java | 21 +++++++------------ 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java index ee54cb12..00571bc9 100644 --- a/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java @@ -1,6 +1,8 @@ package com.booleanuk.api.cinema.customers; +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; @@ -17,14 +19,18 @@ public class CustomerController { CustomerRepository customerRepository; @GetMapping - public ResponseEntity> getAllCustomers() { - return ResponseEntity.ok(customerRepository.findAll()); + public ResponseEntity> getAllCustomers() { + return new ResponseEntity<>(new Response<>(customerRepository.findAll()), HttpStatus.OK); } @PostMapping - public ResponseEntity createCustomer(@RequestBody Customer customer) { + public ResponseEntity> createCustomer(@RequestBody Customer customer) { + if (customer == null) { + ErrorResponse errorResponse = new ErrorResponse("Failed to create customer"); + return new ResponseEntity<>(errorResponse, HttpStatus.BAD_GATEWAY); + } customer.setDate_created(String.valueOf(LocalDateTime.now())); - return new ResponseEntity<>(this.customerRepository.save(customer), HttpStatus.CREATED); + return new ResponseEntity<>(new Response<>(this.customerRepository.save(customer)), HttpStatus.CREATED); } @PutMapping("/{id}") diff --git a/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java index 52016522..dd942388 100644 --- a/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java +++ b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java @@ -8,16 +8,11 @@ @Getter -public class ErrorResponse extends Response>{ +public class ErrorResponse extends Response{ - public ErrorResponse(String status, Map data) { - super(status, data); + public ErrorResponse(String data) { + super(data); + this.status = "Error"; } - - public void set(String message) { - 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/Response.java b/src/main/java/com/booleanuk/api/cinema/responses/Response.java index 3f3b3696..473d50ae 100644 --- a/src/main/java/com/booleanuk/api/cinema/responses/Response.java +++ b/src/main/java/com/booleanuk/api/cinema/responses/Response.java @@ -7,8 +7,9 @@ public class Response { protected String status; protected T data; - public Response(String status, T data) { - this.status = status; + public Response(T data) { + this.status = "Success"; this.data = data; } + } diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java index c09f65f9..05dba335 100644 --- a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java @@ -36,8 +36,7 @@ public ResponseEntity> getAllTickets(@PathVariable(name = "customerI Customer customer = this.customerRepository.findById(customerId).orElse(null); if (customer == null) { - ErrorResponse error = new ErrorResponse("Error", null); - error.set("No such customer found"); + ErrorResponse error = new ErrorResponse("No such customer found"); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } // Check if the tickets belonging to the customer ID match the screenID @@ -49,12 +48,11 @@ public ResponseEntity> getAllTickets(@PathVariable(name = "customerI } if (tickets.isEmpty()) { - ErrorResponse noMatchingTicketsError = new ErrorResponse("Error", null); - noMatchingTicketsError.set("The customer exists but does not have any tickets with that screening ID"); + ErrorResponse noMatchingTicketsError = new ErrorResponse("The customer exists but does not have any tickets with that screening ID"); return new ResponseEntity<>(noMatchingTicketsError, HttpStatus.NOT_FOUND); } - return new ResponseEntity<>(new Response<>("Success", tickets), HttpStatus.OK); + return new ResponseEntity<>(new Response<>(tickets), HttpStatus.OK); } @@ -66,23 +64,18 @@ public ResponseEntity> bookNewTicket(@PathVariable(name = "customerI Customer customer = this.customerRepository.findById(customerId).orElse(null); if (customer == null) { - ErrorResponse error = new ErrorResponse("Error", null); - error.set("No such customer found"); + ErrorResponse error = new ErrorResponse("No such customer found"); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } - Screen screen = this.screenRepository.findById(customerId).orElse(null); + Screen screen = this.screenRepository.findById(screeningId).orElse(null); if (screen == null) { - ErrorResponse error = new ErrorResponse("Error", null); - error.set("Customer exists but no such screen found."); + ErrorResponse error = new ErrorResponse("Customer exists but no such screen found."); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } ticket.setCustomer(customer); ticket.setScreen(screen); ticket.setCreated_at(String.valueOf(LocalDateTime.now())); - return new ResponseEntity<>(new Response<>("Success", this.ticketRepository.save(ticket)), HttpStatus.CREATED); - - - + return new ResponseEntity<>(new Response<>(this.ticketRepository.save(ticket)), HttpStatus.CREATED); } } From e30ce6bb31163dc800428940f2213c2399245f93 Mon Sep 17 00:00:00 2001 From: Magnus-droid Date: Thu, 30 Jan 2025 17:10:01 +0100 Subject: [PATCH 4/4] added errors in the format of "message: error_message" to data --- .../api/cinema/customers/CustomerController.java | 3 ++- .../booleanuk/api/cinema/responses/ErrorResponse.java | 4 ++-- .../booleanuk/api/cinema/tickets/TicketController.java | 9 ++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java index 00571bc9..be7eb484 100644 --- a/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java @@ -10,6 +10,7 @@ import org.springframework.web.server.ResponseStatusException; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; @RestController @RequestMapping("customers") @@ -26,7 +27,7 @@ public ResponseEntity> getAllCustomers() { @PostMapping public ResponseEntity> createCustomer(@RequestBody Customer customer) { if (customer == null) { - ErrorResponse errorResponse = new ErrorResponse("Failed to create customer"); + ErrorResponse errorResponse = new ErrorResponse(Map.of("message","Failed to create customer")); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_GATEWAY); } customer.setDate_created(String.valueOf(LocalDateTime.now())); diff --git a/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java index dd942388..35375dcb 100644 --- a/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java +++ b/src/main/java/com/booleanuk/api/cinema/responses/ErrorResponse.java @@ -8,9 +8,9 @@ @Getter -public class ErrorResponse extends Response{ +public class ErrorResponse extends Response>{ - public ErrorResponse(String data) { + public ErrorResponse(Map data) { super(data); this.status = "Error"; diff --git a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java index 05dba335..440a702a 100644 --- a/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java +++ b/src/main/java/com/booleanuk/api/cinema/tickets/TicketController.java @@ -14,7 +14,6 @@ import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,7 +35,7 @@ public ResponseEntity> getAllTickets(@PathVariable(name = "customerI Customer customer = this.customerRepository.findById(customerId).orElse(null); if (customer == null) { - ErrorResponse error = new ErrorResponse("No such customer found"); + ErrorResponse error = new ErrorResponse(Map.of("message","No such customer found")); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } // Check if the tickets belonging to the customer ID match the screenID @@ -48,7 +47,7 @@ public ResponseEntity> getAllTickets(@PathVariable(name = "customerI } if (tickets.isEmpty()) { - ErrorResponse noMatchingTicketsError = new ErrorResponse("The customer exists but does not have any tickets with that screening ID"); + ErrorResponse noMatchingTicketsError = new ErrorResponse(Map.of("message","The customer exists but does not have any tickets with that screening ID")); return new ResponseEntity<>(noMatchingTicketsError, HttpStatus.NOT_FOUND); } @@ -64,12 +63,12 @@ public ResponseEntity> bookNewTicket(@PathVariable(name = "customerI Customer customer = this.customerRepository.findById(customerId).orElse(null); if (customer == null) { - ErrorResponse error = new ErrorResponse("No such customer found"); + ErrorResponse error = new ErrorResponse(Map.of("message","No such customer found")); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } Screen screen = this.screenRepository.findById(screeningId).orElse(null); if (screen == null) { - ErrorResponse error = new ErrorResponse("Customer exists but no such screen found."); + ErrorResponse error = new ErrorResponse(Map.of("message","Customer exists but no such screen found.")); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } ticket.setCustomer(customer);