diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/FridgeController.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/FridgeController.java index 6e6ce1e9aaa065dc0e066b664933686eb301bb9d..9053405f2ca4b5722ddfeb6e36885138023aac7f 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/FridgeController.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/FridgeController.java @@ -8,6 +8,8 @@ import ntnu.idatt2016.v233.SmartMat.service.group.FridgeService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.sql.Date; + /** * Controller for fridges API, providing endpoints for fridge management * @@ -64,6 +66,7 @@ public class FridgeController { /** * Removes a product from the fridge of a group + * todo: remove the date parameter when the frontend is done * * @param groupId the id of the group * group must exist @@ -80,7 +83,7 @@ public class FridgeController { } try { - if (fridgeService.removeProductFromFridge(groupId, productId)) { + if (fridgeService.removeProductFromFridge(groupId, productId, Date.valueOf("2023-04-24"))) { return ResponseEntity.ok("Success"); } return ResponseEntity.badRequest().body("Product not found in the fridge"); diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/fridgeProduct/FridgeProductAsso.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/fridgeProduct/FridgeProductAsso.java new file mode 100644 index 0000000000000000000000000000000000000000..55dce18f0f505a93a2f85c2ff3f42517059777cb --- /dev/null +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/fridgeProduct/FridgeProductAsso.java @@ -0,0 +1,37 @@ +package ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import ntnu.idatt2016.v233.SmartMat.entity.group.Fridge; +import ntnu.idatt2016.v233.SmartMat.entity.product.Product; + +import java.sql.Date; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity(name = "fridge_product") +@Builder +@IdClass(FridgeProductId.class) +public class FridgeProductAsso { + @Id + @ManyToOne + @MapsId("fridge_id") + @JoinColumn(name = "fridge_id") + private Fridge fridgeId; + + @Id + @ManyToOne + @MapsId("ean") + @JoinColumn(name = "ean") + private Product ean; + + @Id + @MapsId("purchase_date") + @Column(name = "purchase_date") + private Date purchaseDate; + +} diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/fridgeProduct/FridgeProductId.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/fridgeProduct/FridgeProductId.java new file mode 100644 index 0000000000000000000000000000000000000000..932babae66e437de1ae5dd1b9ee432065863bd9b --- /dev/null +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/fridgeProduct/FridgeProductId.java @@ -0,0 +1,28 @@ +package ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.sql.Date; + +/** + * This class represents a fridge product association id + * @author Birk + * @version 1.0 + * @since 25.04.2023 + */ +@EqualsAndHashCode +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FridgeProductId implements Serializable { + private long fridgeId; + + private long ean; + + private Date purchaseDate; +} diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/group/Fridge.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/group/Fridge.java index 056767ad0f14dbdc5d49ddfd2ff68efe95804a80..869f51b495f090c9234aa9661e9cce7083a42e61 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/group/Fridge.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/group/Fridge.java @@ -1,5 +1,6 @@ package ntnu.idatt2016.v233.SmartMat.entity.group; +import java.util.ArrayList; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -9,14 +10,14 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import ntnu.idatt2016.v233.SmartMat.entity.product.Product; +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductAsso; /** * Fridge is an entity class representing a fridge in the system. * - * @author Anders - * @version 1.1.002 - * @since 15.04.2023 + * @author Anders & Birk + * @version 1.2 + * @since 25.04.2023 */ @NoArgsConstructor @@ -33,10 +34,21 @@ public class Fridge{ @Column(name = "group_id") long groupId; - @ManyToMany - @JoinTable(name = "fridge_product", - joinColumns = @JoinColumn(name = "fridge_id"), - inverseJoinColumns = @JoinColumn(name = "ean")) - @JsonIgnoreProperties({"allergies", "fridges"}) - List<Product> products; + @OneToMany + @JoinColumn(name = "ean") + @JsonIgnoreProperties("fridge") + List<FridgeProductAsso> products; + + + /** + * Adds a product to the fridge + * @param product the product to add to the fridge + */ + public void addProduct(FridgeProductAsso product){ + if(products == null){ + products = new ArrayList<>(); + } + + products.add(product); + } } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/product/Product.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/product/Product.java index 3030ef93b53a973e98def00b4e458fef9896eef8..7c2f1bc6613d46d92c7da35fa185791267a6005d 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/product/Product.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/entity/product/Product.java @@ -8,7 +8,9 @@ import lombok.Data; import lombok.NoArgsConstructor; import ntnu.idatt2016.v233.SmartMat.entity.group.Fridge; import ntnu.idatt2016.v233.SmartMat.entity.Recipe; +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductAsso; +import java.util.ArrayList; import java.util.List; /** @@ -61,12 +63,24 @@ public class Product{ inverseJoinColumns = @JoinColumn(name = "allergy_name")) List<Allergy> allergies; - @ManyToMany(mappedBy = "products") + @OneToMany + @JoinColumn(name = "ean") @JsonIgnoreProperties({"products"}) - List<Fridge> fridges; + List<FridgeProductAsso> fridges; @ManyToMany(mappedBy = "products") @JsonIgnoreProperties({"products"}) List<Recipe> recipes; + /** + * Adds a fridge to the product + * @param fridge the fridge product association to add to the product + */ + public void addFridge(FridgeProductAsso fridge){ + if(fridges == null){ + fridges = new ArrayList<>(); + } + + fridges.add(fridge); + } } \ No newline at end of file diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/FridgeProductAssoRepository.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/FridgeProductAssoRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..4402cc48bb80af0597a523e6870dab2815f2ad02 --- /dev/null +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/FridgeProductAssoRepository.java @@ -0,0 +1,14 @@ +package ntnu.idatt2016.v233.SmartMat.repository.group; + +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductAsso; +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductId; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * FridgeProductAssoRepository is a repository class for fridge product associations + * @author Birk + * @version 1.0 + * @since 25.04.2023 + */ +public interface FridgeProductAssoRepository extends JpaRepository<FridgeProductAsso, FridgeProductId> { +} diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeProductAssoService.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeProductAssoService.java new file mode 100644 index 0000000000000000000000000000000000000000..6dccc0791a15e71b29e22999fd7db1b9260ec0be --- /dev/null +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeProductAssoService.java @@ -0,0 +1,63 @@ +package ntnu.idatt2016.v233.SmartMat.service.group; + +import lombok.AllArgsConstructor; +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductAsso; +import ntnu.idatt2016.v233.SmartMat.entity.group.Fridge; +import ntnu.idatt2016.v233.SmartMat.entity.product.Product; +import ntnu.idatt2016.v233.SmartMat.repository.ProductRepository; +import ntnu.idatt2016.v233.SmartMat.repository.group.FridgeProductAssoRepository; +import ntnu.idatt2016.v233.SmartMat.repository.group.FridgeRepository; +import ntnu.idatt2016.v233.SmartMat.service.product.ProductService; +import org.springframework.stereotype.Service; + +import java.sql.Date; + +@Service +@AllArgsConstructor +public class FridgeProductAssoService { + + FridgeProductAssoRepository fridgeProductAssoRepository; + + FridgeRepository fridgeRepository; + + ProductRepository productRepository; + + /** + * Creates a fridge product association + * the FridgeProductAssosiation object needs to be added to the fridge and product + * @param fridge the fridge to add the product to + * @param product the product to add to the fridge + * @param purchaseDate the date the product was purchased + * @return the fridge product association + */ + public FridgeProductAsso createFridgeProductAsso(Fridge fridge, Product product, Date purchaseDate) { + FridgeProductAsso temp = new FridgeProductAsso(); + temp.setFridgeId(fridge); + temp.setEan(product); + temp.setPurchaseDate(purchaseDate); + fridgeProductAssoRepository.save(temp); + + fridge.addProduct(temp); + product.addFridge(temp); + + fridgeRepository.save(fridge); + + productRepository.save(product); + + return temp; + } + + /** + * Deletes a fridge product association + * @param fridgeProductAsso the fridge product association to delete + */ + public void deleteFridgeProductAsso(FridgeProductAsso fridgeProductAsso) { + fridgeProductAsso.getFridgeId().getProducts().remove(fridgeProductAsso); + fridgeProductAsso.getEan().getFridges().remove(fridgeProductAsso); + fridgeProductAssoRepository.delete(fridgeProductAsso); + + fridgeRepository.save(fridgeProductAsso.getFridgeId()); + + productRepository.save(fridgeProductAsso.getEan()); + } +} diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeService.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeService.java index c36c80847d01bace953ebdacab1494ae1a1db874..8650f11264f6dc6a51a2bc56bc82018ef823df51 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeService.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeService.java @@ -1,12 +1,15 @@ package ntnu.idatt2016.v233.SmartMat.service.group; import lombok.AllArgsConstructor; +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductAsso; import ntnu.idatt2016.v233.SmartMat.entity.group.Fridge; import ntnu.idatt2016.v233.SmartMat.repository.group.FridgeRepository; import ntnu.idatt2016.v233.SmartMat.entity.product.Product; import ntnu.idatt2016.v233.SmartMat.service.product.ProductService; import org.springframework.stereotype.Service; +import java.sql.Date; +import java.time.LocalDate; import java.util.Optional; /** @@ -23,6 +26,8 @@ public class FridgeService { private final FridgeRepository fridgeRepository; private final ProductService productService; + private final FridgeProductAssoService fridgeProductAssoService; + /** * Gets the fridge of a group * @@ -47,11 +52,11 @@ public class FridgeService { if (product.isPresent()) { Product productToAdd = product.get(); - if (fridge.getProducts().contains(productToAdd)) { + FridgeProductAsso temp = new FridgeProductAsso(fridge, productToAdd, new Date(LocalDate.now().toEpochDay())); + if (fridge.getProducts().contains(temp)) { return false; } - fridge.getProducts().add(productToAdd); - fridgeRepository.save(fridge); + fridgeProductAssoService.createFridgeProductAsso(fridge, productToAdd, new Date(LocalDate.now().toEpochDay())); return true; } else { return false; @@ -66,20 +71,34 @@ public class FridgeService { * @param ean the ean of the product * @return true if the product was removed */ - public boolean removeProductFromFridge(long groupId, long ean) { + public boolean removeProductFromFridge(long groupId, long ean, Date purchaseDate) { Optional<Product> product = productService.getProductById(ean); Fridge fridge = fridgeRepository.findByGroupId(groupId).orElseThrow(() -> new IllegalArgumentException("Fridge does not exist")); + + if (product.isPresent()) { Product productToRemove = product.get(); - if (!fridge.getProducts().contains(productToRemove)) { + if (!fridge.getProducts().contains( + new FridgeProductAsso(fridge, productToRemove, purchaseDate))) { return false; } - fridge.getProducts().remove(productToRemove); - fridgeRepository.save(fridge); + fridgeProductAssoService.deleteFridgeProductAsso(new FridgeProductAsso(fridge, + productToRemove, purchaseDate)); + return true; } else { return false; } } + + /** + * Updates a fridge + * @param fridge the fridge to update + */ + public void updateFridge(Fridge fridge) { + if (fridgeRepository.findById(fridge.getFridgeId()).isEmpty()) + return; + fridgeRepository.save(fridge); + } } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/product/ProductService.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/product/ProductService.java index 13d85862d479f6691e17009beb661867173d444d..e668812f2caab46bcd4e121be3c6cc979bf517a4 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/product/ProductService.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/product/ProductService.java @@ -83,5 +83,16 @@ public class ProductService { return ProductUtil.getVolumeFromProduct(productRepository.findById(id).get()); } + /** + * Updates a product + * @param product The product to update + */ + public void updateProduct(Product product) { + if(productRepository.findById(product.getEan()).isEmpty()) + return; + + productRepository.save(product); + } + } diff --git a/src/test/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeProductAssoServiceTest.java b/src/test/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeProductAssoServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..777986ebd2e879f81e8504902eec232b18ee0ce7 --- /dev/null +++ b/src/test/java/ntnu/idatt2016/v233/SmartMat/service/group/FridgeProductAssoServiceTest.java @@ -0,0 +1,97 @@ +package ntnu.idatt2016.v233.SmartMat.service.group; + +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductAsso; +import ntnu.idatt2016.v233.SmartMat.entity.fridgeProduct.FridgeProductId; +import ntnu.idatt2016.v233.SmartMat.entity.group.Fridge; +import ntnu.idatt2016.v233.SmartMat.entity.product.Product; +import ntnu.idatt2016.v233.SmartMat.repository.group.FridgeProductAssoRepository; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; + +import java.sql.Date; +import java.time.Instant; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +@DataJpaTest +class FridgeProductAssoServiceTest { + + @Autowired + TestEntityManager entityManager; + + @Autowired + FridgeProductAssoRepository fridgeProductAssoRepository; + + private Product product; + + private Fridge fridge; + @BeforeEach + void setUp() { + entityManager.clear(); + + product = Product.builder() + .ean(1234567890123L) + .name("Test") + .description("Test") + .build(); + + fridge = Fridge.builder() + .build(); + + FridgeProductAsso fridgeProductAsso = FridgeProductAsso.builder() + .ean(product) + .fridgeId(fridge) + .purchaseDate(Date.valueOf("2023-04-24")) + .build(); + + product.addFridge(fridgeProductAsso); + fridge.addProduct(fridgeProductAsso); + + entityManager.persist(product); + entityManager.persist(fridge); + entityManager.persist(fridgeProductAsso); + + } + + @Test + void createFridgeProductAsso() { + Optional<FridgeProductAsso> temp = fridgeProductAssoRepository.findById( + new FridgeProductId(fridge.getFridgeId(), product.getEan(), Date.valueOf("2023-04-24"))); + assertTrue(temp.isPresent()); + + assertTrue(entityManager.find(Fridge.class, fridge.getFridgeId()).getProducts().contains(temp.get())); + assertTrue(entityManager.find(Product.class, product.getEan()).getFridges().contains(temp.get())); + + assertEquals(product.getEan(), temp.get().getEan().getEan()); + assertEquals(fridge.getFridgeId(), temp.get().getFridgeId().getFridgeId()); + } + + @Test + void deleteFridgeProductAsso() { + + Optional<FridgeProductAsso> temp = fridgeProductAssoRepository.findById( + new FridgeProductId(fridge.getFridgeId(), product.getEan(), Date.valueOf("2023-04-24"))); + assertTrue(temp.isPresent()); + + fridgeProductAssoRepository.delete(temp.get()); + + assertFalse(fridgeProductAssoRepository.findById( + new FridgeProductId(fridge.getFridgeId(), product.getEan(), Date.valueOf("2023-04-24"))).isPresent()); + + fridge.getProducts().remove(temp.get()); + product.getFridges().remove(temp.get()); + + entityManager.persist(fridge); + entityManager.persist(product); + + assertFalse(entityManager.find(Fridge.class, fridge.getFridgeId()).getProducts().contains(temp.get())); + assertFalse(entityManager.find(Product.class, product.getEan()).getFridges().contains(temp.get())); + } +} \ No newline at end of file