From a8938d94dee4755463bee5b1f32abe72bbc8f256 Mon Sep 17 00:00:00 2001
From: "quentin.fasler" <quentin.fasler@etu.hesge.ch>
Date: Fri, 16 Feb 2024 20:17:33 +0100
Subject: [PATCH] add product and purchase

---
 pom.xml                                       |  7 +-
 .../demobdd/controller/ProductController.java | 30 +++++++
 .../controller/PurchaseController.java        | 66 +++++++++++++++
 .../hepia/demobdd/dto/PurchaseRequest.java    | 39 +++++++++
 .../com/hepia/demobdd/entity/Product.java     | 58 ++++++++++++++
 .../com/hepia/demobdd/entity/Purchase.java    | 80 +++++++++++++++++++
 .../java/com/hepia/demobdd/entity/User.java   | 19 ++++-
 .../demobdd/repository/ProductRepository.java |  8 ++
 .../repository/PurchaseRepository.java        |  9 +++
 src/main/resources/application.properties     |  4 +-
 src/main/resources/data.sql                   |  1 +
 .../db/migration/V2_0__Order_table.sql        | 15 ++++
 .../db/migration/V2_1__Initial_data.sql       |  0
 13 files changed, 330 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/com/hepia/demobdd/controller/ProductController.java
 create mode 100644 src/main/java/com/hepia/demobdd/controller/PurchaseController.java
 create mode 100644 src/main/java/com/hepia/demobdd/dto/PurchaseRequest.java
 create mode 100644 src/main/java/com/hepia/demobdd/entity/Product.java
 create mode 100644 src/main/java/com/hepia/demobdd/entity/Purchase.java
 create mode 100644 src/main/java/com/hepia/demobdd/repository/ProductRepository.java
 create mode 100644 src/main/java/com/hepia/demobdd/repository/PurchaseRepository.java
 create mode 100644 src/main/resources/data.sql
 create mode 100644 src/main/resources/db/migration/V2_0__Order_table.sql
 create mode 100644 src/main/resources/db/migration/V2_1__Initial_data.sql

diff --git a/pom.xml b/pom.xml
index b4d3df7..8e6ffc9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,7 +44,12 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>2.16.1</version>
+        </dependency>
+    </dependencies>
 
 	<build>
 		<plugins>
