1 Commits

Author SHA1 Message Date
Inohara
a36c6e9130 урааааа, сдана 4 2023-05-02 12:04:41 +04:00
39 changed files with 218 additions and 765 deletions

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id 'java' id 'java'
id 'org.springframework.boot' version '2.6.3' id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.1.0'
} }
group = 'com.example' group = 'com.example'
@@ -17,20 +17,11 @@ jar{
} }
dependencies { dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
implementation 'org.webjars:bootstrap:5.1.3'
implementation 'org.webjars:jquery:3.6.0'
implementation 'org.webjars:font-awesome:6.1.0'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210' implementation 'com.h2database:h2:2.1.210'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.hibernate.validator:hibernate-validator'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5' implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'

View File

@@ -4,20 +4,19 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
public class WebConfiguration implements WebMvcConfigurer { @EnableWebMvc
public class WebConfiguration {
@Override @Bean
public void addViewControllers(ViewControllerRegistry registry) { public WebMvcConfigurer corsConfigurer() {
WebMvcConfigurer.super.addViewControllers(registry); return new WebMvcConfigurer() {
registry.addViewController("rest-test");
}
@Override @Override
public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*"); registry.addMapping("/**")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS");
}
};
} }
} }

View File

@@ -3,18 +3,13 @@ package com.example.demo.supply.Order;
import com.example.demo.supply.Product.Product; import com.example.demo.supply.Product.Product;
import com.example.demo.supply.Supplier.Supplier; import com.example.demo.supply.Supplier.Supplier;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Objects;
import javax.persistence.*;
import java.util.Date; import java.util.Date;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
@Entity @Entity
@Table(name = "tab_order") @Table(name = "tab_order")

View File

@@ -11,7 +11,7 @@ import java.util.List;
@RestController @RestController
@CrossOrigin @CrossOrigin
@RequestMapping("/api/order") @RequestMapping("/order")
public class OrderController { public class OrderController {
private OrderService orderService; private OrderService orderService;

View File

@@ -14,8 +14,6 @@ public class OrderDto {
private Supplier supplier; private Supplier supplier;
private List<Product> products; private List<Product> products;
public OrderDto(){
}
public OrderDto(Order order){ public OrderDto(Order order){
this.id = order.getId(); this.id = order.getId();
this.dateOfOrder = order.getDateOfOrder(); this.dateOfOrder = order.getDateOfOrder();
@@ -38,15 +36,4 @@ public class OrderDto {
public List<Product> getProducts() { public List<Product> getProducts() {
return products; return products;
} }
public void setDateOfOrder(Date dateOfOrder) {
this.dateOfOrder = dateOfOrder;
}
public void setSupplier(Supplier supplier) {
this.supplier = supplier;
}
public void setProducts(List<Product> products) {
this.products = products;
}
} }

View File

@@ -1,52 +0,0 @@
package com.example.demo.supply.Order;
import com.example.demo.supply.Product.Product;
import com.example.demo.supply.Supplier.Supplier;
import java.util.Date;
import java.util.List;
public class OrderDtoForCreate {
private Long id;
private Date dateOfOrder;
private long supplierId;
private List<Long> productsId;
public OrderDtoForCreate(){
}
public OrderDtoForCreate(Order order){
this.id = order.getId();
this.dateOfOrder = order.getDateOfOrder();
this.supplierId = order.getSupplier().getId();
this.productsId = order.getProducts().stream().map(Product::getId).toList();
}
public long getId() {
return id;
}
public Date getDateOfOrder() {
return dateOfOrder;
}
public void setDateOfOrder(Date dateOfOrder) {
this.dateOfOrder = dateOfOrder;
}
public long getSupplierId() {
return supplierId;
}
public void setSupplierId(long supplierId) {
this.supplierId = supplierId;
}
public List<Long> getProductsId() {
return productsId;
}
public void setProductsId(List<Long> productsId) {
this.productsId = productsId;
}
}

View File

@@ -1,87 +0,0 @@
package com.example.demo.supply.Order;
import com.example.demo.supply.Product.ProductDto;
import com.example.demo.supply.Product.ProductService;
import com.example.demo.supply.Supplier.SupplierDto;
import com.example.demo.supply.Supplier.SupplierService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.sql.Array;
import java.util.ArrayList;
@Controller
@RequestMapping("/order")
public class OrderMvcController {
private OrderService orderService;
private ProductService productService;
private SupplierService supplierService;
public OrderMvcController(OrderService orderService,
ProductService productService,
SupplierService supplierService){
this.orderService = orderService;
this.productService = productService;
this.supplierService = supplierService;
}
@GetMapping
public String getOrders(Model model) {
model.addAttribute("orders",
orderService.findAllOrders().stream()
.map(OrderDto::new)
.toList());
return "order";
}
@GetMapping("/dop")
public String getSuppliers(Model model,
@RequestParam(required = false) Long id) {
if(id == null || id <= 0) {
model.addAttribute("productDto", new ProductDto());
model.addAttribute("suppliers", null);
model.addAttribute("selectedProduct", null);
}
else{
ProductDto product = new ProductDto(productService.findProduct(id));
model.addAttribute("productDto", product);
model.addAttribute("selectedProduct", null);
model.addAttribute("suppliers", orderService.suppliers(id).stream().map(SupplierDto::new).toList());
}
model.addAttribute("products", productService.findAllProducts().stream().map(ProductDto::new).toList());
// model.addAttribute("orderDto", new OrderDto(orderService.findOrder(id)));
return "order-dop";
}
@GetMapping("/add")
public String addOrder(Model model) {
model.addAttribute("orderDto", new OrderDtoForCreate());
model.addAttribute("selectedSupplier", null);
model.addAttribute("suppliers", supplierService.findAllSuppliers().stream().map(SupplierDto::new).toList());
model.addAttribute("products", productService.findAllProducts().stream().map(ProductDto::new).toList());
return "order-add";
}
@PostMapping("/create")
public String saveOrder(Model model,
@ModelAttribute("orderDto") @Valid OrderDtoForCreate order,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "order-add";
}
Order newOrder = orderService.addOrder(supplierService.findSupplier(order.getSupplierId()).getId());
for(Long obj: order.getProductsId())
orderService.addProduct(newOrder.getId(), obj);
return "redirect:/order";
}
@PostMapping("/delete/{id}")
public String deleteOrder(@PathVariable Long id) {
orderService.deleteOrder(id);
return "redirect:/order";
}
}

View File

@@ -8,6 +8,8 @@ import org.springframework.data.jpa.repository.Query;
import java.util.List; import java.util.List;
public interface OrderRepository extends JpaRepository<Order, Long> { public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("SELECT o.supplier FROM Order o where ?1 member of o.products") @Query("SELECT distinct o.supplier FROM Order o join Product p where p = ?1")
// @Query("SELECT distinct o.supplier FROM Order o where ?1 member of o.products")
List<Supplier> getSomeSuppliers(Product product); List<Supplier> getSomeSuppliers(Product product);
} }

View File

@@ -2,12 +2,11 @@ package com.example.demo.supply.Product;
import com.example.demo.supply.Order.Order; import com.example.demo.supply.Order.Order;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import javax.persistence.*;
import java.util.Objects;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
@Entity @Entity
public class Product { public class Product {

View File

@@ -6,7 +6,7 @@ import java.util.List;
@RestController @RestController
@CrossOrigin @CrossOrigin
@RequestMapping("/api/product") @RequestMapping("/product")
public class ProductController { public class ProductController {
private final ProductService productService; private final ProductService productService;

View File

@@ -10,8 +10,6 @@ public class ProductDto {
private double cost; private double cost;
private List<Order> orders; private List<Order> orders;
public ProductDto() {}
public ProductDto(Product product) { public ProductDto(Product product) {
this.id = product.getId(); this.id = product.getId();
this.name = product.getName(); this.name = product.getName();
@@ -31,16 +29,4 @@ public class ProductDto {
public List<Order> getOrders() { public List<Order> getOrders() {
return orders; return orders;
} }
public void setName(String name) {
this.name = name;
}
public void setCost(double cost) {
this.cost = cost;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
} }

View File

@@ -1,60 +0,0 @@
package com.example.demo.supply.Product;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Controller
@RequestMapping("/product")
public class ProductMvcController {
private final ProductService productService;
public ProductMvcController(ProductService productService){ this.productService = productService;}
@GetMapping
public String getProducts(Model model) {
model.addAttribute("products",
productService.findAllProducts().stream()
.map(ProductDto::new)
.toList());
return "product";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editProduct(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("productDto", new ProductDto());
} else {
model.addAttribute("productId", id);
model.addAttribute("productDto", new ProductDto(productService.findProduct(id)));
}
return "product-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveProduct(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ProductDto productDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "product-edit";
}
if (id == null || id <= 0) {
productService.addProduct(productDto.getName(), productDto.getCost());
} else {
productService.updateProduct(id, productDto.getName(), productDto.getCost());
}
return "redirect:/product";
}
@PostMapping("/delete/{id}")
public String deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
return "redirect:/product";
}
}

View File

@@ -1,5 +1,6 @@
package com.example.demo.supply.Product; package com.example.demo.supply.Product;
import com.example.demo.util.ValidatorUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;

View File

@@ -2,12 +2,11 @@ package com.example.demo.supply.Supplier;
import com.example.demo.supply.Order.Order; import com.example.demo.supply.Order.Order;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import javax.persistence.*;
import java.util.Objects;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
@Entity @Entity
public class Supplier { public class Supplier {

View File

@@ -6,7 +6,7 @@ import java.util.List;
@RestController @RestController
@CrossOrigin @CrossOrigin
@RequestMapping("/api/supplier") @RequestMapping("/supplier")
public class SupplierController { public class SupplierController {
private final SupplierService supplierService; private final SupplierService supplierService;

View File

@@ -10,9 +10,6 @@ public class SupplierDto {
private int license; private int license;
private List<Order> orders; private List<Order> orders;
public SupplierDto(){
}
public SupplierDto(Supplier supplier){ public SupplierDto(Supplier supplier){
this.id = supplier.getId(); this.id = supplier.getId();
this.name = supplier.getName(); this.name = supplier.getName();
@@ -30,16 +27,4 @@ public class SupplierDto {
public List<Order> getOrders() { public List<Order> getOrders() {
return orders; return orders;
} }
public void setName(String name) {
this.name = name;
}
public void setLicense(int license) {
this.license = license;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
} }

View File

@@ -1,60 +0,0 @@
package com.example.demo.supply.Supplier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Controller
@RequestMapping("/supplier")
public class SupplierMvcController {
private final SupplierService supplierService;
public SupplierMvcController(SupplierService supplierService){ this.supplierService = supplierService;}
@GetMapping
public String getSuppliers(Model model) {
model.addAttribute("suppliers",
supplierService.findAllSuppliers().stream()
.map(SupplierDto::new)
.toList());
return "supplier";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editSuppliers(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("supplierDto", new SupplierDto());
} else {
model.addAttribute("supplierId", id);
model.addAttribute("supplierDto", new SupplierDto(supplierService.findSupplier(id)));
}
return "supplier-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveSuppliers(@PathVariable(required = false) Long id,
@ModelAttribute @Valid SupplierDto supplierDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "supplier-edit";
}
if (id == null || id <= 0) {
supplierService.addSupplier(supplierDto.getName(), supplierDto.getLicense());
} else {
supplierService.updateSupplier(id, supplierDto.getName(), supplierDto.getLicense());
}
return "redirect:/supplier";
}
@PostMapping("/delete/{id}")
public String deleteSuppliers(@PathVariable Long id) {
supplierService.deleteSupplier(id);
return "redirect:/supplier";
}
}

View File

@@ -0,0 +1,37 @@
package com.example.demo.util;
import com.example.demo.supply.Product.ProductNotFoundException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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({
ProductNotFoundException.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 com.example.demo.util;
import java.util.Set;
public class ValidationException extends RuntimeException {
public ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
}

View File

@@ -0,0 +1,29 @@
package com.example.demo.util;
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,15 +0,0 @@
.container-padding {
padding: 10px;
}
.margin-bottom {
margin-bottom: 10px;
}
.button-fixed {
min-width: 120px;
}
.button-sm {
padding: 1px;
}

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"><!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path d="M448 48V384c-63.09 22.54-82.34 32-119.5 32c-62.82 0-86.6-32-149.3-32C158.6 384 142.6 387.6 128 392.2v-64C142.6 323.6 158.6 320 179.2 320c62.73 0 86.51 32 149.3 32C348.9 352 364.1 349 384 342.7v-208C364.1 141 348.9 144 328.5 144c-62.82 0-86.6-32-149.3-32C128.4 112 104.3 132.6 64 140.7v307.3C64 465.7 49.67 480 32 480S0 465.7 0 448V63.1C0 46.33 14.33 32 31.1 32S64 46.33 64 63.1V76.66C104.3 68.63 128.4 48 179.2 48c62.73 0 86.51 32 149.3 32C365.7 80 384.9 70.54 448 48z"/>
</svg>

Before

Width:  |  Height:  |  Size: 727 B

View File

@@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

View File

@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8"/>
<title>Поставки</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="icon" href="/favicon.svg">
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
<link rel="stylesheet" href="/css/style.css"/>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<i class="fa-solid fa-font-awesome"></i>
Поставки
</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-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" th:with="activeLink=${#request.requestURI}">
<a class="nav-link" href="/"
th:classappend="${#strings.equals(activeLink, '/')} ? 'active' : ''">Главная</a>
<a class="nav-link" href="/product"
th:classappend="${#strings.equals(activeLink, '/product')} ? 'active' : ''">Продукты</a>
<a class="nav-link" href="/supplier"
th:classappend="${#strings.equals(activeLink, '/supplier')} ? 'active' : ''">Поставщики</a>
<a class="nav-link" href="/order"
th:classappend="${#strings.equals(activeLink, '/order')} ? 'active' : ''">Заказы</a>
<a class="nav-link" href="/order/dop"
th:classappend="${#strings.equals(activeLink, '/order')} ? 'active' : ''">Доп задание</a>
<a class="nav-link" href="/swagger-ui/index.html" target="_blank">Документация REST API</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="container container-padding" layout:fragment="content">
</div>
</div>
</body>
<th:block layout:fragment="scripts">
</th:block>
</html>

View File

@@ -1,12 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>It's works!</div>
</div>
</body>
</html>

View File

@@ -1,35 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<form action="#" th:action="@{/order/create}" th:object="${orderDto}" method="post">
<div class="mb-3">
<button type="submit" class="btn btn-primary btn-success">Создать</button>
<a class="btn btn-primary btn-danger" th:href="@{/order}">
Назад
</a>
</div>
<div class="mb-3">
<label for="supplier" class="form-label">Поставщик</label>
<select id="supplier" class="form-select" th:field="*{supplierId}" th:name="${selectedSupplier}">
<option th:each="value: ${suppliers}" th:selected="${selectedSupplier != null and selectedSupplier == value.id}" th:value="${value.id}" th:text=" ${value.name}"></option>
</select>
</div>
<label>Продукты:</label>
<select id="author" class="form-select" multiple size="6" th:field="*{productsId}" >
<option th:each="product: ${products}"
th:value="${product.id}"
th:text="${product.name}" ></option>
</select>
</form>
</div>
</body>
</html>

View File

@@ -1,44 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<form action="#" th:action="@{/order/dop}" th:object="${productDto}" method="get">
<div class="mb-3">
<label for="product" class="form-label">Продукт</label>
<select id="product" class="form-select" th:field="*{id}" th:name="${selectedProduct}">
<option th:each="value: ${products}" th:selected="${selectedProduct != null and selectedProduct == value.id}" th:value="${value.id}" th:text="${value.name}"></option>
</select>
</div>
<button type="submit" class="btn btn-success button-fixed">Сформировать</button>
</form>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Название</th>
<th scope="col">Лицензия</th>
</tr>
</thead>
<tbody>
<tr th:each="supplier, iterator: ${suppliers}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${supplier.id}"/>
<td th:text="${supplier.name}"/>
<td th:text="${supplier.license}"/>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@@ -1,55 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/order/add}">
<i class="fa-solid fa-plus"></i> Создать заказ
</a>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Дата создания</th>
<th scope="col">Поставщик</th>
<th scope="col">Продукты</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="order, iterator: ${orders}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${order.id}"/>
<td th:text="${order.dateOfOrder}" />
<td th:text="${order.supplier.name}" />
<td>
<li th:each="product : ${order.products}" th:text="${product.name}"></li>
</td>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${order.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/order/delete/{id}(id=${order.id})}" method="post">
<button th:id="'remove-' + ${order.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<form action="#" th:action="@{/product/{id}(id=${id})}" th:object="${productDto}" method="post">
<div class="mb-3">
<label for="name" class="form-label">Название</label>
<input type="text" class="form-control" id="name" th:field="${productDto.name}" required="true">
</div>
<div class="mb-3">
<label for="cost" class="form-label">Цена</label>
<input type="text" class="form-control" id="cost" th:field="${productDto.cost}" required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/product}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@@ -1,55 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/product/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Название</th>
<th scope="col">Цена</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="product, iterator: ${products}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${product.id}"/>
<td th:text="${product.name}" />
<td th:text="${product.cost}" />
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/product/edit/{id}(id=${product.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${product.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/product/delete/{id}(id=${product.id})}" method="post">
<button th:id="'remove-' + ${product.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<form action="#" th:action="@{/supplier/{id}(id=${id})}" th:object="${supplierDto}" method="post">
<div class="mb-3">
<label for="name" class="form-label">Название</label>
<input type="text" class="form-control" id="name" th:field="${supplierDto.name}" required="true">
</div>
<div class="mb-3">
<label for="license" class="form-label">Лицензия</label>
<input type="text" class="form-control" id="license" th:field="${supplierDto.license}" required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/supplier}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@@ -1,55 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/supplier/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Название</th>
<th scope="col">Лицензия</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="supplier, iterator: ${suppliers}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${supplier.id}"/>
<td th:text="${supplier.name}"/>
<td th:text="${supplier.license}"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/supplier/edit/{id}(id=${supplier.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${supplier.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/supplier/delete/{id}(id=${supplier.id})}" method="post">
<button th:id="'remove-' + ${supplier.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@@ -3,6 +3,7 @@ import CatalogProducts from "./Pages/CatalogProducts";
import CatalogSuppliers from "./Pages/CatalogSuppliers"; import CatalogSuppliers from "./Pages/CatalogSuppliers";
import OrderPage from "./Pages/OrdersPage"; import OrderPage from "./Pages/OrdersPage";
import CreateOrderPage from "./Pages/CreateOrderPage"; import CreateOrderPage from "./Pages/CreateOrderPage";
import GetSomeSuppliers from "./Pages/GetSomeSuppliers";
import Header from "./general/Header"; import Header from "./general/Header";
function App() { function App() {
@@ -16,6 +17,7 @@ function App() {
<Route path="/suppliers" Component={CatalogSuppliers} /> <Route path="/suppliers" Component={CatalogSuppliers} />
<Route path="/orders" Component={OrderPage} /> <Route path="/orders" Component={OrderPage} />
<Route path="/createOrder" Component={CreateOrderPage} /> <Route path="/createOrder" Component={CreateOrderPage} />
<Route path="/dop" Component={GetSomeSuppliers} />
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>

View File

@@ -6,7 +6,6 @@ function getFullUrl(url, data) {
const fields = Object.getOwnPropertyNames(data); const fields = Object.getOwnPropertyNames(data);
//проходимся по каждому полю //проходимся по каждому полю
for (const field of fields) { for (const field of fields) {
if (field === undefined) continue if (field === undefined) continue
if (field === 'id') continue if (field === 'id') continue
if (field === 'date') continue if (field === 'date') continue
@@ -51,26 +50,12 @@ export default class DataService {
return true; return true;
} }
static async getSomeSuppliers(){ static async getSomeSuppliers(url){
const arr =[ const response = await fetch(this.mainUrl + url, {
{ method: 'GET',
"id":104, }).catch(e => console.log(e))
"name":"prod3", const res = response.json()
"cost":3333 return res
},
{
"id":153,
"name":"prod3",
"cost":5555
}
]
//const resArr = JSON.stringify(arr)
//console.log(resArr)
const response = await axios.post(this.mainUrl + `order/someSuppliers/`, {
body: {arr}
});
console.log(response)
} }
static async update(url, data) { static async update(url, data) {

View File

@@ -4,7 +4,6 @@ import Order from '../models/Order';
import Supplier from '../models/Supplier'; import Supplier from '../models/Supplier';
import Product from '../models/Product'; import Product from '../models/Product';
import DataService from '../DataService'; import DataService from '../DataService';
import Modal from '../general/Modal';
export default function CatalogOrders(props) { export default function CatalogOrders(props) {
const url = 'order/' const url = 'order/'

View File

@@ -0,0 +1,97 @@
import React, { useState, useEffect } from "react";
import Modal from "../general/Modal";
import Table from "../general/Table";
import DataService from "../DataService";
import Product from "../models/Product";
import Supplier from "../models/Supplier";
export default function GetSomeSuppliers(props) {
const url = 'order/someSuppliers/'
const productUrl = 'product/'
const headers = [
{ name: 'name', label: 'Поставщик' },
{ name: 'license', label: 'Лицензия' }
];
const transformer = (data) => new Supplier(data)
const transformerProduct = (data) => new Product(data)
const [suppliers, setSuppliers] = useState([])
const [products, setProducts] = useState([])
const [product, setProduct] = useState(new Product())
const [modalHeader, setModalHeader] = useState('')
const [modalConfirm, setModalConfirm] = useState('')
const [modalVisible, setModalVisible] = useState(false)
useEffect(() => {
loadItems()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const loadItems = () => {
DataService.readAll(productUrl, transformerProduct).then(data =>{
console.log(data)
setProducts(data)
})
}
const chooseProduct = () => {
setModalHeader('Добавление')
setModalConfirm('Добавить')
setModalVisible(true)
}
const save = () => {
console.log(product)
DataService.getSomeSuppliers(`${url}${product.id}`)
.then(data => setSuppliers(data))
}
const handleChooseProduct = (event) => {
// console.log(event.target.id)
// console.log(event.target.value)
setProduct({ ...product, [event.target.id]: event.target.value })
}
const handleTableClick = (tableSelectedItems) => console.log("")
const handleTableDblClick = (tableSelectedItem) => console.log("")
const hideModal = () => {
setModalVisible(false)
}
const modalDone = () => save()
return (
<>
<button type="button" className="btn btn-success" onClick={chooseProduct}>Выбрать продукт</button>
<Table
headers={headers}
items={suppliers}
selectable={false}
onClick={handleTableClick}
onDblClick={handleTableDblClick}/>
<Modal
header={modalHeader}
confirm={modalConfirm}
visible={modalVisible}
onHide={hideModal}
onDone={modalDone}>
<div className="mb-3">
<p className="h4" htmlFor="id">Продукт</p>
<select id="id" className="form-select" required
value={product.id} onChange={handleChooseProduct}>
<option disabled value="">Укажите продукт</option>
{
products.map(product =>
<option key={product.id} value={product.id}>{product.name}</option>
)
}
</select>
</div>
</Modal>
</>
);
}

View File

@@ -12,7 +12,6 @@ function Catalog(props) {
const [modalVisible, setModalVisible] = useState(false) const [modalVisible, setModalVisible] = useState(false)
const [addProdVisible, setAddProdVisible] = useState(false) const [addProdVisible, setAddProdVisible] = useState(false)
const [isEdit, setEdit] = useState(false) const [isEdit, setEdit] = useState(false)
const [isAddProd, setIsAddProd] = useState(false)
let selectedItems = []; let selectedItems = [];
@@ -24,7 +23,10 @@ function Catalog(props) {
const loadItems = () => { const loadItems = () => {
DataService.readAll(props.url, props.transformer) DataService.readAll(props.url, props.transformer)
.then(data => setItems(data)) .then(data =>{
console.log(data)
setItems(data)
} )
} }
const saveItem = () => { const saveItem = () => {

View File

@@ -27,6 +27,11 @@ export default function Header() {
Заказы Заказы
</Link> </Link>
</li> </li>
<li className="nav-item">
<Link className="nav-link" to="/dop">
Доп задание
</Link>
</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -43,7 +43,7 @@ export default function Table(props) {
return data return data
else{ else{
let prod = '' let prod = ''
data.map(product => prod += ` <${product.name}> `) data.map(product => prod += ` ${product.name},`)
return prod return prod
} }
} }