ProductController.java
package ntnu.idatt2016.v233.SmartMat.controller.product;
import lombok.AllArgsConstructor;
import ntnu.idatt2016.v233.SmartMat.dto.request.product.ProductRequest;
import ntnu.idatt2016.v233.SmartMat.entity.product.Allergy;
import ntnu.idatt2016.v233.SmartMat.entity.product.Category;
import ntnu.idatt2016.v233.SmartMat.entity.product.Product;
import ntnu.idatt2016.v233.SmartMat.service.product.AllergyService;
import ntnu.idatt2016.v233.SmartMat.service.product.CategoryService;
import ntnu.idatt2016.v233.SmartMat.service.product.ProductService;
import ntnu.idatt2016.v233.SmartMat.util.CategoryUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* The product controller is responsible for handling requests related to products.
* It uses the product service to handle the requests.
* @version 1.0
* @Author Birk
*/
@RestController
@AllArgsConstructor
@RequestMapping("/api/product")
public class ProductController {
private final ProductService productService;
private final CategoryService categoryService;
private final AllergyService allergyService;
/**
* Creates a product if it does not already exist.
* @param productRequest The product to be registered.
* @return The product that was registered.
*/
@PostMapping("/")
public ResponseEntity<Product> createProduct(@RequestBody ProductRequest productRequest) {
Product product = Product.builder()
.ean(productRequest.ean())
.name(productRequest.name())
.description(productRequest.description())
.url(productRequest.image())
.build();
Category category = categoryService
.getCategoryByName(CategoryUtil.defineCategory(product.getName(),product.getDescription()))
.orElse(null);
if (category == null)
return ResponseEntity.badRequest().build();
product.setCategory(category);
if(productService.getProductById(productRequest.ean()).isPresent())
return ResponseEntity.status(409).build();
Optional<List<String>> volumeUnit = productService.getProductVolume(productRequest.ean());
if(volumeUnit.isPresent()){
if(volumeUnit.get().size() > 1){
product.setUnit(volumeUnit.get().get(1));
product.setAmount(Double.parseDouble(volumeUnit.get().get(0)));
}else {
product.setUnit("STK");
product.setAmount(1.0);
}
}else {
product.setUnit("STK");
product.setAmount(1.0);
}
if(productRequest.allergies() != null){
product.setAllergies(new ArrayList<>());
productRequest.allergies().forEach(allergyName-> {
allergyService.getAllergyByName(allergyName).ifPresent(allergy -> {
product.addAllergy(allergy);
allergy.addProduct(product);
});
});
}
boolean vegan = CategoryUtil.isVegan(product.getName(),product.getDescription());
if(!vegan){
Allergy allergy = allergyService.getAllergyByName("Ikke vegansk").get();
product.addAllergy(allergy);
allergy.addProduct(product);
allergy = allergyService.getAllergyByName("Ikke vegetariansk").get();
product.addAllergy(allergy);
allergy.addProduct(product);
}
boolean vegetarian = CategoryUtil.isVegetarian(product.getName(),product.getDescription(),vegan);
if(!vegetarian){
Allergy allergy = allergyService.getAllergyByName("Ikke vegetariansk").get();
product.addAllergy(allergy);
allergy.addProduct(product);
}
if(!CategoryUtil.isHalal(product.getName(),product.getDescription(),vegetarian)){
Allergy allergy = allergyService.getAllergyByName("Haram").get() ;
product.addAllergy(allergy);
allergy.addProduct(product);
}
productService.saveProduct(product);
return ResponseEntity.ok(product);
}
/**
* Returns a product with the given ean.
* @param ean The ean of the product to be returned.
* @return The product with the given ean.
*/
@GetMapping("ean/{ean}")
public ResponseEntity<Product> getProduct(@PathVariable long ean) {
return productService.getProductById(ean)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
/**
* Returns all products in the database.
* @return A list of all products in the database.
*/
@GetMapping("/")
public ResponseEntity<List<Product>> getAllProducts() {
return ResponseEntity.ok(productService.getAllProducts());
}
/**
* Deletes a product with the given ean.
* @param ean The ean of the product to be deleted.
* @return The product that was deleted.
*/
@DeleteMapping("ean/{ean}")
public ResponseEntity<String> deleteProduct(@PathVariable long ean) {
Optional<Product> product = productService.getProductById(ean);
if(product.isPresent()) {
product.get().getAllergies().stream().filter(allergy -> allergy.getProducts().contains(product.get()))
.forEach(allergy -> allergy.getProducts().remove(product.get()));
product.get().getAllergies().clear();
productService.deleteProductById(product.get().getEan());
return ResponseEntity.ok("Product deleted");
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Product not found");
}
/**
* Updates a product with the given ean.
* @param ean The ean of the product to be updated.
* @param productRequest The product to be updated.
* @return The product that was updated.
*/
@PutMapping("ean/{ean}")
public ResponseEntity<Product> updateProduct(@PathVariable long ean, @RequestBody ProductRequest productRequest) {
Optional<Product> product = productService.getProductById(ean);
if(product.isPresent()) {
product.get().setName(productRequest.name());
product.get().setDescription(productRequest.description());
product.get().setUrl(productRequest.image());
Optional<List<String>> volumeUnit = productService.getProductVolume(productRequest.ean());
if(volumeUnit.isPresent()){
product.get().setUnit(volumeUnit.get().get(1));
product.get().setAmount(Double.parseDouble(volumeUnit.get().get(0)));
}
product.get().getAllergies().stream().filter(allergy -> allergy.getProducts().contains(product.get()))
.forEach(allergy -> allergy.getProducts().remove(product.get()));
product.get().getAllergies().clear();
if(productRequest.allergies() != null){
productRequest.allergies().forEach(allergyName-> {
allergyService.getAllergyByName(allergyName).ifPresent(allergy -> {
product.get().addAllergy(allergy);
allergy.addProduct(product.get());
});
});
}
productService.updateProduct(product.get());
return ResponseEntity.ok(product.get());
}
return ResponseEntity.notFound().build();
}
/**
*
* Retrieve a product by name using a GET request.
*
* @param name The name of the product to retrieve.
* @return A ResponseEntity containing the product if found, or a 404 Not Found response if not found.
*/
@GetMapping("name/{name}")
public ResponseEntity<Product> getProductByName(@PathVariable String name) {
return productService.getProductByName(name)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}