diff options
Diffstat (limited to 'src')
6 files changed, 346 insertions, 27 deletions
diff --git a/src/main/java/ru/mrfoxygmfr/warehouse_accounting/http/controllers/OperationsController.java b/src/main/java/ru/mrfoxygmfr/warehouse_accounting/http/controllers/OperationsController.java index f4acdd1..6e29e09 100644 --- a/src/main/java/ru/mrfoxygmfr/warehouse_accounting/http/controllers/OperationsController.java +++ b/src/main/java/ru/mrfoxygmfr/warehouse_accounting/http/controllers/OperationsController.java @@ -4,11 +4,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import ru.mrfoxygmfr.warehouse_accounting.db.dao.*; import ru.mrfoxygmfr.warehouse_accounting.db.dao.specs.OperationSpecs; +import ru.mrfoxygmfr.warehouse_accounting.db.dao.specs.ProductSpecs; import ru.mrfoxygmfr.warehouse_accounting.db.models.*; import java.util.List; @@ -17,6 +16,10 @@ import java.util.List; public class OperationsController { @Autowired private OperationDAO operationDAO; + @Autowired + private PartnerDAO partnerDAO; + @Autowired + private ProductDAO productDAO; @GetMapping(value = { "/", "/index", "/operations"}) public String operations(@RequestParam(name = "operationType", required = false) OperationType type, @@ -50,29 +53,136 @@ public class OperationsController { public String operation(@RequestParam(name = "id") Integer id, Model model) { Operation operation = operationDAO.findById(id).orElseThrow(); model.addAttribute("operation", operation); - return "operationEdit"; + return "operationView"; } @PostMapping("operation") public String operation( - @RequestParam(name = "id") Integer id, - @RequestParam(name = "type") String type, - @RequestParam(name = "status") String status, - @RequestParam(name = "partner_id") Integer partnerId, - @RequestParam(name = "responsible_id") Integer responsibleId, + @RequestParam(name = "operationId") Integer operationId, + @RequestParam(name = "operationResponsible") Integer responsibleId, + @RequestParam(name = "operationAddress") String address, Model model) { - Operation operation; - if (id != null) { - operation = operationDAO.findById(id).orElseThrow(); - } else { - operation = new Operation(); - } + Operation operation = operationDAO.findById(operationId).orElseThrow(); + + operation.setResponsible(operation.getPartner().getContacts().stream().filter( + contact -> contact.getId() == responsibleId + ).findFirst().orElseThrow()); + operation.setAddress(address); + + operationDAO.save(operation); return String.format("redirect:/operation?id=%d", operation.getId()); } @GetMapping("newOperation") - public String newOperation(Model model) { - return "operationEdit"; + public String newOperation(@RequestParam(name = "partnerId") Integer partnerId, + Model model) { + Partner partner = partnerDAO.findById(partnerId).orElseThrow(); + + Operation operation = new Operation(); + operation.setPartner(partner); + operation.setAddress(partner.getAddress()); + operation.setStatus(OperationStatus.CHECKOUT); + if (partner.getType() == PartnerType.ISSUER) { + operation.setType(OperationType.ISSUE); + } else { + operation.setType(OperationType.SUPPLY); + } + operation.setResponsible(partner.getContacts().stream().findFirst().orElseThrow()); + + operationDAO.save(operation); + return "redirect:/operations"; + } + + @RequestMapping("/operationProducts/{operationId}") + public String operationProducts(@PathVariable(value = "operationId") Integer operationId, + Model model) { + + Operation operation = operationDAO.findById(operationId).orElseThrow(); + model.addAttribute("products", operation.getProducts()); + model.addAttribute("operationId", operationId); + return "operationProducts"; + } + + @RequestMapping("/operationProducts/{operationId}/new/") + public String operationProductsNew(@PathVariable(value = "operationId") Integer operationId, + @RequestParam(name = "operationProductName", required = false) String name, + @RequestParam(name = "operationProductHeightLess", required = false) Integer heightLess, + @RequestParam(name = "operationProductHeightGreater", required = false) Integer heightGreater, + @RequestParam(name = "operationProductWidthLess", required = false) Integer widthLess, + @RequestParam(name = "operationProductWidthGreater", required = false) Integer widthGreater, + @RequestParam(name = "operationProductDepthLess", required = false) Integer depthLess, + @RequestParam(name = "operationProductDepthGreater", required = false) Integer depthGreater, + Model model) { + Specification<Product> spec = Specification.where(null); + if (name != null && !name.isEmpty()) { + spec = spec.and(ProductSpecs.productNameLike(name)); + model.addAttribute("operationProductNameFilter", name); + } + if (heightLess != null) { + spec = spec.and(ProductSpecs.productHeightLess(heightLess)); + model.addAttribute("operationProductHeightLessFilter", heightLess); + } + if (heightGreater != null) { + spec = spec.and(ProductSpecs.productHeightGreater(heightGreater)); + model.addAttribute("operationProductHeightGreaterFilter", heightGreater); + } + if (widthLess != null) { + spec = spec.and(ProductSpecs.productWidthLess(widthLess)); + model.addAttribute("operationProductWidthLessFilter", widthLess); + } + if (widthGreater != null) { + spec = spec.and(ProductSpecs.productWidthGreater(widthGreater)); + model.addAttribute("operationProductWidthGreaterFilter", widthGreater); + } + if (depthLess != null) { + spec = spec.and(ProductSpecs.productDepthLess(depthLess)); + model.addAttribute("operationProductDepthLessFilter", depthLess); + } + if (depthGreater != null) { + spec = spec.and(ProductSpecs.productDepthGreater(depthGreater)); + model.addAttribute("operationProductDepthGreaterFilter", depthGreater); + } + + List<Product> products = productDAO.findAll(spec); + model.addAttribute("products", products); + model.addAttribute("operationId", operationId); + return "operationProductNew"; + } + + @RequestMapping("/operationProducts/{operationId}/edit/") + public String operationProductsEdit_GET(@PathVariable(value = "operationId") Integer operationId, + @RequestParam(name = "id") Integer productId, + + Model model) { + + Operation operation = operationDAO.findById(operationId).orElseThrow(); + Product product = productDAO.findById(productId).orElseThrow(); + + model.addAttribute("product", product); + model.addAttribute("operation", operation); + model.addAttribute("amount", operation.getProducts().parallelStream().filter(p -> p.getProduct().getId() == productId).findFirst().orElse(new OperationProduct()).getAmount()); + return "operationProductEdit"; + } + + @RequestMapping(value="/operationProducts/{operationId}/edit/", method = RequestMethod.POST) + public String operationProductsEdit_POST(@PathVariable(value = "operationId") Integer operationId, + @RequestParam(name = "productId") Integer productId, + @RequestParam(name = "productAmount") Integer amount, + Model model) { + + Operation operation = operationDAO.findById(operationId).orElseThrow(); + Product product = productDAO.findById(productId).orElseThrow(); + + OperationProduct op = operation.getProducts().parallelStream() + .filter(p -> p.getProduct().getId() == productId) + .findAny() + .orElse(new OperationProduct(operation, product, amount)); + op.setAmount(amount); + + operation.updateProduct(op); + operationDAO.save(operation); + + return String.format("redirect:/operationProducts/%d", operationId); } } diff --git a/src/main/resources/templates/operationEdit.html b/src/main/resources/templates/operationEdit.html deleted file mode 100644 index 566549b..0000000 --- a/src/main/resources/templates/operationEdit.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <title>Title</title> -</head> -<body> - -</body> -</html>
\ No newline at end of file diff --git a/src/main/resources/templates/operationProductEdit.html b/src/main/resources/templates/operationProductEdit.html new file mode 100644 index 0000000..f764c80 --- /dev/null +++ b/src/main/resources/templates/operationProductEdit.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html xmlns:th="http://www.thymeleaf.org" lang="en"> +<div th:replace="~{common :: head}"></div> + +<body> +<div th:replace="~{common :: page-header}"></div> + +<div class="indent"> + <form method="post" th:action="'/operationProducts/' + ${operationId} + '/edit/'"> + <input hidden id="operationId" name="operationId" th:value="${operation.getId()}"> + <input hidden id="productId" name="productId" th:value="${product.getId()}"> + + + <p th:text="'Продукт: ' + ${product.getName()}"></p> + <label for="productAmount">Количество:</label> + <input type="text" id="productAmount" name="productAmount" required th:value="${amount}"><br><br> + + <input id="saveBtn" type="submit" value="Сохранить" class="btn btn-primary"> + </form> +</div> + + +<div th:replace="~{common :: site-footer}"></div> +<div th:replace="~{common :: site-script}"></div> +<div th:replace="~{common :: editFieldsToggle}"></div> + +</body> +</html>
\ No newline at end of file diff --git a/src/main/resources/templates/operationProductNew.html b/src/main/resources/templates/operationProductNew.html new file mode 100644 index 0000000..c5f68b7 --- /dev/null +++ b/src/main/resources/templates/operationProductNew.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML> +<html xmlns:th="http://www.thymeleaf.org" lang="en"> +<div th:replace="~{common :: head}"></div> + +<body> +<div th:replace="~{common :: page-header}"></div> + +<div class="indent"> + <form method="get" th:action="'/operationProducts/' + ${operationId} + '/new/'"> + <table class="table"> + <thead class="theme-dark"> + <tr> + <th colspan="6">Фильтры</th> + </tr> + </thead> + <tbody> + <tr> + <td>Название</td> + <td> + <input type="text" id="operationProductNameFilter" name="operationProductName" th:value="${operationProductNameFilter}"> + </td> + </tr> + <tr> + <td>Высота</td> + <td> + от <input type="text" id="operationProductHeightGreaterFilter" name="operationProductHeightGreater" th:value="${operationProductHeightGreaterFilter}"> + до <input type="text" id="operationProductHeightLessFilter" name="operationProductHeightLess" th:value="${operationProductHeightLessFilter}"> + </td> + </tr> + <tr> + <td>Ширина</td> + <td> + от <input type="text" id="operationProductWidthGreaterFilter" name="operationProductWidthGreater" th:value="${operationProductWidthGreaterFilter}"> + до <input type="text" id="operationProductWidthLessFilter" name="operationProductWidthLess" th:value="${operationProductWidthLessFilter}"> + </td> + </tr> + <tr> + <td>Глубина</td> + <td> + от <input type="text" id="operationProductDepthGreaterFilter" name="operationProductDepthGreater" th:value="${operationProductDepthGreaterFilter}"> + до <input type="text" id="operationProductDepthLessFilter" name="operationProductDepthLess" th:value="${operationProductDepthLessFilter}"> + </td> + </tr> + <tr> + <td colspan="6"><input id="saveBtn" type="submit" value="Применить" class="btn btn-primary"></td> + </tr> + </tbody> + </table> + </form> + + <table class="table table-bordered table-warning"> + <thead class="thead-dark"> + <tr> + <th scope="col">Название</th> + <th scope="col">Габариты (В*Ш*Г)</th> + <th scope="col">Добавить</th> + </tr> + </thead> + <tbody> + <tr th:if="${products.isEmpty()}"> + <td colspan="6">Данному фильтру не удовлетворяет ни одного продукта.</td> + </tr> + <tr th:each="product : ${products}"> + <td> + <a th:href="'/product?id=' + ${product.getId()}"> + <span th:text="${product.getName()}"></span> + </a> + </td> + <td> + <span th:text="${product.getHeight()} + ' * ' + ${product.getWidth()} + ' * ' + ${product.getDepth()}"></span> + </td> + <td> + <a th:href="'/operationProducts/' + ${operationId} + '/edit/?id=' + ${product.getId()}"> + <span th:text="Добавить"></span> + </a> + </td> + </tr> + </tbody> + </table> +</div> + +<div th:replace="~{common :: site-footer}"></div> +<div th:replace="~{common :: site-script}"></div> +</body> +</html>
\ No newline at end of file diff --git a/src/main/resources/templates/operationProducts.html b/src/main/resources/templates/operationProducts.html new file mode 100644 index 0000000..f3997b4 --- /dev/null +++ b/src/main/resources/templates/operationProducts.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html xmlns:th="http://www.thymeleaf.org" lang="en"> +<div th:replace="~{common :: head}"></div> + +<body> +<div th:replace="~{common :: page-header}"></div> + +<div class="indent"> + <form method="get" th:action="'/operationProducts/' + ${operationId} + '/new/'"> + <button id="newPartnerContactBtn" type="submit" class="btn btn-primary">Добавить новый продукт</button> + </form> + <br> + + <table class="table table-bordered table-warning"> + <thead class="thead-dark"> + <tr> + <th scope="col">Название</th> + <th scope="col">Габариты (В*Ш*Г)</th> + <th scope="col">Количество</th> + </tr> + </thead> + <tbody> + <tr th:if="${products.isEmpty()}"> + <td colspan="6">В операции нет ни одного продукта.</td> + </tr> + <tr th:each="opProduct : ${products}"> + <td> + <a th:href="'/product?id=' + ${opProduct.getProduct().getId()}"> + <span th:text="${opProduct.getProduct().getName()}"></span> + </a> + </td> + <td> + <span th:text="${opProduct.getProduct().getHeight()} + ' * ' + ${opProduct.getProduct().getWidth()} + ' * ' + ${opProduct.getProduct().getDepth()}"></span> + </td> + <td> + <a th:href="'/operationProducts/' + ${opProduct.getOperation().getId()} + '/edit/?id=' + ${opProduct.getProduct().getId()}"> + <span th:text="${opProduct.getAmount()}"></span> + </a> + </td> + </tr> + </tbody> + </table> +</div> + +<div th:replace="~{common :: site-footer}"></div> +<div th:replace="~{common :: site-script}"></div> +</body> +</html>
\ No newline at end of file diff --git a/src/main/resources/templates/operationView.html b/src/main/resources/templates/operationView.html new file mode 100644 index 0000000..37631b8 --- /dev/null +++ b/src/main/resources/templates/operationView.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html xmlns:th="http://www.thymeleaf.org" lang="en"> +<div th:replace="~{common :: head}"></div> + +<body> +<div th:replace="~{common :: page-header}"></div> + +<div class="indent"> + <div id="updateToggleSelector"> + <button id="updateBtn" class="btn btn-primary" onclick="toggleDisabled()">Изменить</button><br><br> + <a th:href="'/operationProducts/' + ${operation.getId()}"> + <button class="btn btn-primary">Управление продуктами</button> + </a><br><br> + </div> + + <form method="post" action="/operation"> + <input disabled hidden id="operationId" name="operationId" th:value="${operation.getId()}"> + + <p th:text="'Тип: ' + ${operation.getType().toString()}"></p> + <label for="operationStatus">Статус:</label> + <select disabled id="operationStatus" name="operationStatus" required> + <option value="0" disabled>Выберите статус</option> + <option th:value="'CHECKOUT'" th:text="CHECKOUT" th:selected="${operation.getStatus().toString() == 'CHECKOUT'}"></option> + <option th:value="'APPROVAL'" th:text="APPROVAL" th:selected="${operation.getStatus().toString() == 'APPROVAL'}"></option> + <option th:value="'READY'" th:text="READY" th:selected="${operation.getStatus().toString() == 'READY'}"></option> + <option th:value="'EXECUTED'" th:text="EXECUTED" th:selected="${operation.getStatus().toString() == 'EXECUTED'}"></option> + <option th:value="'CANCELLED'" th:text="CANCELLED" th:selected="${operation.getStatus().toString() == 'CANCELLED'}"></option> + </select> <br><br> + + <a th:href="@{/partner(id=${operation.getPartner().getId()})}"> + <p th:text="'Партнер: ' + ${operation.getPartner().getName()}"></p> + </a> + + <label for="operationResponsible">Ответственное лицо:</label> + <select disabled id="operationResponsible" name="operationResponsible" required> + <option value="0" disabled>Выберите ответственного</option> + <option th:each="contact : ${operation.getPartner().getContacts()}" + th:value="${contact.getId()}" th:text="${contact.getSurname()} + ' ' + ${contact.getName()}" th:selected="${operation.getResponsible() == contact}"></option> + </select> <br><br> + + <label for="operationAddress">Адрес:</label> + <input disabled type="text" id="operationAddress" name="operationAddress" required th:value="${operation.getAddress()}"><br><br> + + <p th:text="'Дата создания: ' + ${operation.getDateCreated()}"></p> + <p th:text="'Дата изменения: ' + ${operation.getDateModified()}"></p> + <p th:if="${operation.getDateFinished() != null}" th:text="'Дата окончания: ' + ${operation.getDateFinished()}"></p> + + <input id="saveBtn" type="submit" value="Сохранить" class="btn btn-primary" hidden> + </form> +</div> + + +<div th:replace="~{common :: site-footer}"></div> +<div th:replace="~{common :: site-script}"></div> +<div th:replace="~{common :: editFieldsToggle}"></div> + +</body> +</html>
\ No newline at end of file |