Сохранение перед добавлением фронта

This commit is contained in:
Nikita Sergeev 2023-03-25 22:57:08 +04:00
parent b56c295266
commit 2a876f5516
37 changed files with 5111 additions and 669 deletions

26
Front/.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.parcel-cache

58
Front/build.gradle Normal file
View File

@ -0,0 +1,58 @@
import com.github.gradle.node.util.PlatformHelper
import groovy.text.SimpleTemplateEngine
plugins {
id 'java'
id 'com.github.node-gradle.node' version '3.5.1'
id "de.undercouch.download" version '5.3.1'
}
node {
version = '18.15.0'
download = true
}
jar.dependsOn 'npmBuild'
clean.dependsOn 'npmClean'
nodeSetup.dependsOn 'downloadNode'
jar {
from 'dist'
into 'static'
final devHost = 'http://localhost:8080'
final prodHost = ''
filesMatching('index.html') {
filter { line -> line.replaceAll(devHost, prodHost) }
}
}
task downloadNode(type: Download) {
final helper = new PlatformHelper()
final templateData = [
"url" : node.distBaseUrl.get(),
"version": node.version.get(),
"os" : helper.osName,
"arch" : helper.osArch,
"ext" : helper.windows ? 'zip' : 'tar.gz'
]
final urlTemplate = '${url}/v${version}/node-v${version}-${os}-${arch}.${ext}'
final engine = new SimpleTemplateEngine()
final url = engine.createTemplate(urlTemplate).make(templateData).toString()
final String destDir = '.gradle/'
file(destDir).mkdirs()
src url
dest destDir
overwrite false
}
tasks.register('npmBuild', NpmTask) {
dependsOn npmInstall
args = ['run-script', 'build']
}
tasks.register('npmClean', NpmTask) {
dependsOn npmInstall
args = ['run-script', 'clean']
}

View File

@ -1,40 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<title>Document</title>
</head>
<body>
<form id="frm-items" class="row g-3">
<div class="d-flex flex-column w-25 my-5 mx-3">
Введите первое число
<input id="first"></input>
Введите второе число
<input id="second" ></input>
Выберите операцию
<div>
<button type="button" class="btn btn-primary" id="buttonPlus">+</button>
<button type="button" class="btn btn-primary" id="buttonMinus">-</button>
<button type="button" class="btn btn-primary" id="buttonMulti">*</button>
<button type="button" class="btn btn-primary" id="buttonDiv">/</button>
</div>
Выберите тип данных
<div>
<select id="type" class="form-select" >
<option value="int">Число</option>
<option value="string">Строка</option>
</select>
</div>
Результат
<input id="res" type="text"></input>
</div>
</form>
<script src="/script.js"></script>
</body>
</html>

4835
Front/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,17 @@
{
"name": "int-prog",
"version": "1.0.0",
"main": "index.html",
"main": "src/index.html",
"scripts": {
"start": "http-server -p 3000 ./",
"test": "echo \"Error: no test specified\" && exit 1"
"start": "parcel --port 3000",
"build": "npm run clean && parcel build",
"clean": "rimraf dist"
},
"dependencies": {
"bootstrap": "5.2.1",
"@fortawesome/fontawesome-free": "6.2.0"
"bootstrap": "5.2.1"
},
"devDependencies": {
"http-server": "14.1.1"
"parcel": "2.8.3",
"rimraf": "4.4.0"
}
}

152
Front/src/index.html Normal file
View File

