diff --git a/.gitignore b/.gitignore index dc01f204..4d6c7236 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ out/ ### VS Code ### .vscode/ + +application.yml diff --git a/build.gradle b/build.gradle index 3d7f7607..d6f2d1f9 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,12 +26,16 @@ 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') { useJUnitPlatform() -} \ No newline at end of file +} 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..ddb837ab --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/Customer.java @@ -0,0 +1,40 @@ +package com.booleanuk.api.cinema.customers; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "customers") +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 String createdAt; + @Column + private String updatedAt; + + public Customer(String name, String email, String phone) { + this.name = name; + this.email = email; + this.phone = phone; + } +} 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..f96e7120 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerController.java @@ -0,0 +1,57 @@ +package com.booleanuk.api.cinema.customers; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("customers") +public class CustomerController { + @Autowired + private CustomerRepository customerRepository; + + @GetMapping + public ResponseEntity> getAllCustomers() { + return ResponseEntity.ok(customerRepository.findAll()); + } + + @PostMapping + public ResponseEntity addCustomer(@RequestBody Customer customer) { + customer.setCreatedAt(LocalDateTime.now().toString()); + customer.setUpdatedAt(LocalDateTime.now().toString()); + return new ResponseEntity(customerRepository.save(customer), HttpStatus.CREATED); + } + + @PutMapping("{id}") + public ResponseEntity updateCustomer(@PathVariable int id, @RequestBody Customer customer) { + Customer customerToUpdate = customerRepository.findById(id).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find customer with this id")); + customerToUpdate.setName(customer.getName()); + customerToUpdate.setEmail(customer.getEmail()); + customerToUpdate.setPhone(customer.getPhone()); + customerToUpdate.setUpdatedAt(LocalDateTime.now().toString()); + + return new ResponseEntity(customerRepository.save(customerToUpdate), HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity deleteCustomer(@PathVariable int id) { + Customer customerToDelete = customerRepository.findById(id).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find customer with this id")); + customerRepository.delete(customerToDelete); + + return ResponseEntity.ok(customerToDelete); + } +} 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..30cd28db --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/customers/CustomerRepository.java @@ -0,0 +1,6 @@ +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..e9e15cc2 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/Movie.java @@ -0,0 +1,53 @@ +package com.booleanuk.api.cinema.movies; + +import java.util.List; + +import com.booleanuk.api.cinema.screenings.Screening; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "movies") +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 String createdAt; + @Column + private String updatedAt; + + @OneToMany(mappedBy = "movie") + @JsonIgnore + 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; + } +} 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..fd19e87c --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/MovieController.java @@ -0,0 +1,58 @@ +package com.booleanuk.api.cinema.movies; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("movies") +public class MovieController { + @Autowired + private MovieRepository movieRepository; + + @GetMapping + public ResponseEntity> getAllMovies() { + return ResponseEntity.ok(movieRepository.findAll()); + } + + @PostMapping + public ResponseEntity addMovie(@RequestBody Movie movie) { + movie.setCreatedAt(LocalDateTime.now().toString()); + movie.setUpdatedAt(LocalDateTime.now().toString()); + return new ResponseEntity(movieRepository.save(movie), HttpStatus.CREATED); + } + + @PutMapping("{id}") + public ResponseEntity updateMovie(@PathVariable int id, @RequestBody Movie movie) { + Movie movieToUpdate = movieRepository.findById(id).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find movie with this id")); + movieToUpdate.setTitle(movie.getTitle()); + movieToUpdate.setRating(movie.getRating()); + movieToUpdate.setDescription(movie.getDescription()); + movieToUpdate.setRuntimeMins(movie.getRuntimeMins()); + movieToUpdate.setUpdatedAt(LocalDateTime.now().toString()); + + return new ResponseEntity(movieRepository.save(movieToUpdate), HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity deleteMovie(@PathVariable int id) { + Movie movieToDelete = movieRepository.findById(id).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find movie with this id")); + movieRepository.delete(movieToDelete); + + return ResponseEntity.ok(movieToDelete); + } +} 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..d7d111cf --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/movies/MovieRepository.java @@ -0,0 +1,6 @@ +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/screenings/Screening.java b/src/main/java/com/booleanuk/api/cinema/screenings/Screening.java new file mode 100644 index 00000000..cdeb9450 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screenings/Screening.java @@ -0,0 +1,52 @@ +package com.booleanuk.api.cinema.screenings; + +import com.booleanuk.api.cinema.movies.Movie; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "screenings") +public class Screening { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + @Column + private int screenNumber; + @Column + private int capacity; + @Column + private String startsAt; + @Column + private String createdAt; + @Column + private String updatedAt; + + @ManyToOne + @JoinColumn(name = "movie_id") + @JsonIgnoreProperties({ "screenings", "movie" }) + @JsonIgnore + private Movie movie; + + public Screening(int screenNumber, int capacity, String startsAt) { + this.screenNumber = screenNumber; + this.capacity = capacity; + this.startsAt = startsAt; + } +} 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..11928f99 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningController.java @@ -0,0 +1,44 @@ +package com.booleanuk.api.cinema.screenings; + +import java.time.LocalDateTime; +import java.util.List; +import com.booleanuk.api.cinema.movies.*; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.http.HttpStatus; + +@RestController +@RequestMapping("movies/{id}/screenings") +public class ScreeningController { + @Autowired + private ScreeningRepository screeningRepository; + @Autowired + private MovieRepository movieRepository; + + @GetMapping + public ResponseEntity> getAllScreeningsOfMovie(@PathVariable int id) { + Movie movie = movieRepository.findById(id).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find movie with this id")); + return ResponseEntity.ok(movie.getScreenings()); + } + + @PostMapping + public ResponseEntity addScreening(@PathVariable int id, @RequestBody Screening screening) { + Movie movie = movieRepository.findById(id).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find movie with this id")); + movie.getScreenings().add(screening); + screening.setMovie(movie); + screening.setCreatedAt(LocalDateTime.now().toString()); + screening.setUpdatedAt(LocalDateTime.now().toString()); + + return new ResponseEntity(screeningRepository.save(screening), 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..98fc8114 --- /dev/null +++ b/src/main/java/com/booleanuk/api/cinema/screenings/ScreeningRepository.java @@ -0,0 +1,6 @@ +package com.booleanuk.api.cinema.screenings; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ScreeningRepository extends JpaRepository { +}