diff --git a/ThunderClient/EndpointTests.json b/ThunderClient/EndpointTests.json index 44d6926..f411345 100644 --- a/ThunderClient/EndpointTests.json +++ b/ThunderClient/EndpointTests.json @@ -1,28 +1,42 @@ { "client": "Thunder Client", "collectionName": "SmartInventory", - "dateExported": "2024-03-25T07:31:20.903Z", + "dateExported": "2024-03-29T15:11:15.315Z", "version": "1.1", "folders": [ { - "_id": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Customer", "containerId": "", - "created": "2024-03-24T04:28:29.833Z", + "created": "2024-03-29T06:19:27.787Z", "sortNum": 10000 + }, + { + "_id": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Product", + "containerId": "", + "created": "2024-03-29T06:21:13.542Z", + "sortNum": 20000 + }, + { + "_id": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Review", + "containerId": "", + "created": "2024-03-29T12:28:07.289Z", + "sortNum": 30000 } ], "requests": [ { - "_id": "9e08f024-8b20-4f4d-b49f-b45d3c5a8bac", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "5ab63b29-5cca-49b0-aaa6-b4096cd063f6", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Create Customer", "url": "http://localhost:9090/customers", "method": "POST", "sortNum": 30000, - "created": "2024-03-24T04:29:24.892Z", - "modified": "2024-03-24T07:13:21.478Z", + "created": "2024-03-29T06:19:27.788Z", + "modified": "2024-03-29T06:19:27.788Z", "headers": [], "params": [], "body": { @@ -33,29 +47,29 @@ "tests": [] }, { - "_id": "77ac4300-178d-4d25-ab90-7132d09ba81f", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "6ad34b41-f511-42f8-9871-b05ce1326906", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Get All Customers", "url": "http://localhost:9090/customers", "method": "GET", "sortNum": 40000, - "created": "2024-03-24T04:29:30.285Z", - "modified": "2024-03-24T04:38:04.649Z", + "created": "2024-03-29T06:19:27.789Z", + "modified": "2024-03-29T06:19:27.789Z", "headers": [], "params": [], "tests": [] }, { - "_id": "171a9cf1-4dcb-443a-bf62-3c32cab85409", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "80fa1d7b-791c-4a7e-ae07-a14fd39056a8", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Get 1 Customer", "url": "http://localhost:9090/customers/{uuid}", "method": "GET", "sortNum": 50000, - "created": "2024-03-24T04:29:42.726Z", - "modified": "2024-03-24T14:49:05.718Z", + "created": "2024-03-29T06:19:27.790Z", + "modified": "2024-03-29T06:19:27.790Z", "headers": [], "params": [ { @@ -67,15 +81,15 @@ "tests": [] }, { - "_id": "7d08442c-1f3c-4482-95d1-9d5cfa782411", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "24ccf681-63a9-43ac-ab16-dab10996caa6", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Search by FirstName", "url": "http://localhost:9090/customers/search?firstName=e", "method": "GET", "sortNum": 55000, - "created": "2024-03-24T08:58:37.049Z", - "modified": "2024-03-24T09:19:19.062Z", + "created": "2024-03-29T06:19:27.793Z", + "modified": "2024-03-29T06:19:27.793Z", "headers": [], "params": [ { @@ -87,15 +101,15 @@ "tests": [] }, { - "_id": "a2f8e24c-f9c2-49f1-8d37-bdb64b4c6286", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "fe9bb8f8-1dfa-4c5a-9461-4176d29429f3", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Update Customer", "url": "http://localhost:9090/customers/{uuid}", "method": "PUT", "sortNum": 60000, - "created": "2024-03-24T04:29:48.079Z", - "modified": "2024-03-24T06:30:25.441Z", + "created": "2024-03-29T06:19:27.791Z", + "modified": "2024-03-29T06:19:27.791Z", "headers": [], "params": [ { @@ -112,15 +126,15 @@ "tests": [] }, { - "_id": "40e4584b-eb1a-43c6-8eb2-8cf2f13beb4a", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "999623d2-4d6f-4e4e-8a38-08e87cf93898", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Delete Customer", "url": "http://localhost:9090/customers/{id}", "method": "DELETE", "sortNum": 70000, - "created": "2024-03-24T04:29:54.857Z", - "modified": "2024-03-24T06:30:32.997Z", + "created": "2024-03-29T06:19:27.792Z", + "modified": "2024-03-29T06:19:27.792Z", "headers": [], "params": [ { @@ -132,29 +146,226 @@ "tests": [] }, { - "_id": "460ee27b-cfe3-448e-ab60-8f402c8acd0b", - "colId": "5c57004c-dd7a-4942-ab04-3da3fb363ce1", - "containerId": "f5054f57-4880-45fa-b08a-f4d9b5359c2c", + "_id": "92d5c718-598b-4f66-b30e-459e1470f723", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Add Review to Customer", - "url": "http://localhost:9090/customers/{id}/reviews", + "url": "http://localhost:9090/customers/{id}/products/{productId}/reviews", "method": "POST", "sortNum": 80000, - "created": "2024-03-24T14:43:48.836Z", - "modified": "2024-03-24T14:47:53.708Z", + "created": "2024-03-29T06:19:27.794Z", + "modified": "2024-03-29T15:08:54.672Z", "headers": [], "params": [ { "name": "id", "value": "1", "isPath": true + }, + { + "name": "productId", + "value": "5", + "isPath": true + } + ], + "body": { + "type": "json", + "raw": "{\n \"category\": \"Books\",\n \"reviewContent\": \"Expected more from the ending, felt rushed.\",\n \"rating\": 4\n}", + "form": [] + }, + "tests": [] + }, + { + "_id": "384b3198-6b05-46e8-b1d4-f417dabcd3cf", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Create Product", + "url": "http://localhost:9090/products", + "method": "POST", + "sortNum": 90000, + "created": "2024-03-29T06:21:49.579Z", + "modified": "2024-03-29T06:27:27.003Z", + "headers": [], + "params": [], + "body": { + "type": "json", + "raw": "{\n \"category\": \"Electronics\",\n \"name\": \"iPhone 15\",\n \"description\": \"Latest High-end smartphone\",\n \"price\": 1999.99,\n \"stockQuantity\": 40\n}", + "form": [] + }, + "tests": [] + }, + { + "_id": "5f776c4e-cd3b-4aae-a55d-d9e3df5f7225", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Get All Products", + "url": "http://localhost:9090/products", + "method": "GET", + "sortNum": 100000, + "created": "2024-03-29T06:27:49.406Z", + "modified": "2024-03-29T06:30:48.289Z", + "headers": [], + "params": [], + "tests": [] + }, + { + "_id": "2540b4c8-bce7-44d1-8a4e-b020e48cf099", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Get All Reviews", + "url": "http://localhost:9090/reviews", + "method": "GET", + "sortNum": 100000, + "created": "2024-03-29T12:28:07.290Z", + "modified": "2024-03-29T12:31:37.627Z", + "headers": [], + "params": [], + "tests": [] + }, + { + "_id": "55a70043-6bf7-451d-b62b-8ac0a1b825f6", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Get 1 Product", + "url": "http://localhost:9090/products/{id}", + "method": "GET", + "sortNum": 110000, + "created": "2024-03-29T06:27:57.526Z", + "modified": "2024-03-29T09:29:04.154Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "6", + "isPath": true + } + ], + "tests": [] + }, + { + "_id": "20641995-f278-4f9a-9617-e551ed4b932d", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Get 1 Review", + "url": "http://localhost:9090/reviews/{id}", + "method": "GET", + "sortNum": 110000, + "created": "2024-03-29T12:28:07.291Z", + "modified": "2024-03-29T14:09:12.966Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "2", + "isPath": true + } + ], + "tests": [] + }, + { + "_id": "24969b8e-21da-4985-ab11-120cc26e3949", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Search by name", + "url": "http://localhost:9090/products/search?name=iPhone 15", + "method": "GET", + "sortNum": 120000, + "created": "2024-03-29T06:28:04.237Z", + "modified": "2024-03-29T06:32:42.915Z", + "headers": [], + "params": [ + { + "name": "name", + "value": "iPhone 15", + "isPath": false + } + ], + "tests": [] + }, + { + "_id": "3890c062-8bf4-40a8-b938-a96cff06d136", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Search by Category", + "url": "http://localhost:9090/products/search/category?category=Elec", + "method": "GET", + "sortNum": 125000, + "created": "2024-03-29T06:28:58.671Z", + "modified": "2024-03-29T06:36:21.520Z", + "headers": [], + "params": [ + { + "name": "category", + "value": "Elec", + "isPath": false + } + ], + "tests": [] + }, + { + "_id": "284be03e-7cea-4fb1-b181-593b29ebf95d", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Update Product", + "url": "http://localhost:9090/products/{id}", + "method": "PUT", + "sortNum": 130000, + "created": "2024-03-29T06:28:09.610Z", + "modified": "2024-03-29T09:29:21.073Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "6", + "isPath": true } ], "body": { "type": "json", - "raw": "{\n \"category\": \"Books\",\n \"reviewContent\": \"Expected more from the ending, felt rushed.\",\n \"rating\": 3 ,\n \"productId\": 1 \n}", + "raw": "{\n \"category\": \"Electronics\",\n \"name\": \"iPhone 15\",\n \"description\": \"Latest High-end smartphone\",\n \"price\": 2499.99,\n \"stockQuantity\": 40\n}", "form": [] }, "tests": [] + }, + { + "_id": "6eccdb31-ed53-45bf-8ced-a548d706cd7b", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "b5e69375-1661-4eb4-ba9c-9e01213e091c", + "name": "Delete Product", + "url": "http://localhost:9090/products/{id}", + "method": "DELETE", + "sortNum": 140000, + "created": "2024-03-29T06:28:13.074Z", + "modified": "2024-03-29T06:39:17.903Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "6", + "isPath": true + } + ], + "tests": [] + }, + { + "_id": "fb7039d9-56e5-4883-995c-d06a7eea82b0", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Delete Product", + "url": "http://localhost:9090/reviews/{id}", + "method": "DELETE", + "sortNum": 140000, + "created": "2024-03-29T12:28:07.295Z", + "modified": "2024-03-29T12:38:39.979Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "9", + "isPath": true + } + ], + "tests": [] } ] } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/controllers/CustomerController.java b/src/main/java/sg/com/smartinventory/controllers/CustomerController.java index 3c0735c..5b953bf 100644 --- a/src/main/java/sg/com/smartinventory/controllers/CustomerController.java +++ b/src/main/java/sg/com/smartinventory/controllers/CustomerController.java @@ -28,71 +28,72 @@ @RestController @RequestMapping("/customers") public class CustomerController { - private CustomerService customerService; - - // @Autowired - public CustomerController(CustomerService customerService) { - this.customerService = customerService; - } - - // CREATE. - @PostMapping("") - public ResponseEntity createCustomer(@Valid @RequestBody Customer customer) { - // if(bindingResult.hasErrors()) { - // return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - // } - - Customer newCustomer = customerService.createCustomer(customer); - return new ResponseEntity<>(newCustomer, HttpStatus.CREATED); - } - - @PostMapping("/{id}/reviews") - public ResponseEntity addReviewToCustomer(@PathVariable long id, @RequestBody Review review) { - // TODO: process POST request - Review newReview = customerService.addReviewToCustomer(id, review); - return new ResponseEntity<>(newReview, HttpStatus.OK); - } - - // READ (all) - @GetMapping("") - public ResponseEntity> getAllCustomers() { - ArrayList allCustomers = customerService.getAllCustomers(); - return new ResponseEntity<>(allCustomers, HttpStatus.OK); - } - - // READ (id) - @GetMapping("/{id}") - public ResponseEntity getCustomer(@PathVariable long id) { - Customer foundCustomer = customerService.getCustomer(id); - return new ResponseEntity<>(foundCustomer, HttpStatus.OK); - } - - // READ (by name CONTAINS) - @GetMapping("/search") - public ResponseEntity> searchCustomer(@RequestParam String firstName) { - ArrayList customers = customerService.searchCustomer(firstName); - return new ResponseEntity<>(customers, HttpStatus.OK); - } - - // UPDATE - @PutMapping("/{id}") - public ResponseEntity updateCustomer(@PathVariable long id, @RequestBody Customer customer) { - Customer updatedCustomer = customerService.updateCustomer(id, customer); - return new ResponseEntity<>(updatedCustomer, HttpStatus.OK); - } - - // DELETE - @DeleteMapping("/{id}") - public ResponseEntity deleteCustomer(@PathVariable long id) { - customerService.deleteCustomer(id); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - // // Nested route - Add review to customer. - // @PostMapping("/{id}/reviews") - // public ResponseEntity addReviewToCustomer(@PathVariable Long id, - // @Valid @RequestBody Review review) { - // Review newReview = customerService.addReviewToCustomer(id, review); - // return new ResponseEntity<>(newReview, HttpStatus.CREATED); + private CustomerService customerService; + + // @Autowired + public CustomerController(CustomerService customerService) { + this.customerService = customerService; + } + + // CREATE. + @PostMapping("") + public ResponseEntity createCustomer(@Valid @RequestBody Customer customer) { + // if(bindingResult.hasErrors()) { + // return new ResponseEntity<>(HttpStatus.BAD_REQUEST); // } + + Customer newCustomer = customerService.createCustomer(customer); + return new ResponseEntity<>(newCustomer, HttpStatus.CREATED); + } + + @PostMapping("/{id}/products/{productId}/reviews") + public ResponseEntity addReviewToCustomer(@PathVariable long id, @PathVariable long productId, + @RequestBody Review review) { + // TODO: process POST request + Review newReview = customerService.addReviewToCustomer(id, productId, review); + return new ResponseEntity<>(newReview, HttpStatus.OK); + } + + // READ (all) + @GetMapping("") + public ResponseEntity> getAllCustomers() { + ArrayList allCustomers = customerService.getAllCustomers(); + return new ResponseEntity<>(allCustomers, HttpStatus.OK); + } + + // READ (id) + @GetMapping("/{id}") + public ResponseEntity getCustomer(@PathVariable long id) { + Customer foundCustomer = customerService.getCustomer(id); + return new ResponseEntity<>(foundCustomer, HttpStatus.OK); + } + + // READ (by name CONTAINS) + @GetMapping("/search") + public ResponseEntity> searchCustomer(@RequestParam String firstName) { + ArrayList customers = customerService.searchCustomer(firstName); + return new ResponseEntity<>(customers, HttpStatus.OK); + } + + // UPDATE + @PutMapping("/{id}") + public ResponseEntity updateCustomer(@PathVariable long id, @RequestBody Customer customer) { + Customer updatedCustomer = customerService.updateCustomer(id, customer); + return new ResponseEntity<>(updatedCustomer, HttpStatus.OK); + } + + // DELETE + @DeleteMapping("/{id}") + public ResponseEntity deleteCustomer(@PathVariable long id) { + customerService.deleteCustomer(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + // // Nested route - Add review to customer. + // @PostMapping("/{id}/reviews") + // public ResponseEntity addReviewToCustomer(@PathVariable Long id, + // @Valid @RequestBody Review review) { + // Review newReview = customerService.addReviewToCustomer(id, review); + // return new ResponseEntity<>(newReview, HttpStatus.CREATED); + // } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/controllers/ProductController.java b/src/main/java/sg/com/smartinventory/controllers/ProductController.java index 07f49a0..d43b40e 100644 --- a/src/main/java/sg/com/smartinventory/controllers/ProductController.java +++ b/src/main/java/sg/com/smartinventory/controllers/ProductController.java @@ -1,10 +1,17 @@ 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import jakarta.validation.Valid; @@ -14,21 +21,68 @@ @RestController @RequestMapping("/products") public class ProductController { - private ProductService productService; - - // @Autowired - public ProductController(ProductService productService) { - this.productService = productService; - } - - // CREATE. - @PostMapping("") - public ResponseEntity createProduct(@Valid @RequestBody Product product) { - // if(bindingResult.hasErrors()) { - // return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - // } - - Product newProduct = productService.createProduct(product); - return new ResponseEntity<>(newProduct, HttpStatus.CREATED); - } + private ProductService productService; + + // @Autowired + public ProductController(ProductService productService) { + this.productService = productService; + } + + // CREATE. + @PostMapping("") + public ResponseEntity createProduct(@Valid @RequestBody Product product) { + // if(bindingResult.hasErrors()) { + // return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + // } + + Product newProduct = productService.createProduct(product); + return new ResponseEntity<>(newProduct, HttpStatus.CREATED); + } + + // Get All + @GetMapping({ "", "/" }) + public ResponseEntity> getAllProducts() { + ArrayList allProducts = productService.getAllProducts(); + return new ResponseEntity<>(allProducts, HttpStatus.OK); + } + + // READ (id) + @GetMapping("/{id}") + public ResponseEntity getProduct(@PathVariable long id) { + Product foundProduct = productService.getProduct(id); + return new ResponseEntity<>(foundProduct, HttpStatus.OK); + } + + // READ (search by name) + @GetMapping("/search") + public ResponseEntity> searchProduct(@RequestParam String name) { + ArrayList products = productService.searchProduct(name); + return new ResponseEntity<>(products, HttpStatus.OK); + } + + // READ (search by category) + @GetMapping("/search/category") + public ResponseEntity> searchCategory(@RequestParam String category) { + ArrayList foundCategory = productService.searchProductCat(category); + return new ResponseEntity<>(foundCategory, HttpStatus.OK); + } + + // UPDATE + @PutMapping("/{id}") + public ResponseEntity updateProduct(@PathVariable Long id, @RequestBody Product product) { + // try { + Product updateProduct = productService.updateProduct(id, product); + return new ResponseEntity<>(updateProduct, HttpStatus.OK); + // } catch (ProductNotFoundException ex) { + // return new ResponseEntity<>(HttpStatus.NOT_FOUND); + // } -> Not needed already throw error in serviceImpls + } + + // Delete - refactor try catch block by adding throw in ProductServiceImpl + @DeleteMapping("/{id}") + public ResponseEntity deleteProduct(@PathVariable long id) { + productService.deleteProduct(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/entities/Customer.java b/src/main/java/sg/com/smartinventory/entities/Customer.java index f10b601..fa50cae 100644 --- a/src/main/java/sg/com/smartinventory/entities/Customer.java +++ b/src/main/java/sg/com/smartinventory/entities/Customer.java @@ -1,5 +1,6 @@ package sg.com.smartinventory.entities; +import java.util.ArrayList; import java.util.List; import jakarta.persistence.CascadeType; @@ -12,7 +13,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; - +import jakarta.persistence.Transient; import jakarta.validation.constraints.Digits; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; @@ -61,9 +62,25 @@ public class Customer { private String email; @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL) - private List reviews; + @Transient + private List reviewedProducts; + + public List getReviewedProducts() { + if (this.reviews == null) { + return new ArrayList<>(); // return empty list if no reviews + } + + if (reviewedProducts == null) { + reviewedProducts = new ArrayList<>(); + for (Review review : this.reviews) { + reviewedProducts.add(review.getProduct()); + } + } + return reviewedProducts; + } + public Customer() { } diff --git a/src/main/java/sg/com/smartinventory/entities/Product.java b/src/main/java/sg/com/smartinventory/entities/Product.java index fbcde3c..e61c605 100644 --- a/src/main/java/sg/com/smartinventory/entities/Product.java +++ b/src/main/java/sg/com/smartinventory/entities/Product.java @@ -1,18 +1,14 @@ 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; import lombok.Builder; import lombok.Getter; @@ -59,6 +55,9 @@ public class Product { // @JoinColumn(name = "product_id", referencedColumnName = "id") // private List reviews; + // @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) + // private List reviews; + public Product() { } @@ -74,4 +73,5 @@ public Product(String category, String name, String description, double price, i } // @ManyToOne Customer -> Many Products can be linked to 1 Customer + } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/entities/Review.java b/src/main/java/sg/com/smartinventory/entities/Review.java index ab871d5..c41fe53 100644 --- a/src/main/java/sg/com/smartinventory/entities/Review.java +++ b/src/main/java/sg/com/smartinventory/entities/Review.java @@ -3,6 +3,7 @@ import org.springframework.stereotype.Component; import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -44,9 +45,9 @@ public class Review { @Column(name = "rating") private int rating; - // @Min(value = 1, message = "Product ID should start from 1. ") - @Column(name = "product_id") - private long productId; // FK. PostgreSQL bigserial data type. + // // @Min(value = 1, message = "Product ID should start from 1. ") + // @Column(name = "product_id") + // private long productId; // FK. PostgreSQL bigserial data type. // @ManyToOne Customer -> Many Reviews can be linked to 1 Customer // @Min(value = 1, message = "Customer ID should start from 1. ") @@ -56,7 +57,11 @@ public class Review { private Customer customer; // @ManyToOne Product -> Many Reviews can be linked to 1 Product - // TODO + + // @JsonBackReference + @ManyToOne(optional = false) + @JoinColumn(name = "product_id", referencedColumnName = "id") + private Product product; public Review() { } @@ -69,7 +74,7 @@ public Review(String category, String reviewContent, int rating, long customerId this.reviewContent = reviewContent; this.rating = rating; // this.customerId = customerId; - this.productId = productId; + // this.productId = productId; } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/repositories/ProductRepository.java b/src/main/java/sg/com/smartinventory/repositories/ProductRepository.java index ce18b85..a83eb07 100644 --- a/src/main/java/sg/com/smartinventory/repositories/ProductRepository.java +++ b/src/main/java/sg/com/smartinventory/repositories/ProductRepository.java @@ -10,21 +10,21 @@ // 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 { - // Custom query to find all products with a certain ID. - // List findById(long id); + // Custom query to find all products with a certain ID. + // List findById(long id); - // Custom query to find all products with a certain category. - List findByCategory(String category); + // Custom query to find all products with a certain category. + List findByCategoryContaining(String category); - // Custom query to find all products with a certain name. - List findByName(String name); + // Custom query to find all products with a certain name. + List findByName(String name); - // Custom query to find all products with a certain description. - List findByDescription(String description); + // Custom query to find all products with a certain description. + List findByDescription(String description); - // Custom query to find all products with a certain price. - List findByPrice(double price); + // Custom query to find all products with a certain price. + List findByPrice(double price); - // Custom query to find all products with a certain stock quantity. - List findByStockQuantity(int stockQuantity); + // Custom query to find all products with a certain stock quantity. + List findByStockQuantity(int stockQuantity); } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java b/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java index 9e5c903..0532533 100644 --- a/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java +++ b/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java @@ -6,99 +6,107 @@ import org.springframework.stereotype.Service; import sg.com.smartinventory.entities.Customer; +import sg.com.smartinventory.entities.Product; import sg.com.smartinventory.entities.Review; // import sg.com.smartinventory.entities.Review; import sg.com.smartinventory.exceptions.CustomerNotFoundException; +import sg.com.smartinventory.exceptions.ProductNotFoundException; import sg.com.smartinventory.repositories.CustomerRepository; +import sg.com.smartinventory.repositories.ProductRepository; import sg.com.smartinventory.repositories.ReviewRepository; import sg.com.smartinventory.services.CustomerService; @Service public class CustomerServiceImpl implements CustomerService { - private CustomerRepository customerRepository; - private ReviewRepository reviewRepository; - - // @Autowired - public CustomerServiceImpl(CustomerRepository customerRepository, ReviewRepository reviewRepository) { - this.customerRepository = customerRepository; - this.reviewRepository = reviewRepository; - } - - // - - - POST METHODS - @Override - public Customer createCustomer(Customer customer) { - Customer newCustomer = customerRepository.save(customer); - return newCustomer; - } - - public Review addReviewToCustomer(long id, Review review) { - Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); - review.setCustomer(customer); - Review newReview = reviewRepository.save(review); - return newReview; - } - - // - - - GET METHODS - @Override - public Customer getCustomer(Long id) { - return customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); - } - - @Override - public ArrayList getAllCustomers() { - List allCustomers = customerRepository.findAll(); - return (ArrayList) allCustomers; - } - - // searches for first name that contains search term - @Override - public ArrayList searchCustomer(String firstName) { - List customers = customerRepository.findByFirstNameContaining(firstName); - return (ArrayList) customers; - } - - // - - - PUT METHODS - @Override - public Customer updateCustomer(Long id, Customer customer) { - // Retrieve the customer from the database. - Customer customerToUpdate = customerRepository.findById(id) - .orElseThrow(() -> new CustomerNotFoundException(id)); - - // Update the customer retrieved from the database. - customerToUpdate.setFirstName(customer.getFirstName()); - customerToUpdate.setLastName(customer.getLastName()); - customerToUpdate.setCountry(customer.getCountry()); - customerToUpdate.setAddress(customer.getAddress()); - customerToUpdate.setPostalCode(customer.getPostalCode()); - customerToUpdate.setPhoneNumber(customer.getPhoneNumber()); - customerToUpdate.setEmail(customer.getEmail()); - - // Save the updated customer back to the database. - return customerRepository.save(customerToUpdate); - } - - // - - - DELETE METHODS - @Override - public void deleteCustomer(long id) { - // findById method allows deleteCustomer to throw exception if no id of - // such type is avail to be deleted i.e response will be 404 (Expected) instead - // of 204, to tell client that resource not found - customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); - customerRepository.deleteById(id); - } - - // @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); - // } + private ProductRepository productRepository; + private CustomerRepository customerRepository; + private ReviewRepository reviewRepository; + + // @Autowired + public CustomerServiceImpl(CustomerRepository customerRepository, ProductRepository productRepository, + ReviewRepository reviewRepository) { + this.customerRepository = customerRepository; + this.reviewRepository = reviewRepository; + this.productRepository = productRepository; + } + + // - - - POST METHODS + @Override + public Customer createCustomer(Customer customer) { + Customer newCustomer = customerRepository.save(customer); + return newCustomer; + } + + public Review addReviewToCustomer(long id, long productId, Review review) { + Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); + Product product = productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException(productId)); + review.setCustomer(customer); + review.setProduct(product); + Review newReview = reviewRepository.save(review); + return newReview; + } + + // - - - GET METHODS + @Override + public Customer getCustomer(Long id) { + return customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); + } + + @Override + public ArrayList getAllCustomers() { + List allCustomers = customerRepository.findAll(); + return (ArrayList) allCustomers; + } + + // searches for first name that contains search term + @Override + public ArrayList searchCustomer(String firstName) { + List customers = customerRepository.findByFirstNameContaining(firstName); + return (ArrayList) customers; + } + + // - - - PUT METHODS + @Override + public Customer updateCustomer(Long id, Customer customer) { + // Retrieve the customer from the database. + Customer customerToUpdate = customerRepository.findById(id) + .orElseThrow(() -> new CustomerNotFoundException(id)); + + // Update the customer retrieved from the database. + customerToUpdate.setFirstName(customer.getFirstName()); + customerToUpdate.setLastName(customer.getLastName()); + customerToUpdate.setCountry(customer.getCountry()); + customerToUpdate.setAddress(customer.getAddress()); + customerToUpdate.setPostalCode(customer.getPostalCode()); + customerToUpdate.setPhoneNumber(customer.getPhoneNumber()); + customerToUpdate.setEmail(customer.getEmail()); + + // Save the updated customer back to the database. + return customerRepository.save(customerToUpdate); + } + + // - - - DELETE METHODS + @Override + public void deleteCustomer(long id) { + // findById method allows deleteCustomer to throw exception if no id of + // such type is avail to be deleted i.e response will be 404 (Expected) instead + // of 204, to tell client that resource not found + customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); + customerRepository.deleteById(id); + } + + // @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); + // } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/serviceImpls/ProductServiceImpl.java b/src/main/java/sg/com/smartinventory/serviceImpls/ProductServiceImpl.java index c1abeeb..f0ba617 100644 --- a/src/main/java/sg/com/smartinventory/serviceImpls/ProductServiceImpl.java +++ b/src/main/java/sg/com/smartinventory/serviceImpls/ProductServiceImpl.java @@ -12,55 +12,72 @@ @Service public class ProductServiceImpl implements ProductService { - private ProductRepository productRepository; + private ProductRepository productRepository; - // @Autowired - public ProductServiceImpl(ProductRepository productRepository) { - this.productRepository = productRepository; - } + // @Autowired + public ProductServiceImpl(ProductRepository productRepository) { + this.productRepository = productRepository; + } - @Override - public Product createProduct(Product product) { - Product newProduct = productRepository.save(product); + // - - - POST METHODS + @Override + public Product createProduct(Product product) { + Product newProduct = productRepository.save(product); - return newProduct; - } + return newProduct; + } - @Override - public Product getProduct(Long id) { - // Optional optionalProduct = productRepository.findById(id); - // if(optionalProduct.isPresent()) { - // Product foundProduct = optionalProduct.get(); - // return foundProduct; - // } - // throw new ProductNotFoundException(id); - return productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException(id)); - } + // - - - GET METHODS + @Override + public Product getProduct(Long id) { + // Optional optionalProduct = productRepository.findById(id); + // if(optionalProduct.isPresent()) { + // Product foundProduct = optionalProduct.get(); + // return foundProduct; + // } + // throw new ProductNotFoundException(id); + return productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException(id)); + } - @Override - public ArrayList getAllProducts() { - List allProducts = productRepository.findAll(); - return (ArrayList) allProducts; - } + @Override + public ArrayList getAllProducts() { + List allProducts = productRepository.findAll(); + return (ArrayList) allProducts; + } - @Override - public Product updateProduct(Long id, Product product) { - // Retrieve the product from the database. - Product productToUpdate = productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException(id)); + @Override + public ArrayList searchProduct(String name) { + List products = productRepository.findByName(name); + return (ArrayList) products; + } - // Update the product retrieved from the database. - productToUpdate.setCategory(product.getCategory()); - productToUpdate.setName(product.getName()); - productToUpdate.setDescription(product.getDescription()); - productToUpdate.setPrice(product.getPrice()); - productToUpdate.setStockQuantity(product.getStockQuantity()); + @Override + public ArrayList searchProductCat(String category) { + List products = productRepository.findByCategoryContaining(category); + return (ArrayList) products; + } - // Save the updated product back to the database. - return productRepository.save(productToUpdate); - } + // - - - PUT METHODS + @Override + public Product updateProduct(Long id, Product product) { + // Retrieve the product from the database. + Product productToUpdate = productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException(id)); - @Override - public void deleteProduct(long id) { - productRepository.deleteById(id); - } + // Update the product retrieved from the database. + productToUpdate.setCategory(product.getCategory()); + productToUpdate.setName(product.getName()); + productToUpdate.setDescription(product.getDescription()); + productToUpdate.setPrice(product.getPrice()); + productToUpdate.setStockQuantity(product.getStockQuantity()); + + // Save the updated product back to the database. + return productRepository.save(productToUpdate); + } + + // - - - DELETE METHODS + @Override // use long primitive type as args cannot be null + public void deleteProduct(long id) { + productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException(id)); + productRepository.deleteById(id); + } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java b/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java index 6cb1977..cef7e4b 100644 --- a/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java +++ b/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java @@ -14,73 +14,73 @@ @Service public class ReviewServiceImpl implements ReviewService { - private ReviewRepository reviewRepository; - - // @Autowired - public ReviewServiceImpl(ReviewRepository reviewRepository) { - this.reviewRepository = reviewRepository; - } - - // - - - POST - - - - @Override - public Review createReview(Review review) { - Review newReview = reviewRepository.save(review); - - return newReview; - } - - // - - - GET - - - - @Override - public ArrayList searchCustomerReviews(long customerId) { - List foundReviews = reviewRepository.findByCustomerId(customerId); - return (ArrayList) foundReviews; - } - - @Override - public ArrayList searchProductReviews(long productId) { - List foundReviews = reviewRepository.findByProductId(productId); - return (ArrayList) foundReviews; - } - - @Override - public ArrayList getRatings(int id) { - if (reviewRepository.findByRating(id).isEmpty()) { - throw new RatingNotFoundException(id); - } - List reviews = reviewRepository.findByRating(id); - return (ArrayList) reviews; - } - - @Override - public Review getReview(Long id) { - return reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); - } - - @Override - public ArrayList getAllReviews() { - List allReviews = reviewRepository.findAll(); - return (ArrayList) allReviews; - } - - // - - - PUT - - - - @Override - public Review updateReview(Long id, Review review) { - // Retrieve the review from the database. - Review reviewToUpdate = reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); - - // Update the review retrieved from the database. - reviewToUpdate.setCategory(review.getCategory()); - reviewToUpdate.setReviewContent(review.getReviewContent()); - reviewToUpdate.setRating(review.getRating()); - reviewToUpdate.setProductId(review.getProductId()); - - // Save the updated review back to the database. - return reviewRepository.save(reviewToUpdate); - } - - // - - - DELETE - - - - @Override - public void deleteReview(long id) { - reviewRepository.deleteById(id); + private ReviewRepository reviewRepository; + + // @Autowired + public ReviewServiceImpl(ReviewRepository reviewRepository) { + this.reviewRepository = reviewRepository; + } + + // - - - POST - - - + @Override + public Review createReview(Review review) { + Review newReview = reviewRepository.save(review); + + return newReview; + } + + // - - - GET - - - + @Override + public ArrayList searchCustomerReviews(long customerId) { + List foundReviews = reviewRepository.findByCustomerId(customerId); + return (ArrayList) foundReviews; + } + + @Override + public ArrayList searchProductReviews(long productId) { + List foundReviews = reviewRepository.findByProductId(productId); + return (ArrayList) foundReviews; + } + + @Override + public ArrayList getRatings(int id) { + if (reviewRepository.findByRating(id).isEmpty()) { + throw new RatingNotFoundException(id); } + List reviews = reviewRepository.findByRating(id); + return (ArrayList) reviews; + } + + @Override + public Review getReview(Long id) { + return reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); + } + + @Override + public ArrayList getAllReviews() { + List allReviews = reviewRepository.findAll(); + return (ArrayList) allReviews; + } + + // - - - PUT - - - + @Override + public Review updateReview(Long id, Review review) { + // Retrieve the review from the database. + Review reviewToUpdate = reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); + + // Update the review retrieved from the database. + reviewToUpdate.setCategory(review.getCategory()); + reviewToUpdate.setReviewContent(review.getReviewContent()); + reviewToUpdate.setRating(review.getRating()); + reviewToUpdate.setProduct(review.getProduct()); + + // Save the updated review back to the database. + return reviewRepository.save(reviewToUpdate); + } + + // - - - DELETE - - - + @Override + public void deleteReview(long id) { + reviewRepository.deleteById(id); + } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/services/CustomerService.java b/src/main/java/sg/com/smartinventory/services/CustomerService.java index 59bff4a..aa28f52 100644 --- a/src/main/java/sg/com/smartinventory/services/CustomerService.java +++ b/src/main/java/sg/com/smartinventory/services/CustomerService.java @@ -7,19 +7,20 @@ import sg.com.smartinventory.entities.Review; public interface CustomerService { - Customer createCustomer(Customer customer); + Customer createCustomer(Customer customer); - Review addReviewToCustomer(long id, Review review); + // Review addReviewToCustomer(long id, Review review); - Customer getCustomer(Long id); + Customer getCustomer(Long id); - ArrayList searchCustomer(String name); + ArrayList searchCustomer(String name); - ArrayList getAllCustomers(); + ArrayList getAllCustomers(); - Customer updateCustomer(Long id, Customer customer); + Customer updateCustomer(Long id, Customer customer); - void deleteCustomer(long id); + void deleteCustomer(long id); - // Review addReviewToCustomer(long customerId, long productId, Review review); + Review addReviewToCustomer(long id, long productId, Review review); + // Review addReviewToCustomer(long customerId, long productId, Review review); } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/services/ProductService.java b/src/main/java/sg/com/smartinventory/services/ProductService.java index 9db88ab..bdf3df6 100644 --- a/src/main/java/sg/com/smartinventory/services/ProductService.java +++ b/src/main/java/sg/com/smartinventory/services/ProductService.java @@ -5,13 +5,17 @@ import sg.com.smartinventory.entities.Product; public interface ProductService { - Product createProduct(Product product); + Product createProduct(Product product); - Product getProduct(Long id); + Product getProduct(Long id); - ArrayList getAllProducts(); + ArrayList getAllProducts(); - Product updateProduct(Long id, Product product); + ArrayList searchProduct(String name); - void deleteProduct(long id); + ArrayList searchProductCat(String category); + + Product updateProduct(Long id, Product product); + + void deleteProduct(long id); } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/utility/DataLoader.java b/src/main/java/sg/com/smartinventory/utility/DataLoader.java index be49e14..542afcb 100644 --- a/src/main/java/sg/com/smartinventory/utility/DataLoader.java +++ b/src/main/java/sg/com/smartinventory/utility/DataLoader.java @@ -14,127 +14,136 @@ @Component public class DataLoader { - // Inject all repositories. - private CustomerRepository customerRepository; - private ProductRepository productRepository; - private ReviewRepository reviewRepository; - private Review review; - - // @Autowired - public DataLoader(CustomerRepository customerRepository, ProductRepository productRepository, - ReviewRepository reviewRepository, Review review) { - this.customerRepository = customerRepository; - this.productRepository = productRepository; - this.reviewRepository = reviewRepository; - this.review = review; - } - - @PostConstruct - public void loadData() { - // // Clear all data. - // clearTableData(); - - // // Create fake data. - // generateFakeData(); - // } - - // public void clearTableData() { - // Clear all data. - customerRepository.deleteAll(); - productRepository.deleteAll(); - reviewRepository.deleteAll(); - // } - - // <<<<<<< SIS-39 - // = = = CUSTOMER DATA = = = - Customer customer1 = customerRepository - .save(new Customer("John", "Doe", "USA", "123 Main St", 123456, 12345678, - "john.doe@example.com")); - Customer customer2 = customerRepository - .save(new Customer("Alice", "Smith", "Canada", "456 Maple Ave", 543210, 98765432, - "alice.smith@example.com")); - Customer customer3 = customerRepository - .save(new Customer("Michael", "Johnson", "UK", "789 Oak Rd", 567890, 98761234, - "michael.johnson@example.com")); - Customer customer4 = customerRepository - .save(new Customer("Emily", "Brown", "Australia", "321 Elm St", 135790, 45678912, - "emily.brown@example.com")); - Customer customer5 = customerRepository - .save(new Customer("David", "Wilson", "Germany", "654 Pine Rd", 987655, 36985214, - "david.wilson@example.com")); - // ======= - // public void generateFakeData() { - // // Create fake data. - // customerRepository.save(new Customer("John", "Doe", "USA", "123 Main St", - // 123456, 12345678, - // "john.doe@example.com")); - // customerRepository.save(new Customer("Alice", "Smith", "Canada", "456 Maple - // Ave", 543210, 98765432, - // "alice.smith@example.com")); - // customerRepository.save(new Customer("Michael", "Johnson", "UK", "789 Oak - // Rd", 567890, 98761234, - // "michael.johnson@example.com")); - // customerRepository.save(new Customer("Emily", "Brown", "Australia", "321 Elm - // St", 135790, 45678912, - // "emily.brown@example.com")); - // customerRepository.save(new Customer("David", "Wilson", "Germany", "654 Pine - // Rd", 987655, 36985214, - // "david.wilson@example.com")); - // >>>>>>> main - - // = = = REVIEW DATA = = = - // Adding review data (note that the "same" review object is being used in all, - // this is because of Bean injection so its actually diff instances) - Review review = new Review("Books", "Expected more from the ending, felt rushed. ", 3, 1, 1); - review.setCustomer(customer1); - reviewRepository.save(review); - - review = new Review("Electronics", "Fast delivery, product works as expected. ", 4, 1, 2); - review.setCustomer(customer2); - reviewRepository.save(review); - - review = new Review("Home & Kitchen", "Difficult to assemble, but sturdy once done. ", 3, 2, 4); - review.setCustomer(customer3); - reviewRepository.save(review); - - review = new Review("Electronics", "Great smartphone with excellent features. ", 5, 3, 1); - review.setCustomer(customer4); - reviewRepository.save(review); - - review = new Review("Clothing", "The color faded after a few washes. ", 2, 3, 3); - review.setCustomer(customer5); - reviewRepository.save(review); - - review = (new Review("Beauty", "Lovely fragrance, long-lasting. ", 5, 4, 4)); - review.setCustomer(customer1); - reviewRepository.save(review); - - review = (new Review("Home & Kitchen", "Makes delicious coffee, easy to use. ", 4, 4, 3)); - review.setCustomer(customer2); - reviewRepository.save(review); - - review = (new Review("Books", "Intriguing plot, couldn't put it down. ", 5, 5, 5)); - review.setCustomer(customer3); - reviewRepository.save(review); - - review = (new Review("Beauty", "Disappointed with the scent, doesn't last long. ", 2, 5, 5)); - review.setCustomer(customer4); - reviewRepository.save(review); - - // = = = PRODUCT = = = - productRepository.save(new Product("Electronics", "Smartphone", - "High-end smartphone with advanced features. ", 999.99, 100)); - productRepository.save(new Product("Clothing", "Men's T-Shirt", - "Comfortable cotton t-shirt for everyday wear. ", 29.99, 500)); - productRepository.save(new Product("Home & Kitchen", "Coffee Maker", - "Automatic coffee maker with programmable settings. ", 49.99, 50)); - productRepository.save(new Product("Beauty", "Perfume", - "Elegant fragrance with floral and citrus notes. ", 79.99, 200)); - productRepository.save(new Product("Books", "Science Fiction Novel", - "Bestselling sci-fi novel set in a dystopian future. ", 14.99, 300)); - - // = = = NOTE: DATALOADER DONT WORK FOR ENTITIES WITH FK* (cant specify - // customer_id column) = = = - - } + // Inject all repositories. + private CustomerRepository customerRepository; + private ProductRepository productRepository; + private ReviewRepository reviewRepository; + private Review review; + + // @Autowired + public DataLoader(CustomerRepository customerRepository, ProductRepository productRepository, + ReviewRepository reviewRepository, Review review) { + this.customerRepository = customerRepository; + this.productRepository = productRepository; + this.reviewRepository = reviewRepository; + this.review = review; + } + + @PostConstruct + public void loadData() { + // // Clear all data. + // clearTableData(); + + // // Create fake data. + // generateFakeData(); + // } + + // public void clearTableData() { + // Clear all data. + customerRepository.deleteAll(); + productRepository.deleteAll(); + reviewRepository.deleteAll(); + // } + + // <<<<<<< SIS-39 + // = = = CUSTOMER DATA = = = + Customer customer1 = customerRepository + .save(new Customer("John", "Doe", "USA", "123 Main St", 123456, 12345678, + "john.doe@example.com")); + Customer customer2 = customerRepository + .save(new Customer("Alice", "Smith", "Canada", "456 Maple Ave", 543210, 98765432, + "alice.smith@example.com")); + Customer customer3 = customerRepository + .save(new Customer("Michael", "Johnson", "UK", "789 Oak Rd", 567890, 98761234, + "michael.johnson@example.com")); + Customer customer4 = customerRepository + .save(new Customer("Emily", "Brown", "Australia", "321 Elm St", 135790, 45678912, + "emily.brown@example.com")); + Customer customer5 = customerRepository + .save(new Customer("David", "Wilson", "Germany", "654 Pine Rd", 987655, 36985214, + "david.wilson@example.com")); + // ======= + // public void generateFakeData() { + // // Create fake data. + // customerRepository.save(new Customer("John", "Doe", "USA", "123 Main St", + // 123456, 12345678, + // "john.doe@example.com")); + // customerRepository.save(new Customer("Alice", "Smith", "Canada", "456 Maple + // Ave", 543210, 98765432, + // "alice.smith@example.com")); + // customerRepository.save(new Customer("Michael", "Johnson", "UK", "789 Oak + // Rd", 567890, 98761234, + // "michael.johnson@example.com")); + // customerRepository.save(new Customer("Emily", "Brown", "Australia", "321 Elm + // St", 135790, 45678912, + // "emily.brown@example.com")); + // customerRepository.save(new Customer("David", "Wilson", "Germany", "654 Pine + // Rd", 987655, 36985214, + // "david.wilson@example.com")); + // >>>>>>> main + + // = = = PRODUCT = = = + Product product1 = productRepository.save(new Product("Electronics", "Smartphone", + "High-end smartphone with advanced features. ", 999.99, 100)); + Product product2 = productRepository.save(new Product("Clothing", "Men's T-Shirt", + "Comfortable cotton t-shirt for everyday wear. ", 29.99, 500)); + Product product3 = productRepository.save(new Product("Home & Kitchen", "Coffee Maker", + "Automatic coffee maker with programmable settings. ", 49.99, 50)); + Product product4 = productRepository.save(new Product("Beauty", "Perfume", + "Elegant fragrance with floral and citrus notes. ", 79.99, 200)); + Product product5 = productRepository.save(new Product("Books", "Science Fiction Novel", + "Bestselling sci-fi novel set in a dystopian future. ", 14.99, 300)); + + // = = = REVIEW DATA = = = + // Adding review data (note that the "same" review object is being used in all, + // this is because of Bean injection so its actually diff instances) + Review review = new Review("Books", "Expected more from the ending, felt rushed. ", 3, 1, 5); + review.setCustomer(customer1); + review.setProduct(product5); + reviewRepository.save(review); + + review = new Review("Electronics", "Fast delivery, product works as expected. ", 4, 1, 1); + review.setCustomer(customer2); + review.setProduct(product1); + reviewRepository.save(review); + + review = new Review("Home & Kitchen", "Difficult to assemble, but sturdy once done. ", 3, 2, 3); + review.setCustomer(customer3); + review.setProduct(product3); + reviewRepository.save(review); + + review = new Review("Electronics", "Great smartphone with excellent features. ", 5, 3, 1); + review.setCustomer(customer4); + review.setProduct(product1); + reviewRepository.save(review); + + review = new Review("Clothing", "The color faded after a few washes. ", 2, 3, 2); + review.setCustomer(customer5); + review.setProduct(product2); + reviewRepository.save(review); + + review = (new Review("Beauty", "Lovely fragrance, long-lasting. ", 5, 4, 4)); + review.setCustomer(customer1); + review.setProduct(product4); + reviewRepository.save(review); + + review = (new Review("Home & Kitchen", "Makes delicious coffee, easy to use. ", 4, 4, 3)); + review.setCustomer(customer2); + review.setProduct(product3); + reviewRepository.save(review); + + review = (new Review("Books", "Intriguing plot, couldn't put it down. ", 5, 5, 5)); + review.setCustomer(customer3); + review.setProduct(product5); + reviewRepository.save(review); + + review = (new Review("Beauty", "Disappointed with the scent, doesn't last long. ", 2, 5, 4)); + review.setCustomer(customer4); + review.setProduct(product4); + reviewRepository.save(review); + + // = = = NOTE: DATALOADER DONT WORK FOR ENTITIES WITH FK* (cant specify + // customer_id column) = = = + + } } \ No newline at end of file diff --git a/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java b/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java index 6d38c1d..fa6696a 100644 --- a/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java +++ b/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java @@ -28,61 +28,60 @@ @SpringBootTest public class ReviewServiceImplTest { - @Mock - private ReviewRepository reviewRepository; + @Mock + private ReviewRepository reviewRepository; - @InjectMocks - ReviewServiceImpl reviewService; + @InjectMocks + ReviewServiceImpl reviewService; - /// Name this according to your class name. - // The Logback library defines 5 log levels in order of priority: TRACE, DEBUG, - // INFO, WARN, ERROR, with each of these having a corresponding logging method: - // trace(), debug(), info(), warn(), error(). - private static final Logger test_logger = LoggerFactory.getLogger(ReviewServiceImplTest.class); + /// Name this according to your class name. + // The Logback library defines 5 log levels in order of priority: TRACE, DEBUG, + // INFO, WARN, ERROR, with each of these having a corresponding logging method: + // trace(), debug(), info(), warn(), error(). + private static final Logger test_logger = LoggerFactory.getLogger(ReviewServiceImplTest.class); - // Test Setup and Teardown configuration. - @BeforeAll - static void initAll() { + // Test Setup and Teardown configuration. + @BeforeAll + static void initAll() { - } + } - @AfterAll - static void teardownAll() { + @AfterAll + static void teardownAll() { - } + } - @BeforeEach - void init() { + @BeforeEach + void init() { - } + } - @AfterEach - void teardown() { + @AfterEach + void teardown() { - } + } - @Test - public void createReviewTest() { - test_logger.info("Starting test: " + getCurrentMethodName() + ". "); + @Test + public void createReviewTest() { + test_logger.info("Starting test: " + getCurrentMethodName() + ". "); - // 1. SETUP. - // Create a new review. - Review review = Review.builder().category("Electronics") - .reviewContent("Great smartphone with excellent features. ").rating(5) - .productId(2).build(); + // 1. SETUP. + // Create a new review. + Review review = Review.builder().category("Electronics").reviewContent("Great smartphone with excellent features. ") + .rating(5).build(); - // Mock the save method of the review repository. - when((reviewRepository.save(review))).thenReturn(review); + // Mock the save method of the review repository. + when((reviewRepository.save(review))).thenReturn(review); - // 2. EXECUTE. - Review savedReview = reviewService.createReview(review); + // 2. EXECUTE. + Review savedReview = reviewService.createReview(review); - // 3. ASSERT. - assertEquals(review, savedReview, "The saved review should be the same as the new review created. "); + // 3. ASSERT. + assertEquals(review, savedReview, "The saved review should be the same as the new review created. "); - // Verify that the save method of the review repository is called once only. - verify(reviewRepository, times(1)).save(review); + // Verify that the save method of the review repository is called once only. + verify(reviewRepository, times(1)).save(review); - test_logger.info("Ending test: " + getCurrentMethodName() + ". "); - } + test_logger.info("Ending test: " + getCurrentMethodName() + ". "); + } } \ No newline at end of file