@ -0,0 +1,152 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="../node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<title>Rest CLient</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
</div>
</nav>
<div class="container">
<form id="formComponent">
<div class="row mt-3">
<div class="col-sm-6">
<label for="lastName" class="form-label">Last name</label>
<input type="text" class="form-control" id="lastName" required>
</div>
<div class="col-sm-6">
<label for="firstName" class="form-label">First name</label>
<input type="text" class="form-control" id="firstName" required>
</div>
</div>
<div class="row mt-3">
<div class="d-grid col-sm-4 mx-auto">
<button type="submit" class="btn btn-success">Add</button>
</div>
<div class="d-grid col-sm-4 mx-auto mt-3 mt-sm-0">
<button id="testError" type="button" class="btn btn-danger">Test</button>
</div>
<div class="d-grid col-sm-4 mx-auto mt-3 mt-sm-0">
<button id="testNormal" type="button" class="btn btn-secondary">Test</button>
</div>
</div>
</form>
<div class="row table-responsive">
<table class="table mt-3">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First name</th>
<th scope="col">Last name</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</div>
</div>
<div class="container">
<form id="form">
<div class="row mt-3">
<div class="col-sm-6">
<label for="lastName" class="form-label">Last name</label>
<input type="text" class="form-control" id="lastName" required>
</div>
<div class="col-sm-6">
<label for="firstName" class="form-label">First name</label>
<input type="text" class="form-control" id="firstName" required>
</div>
</div>
<div class="row mt-3">
<div class="d-grid col-sm-4 mx-auto">
<button type="submit" class="btn btn-success">Add</button>
</div>
<div class="d-grid col-sm-4 mx-auto mt-3 mt-sm-0">
<button id="testError" type="button" class="btn btn-danger">Test</button>
</div>
<div class="d-grid col-sm-4 mx-auto mt-3 mt-sm-0">
<button id="testNormal" type="button" class="btn btn-secondary">Test</button>
</div>
</div>
</form>
<div class="row table-responsive">
<table class="table mt-3">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First name</th>
<th scope="col">Last name</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</div>
</div>
<div class="container">
<form id="form">
<div class="row mt-3">
<div class="col-sm-6">
<label for="lastName" class="form-label">Last name</label>
<input type="text" class="form-control" id="lastName" required>
</div>
<div class="col-sm-6">
<label for="firstName" class="form-label">First name</label>
<input type="text" class="form-control" id="firstName" required>
</div>
</div>
<div class="row mt-3">
<div class="d-grid col-sm-4 mx-auto">
<button type="submit" class="btn btn-success">Add</button>
</div>
<div class="d-grid col-sm-4 mx-auto mt-3 mt-sm-0">
<button id="testError" type="button" class="btn btn-danger">Test</button>
</div>
<div class="d-grid col-sm-4 mx-auto mt-3 mt-sm-0">
<button id="testNormal" type="button" class="btn btn-secondary">Test</button>
</div>
</div>
</form>
<div class="row table-responsive">
<table class="table mt-3">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First name</th>
<th scope="col">Last name</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</div>
</div>
<script src="/script.js"></script>
</body>
</html>

View File

@ -12,11 +12,19 @@ repositories {
mavenCentral()
}
jar {
enabled = false
}
dependencies {
implementation(project(':Front'))
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
implementation 'org.hibernate.validator:hibernate-validator'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
}

View File

@ -1 +1,2 @@
rootProject.name = 'labwork'
include 'Front'

View File

