Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -13,17 +13,27 @@ java {
}
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

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') {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/booleanuk/api/cinema/Main.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
51 changes: 51 additions & 0 deletions src/main/java/com/booleanuk/api/cinema/customers/Customer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.booleanuk.api.cinema.customers;

import com.booleanuk.api.cinema.tickets.Ticket;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
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")
@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 LocalDateTime createdAt;
@Column
private LocalDateTime updatedAt;

@OneToMany(mappedBy = "customer", cascade = CascadeType.REMOVE)
@JsonIncludeProperties({"customer_id", "screening_id", "num_seats"})
private List<Ticket> tickets;

public Customer(String name, String email, String phone) {
this.name = name;
this.email = email;
this.phone = phone;
}

public Customer(int id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
@@ -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.LocalDateTime;

@RestController
@RequestMapping("customers")
public class CustomerController {
@Autowired
private CustomerRepository customerRepository;

private ErrorResponse errorResponse = new ErrorResponse();
private CustomerResponse customerResponse = new CustomerResponse();
private CustomerListResponse customerListResponse = new CustomerListResponse();

@GetMapping
public ResponseEntity<Response<?>> getAllCustomers() {
this.customerListResponse.set(this.customerRepository.findAll());
return ResponseEntity.ok(customerListResponse);
}

@PostMapping
public ResponseEntity<Response<?>> createCustomer(@RequestBody Customer customer) {
customer.setCreatedAt(LocalDateTime.now());
customer.setUpdatedAt(LocalDateTime.now());
if (customer.getName() == null || customer.getEmail() == null || customer.getPhone() == null) {
this.errorResponse.set("Could not create a new customer, please check all fields are correct");
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
this.customerResponse.set(this.customerRepository.save(customer));
return new ResponseEntity<>(customerResponse, HttpStatus.CREATED);
}

@GetMapping("{id}")
public ResponseEntity<Response<?>> getCustomerById(@PathVariable int id) {
Customer customer = this.customerRepository.findById(id).orElse(null);
if (customer == null) {
this.errorResponse.set("No customer with that id found");
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
this.customerResponse.set(customer);
return ResponseEntity.ok(customerResponse);
}

@PutMapping("{id}")
public ResponseEntity<Response<?>> updateCustomer(@PathVariable int id, @RequestBody Customer customer) {
Customer customerToUpdate = this.customerRepository.findById(id).orElse(null);
if (customerToUpdate == null) {
this.errorResponse.set("No customer with that id found");
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}

if (customer.getName() == null || customer.getEmail() == null || customer.getPhone() == null) {
this.errorResponse.set("Could not update the specified customer, please check all fields are correct");
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
customerToUpdate.setName(customer.getName());
customerToUpdate.setEmail(customer.getEmail());
customerToUpdate.setPhone(customer.getPhone());
customerToUpdate.setUpdatedAt(LocalDateTime.now());
this.customerResponse.set(this.customerRepository.save(customerToUpdate));
return new ResponseEntity<>(customerResponse, HttpStatus.CREATED);
}

@DeleteMapping("{id}")
public ResponseEntity<Response<?>> deleteCustomerById(@PathVariable int id) {
Customer customerToDelete = this.customerRepository.findById(id).orElse(null);
if (customerToDelete == null) {
this.errorResponse.set("No customer with that id found");
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
this.customerRepository.delete(customerToDelete);
this.customerResponse.set(customerToDelete);
return ResponseEntity.ok(customerResponse);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.booleanuk.api.cinema.customers;

import org.springframework.data.jpa.repository.JpaRepository;

public interface CustomerRepository extends JpaRepository<Customer, Integer> {

}
51 changes: 51 additions & 0 deletions src/main/java/com/booleanuk/api/cinema/movies/Movie.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.booleanuk.api.cinema.movies;

import com.booleanuk.api.cinema.screenings.Screening;
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
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 = "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 LocalDateTime createdAt;
@Column
private LocalDateTime updatedAt;

@OneToMany(mappedBy = "movie", cascade = CascadeType.REMOVE)
@JsonIncludeProperties({"screenNumber", "startsAt", "capacity"})
private List<Screening> screenings;

public Movie(String title, String rating, String description, int runtimeMins) {
this.title = title;
this.rating = rating;
this.description = description;
this.runtimeMins = runtimeMins;
}

public Movie(int id) {
this.id = id;
}
}
98 changes: 98 additions & 0 deletions src/main/java/com/booleanuk/api/cinema/movies/MovieController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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.LocalDateTime;

@RestController
@RequestMapping("movies")
public class MovieController {
@Autowired
private MovieRepository movieRepository;

@Autowired
private ScreeningRepository screeningRepository;

private ErrorResponse errorResponse = new ErrorResponse();
private MovieResponse movieResponse = new MovieResponse();
private MovieListResponse movieListResponse = new MovieListResponse();
private ScreeningResponse screeningResponse = new ScreeningResponse();

@GetMapping
public ResponseEntity<Response<?>> getAllMovies() {
this.movieListResponse.set(this.movieRepository.findAll());
return ResponseEntity.ok(movieListResponse);
}

@PostMapping
public ResponseEntity<Response<?>> createMovie(@RequestBody Movie movie) {
movie.setCreatedAt(LocalDateTime.now());
movie.setUpdatedAt(LocalDateTime.now());
if (movie.getTitle() == null || movie.getRating() == null || movie.getDescription() == null || movie.getRuntimeMins() <= 0) {
this.errorResponse.set("Could not create a new movie, please check all fields are correct");
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}

this.movieResponse.set(this.movieRepository.save(movie));
if (!(movie.getScreenings() == null)) {
for (Screening screening : movie.getScreenings()) {
screening = new Screening(movie, screening.getScreenNumber(), screening.getStartsAt(), screening.getCapacity());
this.screeningResponse.set(this.screeningRepository.save(screening));
}
}
return new ResponseEntity<>(movieResponse, HttpStatus.CREATED);
}

@GetMapping("{id}")
public ResponseEntity<Response<?>> getMovieById(@PathVariable int id) {
Movie movie = this.movieRepository.findById(id).orElse(null);
if (movie == null) {
this.errorResponse.set("No movie with that id found");
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
this.movieResponse.set(movie);
return ResponseEntity.ok(movieResponse);
}

@PutMapping("{id}")
public ResponseEntity<Response<?>> updateMovie(@PathVariable int id, @RequestBody Movie movie) {
Movie movieToUpdate = this.movieRepository.findById(id).orElse(null);
if (movieToUpdate == null) {
this.errorResponse.set("No movie with that id found");
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}

if (movie.getTitle() == null || movie.getRating() == null || movie.getDescription() == null || movie.getRuntimeMins() <= 0) {
this.errorResponse.set("Could not update the specified movie, please check all fields are correct");
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
movieToUpdate.setTitle(movie.getTitle());
movieToUpdate.setRating(movie.getRating());
movieToUpdate.setDescription(movie.getDescription());
movieToUpdate.setRuntimeMins(movie.getRuntimeMins());
movieToUpdate.setUpdatedAt(LocalDateTime.now());
this.movieResponse.set(this.movieRepository.save(movieToUpdate));
return new ResponseEntity<>(movieResponse, HttpStatus.CREATED);
}

@DeleteMapping("{id}")
public ResponseEntity<Response<?>> deleteMovieById(@PathVariable int id) {
Movie movieToDelete = this.movieRepository.findById(id).orElse(null);
if (movieToDelete == null) {
this.errorResponse.set("No movie with that id found");
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
this.movieRepository.delete(movieToDelete);
this.movieResponse.set(movieToDelete);
return ResponseEntity.ok(movieResponse);
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.booleanuk.api.cinema.movies;

import org.springframework.data.jpa.repository.JpaRepository;

public interface MovieRepository extends JpaRepository<Movie, Integer> {

}
Original file line number Diff line number Diff line change
@@ -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<List<Customer>>{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.booleanuk.api.cinema.responses;

import com.booleanuk.api.cinema.customers.Customer;

public class CustomerResponse extends Response<Customer>{
}
Original file line number Diff line number Diff line change
@@ -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<Map<String, String>>{

public void set(String message) {
this.status = "error";
Map<String, String> reply = new HashMap<>();
reply.put("message", message);
this.data = reply;
}
}
Loading