diff --git a/src/main/java/com/hepia/demobdd/controller/ProductController.java b/src/main/java/com/hepia/demobdd/controller/ProductController.java
new file mode 100644
index 0000000..b7408fa
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/controller/ProductController.java
@@ -0,0 +1,30 @@
+package com.hepia.demobdd.controller;
+
+import com.hepia.demobdd.entity.Product;
+import com.hepia.demobdd.repository.ProductRepository;
+import org.springframework.beans.factory.annotation.*;
+import org.springframework.web.bind.annotation.*;
+
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/products")
+public class ProductController {
+
+    @Autowired
+    private ProductRepository productRepository;
+
+    @GetMapping
+    public List<Product> getAllProducts() {
+        return productRepository.findAll();
+    }
+
+    @GetMapping("/{id}")
+    public Product getProductById(@PathVariable Long id) {
+        return productRepository.findById(id).orElse(null);
+    }
+
+
+
+}
diff --git a/src/main/java/com/hepia/demobdd/controller/PurchaseController.java b/src/main/java/com/hepia/demobdd/controller/PurchaseController.java
new file mode 100644
index 0000000..ace3065
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/controller/PurchaseController.java
@@ -0,0 +1,66 @@
+package com.hepia.demobdd.controller;
+
+import com.hepia.demobdd.dto.PurchaseRequest;
+import com.hepia.demobdd.entity.Product;
+import com.hepia.demobdd.entity.Purchase;
+import com.hepia.demobdd.entity.User;
+import com.hepia.demobdd.repository.ProductRepository;
+import com.hepia.demobdd.repository.PurchaseRepository;
+import com.hepia.demobdd.repository.UserRepository;
+import jakarta.transaction.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+@RestController
+@RequestMapping("/purchases")
+public class PurchaseController {
+
+    @Autowired
+    private PurchaseRepository purchaseRepository;
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private ProductRepository productRepository;
+
+    @GetMapping
+    public List<Purchase> getAllPurchases() {
+        return purchaseRepository.findAll();
+    }
+
+    @GetMapping("/{id}")
+    public Purchase getPurchaseById(@PathVariable Long id) {
+        return purchaseRepository.findById(id).orElse(null);
+    }
+
+    @Transactional
+    @PostMapping
+    public ResponseEntity<String> addPurchase(@RequestBody PurchaseRequest purchaseRequest) {
+        User user = userRepository.findById(purchaseRequest.getUserId())
+                .orElseThrow(() -> new IllegalArgumentException("Utilisateur non trouvé"));
+
+        Product product = productRepository.findById(purchaseRequest.getProductId())
+                .orElseThrow(() -> new IllegalArgumentException("Produit non trouvé"));
+
+        if (product.getStock() < purchaseRequest.getQuantity()) {
+            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Stock insuffisant pour le produit.");
+        }
+
+        if (purchaseRequest.getQuantity() <= 0) {
+            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("La quantité doit être supérieure à 0.");
+        }
+
+        Purchase purchase = new Purchase(user, product, purchaseRequest.getQuantity());
+        product.setStock(product.getStock() - purchaseRequest.getQuantity());
+
+        purchaseRepository.save(purchase);
+        productRepository.save(product);
+
+        return ResponseEntity.status(HttpStatus.CREATED).body("Commande ajoutée avec succès.");
+    }
+
+}
diff --git a/src/main/java/com/hepia/demobdd/dto/PurchaseRequest.java b/src/main/java/com/hepia/demobdd/dto/PurchaseRequest.java
new file mode 100644
index 0000000..aaae36c
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/dto/PurchaseRequest.java
@@ -0,0 +1,39 @@
+package com.hepia.demobdd.dto;
+
+public class PurchaseRequest {
+    private Long userId;
+    private Long productId;
+    private int quantity;
+
+    //#region getters
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public Long getProductId() {
+        return productId;
+    }
+
+    public int getQuantity() {
+        return quantity;
+    }
+
+    //#endregion
+
+    //#region setters
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public void setProductId(Long productId) {
+        this.productId = productId;
+    }
+
+    public void setQuantity(int quantity) {
+        this.quantity = quantity;
+    }
+
+    //#endregion
+}
diff --git a/src/main/java/com/hepia/demobdd/entity/Product.java b/src/main/java/com/hepia/demobdd/entity/Product.java
new file mode 100644
index 0000000..71598f2
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/entity/Product.java
@@ -0,0 +1,58 @@
+package com.hepia.demobdd.entity;
+
+import jakarta.persistence.*;
+import java.math.BigDecimal;
+
+@Entity
+@Table(name = "product")
+public class Product {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String name;
+
+    @Column(precision = 10, scale = 2)
+    private BigDecimal price;
+
+    private int stock;
+
+    //#region getters
+    public Long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public int getStock() {
+        return stock;
+    }
+
+    //#endregion
+
+    //#region setters
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setPrice(BigDecimal price) {
+        this.price = price;
+    }
+
+    public void setStock(int stock) {
+        this.stock = stock;
+    }
+    //#endregion
+}
diff --git a/src/main/java/com/hepia/demobdd/entity/Purchase.java b/src/main/java/com/hepia/demobdd/entity/Purchase.java
new file mode 100644
index 0000000..c31a673
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/entity/Purchase.java
@@ -0,0 +1,80 @@
+package com.hepia.demobdd.entity;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import jakarta.persistence.*;
+import java.math.BigDecimal;
+
+@Entity
+@Table(name = "purchase")
+public class Purchase {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @ManyToOne
+    @JsonIgnoreProperties("purchases")
+    private User user;
+
+    @ManyToOne
+    private Product product;
+
+    private int quantity;
+
+    public Purchase() {
+    }
+
+    public Purchase(User user, Product product, int quantity) {
+        this.user = user;
+        this.product = product;
+        this.quantity = quantity;
+    }
+
+
+    //#region getters
+
+    public Long getId() {
+        return id;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public Product getProduct() {
+        return product;
+    }
+
+    public int getQuantity() {
+        return quantity;
+    }
+
+    public BigDecimal getTotalAmount() {
+        return getProduct().getPrice().multiply(BigDecimal.valueOf(getQuantity()));
+    }
+
+
+    //#endregion
+
+    //#region setters
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public void setProduct(Product product) {
+        this.product = product;
+    }
+
+    public void setQuantity(int quantity) {
+        this.quantity = quantity;
+    }
+
+
+
+    //#endregion
+}
diff --git a/src/main/java/com/hepia/demobdd/entity/User.java b/src/main/java/com/hepia/demobdd/entity/User.java
index 14dc2cf..0504437 100644
--- a/src/main/java/com/hepia/demobdd/entity/User.java
+++ b/src/main/java/com/hepia/demobdd/entity/User.java
@@ -1,11 +1,11 @@
 package com.hepia.demobdd.entity;
 
-import jakarta.persistence.Id;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import jakarta.persistence.*;
 
+import java.util.List;
 @Entity
+@Table(name = "user")
 public class User {
 
     @Id
@@ -14,6 +14,9 @@ public class User {
     private String name;
     private String email;
 
+    @OneToMany(mappedBy = "user")
+    @JsonIgnoreProperties("user")
+    private List<Purchase> purchases;
     //#region getters
 
     public Long getId() {
@@ -27,6 +30,10 @@ public class User {
     public String getEmail() {
         return email;
     }
+
+    public List<Purchase> getPurchases() {
+        return purchases;
+    }
     //#endregion
 
     //#region setters
@@ -42,6 +49,10 @@ public class User {
     public void setEmail(String email) {
         this.email = email;
     }
+
+    public void setPurchases(List<Purchase> purchases) {
+        this.purchases = purchases;
+    }
     //#endregion
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/hepia/demobdd/repository/ProductRepository.java b/src/main/java/com/hepia/demobdd/repository/ProductRepository.java
new file mode 100644
index 0000000..1d6006c
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/repository/ProductRepository.java
@@ -0,0 +1,8 @@
+package com.hepia.demobdd.repository;
+
+import com.hepia.demobdd.entity.Product;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface ProductRepository extends JpaRepository<Product, Long> {
+}
\ No newline at end of file
diff --git a/src/main/java/com/hepia/demobdd/repository/PurchaseRepository.java b/src/main/java/com/hepia/demobdd/repository/PurchaseRepository.java
new file mode 100644
index 0000000..efbca20
--- /dev/null
+++ b/src/main/java/com/hepia/demobdd/repository/PurchaseRepository.java
@@ -0,0 +1,9 @@
+package com.hepia.demobdd.repository;
+
+import com.hepia.demobdd.entity.Purchase;
+import com.hepia.demobdd.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PurchaseRepository extends JpaRepository<Purchase, Long> {
+
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index c0a7fae..5f31810 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -4,4 +4,6 @@ spring.datasource.password=root
 spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
 
 spring.flyway.enabled=true
-spring.flyway.baseline-on-migrate=true
\ No newline at end of file
+spring.flyway.baseline-on-migrate=true
+spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
+spring.sql.init.mode=always
\ No newline at end of file
diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql
new file mode 100644
index 0000000..4cbe8bd
--- /dev/null
+++ b/src/main/resources/data.sql
@@ -0,0 +1 @@
+UPDATE product SET stock = 10;
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V2_0__Order_table.sql b/src/main/resources/db/migration/V2_0__Order_table.sql
new file mode 100644
index 0000000..beb61fd
--- /dev/null
+++ b/src/main/resources/db/migration/V2_0__Order_table.sql
@@ -0,0 +1,15 @@
+CREATE TABLE product (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    name VARCHAR(50),
+    price DECIMAL(10, 2),
+    stock INT
+);
+
+CREATE TABLE purchase (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    user_id BIGINT,
+    product_id BIGINT,
+    quantity INT,
+    FOREIGN KEY (user_id) REFERENCES user(id),
+    FOREIGN KEY (product_id) REFERENCES product(id)
+);
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V2_1__Initial_data.sql b/src/main/resources/db/migration/V2_1__Initial_data.sql
new file mode 100644
index 0000000..e69de29
-- 
GitLab