@ -1,11 +1,7 @@
package ip.labwork.shop.controller;
import ip.labwork.shop.model.Component;
import ip.labwork.shop.service.ComponentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -19,36 +15,38 @@ public class ComponentController {
this.componentService = componentService;
}
@GetMapping("/add")
public Component create(@RequestParam("name") String name,
@PostMapping
public ComponentDTO createComponent(@RequestParam("name") String name,
@RequestParam("price") Integer price) {
return componentService.addComponent(name, price);
return new ComponentDTO(componentService.addComponent(name, price));
}
@GetMapping("/update")
public Component update(@RequestParam("id") Long id,
@PutMapping("/{id}")
public ComponentDTO updateComponent(@PathVariable Long id,
@RequestParam("name") String name,
@RequestParam("price") Integer price) {
return componentService.updateComponent(id, name, price);
return new ComponentDTO(componentService.updateComponent(id, name, price));
}
@GetMapping("/remove")
public Component remove(@RequestParam("id") Long id) {
return componentService.deleteComponent(id);
@DeleteMapping("/{id}")
public ComponentDTO removeComponent(@PathVariable Long id) {
return new ComponentDTO(componentService.deleteComponent(id));
}
@GetMapping("/removeAll")
public void remove() {
@DeleteMapping
public void removeAllComponent() {
componentService.deleteAllComponent();
}
@GetMapping("/find")
public Component find(@RequestParam("id") Long id) {
return componentService.findComponent(id);
@GetMapping("/{id}")
public ComponentDTO findComponent(@PathVariable Long id) {
return new ComponentDTO(componentService.findComponent(id));
}
@GetMapping("/findAll")
public List<Component> findAll() {
return componentService.findAllComponent();
@GetMapping
public List<ComponentDTO> findAllComponent() {
return componentService.findAllComponent().stream()
.map(ComponentDTO::new)
.toList();
}
}

View File

@ -0,0 +1,27 @@
package ip.labwork.shop.controller;
import ip.labwork.shop.model.Component;
public class ComponentDTO {
private final long id;
private final String componentName;
private final int price;
public ComponentDTO(Component component) {
this.id = component.getId();
this.componentName = component.getComponentName();
this.price = component.getPrice();
}
public long getId() {
return id;
}
public String getComponentName() {
return componentName;
}
public int getPrice() {
return price;
}
}

View File

@ -3,10 +3,7 @@ package ip.labwork.shop.controller;
import ip.labwork.shop.service.ProductService;
import ip.labwork.shop.model.Order;
import ip.labwork.shop.service.OrderService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -20,35 +17,37 @@ public class OrderController {
this.productService = productService;
}
@GetMapping("/add")
public Order create(@RequestParam("date") String date,
@PostMapping
public OrderDTO createOrder(@RequestParam("date") String date,
@RequestParam("price") Integer price,
@RequestParam("count") Integer[] count,
@RequestParam("prod") Long[] prod){
return orderService.addOrder(date, price, count, productService.findFiltredProducts(prod));
return new OrderDTO(orderService.addOrder(date, price, count, productService.findFiltredProducts(prod)));
}
@GetMapping("/update")
public Order update(@RequestParam("id") Long id,
@PutMapping("/{id}")
public OrderDTO updateOrder(@PathVariable Long id,
@RequestParam("date") String date,
@RequestParam("price") Integer price,
@RequestParam("count") Integer[] count,
@RequestParam("prod") Long[] prod){
return orderService.updateOrder(id, date, price, count, productService.findFiltredProducts(prod));
return new OrderDTO(orderService.updateOrder(id, date, price, count, productService.findFiltredProducts(prod)));
}
@GetMapping("/remove")
public Order remove(@RequestParam("id") Long id){
return orderService.deleteOrder(id);
@DeleteMapping("/{id}")
public OrderDTO removeOrder(@PathVariable Long id){
return new OrderDTO(orderService.deleteOrder(id));
}
@GetMapping("/removeAll")
public void remove(){
@DeleteMapping
public void removeAllOrder(){
orderService.deleteAllOrder();
}
@GetMapping("/find")
public Order find(@RequestParam("id") Long id){
return orderService.findOrder(id);
@GetMapping("/{id}")
public OrderDTO findOrder(@PathVariable Long id){
return new OrderDTO(orderService.findOrder(id));
}
@GetMapping("/findAll")
public List<Order> findAll(){
return orderService.findAllOrder();
@GetMapping
public List<OrderDTO> findAllOrder(){
return orderService.findAllOrder().stream()
.map(OrderDTO::new)
.toList();
}
}

View File

@ -0,0 +1,36 @@
package ip.labwork.shop.controller;
import ip.labwork.shop.model.Order;
import java.util.Date;
import java.util.List;
import java.util.Objects;
public class OrderDTO {
private final long id;
private final Date date;
private final int price;
private final List<ProductDTO> productDTOList;
public OrderDTO(Order order) {
this.id = order.getId();
this.date = order.getDate();
this.price = order.getPrice();
this.productDTOList = order.getProducts().stream().filter(x -> Objects.equals(x.getId().getOrderId(), order.getId())).map(x -> new ProductDTO(x.getProduct())).toList();
}
public long getId() {
return id;
}
public Date getDate() {
return date;
}
public int getPrice() {
return price;
}
public List<ProductDTO> getProductDTOList() {
return productDTOList;
}
}

View File

@ -3,10 +3,7 @@ package ip.labwork.shop.controller;
import ip.labwork.shop.service.ProductService;
import ip.labwork.shop.model.Product;
import ip.labwork.shop.service.ComponentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -21,35 +18,37 @@ public class ProductController {
this.componentService = componentService;
}
@GetMapping("/add")
public Product create(@RequestParam("name") String name,
@PostMapping
public ProductDTO createProduct(@RequestParam("name") String name,
@RequestParam("price") Integer price,
@RequestParam("count") Integer[] count,
@RequestParam("comp") Long[] comp){
return productService.addProduct(name, price, count, componentService.findFiltredComponents(comp));
return new ProductDTO(productService.addProduct(name, price, count, componentService.findFiltredComponents(comp)));
}
@GetMapping("/update")
public Product update(@RequestParam("id") Long id,
@PutMapping("/{id}")
public ProductDTO updateProduct(@PathVariable Long id,
@RequestParam("name") String name,
@RequestParam("price") Integer price,
@RequestParam("count") Integer[] count,
@RequestParam("comp") Long[] comp){
return productService.updateProduct(id, name, price, count, componentService.findFiltredComponents(comp));
return new ProductDTO(productService.updateProduct(id, name, price, count, componentService.findFiltredComponents(comp)));
}
@GetMapping("/remove")
public Product remove(@RequestParam("id") Long id){
return productService.deleteProduct(id);
@DeleteMapping("/{id}")
public ProductDTO removeProduct(@PathVariable Long id){
return new ProductDTO(productService.deleteProduct(id));
}
@GetMapping("/removeAll")
public void remove(){
@DeleteMapping
public void removeAllProduct(){
productService.deleteAllProduct();
}
@GetMapping("/find")
public Product find(@RequestParam("id") Long id){
return productService.findProduct(id);
@GetMapping("/{id}")
public ProductDTO findProduct(@PathVariable Long id){
return new ProductDTO(productService.findProduct(id));
}
@GetMapping("/findAll")
public List<Product> findAll(){
return productService.findAllProduct();
@GetMapping
public List<ProductDTO> findAllProduct(){
return productService.findAllProduct().stream()
.map(ProductDTO::new)
.toList();
}
}

View File

@ -0,0 +1,41 @@
package ip.labwork.shop.controller;
import ip.labwork.shop.model.Product;
import java.util.List;
import java.util.Objects;
public class ProductDTO {
private final long id;
private final String productName;
private final int price;
private final List<ComponentDTO> componentDTOList;
private final List<OrderDTO> orderDTOList;
public ProductDTO(Product product) {
this.id = product.getId();
this.productName = product.getProductName();
this.price = product.getPrice();
this.componentDTOList = product.getComponents().stream().filter(x -> Objects.equals(x.getId().getProductId(), product.getId())).map(x -> new ComponentDTO(x.getComponent())).toList();
this.orderDTOList = product.getOrders().stream().filter(x -> Objects.equals(x.getId().getProductId(), product.getId())).map(x -> new OrderDTO(x.getOrder())).toList();
}
public long getId() {
return id;
}
public String getProductName() {
return productName;
}
public int getPrice() {
return price;
}
public List<ComponentDTO> getComponentDTOList() {
return componentDTOList;
}
public List<OrderDTO> getOrderDTOList() {
return orderDTOList;
}
}

View File

@ -2,6 +2,7 @@ package ip.labwork.shop.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
@ -13,8 +14,10 @@ public class Component {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank(message = "ComponentName can't be null or empty")
@Column(name = "name")
private String componentName;
@NotBlank(message = "Price can't be null or empty")
@Column(name = "price")
private Integer price;

View File

@ -1,6 +1,7 @@
package ip.labwork.shop.model;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.Date;
@ -13,8 +14,10 @@ public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank(message = "Date can't be null or empty")
@Column(name = "date")
private Date date;
@NotBlank(message = "Price can't be null or empty")
@Column(name = "price")
private Integer price;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.EAGER)

View File

@ -2,6 +2,7 @@ package ip.labwork.shop.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
@Entity
@Table(name = "order_product")
@ -17,6 +18,7 @@ public class OrderProducts {
@JoinColumn(name = "order_id")
@JsonIgnore
private Order order;
@NotBlank(message = "Count can't be null or empty")
@Column(name = "count")
private Integer count;

View File

@ -2,6 +2,7 @@ package ip.labwork.shop.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
@ -13,8 +14,10 @@ public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank(message = "ProductName can't be null or empty")
@Column(name = "name")
private String productName;
@NotBlank(message = "Price can't be null or empty")
@Column(name = "price")
private Integer price;

View File

@ -2,6 +2,7 @@ package ip.labwork.shop.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
@Entity
@Table(name = "product_component")
@ -17,6 +18,7 @@ public class ProductComponents {
@JoinColumn(name = "product_id")
@JsonIgnore
private Product product;
@NotBlank(message = "Count can't be null or empty")
@Column(name = "count")
private Integer count;

View File

@ -0,0 +1,7 @@
package ip.labwork.shop.repository;
import ip.labwork.shop.model.Component;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ComponentRepository extends JpaRepository<Component, Long> {
}

View File

@ -0,0 +1,12 @@
package ip.labwork.shop.repository;
import ip.labwork.shop.model.OrderProducts;
import ip.labwork.shop.model.OrderProductsKey;
import ip.labwork.shop.model.ProductComponents;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface OrderProductRepository extends JpaRepository<OrderProducts, OrderProductsKey> {
List<OrderProducts> getOrderProductsByOrderId(Long order_id);
}

View File

@ -0,0 +1,7 @@
package ip.labwork.shop.repository;
import ip.labwork.shop.model.Order;
import org.springframework.data.jpa.repository.JpaRepository;
public interface OrderRepository extends JpaRepository<Order, Long> {
}

View File

@ -0,0 +1,11 @@
package ip.labwork.shop.repository;
import ip.labwork.shop.model.ProductComponents;
import ip.labwork.shop.model.ProductComponentsKey;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ProductComponentRepository extends JpaRepository<ProductComponents, ProductComponentsKey> {
List<ProductComponents> getProductComponentsByProductId(Long product_id);
}

View File

@ -0,0 +1,7 @@
package ip.labwork.shop.repository;
import ip.labwork.shop.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductRepository extends JpaRepository<Product, Long> {
}

View File

@ -0,0 +1,7 @@
package ip.labwork.shop.service;
public class ComponentNotFoundException extends RuntimeException {
public ComponentNotFoundException(Long id) {
super(String.format("Component with id [%s] is not found", id));
}
}

View File

@ -1,70 +1,61 @@
package ip.labwork.shop.service;
import ip.labwork.shop.model.Component;
import ip.labwork.shop.model.OrderProducts;
import ip.labwork.shop.model.Product;
import ip.labwork.shop.model.ProductComponents;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceContext;
import ip.labwork.shop.repository.ComponentRepository;
import ip.labwork.shop.repository.ProductComponentRepository;
import ip.labwork.util.validation.ValidatorUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@Service
public class ComponentService {
@PersistenceContext
private EntityManager em;
private final ComponentRepository componentRepository;
private final ProductComponentRepository productComponentRepository;
private final ValidatorUtil validatorUtil;
public ComponentService(ComponentRepository componentRepository,
ValidatorUtil validatorUtil, ProductComponentRepository productComponentRepository) {
this.componentRepository = componentRepository;
this.validatorUtil = validatorUtil;
this.productComponentRepository = productComponentRepository;
}
@Transactional
public Component addComponent(String componentName, Integer price) {
if (!StringUtils.hasText(componentName) || price == 0) {
throw new IllegalArgumentException("Component is null or empty");
}
final Component component = new Component(componentName, price);
em.persist(component);
return component;
validatorUtil.validate(component);
return componentRepository.save(component);
}
@Transactional(readOnly = true)
public Component findComponent(Long id) {
final Component component = em.find(Component.class, id);
if (component == null) {
throw new EntityNotFoundException(String.format("Component with id [%s] is not found", id));
}
return component;
final Optional<Component> student = componentRepository.findById(id);
return student.orElseThrow(() -> new ComponentNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Component> findAllComponent() {
return em.createQuery("select c from Component c", Component.class)
.getResultList();
return componentRepository.findAll();
}
@Transactional(readOnly = true)
public List<Component> findFiltredComponents(Long[] arr) {
if (arr.length == 0) {
throw new IllegalArgumentException("Array id is empty");
}
List<Component> componentList = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
componentList.add(em.find(Component.class, arr[i]));
}
return componentList;
return componentRepository.findAllById(Arrays.stream(arr).toList());
}
@Transactional
public Component updateComponent(Long id, String componentName, Integer price) {
if (!StringUtils.hasText(componentName) || price == 0) {
throw new IllegalArgumentException("Component is null or empty");
}
final Component currentComponent = findComponent(id);
currentComponent.setComponentName(componentName);
currentComponent.setPrice(price);
return em.merge(currentComponent);
validatorUtil.validate(currentComponent);
return componentRepository.save(currentComponent);
}
@Transactional
@ -75,14 +66,14 @@ public class ComponentService {
ProductComponents temp = currentComponent.getProducts().get(0);
temp.getComponent().removeProduct(temp);
temp.getProduct().removeComponent(temp);
em.remove(temp);
productComponentRepository.delete(temp);
}
em.remove(currentComponent);
componentRepository.delete(currentComponent);
return currentComponent;
}
@Transactional
public void deleteAllComponent() {
em.createQuery("delete from ProductComponents").executeUpdate();
em.createQuery("delete from Component").executeUpdate();
productComponentRepository.deleteAll();
componentRepository.deleteAll();
}
}

View File

@ -0,0 +1,7 @@
package ip.labwork.shop.service;
public class OrderNotFoundException extends RuntimeException {
public OrderNotFoundException(Long id) {
super(String.format("Order with id [%s] is not found", id));
}
}

View File

@ -1,36 +1,38 @@
package ip.labwork.shop.service;
import ip.labwork.shop.model.Order;
import ip.labwork.shop.model.OrderProducts;
import ip.labwork.shop.model.Product;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceContext;
import ip.labwork.shop.model.*;
import ip.labwork.shop.repository.OrderProductRepository;
import ip.labwork.shop.repository.OrderRepository;
import ip.labwork.util.validation.ValidatorUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
public class OrderService {
@PersistenceContext
private EntityManager em;
private final OrderRepository orderRepository;
private final OrderProductRepository orderProductRepository;
private final ValidatorUtil validatorUtil;
public OrderService(OrderRepository orderRepository,
ValidatorUtil validatorUtil, OrderProductRepository orderProductRepository) {
this.orderRepository = orderRepository;
this.validatorUtil = validatorUtil;
this.orderProductRepository = orderProductRepository;
}
@Transactional
public Order addOrder(String date, Integer price, Integer[] count, List<Product> products) {
if (!StringUtils.hasText(date) || price == 0 || count.length == 0 || Arrays.stream(count).filter(c -> c == 0).toList().size() != 0 || products.size() == 0 || products.stream().filter(Objects::isNull).toList().size() != 0 || count.length != products.size()) {
throw new IllegalArgumentException("Order is null or empty");
}
Date correctDate = getDate(date);
final Order order = new Order(correctDate, price);
em.persist(order);
validatorUtil.validate(order);
orderRepository.save(order);
for (int i = 0; i < products.size(); i++) {
final OrderProducts orderProducts = new OrderProducts(order, products.get(i), count[i]);
order.addProduct(orderProducts);
products.get(i).addOrder(orderProducts);
em.persist(orderProducts);
orderProductRepository.save(orderProducts);
}
return order;
}
@ -49,30 +51,23 @@ public class OrderService {
@Transactional(readOnly = true)
public Order findOrder(Long id) {
final Order order = em.find(Order.class, id);
if (order == null) {
throw new EntityNotFoundException(String.format("Order with id [%s] is not found", id));
}
return order;
final Optional<Order> order = orderRepository.findById(id);
return order.orElseThrow(() -> new OrderNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Order> findAllOrder() {
return em.createQuery("select o from Order o", Order.class)
.getResultList();
return orderRepository.findAll();
}
@Transactional
public Order updateOrder(Long id, String date, Integer price, Integer[] count, List<Product> products) {
if (!StringUtils.hasText(date) || price == 0 || count.length == 0 || Arrays.stream(count).filter(c -> c == 0).toList().size() != 0 || products.size() == 0 || products.stream().filter(Objects::isNull).toList().size() != 0 || count.length != products.size()) {
throw new IllegalArgumentException("Order is null or empty");
}
final Order currentOrder = findOrder(id);
currentOrder.setDate(getDate(date));
currentOrder.setPrice(price);
em.merge(currentOrder);
List<OrderProducts> orderProductsList = em.createQuery("select o from OrderProducts o where o.id.orderId = " + id, OrderProducts.class)
.getResultList();
validatorUtil.validate(currentOrder);
orderRepository.save(currentOrder);
List<OrderProducts> orderProductsList = orderProductRepository.getOrderProductsByOrderId(id);
List<Long> product_id = new ArrayList<>(orderProductsList.stream().map(p -> p.getId().getProductId()).toList());
for (int i = 0; i < products.size(); i++) {
final Long currentId = products.get(i).getId();
@ -81,18 +76,18 @@ public class OrderService {
orderProductsList.remove(orderProducts);
product_id.remove(products.get(i).getId());
orderProducts.setCount(count[i]);
em.merge(orderProducts);
orderProductRepository.save(orderProducts);
} else {
final OrderProducts orderProducts = new OrderProducts(currentOrder, products.get(i), count[i]);
currentOrder.addProduct(orderProducts);
products.get(i).addOrder(orderProducts);
em.persist(orderProducts);
orderProductRepository.save(orderProducts);
}
}
for (int i = 0; i < orderProductsList.size(); i++) {
orderProductsList.get(i).getProduct().removeOrder(orderProductsList.get(i));
orderProductsList.get(i).getOrder().removeProducts(orderProductsList.get(i));
em.remove(orderProductsList.get(i));
orderProductRepository.delete(orderProductsList.get(i));
}
return currentOrder;
}
@ -105,14 +100,14 @@ public class OrderService {
OrderProducts temp = currentOrder.getProducts().get(0);
temp.getProduct().removeOrder(temp);
temp.getOrder().removeProducts(temp);
em.remove(temp);
orderProductRepository.delete(temp);
}
em.remove(currentOrder);
orderRepository.delete(currentOrder);
return currentOrder;
}
@Transactional
public void deleteAllOrder() {
em.createQuery("delete from OrderProducts").executeUpdate();
em.createQuery("delete from Order").executeUpdate();
orderProductRepository.deleteAll();
orderRepository.deleteAll();
}
}

View File

@ -0,0 +1,7 @@
package ip.labwork.shop.service;
public class ProductNotFoundException extends RuntimeException {
public ProductNotFoundException(Long id) {
super(String.format("Product with id [%s] is not found", id));
}
}

View File

@ -4,6 +4,11 @@ import ip.labwork.shop.model.Component;
import ip.labwork.shop.model.OrderProducts;
import ip.labwork.shop.model.Product;
import ip.labwork.shop.model.ProductComponents;
import ip.labwork.shop.repository.ComponentRepository;
import ip.labwork.shop.repository.OrderProductRepository;
import ip.labwork.shop.repository.ProductComponentRepository;
import ip.labwork.shop.repository.ProductRepository;
import ip.labwork.util.validation.ValidatorUtil;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceContext;
@ -11,58 +16,55 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
@Service
public class ProductService {
@PersistenceContext
private EntityManager em;
private final ProductRepository productRepository;
private final ProductComponentRepository productComponentRepository;
private final OrderProductRepository orderProductRepository;
private final ValidatorUtil validatorUtil;
public ProductService(ProductRepository productRepository,
ValidatorUtil validatorUtil, ProductComponentRepository productComponentRepository, OrderProductRepository orderProductRepository) {
this.productRepository = productRepository;
this.validatorUtil = validatorUtil;
this.productComponentRepository = productComponentRepository;
this.orderProductRepository = orderProductRepository;
}
@Transactional
public Product addProduct(String productName, Integer price, Integer[] count, List<Component> components) {
if (!StringUtils.hasText(productName) || price == 0 || count.length == 0 || Arrays.stream(count).filter(c -> c == 0).toList().size() != 0 || components.size() == 0 || components.stream().filter(Objects::isNull).toList().size() != 0 || count.length != components.size()) {
throw new IllegalArgumentException("Product name is null or empty");
}
final Product product = new Product(productName, price);
em.persist(product);
validatorUtil.validate(product);
productRepository.save(product);
for (int i = 0; i < components.size(); i++) {
final ProductComponents productComponents = new ProductComponents(components.get(i), product, count[i]);
product.addComponent(productComponents);
components.get(i).addProduct(productComponents);
em.persist(productComponents);
productComponentRepository.save(productComponents);
}
return product;
}
@Transactional(readOnly = true)
public Product findProduct(Long id) {
final Product product = em.find(Product.class, id);
if (product == null) {
throw new EntityNotFoundException(String.format("Product with id [%s] is not found", id));
}
return product;
final Optional<Product> product = productRepository.findById(id);
return product.orElseThrow(() -> new ProductNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Product> findAllProduct() {
return em.createQuery("select p from Product p", Product.class)
.getResultList();
return productRepository.findAll();
}
@Transactional
public Product updateProduct(Long id, String productName, Integer price, Integer[] count, List<Component> components) {
if (!StringUtils.hasText(productName) || price == 0 || count.length == 0 || Arrays.stream(count).filter(c -> c == 0).toList().size() != 0 || components.size() == 0 || components.stream().filter(Objects::isNull).toList().size() != 0 || count.length != components.size()) {
throw new IllegalArgumentException("Product name is null or empty");
}
final Product currentProduct = findProduct(id);
currentProduct.setProductName(productName);
currentProduct.setPrice(price);
em.merge(currentProduct);
List<ProductComponents> productComponentsList = em.createQuery("select p from ProductComponents p where p.id.productId = " + id, ProductComponents.class)
.getResultList();
validatorUtil.validate(currentProduct);
productRepository.save(currentProduct);
List<ProductComponents> productComponentsList = productComponentRepository.getProductComponentsByProductId(id);
List<Long> component_id = new ArrayList<>(productComponentsList.stream().map(p -> p.getId().getComponentId()).toList());
for (int i = 0; i < components.size(); i++) {
final Long currentId = components.get(i).getId();
@ -71,18 +73,18 @@ public class ProductService {
productComponentsList.remove(productComponents);
component_id.remove(components.get(i).getId());
productComponents.setCount(count[i]);
em.merge(productComponents);
productComponentRepository.save(productComponents);
} else {
final ProductComponents productComponents = new ProductComponents(components.get(i), currentProduct, count[i]);
currentProduct.addComponent(productComponents);
components.get(i).addProduct(productComponents);
em.persist(productComponents);
productComponentRepository.save(productComponents);
}
}
for (int i = 0; i < productComponentsList.size(); i++) {
productComponentsList.get(i).getComponent().removeProduct(productComponentsList.get(i));
productComponentsList.get(i).getProduct().removeComponent(productComponentsList.get(i));
em.remove(productComponentsList.get(i));
productComponentRepository.delete(productComponentsList.get(i));
}
return currentProduct;
}
@ -95,35 +97,28 @@ public class ProductService {
ProductComponents temp = currentProduct.getComponents().get(0);
temp.getComponent().removeProduct(temp);
temp.getProduct().removeComponent(temp);
em.remove(temp);
productComponentRepository.delete(temp);
}
int ordSize = currentProduct.getOrders().size();
for (int i = 0; i < ordSize; i++){
OrderProducts temp = currentProduct.getOrders().get(0);
temp.getProduct().removeOrder(temp);
temp.getOrder().removeProducts(temp);
em.remove(temp);
orderProductRepository.delete(temp);
}
em.remove(currentProduct);
productRepository.delete(currentProduct);
return currentProduct;
}
@Transactional
public void deleteAllProduct() {
em.createQuery("delete from ProductComponents").executeUpdate();
em.createQuery("delete from OrderProducts ").executeUpdate();
em.createQuery("delete from Product").executeUpdate();
productComponentRepository.deleteAll();
orderProductRepository.deleteAll();
productRepository.deleteAll();
}
@Transactional
public List<Product> findFiltredProducts(Long[] arr) {
if (arr.length == 0) {
throw new IllegalArgumentException("Array id is empty");
}
List<Product> productList = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
productList.add(em.find(Product.class, arr[i]));
}
return productList;
return productRepository.findAllById(Arrays.stream(arr).toList());
}
}

View File

@ -0,0 +1,17 @@
package ip.labwork.test.controller;
import ip.labwork.test.model.TestDto;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
@PostMapping
public TestDto testValidation(@RequestBody @Valid TestDto testDto) {
return testDto;
}
}

View File

@ -0,0 +1,31 @@
package ip.labwork.test.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
public class TestDto {
@NotNull(message = "Id can't be null")
private Long id;
@NotBlank(message = "Name can't be null or empty")
private String name;
public Long getId() {
return id;
}
public String getName() {
return name;
}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public String getData() {
return String.format("%s %s", id, name);
}
@JsonIgnore
public String getAnotherData() {
return "Test";
}
}

View File

@ -0,0 +1,42 @@
package ip.labwork.util.error;
import ip.labwork.shop.service.ComponentNotFoundException;
import ip.labwork.shop.service.OrderNotFoundException;
import ip.labwork.shop.service.ProductNotFoundException;
import ip.labwork.util.validation.ValidationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
@ExceptionHandler({
ComponentNotFoundException.class,
ProductNotFoundException.class,
OrderNotFoundException.class,
ValidationException.class
})
public ResponseEntity<Object> handleException(Throwable e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
final ValidationException validationException = new ValidationException(
e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toSet()));
return handleException(validationException);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleUnknownException(Throwable e) {
e.printStackTrace();
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

View File

@ -0,0 +1,9 @@
package ip.labwork.util.validation;
import java.util.Set;
public class ValidationException extends RuntimeException {
public ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
}

View File

@ -0,0 +1,33 @@
package ip.labwork.util.validation;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class ValidatorUtil {
private final Validator validator;
public ValidatorUtil() {
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
this.validator = factory.getValidator();
}
}
public <T> void validate(T object) {
final Set<ConstraintViolation<T>> errors = validator.validate(object);
if (!errors.isEmpty()) {
throw new ValidationException(errors.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toSet()));
}
}
}

View File

@ -1,5 +1,5 @@
spring.main.banner-mode=off
#server.port=8080
server.port=8080
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa