From 09599f986e0566a77464f26238ac5fb5014956aa Mon Sep 17 00:00:00 2001 From: stickymittens Date: Mon, 6 Oct 2025 14:40:34 +0200 Subject: [PATCH] final --- .idea/.gitignore | 8 ++ .idea/ExerciseCheckPointSpringJPA.iml | 9 ++ .idea/compiler.xml | 18 ++++ .idea/dataSources.xml | 17 +++ .idea/data_source_mapping.xml | 6 ++ .idea/encodings.xml | 6 ++ .idea/jarRepositories.xml | 20 ++++ .idea/misc.xml | 14 +++ .idea/modules.xml | 8 ++ .idea/sqldialects.xml | 6 ++ .idea/vcs.xml | 6 ++ helloSupermarket.iml | 15 +++ src/http-requests.http | 5 + .../HelloSupermarketApplication.java | 13 +++ .../controller/ItemController.java | 90 ++++++++++++++++ .../helloSupermarket/enums/Category.java | 10 ++ .../ironhack/helloSupermarket/model/Item.java | 80 ++++++++++++++ .../helloSupermarket/model/ProduceStock.java | 27 +++++ .../repository/ItemRepository.java | 30 ++++++ .../helloSupermarket/service/ItemService.java | 102 ++++++++++++++++++ .../helloSupermarket/sql/commands.sql | 29 +++++ 21 files changed, 519 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/ExerciseCheckPointSpringJPA.iml create mode 100644 .idea/compiler.xml create mode 100644 .idea/dataSources.xml create mode 100644 .idea/data_source_mapping.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/sqldialects.xml create mode 100644 .idea/vcs.xml create mode 100644 helloSupermarket.iml create mode 100644 src/http-requests.http create mode 100644 src/main/java/com/ironhack/helloSupermarket/HelloSupermarketApplication.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/controller/ItemController.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/enums/Category.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/model/Item.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/model/ProduceStock.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/repository/ItemRepository.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/service/ItemService.java create mode 100644 src/main/java/com/ironhack/helloSupermarket/sql/commands.sql diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/ExerciseCheckPointSpringJPA.iml b/.idea/ExerciseCheckPointSpringJPA.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/ExerciseCheckPointSpringJPA.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..0dbd425 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..6bfce0b --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,17 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306 + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/data_source_mapping.xml b/.idea/data_source_mapping.xml new file mode 100644 index 0000000..ce1f046 --- /dev/null +++ b/.idea/data_source_mapping.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..63e9001 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..eda147d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fce4815 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..18795a5 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/helloSupermarket.iml b/helloSupermarket.iml new file mode 100644 index 0000000..bf84dc1 --- /dev/null +++ b/helloSupermarket.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/http-requests.http b/src/http-requests.http new file mode 100644 index 0000000..ec41a1b --- /dev/null +++ b/src/http-requests.http @@ -0,0 +1,5 @@ +### GET request to example server +GET https://examples.http-client.intellij.net/get + ?generated-in=IntelliJ IDEA + +### \ No newline at end of file diff --git a/src/main/java/com/ironhack/helloSupermarket/HelloSupermarketApplication.java b/src/main/java/com/ironhack/helloSupermarket/HelloSupermarketApplication.java new file mode 100644 index 0000000..bd765da --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/HelloSupermarketApplication.java @@ -0,0 +1,13 @@ +package com.ironhack.helloSupermarket; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class HelloSupermarketApplication { + + public static void main(String[] args) { + SpringApplication.run(HelloSupermarketApplication.class, args); + } + +} diff --git a/src/main/java/com/ironhack/helloSupermarket/controller/ItemController.java b/src/main/java/com/ironhack/helloSupermarket/controller/ItemController.java new file mode 100644 index 0000000..03bada6 --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/controller/ItemController.java @@ -0,0 +1,90 @@ +package com.ironhack.helloSupermarket.controller; + +import com.ironhack.helloSupermarket.enums.Category; +import com.ironhack.helloSupermarket.model.Item; +import com.ironhack.helloSupermarket.model.ProduceStock; +import com.ironhack.helloSupermarket.service.ItemService; +import jakarta.validation.Valid; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.net.URI; +import java.util.List; + +@RestController +public class ItemController { + private final ItemService itemService; + + public ItemController(ItemService itemService){ + this.itemService = itemService; + } + + //crud + //create + @PostMapping("/inventory") + public ResponseEntity create(@Valid @RequestBody Item item){ + Item createdItem = itemService.create(item); + + URI location = ServletUriComponentsBuilder + .fromCurrentRequest() + .path("/{name}") + .buildAndExpand(createdItem.getName()) + .toUri(); + + return ResponseEntity.created(location).body(createdItem); + } + + //read + @GetMapping("/inventory/{id}") + public Item findById(@PathVariable Long id){ + return itemService.findById(id); + } + + //read all + @GetMapping("/inventory") + public List readAll (){ + return itemService.readAll(); + } + + //update + @PutMapping("/inventory/{id}") + public Item update(@PathVariable Long id, @Valid @RequestBody Item item){ + return itemService.update(id, item); + } + + //delete + @DeleteMapping("/inventory/{id}") + public void delete(@PathVariable Long id){ + itemService.delete(id); + } + + + //repository custom methods + @GetMapping("/inventory/category/{categoryString}") + public List findItemsByCategory(@PathVariable String categoryString) { + Category categoryEnum = Category.valueOf(categoryString.toUpperCase()); + return itemService.findItemsByCategory(categoryEnum); + } + + @GetMapping("/inventory/low-stock") + public List findLowStock(){ + return itemService.findLowStock(); + }; + + + @GetMapping("/inventory/to-discount/{price}") + public List findItemsToDiscount(@PathVariable double price){ + return itemService.findItemsToDiscount(price); + }; + + @GetMapping("inventory/alphabetically") + public List sortByName(){ + return itemService.sortByName(); + } + + @GetMapping("/inventory/produce-stock") + public List getProduceStock(){ + return itemService.getProduceStock(); + } +} \ No newline at end of file diff --git a/src/main/java/com/ironhack/helloSupermarket/enums/Category.java b/src/main/java/com/ironhack/helloSupermarket/enums/Category.java new file mode 100644 index 0000000..5233610 --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/enums/Category.java @@ -0,0 +1,10 @@ +package com.ironhack.helloSupermarket.enums; + +public enum Category { + PRODUCE, + DIARY, + BAKERY, + BEVERAGES, + PANTRY, + FROZEN +} diff --git a/src/main/java/com/ironhack/helloSupermarket/model/Item.java b/src/main/java/com/ironhack/helloSupermarket/model/Item.java new file mode 100644 index 0000000..d418c85 --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/model/Item.java @@ -0,0 +1,80 @@ +package com.ironhack.helloSupermarket.model; + +import com.ironhack.helloSupermarket.enums.Category; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.PositiveOrZero; + +import java.util.UUID; + +@Entity +@Table(name = "item") +public class Item { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + + @NotBlank (message = "Name is required") + private String name; + + @NotNull (message = "Category is required") + @Enumerated(EnumType.STRING) + private Category category; + + @Positive (message = "Price must be bigger than 0") + private double price; + + @PositiveOrZero (message = "Stock value cannot be negative") + private int stock; + + + //getters and setters + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public int getStock() { + return stock; + } + + public void setStock(int stock) { + this.stock = stock; + } + + //constructors + public Item (){} + + public Item(String name, Category category, double price, int stock) { + this.name = name; + this.category = category; + this.price = price; + this.stock = stock; + } +} diff --git a/src/main/java/com/ironhack/helloSupermarket/model/ProduceStock.java b/src/main/java/com/ironhack/helloSupermarket/model/ProduceStock.java new file mode 100644 index 0000000..699edb2 --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/model/ProduceStock.java @@ -0,0 +1,27 @@ +package com.ironhack.helloSupermarket.model; + +public class ProduceStock { + private String name; + private int stock; + + public ProduceStock(String name, int stock){ + this.name = name; + this.stock = stock; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getStock() { + return stock; + } + + public void setStock(int stock) { + this.stock = stock; + } +} diff --git a/src/main/java/com/ironhack/helloSupermarket/repository/ItemRepository.java b/src/main/java/com/ironhack/helloSupermarket/repository/ItemRepository.java new file mode 100644 index 0000000..42abcdd --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/repository/ItemRepository.java @@ -0,0 +1,30 @@ +package com.ironhack.helloSupermarket.repository; + +import com.ironhack.helloSupermarket.enums.Category; +import com.ironhack.helloSupermarket.model.Item; +import com.ironhack.helloSupermarket.model.ProduceStock; +import jakarta.validation.constraints.NotNull; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.UUID; + +@Repository +public interface ItemRepository extends JpaRepository { + List findItemsByCategory(Category category); + List findItemsByStockLessThan(int threshold); + List findItemsByPriceGreaterThan(double price); + + + //order alphabetically - JPQL + @Query("SELECT i FROM Item i ORDER BY i.name") + List sortByName(); + + //find only produce - SQL + @Query(value = "SELECT name, stock FROM item WHERE category='PRODUCE'", nativeQuery = true) + List getProduceStock(); + +} + diff --git a/src/main/java/com/ironhack/helloSupermarket/service/ItemService.java b/src/main/java/com/ironhack/helloSupermarket/service/ItemService.java new file mode 100644 index 0000000..a688eb5 --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/service/ItemService.java @@ -0,0 +1,102 @@ +package com.ironhack.helloSupermarket.service; + +import com.ironhack.helloSupermarket.enums.Category; +import com.ironhack.helloSupermarket.model.Item; +import com.ironhack.helloSupermarket.model.ProduceStock; +import com.ironhack.helloSupermarket.repository.ItemRepository; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ItemService { + private final ItemRepository itemRepository; + + public ItemService(ItemRepository itemRepository){ + this.itemRepository = itemRepository; + } + + //CRUD + //read all + public List readAll(){ + return itemRepository.findAll(); + } + + //read by id + public Item findById (Long id){ + return itemRepository + .findById(id) + .orElseThrow(() -> new ResponseStatusException( + HttpStatus.NOT_FOUND, "No item with such ID: " + id)); + } + + //create + public Item create(Item item){ + return itemRepository.save(item); + } + + //update + public Item update(Long id, Item item){ + Item itemToUpdate = findById(id); + + itemToUpdate.setName(item.getName()); + itemToUpdate.setCategory(item.getCategory()); + itemToUpdate.setPrice(item.getPrice()); + itemToUpdate.setStock(item.getStock()); + + return itemRepository.save(itemToUpdate); + } + + //delete + public void delete (Long id){ + itemRepository.deleteById(id); + } + + //repository custom methods + public List findItemsByCategory(Category category){ + + return itemRepository.findItemsByCategory(category); + }; + + private static final int LOW_STOCK_THRESHOLD = 50; + public List findLowStock(){ + return itemRepository.findItemsByStockLessThan(LOW_STOCK_THRESHOLD); + }; + +// private static final double DISCOUNT_PRICE_THRESHOLD = 1.99; + public List findItemsToDiscount(double price){ + List lowStock = findLowStock(); + List toDiscount = new ArrayList<>(); + + for(Item item : lowStock){ + if(item.getPrice() > price){ + toDiscount.add(item); + } + } + return toDiscount; + }; + + public List sortByName(){ + return itemRepository.sortByName(); + }; + + public List getProduceStock(){ + //getting the items with category produce from db + List produceOnly = itemRepository.getProduceStock(); + + //new list to store just the names and stock of the produce items + List produceNameAndStockOnly = new ArrayList<>(); + + //iterating over produce to populate only the name and stock fields using the ProduceStock DTO + for(Object[] row : produceOnly) { + String name = (String) row[0]; + int stock = ((Number) row[1]).intValue(); + produceNameAndStockOnly.add(new ProduceStock(name, stock)); + } + + return produceNameAndStockOnly; + } +} diff --git a/src/main/java/com/ironhack/helloSupermarket/sql/commands.sql b/src/main/java/com/ironhack/helloSupermarket/sql/commands.sql new file mode 100644 index 0000000..8bbe049 --- /dev/null +++ b/src/main/java/com/ironhack/helloSupermarket/sql/commands.sql @@ -0,0 +1,29 @@ +USE Inventory; + +# changing storage space to fit UUID +DESCRIBE item; +ALTER TABLE item MODIFY category VARCHAR(100); +# +INSERT INTO item (name, category, price, stock) VALUES + ('Apple', 'PRODUCE', 0.99, 50), + ('Banana', 'PRODUCE', 0.59, 100), + ('Milk', 'DIARY', 1.49, 40), + ('Cheddar Cheese', 'DIARY', 3.99, 30), + ('Bread', 'BAKERY', 2.49, 25), + ('Croissant', 'BAKERY', 1.99, 20), + ('Orange Juice', 'BEVERAGES', 2.99, 35), + ('Coffee', 'BEVERAGES', 5.99, 15), + ('Pasta', 'PANTRY', 1.79, 60), + ('Rice', 'PANTRY', 2.49, 50), + ('Frozen Pizza', 'FROZEN', 4.99, 20), + ('Ice Cream', 'FROZEN', 3.49, 25), + ('Yogurt', 'DIARY', 0.99, 40), + ('Bagel', 'BAKERY', 1.29, 30), + ('Lettuce', 'PRODUCE', 1.19, 35), + ('Tomato', 'PRODUCE', 0.89, 50), + ('Soda', 'BEVERAGES', 1.49, 60), + ('Cereal', 'PANTRY', 3.99, 20), + ('Frozen Vegetables', 'FROZEN', 2.99, 40), + ('Butter', 'DIARY', 2.79, 25); + +