Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIS-27: Created Endpoints For The Review Entity #10

Merged
merged 6 commits into from
Mar 21, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
// 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;
Expand All @@ -10,6 +11,7 @@
import jakarta.validation.Valid;

import sg.com.smartinventory.entities.Customer;
// import sg.com.smartinventory.entities.Review;
import sg.com.smartinventory.services.CustomerService;

@RestController
Expand All @@ -32,4 +34,12 @@ public ResponseEntity<Customer> createCustomer(@Valid @RequestBody Customer cust
Customer newCustomer = customerService.createCustomer(customer);
return new ResponseEntity<>(newCustomer, HttpStatus.CREATED);
}

// // Nested route - Add review to customer.
// @PostMapping("/{id}/reviews")
// public ResponseEntity<Review> addReviewToCustomer(@PathVariable Long id,
// @Valid @RequestBody Review review) {
// Review newReview = customerService.addReviewToCustomer(id, review);
// return new ResponseEntity<>(newReview, HttpStatus.CREATED);
// }
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package sg.com.smartinventory.controllers;

import java.util.ArrayList;

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;
Expand Down Expand Up @@ -31,4 +37,32 @@ public ResponseEntity<Review> createReview(@Valid @RequestBody Review review) {
Review newReview = reviewService.createReview(review);
return new ResponseEntity<>(newReview, HttpStatus.CREATED);
}

// READ (GET ALL).
@GetMapping("")
public ResponseEntity<ArrayList<Review>> getAllReviews() {
ArrayList<Review> allReviews = reviewService.getAllReviews();
return new ResponseEntity<>(allReviews, HttpStatus.OK);
}

// READ (GET ONE).
@GetMapping("/{id}")
public ResponseEntity<Review> getReview(@PathVariable long id) {
Review foundReview = reviewService.getReview(id);
return new ResponseEntity<>(foundReview, HttpStatus.OK);
}

// UPDATE.
@PutMapping("/{id}")
public ResponseEntity<Review> updateReview(@PathVariable long id, @RequestBody Review review) {
Review updatedReview = reviewService.updateReview(id, review);
return new ResponseEntity<>(updatedReview, HttpStatus.OK);
}

// DELETE.
@DeleteMapping("/{id}")
public ResponseEntity<Review> deleteReview(@PathVariable long id) {
reviewService.deleteReview(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
21 changes: 21 additions & 0 deletions src/main/java/sg/com/smartinventory/entities/Customer.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package sg.com.smartinventory.entities;

import java.util.List;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;

import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
Expand Down Expand Up @@ -53,6 +60,20 @@ public class Customer {
@Column(name = "email")
private String email;

// Uni-directional One to Many mapping -> One Customer (Parent) can have many
// Reviews (Child). The extra column 'customer_id' will be created on the many
// side of the relationship, that is, in the Review table. The cascade attribute
// is set to CascadeType.ALL to cascade all operations (e.g., save, update,
// delete) to the associated Review entities. The @JoinColumn annotation is used
// to specify the foreign key column (customer_id) in the Review table that
// establishes the relationship. Thus, it specifies the foreign key column in
// the child entity’s table that refers to the parent entity. The ‘mappedBy’
// attribute is not used in a unidirectional relationship as it’s specific to
// bidirectional relationships.
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "customer_id", referencedColumnName = "id")
private List<Review> reviews;

public Customer() {
}

Expand Down
22 changes: 21 additions & 1 deletion src/main/java/sg/com/smartinventory/entities/Product.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package sg.com.smartinventory.entities;

import java.util.List;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;

import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -39,11 +45,25 @@ public class Product {
@Column(name = "stock_quantity")
private int stockQuantity;

// Uni-directional One to Many mapping -> One Product (Parent) can have many
// Reviews (Child). The extra column 'product_id' will be created on the many
// side of the relationship, that is, in the Review table. The cascade attribute
// is set to CascadeType.ALL to cascade all operations (e.g., save, update,
// delete) to the associated Review entities. The @JoinColumn annotation is used
// to specify the foreign key column (product_id) in the Review table that
// establishes the relationship. Thus, it specifies the foreign key column in
// the child entity’s table that refers to the parent entity. The ‘mappedBy’
// attribute is not used in a unidirectional relationship as it’s specific to
// bidirectional relationships.
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "product_id", referencedColumnName = "id")
private List<Review> reviews;

public Product() {
}

// Define Constructor for DataLoader.
public Product(String category, String name, String description, double price, int stockQuantity, int reviewId) {
public Product(String category, String name, String description, double price, int stockQuantity) {
this();

this.category = category;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/sg/com/smartinventory/entities/Review.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Min;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
package sg.com.smartinventory.repositories;

import java.util.List;

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

import sg.com.smartinventory.entities.Customer;

// CustomerRepository simply extends JpaRepository, giving us a lot of default methods to access db without the hard work.
// CustomerRepository simply extends JpaRepository, giving us a lot of default methods to access the database without the hard work.
// This is a very powerful feature of Spring Data JPA. It will automatically do a property check and traverse the supported nested properties, translating them into the relevant queries.
// We can also create custom queries using the JPA criteria API by simply creating a method with a certain naming convention specified by the query creation mechanism.
public interface CustomerRepository extends JpaRepository<Customer, Long> {
// Custom query to find all customers with a certain ID.
List<Customer> findById(long id);

// Custom query to find all customers with a certain first name.
List<Customer> findByFirstName(String firstName);

// Custom query to find all customers with a certain last name.
List<Customer> findByLastName(String lastName);

// Custom query to find all customers with a certain first name and last name.
List<Customer> findByFirstNameAndLastName(String firstName, String lastName);

// Custom query to find all customers with a certain country.
List<Customer> findByCountry(String country);

// Custom query to find all customers with a certain address.
List<Customer> findByAddress(String address);

// Custom query to find all customers with a certain postal code.
List<Customer> findByPostalCode(int postalCode);

// Custom query to find all customers with a certain phone number.
List<Customer> findByPhoneNumber(int phoneNumber);

// Custom query to find all customers with a certain email.
List<Customer> findByEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
package sg.com.smartinventory.repositories;

import java.util.List;

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

import sg.com.smartinventory.entities.Product;

// ProductRepository simply extends JpaRepository, giving us a lot of default methods to access the database without the hard work.
// This is a very powerful feature of Spring Data JPA. It will automatically do a property check and traverse the supported nested properties, translating them into the relevant queries.
// We can also create custom queries using the JPA criteria API by simply creating a method with a certain naming convention specified by the query creation mechanism.
public interface ProductRepository extends JpaRepository<Product, Long> {
// Custom query to find all products with a certain ID.
List<Product> findById(long id);

// Custom query to find all products with a certain category.
List<Product> findByCategory(String category);

// Custom query to find all products with a certain name.
List<Product> findByName(String name);

// Custom query to find all products with a certain description.
List<Product> findByDescription(String description);

// Custom query to find all products with a certain price.
List<Product> findByPrice(double price);

// Custom query to find all products with a certain stock quantity.
List<Product> findByStockQuantity(int stockQuantity);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
package sg.com.smartinventory.repositories;

import java.util.List;

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

import sg.com.smartinventory.entities.Review;

// ReviewRepository simply extends JpaRepository, giving us a lot of default methods to access the database without the hard work.
// This is a very powerful feature of Spring Data JPA. It will automatically do a property check and traverse the supported nested properties, translating them into the relevant queries.
// We can also create custom queries using the JPA criteria API by simply creating a method with a certain naming convention specified by the query creation mechanism.
public interface ReviewRepository extends JpaRepository<Review, Long> {
// Custom query to find all reviews with a certain ID.
List<Review> findById(long id);

// Custom query to find all reviews with a certain category.
List<Review> findByCategory(String category);

// Custom query to find all reviews with a certain review content.
List<Review> findByReviewContent(String reviewContent);

// Custom query to find all reviews with a certain rating.
List<Review> findByRating(int rating);

// Custom query to find all reviews with a certain customer ID.
List<Review> findByCustomerId(long customerId);

// Custom query to find all reviews with a certain product ID.
List<Review> findByProductId(long productId);

// Custom query to find all reviews with a certain customer ID and product ID.
List<Review> findByCustomerIdAndProductId(long customerId, long productId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.springframework.stereotype.Service;

import sg.com.smartinventory.entities.Customer;
// import sg.com.smartinventory.entities.Review;
// import sg.com.smartinventory.exceptions.CustomerNotFoundException;
import sg.com.smartinventory.repositories.CustomerRepository;
import sg.com.smartinventory.services.CustomerService;

Expand All @@ -21,4 +23,19 @@ public Customer createCustomer(Customer customer) {

return newCustomer;
}

// @Override
// public Review addReviewToCustomer(long customerId, long productId, Review
// review) {
// // retrieve the customer from the database.
// Customer selectedCustomer =
// customerRepository.findById(customerId).orElseThrow(() -> new
// CustomerNotFoundException(customerId));

// // add the customer to the review
// review.setCustomer(selectedCustomer);

// // save the review to the database
// return reviewRepository.save(review);
// }
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package sg.com.smartinventory.serviceImpls;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import sg.com.smartinventory.entities.Review;
// import sg.com.smartinventory.exceptions.ReviewNotFoundException;
import sg.com.smartinventory.repositories.ReviewRepository;
import sg.com.smartinventory.services.ReviewService;

Expand All @@ -21,4 +25,58 @@ public Review createReview(Review review) {

return newReview;
}

@Override
public Review getReview(long id) {
// Optional<Review> optionalReview = reviewRepository.findById(id);
// if(optionalReview.isPresent()) {
// Review foundReview = optionalReview.get();
// return foundReview;
// }
// throw new ReviewNotFoundException(id);
// return reviewRepository.findById(id).orElseThrow(() -> new
// ReviewNotFoundException(id));
return reviewRepository.findById(id).get(0);
}

@Override
public ArrayList<Review> getAllReviews() {
List<Review> allReviews = reviewRepository.findAll();
return (ArrayList<Review>) allReviews;
}

@Override
public Review updateReview(long id, Review review) {
// Retrieve the review from the database.
// Review reviewToUpdate = reviewRepository.findById(id).orElseThrow(() -> new
// ReviewNotFoundException(id));
Review reviewToUpdate = reviewRepository.findById(id).get(0);

// Update the review retrieved from the database.
reviewToUpdate.setCategory(review.getCategory());
reviewToUpdate.setReviewContent(review.getReviewContent());
reviewToUpdate.setRating(review.getRating());
reviewToUpdate.setCustomerId(review.getCustomerId());
reviewToUpdate.setProductId(review.getProductId());

// Save the updated review back to the database.
return reviewRepository.save(reviewToUpdate);
}

@Override
public void deleteReview(long id) {
reviewRepository.deleteById(id);
}

@Override
public ArrayList<Review> searchCustomerReviews(long customerId) {
List<Review> foundReviews = reviewRepository.findByCustomerId(customerId);
return (ArrayList<Review>) foundReviews;
}

@Override
public ArrayList<Review> searchProductReviews(long productId) {
List<Review> foundReviews = reviewRepository.findByProductId(productId);
return (ArrayList<Review>) foundReviews;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package sg.com.smartinventory.services;

import sg.com.smartinventory.entities.Customer;
// import sg.com.smartinventory.entities.Review;

public interface CustomerService {
Customer createCustomer(Customer customer);

// Review addReviewToCustomer(long customerId, long productId, Review review);
}
Loading