Compare commits

...

No commits in common. "main" and "Lab_6" have entirely different histories.
main ... Lab_6

62 changed files with 3879 additions and 24 deletions

56
.gitignore vendored
View File

@ -1,26 +1,38 @@
# ---> Java
# Compiled class file
*.class
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
# Log file
*.log
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
# BlueJ files
*.ctxt
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
/front/node_modules/

View File

@ -1,2 +0,0 @@
# Pibd-22_Presnyakova.V.V_IP

42
build.gradle Normal file
View File

@ -0,0 +1,42 @@
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.8'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'ru.ulstu.is'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
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 'com.h2database:h2:2.1.210'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'org.hibernate.validator:hibernate-validator'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
implementation 'org.jetbrains:annotations:24.0.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}

BIN
data.mv.db Normal file

Binary file not shown.

1124
data.trace.db Normal file

File diff suppressed because it is too large Load Diff

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

240
gradlew vendored Normal file
View File

@ -0,0 +1,240 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

91
gradlew.bat vendored Normal file
View File

@ -0,0 +1,91 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

1
settings.gradle Normal file
View File

@ -0,0 +1 @@
rootProject.name = 'sbapp'

View File

@ -0,0 +1,14 @@
package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordEncoderConfiguration {
@Bean
public PasswordEncoder createPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,16 @@
package ru.ulstu.is.sbapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class SbappApplication {
public static void main(String[] args) {
SpringApplication.run(SbappApplication.class, args);
}
}

View File

@ -0,0 +1,62 @@
package ru.ulstu.is.sbapp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import ru.ulstu.is.sbapp.repair.model.UserRole;
import ru.ulstu.is.sbapp.repair.mvcController.UserSignupMvcController;
import ru.ulstu.is.sbapp.repair.service.UserService;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private static final String LOGIN_URL = "/login";
private final UserService userService;
public SecurityConfiguration(UserService userService) {
this.userService = userService;
createAdminOnStartup();
}
private void createAdminOnStartup() {
final String admin = "admin";
if (userService.findByLogin(admin) == null) {
log.info("Admin user successfully created");
userService.createUser(admin, admin, admin, UserRole.ADMIN);
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().sameOrigin().and()
.cors().and()
.csrf().disable()
.authorizeRequests()
.antMatchers(UserSignupMvcController.SIGNUP_URL).permitAll()
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(LOGIN_URL).permitAll()
.and()
.logout().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/css/**")
.antMatchers("/js/**")
.antMatchers("/templates/**")
.antMatchers("/webjars/**");
}
}

View File

@ -0,0 +1,21 @@
package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("login");
}
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**").allowedMethods("*");
}
}

View File

@ -0,0 +1,60 @@
package ru.ulstu.is.sbapp.repair.controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.repair.dtos.ComponentDTO;
import ru.ulstu.is.sbapp.repair.service.ComponentService;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/component")
public class ComponentController {
private final ComponentService componentService;
public ComponentController(ComponentService productService){
this.componentService = productService;
}
@PostMapping("/")
public ComponentDTO addComponent(@RequestBody @Valid ComponentDTO componentDTO) throws IOException {
return new ComponentDTO(componentService.addComponent(componentDTO.getComponentName(), componentDTO.getAmount()));
}
@PutMapping("/{id}")
public ComponentDTO updateComponent(@PathVariable Long id,@RequestBody @Valid ComponentDTO componentDTO) {
return new ComponentDTO(componentService.updateComponent(id,componentDTO.getComponentName(), componentDTO.getAmount()));
}
@DeleteMapping("/{id}")
public ComponentDTO removeComponent(@PathVariable Long id) {
return new ComponentDTO(componentService.deleteComponent(id));
}
@DeleteMapping
public void removeAllComponents() {
componentService.deleteAllComponent();
}
@GetMapping("/{id}")
public ComponentDTO findComponent(@PathVariable Long id) {
return new ComponentDTO(componentService.findComponent(id));
}
@GetMapping
public List<ComponentDTO> findAllComponents() {
return componentService.findAllComponent()
.stream()
.map(ComponentDTO::new)
.toList();
}
@GetMapping("/filter")
public List<ComponentDTO> getFilteredComponents(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "componentName", required = false) String componentName,
@RequestParam(value = "amount", required = false) Integer amount ) {
return componentService.findFilteredComponents(id, componentName, amount).stream()
.map(ComponentDTO::new)
.toList();
}
}

View File

@ -0,0 +1,72 @@
package ru.ulstu.is.sbapp.repair.controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.repair.dtos.ComponentDTO;
import ru.ulstu.is.sbapp.repair.dtos.FavorDTO;
import ru.ulstu.is.sbapp.repair.service.FavorService;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/favor")
public class FavorController {
private final FavorService favorService;
public FavorController(FavorService favorService){
this.favorService = favorService;
}
@PostMapping
public FavorDTO addFavor(@RequestBody @Valid FavorDTO favorDTO) {
return new FavorDTO(favorService.addFavor(favorDTO.getFavorName(), favorDTO.getPrice()));
}
@PutMapping("/{id}")
public FavorDTO updateFavor(@PathVariable Long id,@RequestBody @Valid FavorDTO favorDTO) {
return new FavorDTO(favorService.updateFavor(id,favorDTO.getFavorName(), favorDTO.getPrice()));
}
@PostMapping("/{id}/component")
public FavorDTO putIntoFavor(@PathVariable Long id, @RequestParam("compId") Long compId){
return new FavorDTO(favorService.addComponentToFavor(id, compId));
}
@DeleteMapping("/{id}")
public FavorDTO removeFavor(@PathVariable Long id) {
return new FavorDTO(favorService.deleteFavor(id));
}
//promises.push(DataService.delete(this.dataUrl + "/" + favorId + "?compId=" + item));
@DeleteMapping("/{id}/component")
public FavorDTO removeComponentFromFavor(@PathVariable Long id, @RequestParam("compId") Long compId) {
return new FavorDTO(favorService.deleteComponentfromFavor(id, compId));
}
@DeleteMapping
public void removeAllFavors() {
favorService.deleteAllFavor();
}
@GetMapping("/{id}")
public FavorDTO findFavor(@PathVariable Long id) {
return new FavorDTO(favorService.findFavor(id));
}
@GetMapping
public List<FavorDTO> findAllFavors() {
return favorService.findAllFavor()
.stream()
.map(FavorDTO::new)
.toList();
}
@GetMapping("/filter")
public List<FavorDTO> getFilteredFavors(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "favorName", required = false) String favorName,
@RequestParam(value = "price", required = false) Integer price) {
return favorService.findFilteredFavors(id, favorName, price).stream()
.map(FavorDTO::new)
.toList();
}
}

View File

@ -0,0 +1,59 @@
package ru.ulstu.is.sbapp.repair.controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.repair.dtos.FavorDTO;
import ru.ulstu.is.sbapp.repair.dtos.OrderDTO;
import ru.ulstu.is.sbapp.repair.service.OrderService;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
private final OrderService orderService;
public OrderController(OrderService productService){
this.orderService = productService;
}
@PostMapping
public OrderDTO addOrder(@RequestBody @Valid OrderDTO orderDTO) {
return new OrderDTO(orderService.addOrder());
}
@PutMapping("/{id}")
public OrderDTO updateOrder(@PathVariable Long id) {
return new OrderDTO(orderService.updateOrder(id));
}
@PostMapping("/{id}/favor")
public OrderDTO putIntoOrder(@PathVariable Long id, @RequestParam("favId") Long favId){
return new OrderDTO(orderService.addFavorToOrder(id, favId));
}
@DeleteMapping("/{id}/favor")
public OrderDTO removeFavorFromOrder(@PathVariable Long id, @RequestParam("favId") Long favId) {
return new OrderDTO(orderService.deleteFavorfromOrder(id, favId));
}
@DeleteMapping("/{id}")
public OrderDTO removeOrder(@PathVariable Long id) {
return new OrderDTO(orderService.deleteOrder(id));
}
@DeleteMapping
public void removeAllOrders() {
orderService.deleteAllOrder();
}
@GetMapping("/{id}")
public OrderDTO findOrder(@PathVariable Long id) {
return new OrderDTO(orderService.findOrder(id));
}
@GetMapping
public List<OrderDTO> findAllOrders() {
return orderService.findAllOrders()
.stream()
.map(OrderDTO::new)
.toList();
}
}

View File

@ -0,0 +1,29 @@
package ru.ulstu.is.sbapp.repair.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
@RestController
public class ReportController {
// private final Order_FavorService orderFavorService;
// @Autowired
// public ReportController(Order_FavorService orderFavorService) {
// this.orderFavorService = orderFavorService;
// }
// @GetMapping("/report")
// public Map<String, Integer> GetReport (@RequestParam(value = "from") Object value1,
// @RequestParam(value = "to") Object value2) throws ParseException {
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
//
// Date d1 = formatter.parse(value1.toString());
// Date d2 = formatter.parse(value2.toString());
// return orderFavorService.makereport(d1, d2);
// }
}

View File

@ -0,0 +1,45 @@
package ru.ulstu.is.sbapp.repair.dtos;
import ru.ulstu.is.sbapp.repair.model.Component;
import java.util.List;
public class ComponentDTO {
private long id;
private String componentName;
private Integer amount;
private List<FavorDTO> favorsDTOListFromComponents;
public ComponentDTO(Component component){
this.id =component.getId();
this.componentName = component.getComponentName();
this.amount = component.getAmount();
this.favorsDTOListFromComponents = component.getFavors() == null ? null: component.getFavors()
.stream()
.filter(x -> x.getComponents().contains(component.getId()))
.map(y -> new FavorDTO(y))
.toList();
}
public ComponentDTO(){
}
public long getId() {
return id;
}
public String getComponentName(){
return componentName;
}
public Integer getAmount(){
return amount;
}
public void setComponentName(String modelName) {
this.componentName = modelName;
}
public void setAmount(Integer modelAmount) {
this.amount = modelAmount;
}
public List<FavorDTO> getFavorsDTOListFromComponents() {
return favorsDTOListFromComponents;
}
}

View File

@ -0,0 +1,69 @@
package ru.ulstu.is.sbapp.repair.dtos;
import ru.ulstu.is.sbapp.repair.model.Component;
import ru.ulstu.is.sbapp.repair.model.Favor;
import java.util.ArrayList;
import java.util.List;
public class FavorDTO {
private long id;
private String favorName;
private Integer price;
private List<ComponentDTO> componentsDTOList;
//private List<OrderDTO> ordersDTOList;
private List<Long> componentIds;
public FavorDTO(Favor favor){
this.id =favor.getId();
this.favorName = favor.getFavorName();
this.price = favor.getPrice();
if (favor.getComponents() == null){
this. componentIds = new ArrayList<>();
}
else {
this.componentIds = new ArrayList<>();
List<Component> components = favor.getComponents();
for (Component component : components) {
componentIds.add(component.getId());
}
}
this.componentsDTOList = favor.getComponents() == null ? null: favor.getComponents()
.stream()
.filter(x -> x.getFavors().contains(favor))
.map(ComponentDTO::new)
.toList();
//this.ordersDTOList = favor.getOrders() == null ? null: favor.getOrders()
// .stream()
// .filter(x -> x.getFavorsList().contains(favor))
// .map(OrderDTO::new)
//.toList();
}
public FavorDTO(){
}
public long getId() {
return id;
}
public String getFavorName(){
return favorName;
}
public Integer getPrice(){
return price;
}
public List<ComponentDTO> getComponentsDTOList() {
return componentsDTOList;
}
//public List<OrderDTO> getOrdersDTOList() {return ordersDTOList;}
public List<Long> getcomponentIds() { return this.componentIds; }
public void setFavorName(String modelName) {
this.favorName = modelName;
}
public void setPrice(Integer modelPrice) {
this.price = modelPrice;
}
public void setcomponentIds(List<Long> componentIds) { this.componentIds = componentIds; }
}

View File

@ -0,0 +1,54 @@
package ru.ulstu.is.sbapp.repair.dtos;
import ru.ulstu.is.sbapp.repair.dtos.FavorDTO;
import ru.ulstu.is.sbapp.repair.model.Component;
import ru.ulstu.is.sbapp.repair.model.Favor;
import ru.ulstu.is.sbapp.repair.model.Order;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class OrderDTO {
private long id;
private Date date;
private List<FavorDTO> favorsDTOList;
private List<Long> favorIds;
public OrderDTO(Order order){
this.id =order.getId();
this.date = order.getDate();
if (order.getFavorsList() == null){
this. favorIds = new ArrayList<>();
}
else {
this.favorIds = new ArrayList<>();
List<Favor> favors = order.getFavorsList();
for (Favor favor : favors) {
favorIds.add(favor.getId());
}
}
this.favorsDTOList = order.getFavorsList() == null ? null: order.getFavorsList()
.stream()
.filter(x -> x.getOrders().contains(order))
.map(FavorDTO::new)
.toList();
}
public OrderDTO(){
}
public long getId() {
return id;
}
public Date getDate(){
return date;
}
public List<FavorDTO> getFavorsDTOList() {
return favorsDTOList;
}
public List<Long> getfavorIds() { return this.favorIds; }
public void setfavorIds(List<Long> favorIds) { this.favorIds = favorIds; }
public void setDate(Date modeldate) { this.date = modeldate; }
}

View File

@ -0,0 +1,24 @@
package ru.ulstu.is.sbapp.repair.dtos;
import ru.ulstu.is.sbapp.repair.model.User;
import ru.ulstu.is.sbapp.repair.model.UserRole;
public class UserDTO {
private final long id;
private final String login;
private final UserRole role;
public UserDTO(User user) {
this.id = user.getId();
this.login = user.getLogin();
this.role = user.getRole();
}
public long getId() {
return id;
}
public String getLogin() {
return login;
}
public UserRole getRole() {
return role;
}
}

View File

@ -0,0 +1,34 @@
package ru.ulstu.is.sbapp.repair.dtos;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class UserSignupDTO {
@NotBlank
@Size(min = 3, max = 64)
private String login;
@NotBlank
@Size(min = 6, max = 64)
private String password;
@NotBlank
@Size(min = 6, max = 64)
private String passwordConfirm;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordConfirm() {
return passwordConfirm;
}
public void setPasswordConfirm(String passwordConfirm) {
this.passwordConfirm = passwordConfirm;
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.repair.exception;
public class ComponentNotFoundException extends RuntimeException{
public ComponentNotFoundException(Long id) {
super(String.format("Component with id [%s] is not found", id));
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.repair.exception;
public class FavorNotFoundException extends RuntimeException{
public FavorNotFoundException(Long id) {
super(String.format("Favor with id [%s] is not found", id));
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.repair.exception;
public class OrderNotFoundException extends RuntimeException{
public OrderNotFoundException(Long id) {
super(String.format("Order with id [%s] is not found", id));
}
}

View File

@ -0,0 +1,91 @@
package ru.ulstu.is.sbapp.repair.model;
import org.springframework.cache.interceptor.CacheableOperation;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "components")
public class Component {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "componentName")
private String componentName;
@Column(name = "amount")
private Integer amount;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "componentsList", cascade = {CascadeType.MERGE})
private List<Favor> favorsListFromComponents;
public Component() {
favorsListFromComponents = new ArrayList<>();
}
public Component(Integer amount, String componentName) {
this.componentName = componentName;
this.amount = amount;
favorsListFromComponents = new ArrayList<>();
}
public Long getId() {
return id;
}
public String getComponentName() {
return componentName;
}
public void setComponentName(String componentName) {
this.componentName = componentName;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public List<Favor> getFavors() {
return favorsListFromComponents;
}
public void addFavor(Favor favor) {
if (favorsListFromComponents == null)
favorsListFromComponents = new ArrayList<>();
if (!favorsListFromComponents.contains(favor)){
favorsListFromComponents.add(favor);
}
if (!favor.getComponents().contains(this)) {
favor.addComponent(this);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Component component = (Component) o;
return Objects.equals(id, component.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Component{" +
"id=" + id +
", componentName='" + componentName + '\'' +
", amount='" + amount + '\'' +
'}';
}
}

View File

@ -0,0 +1,120 @@
package ru.ulstu.is.sbapp.repair.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "favors")
public class Favor {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name")
private String favorName;
@Column(name = "price")
private Integer price;
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})
private List<Order> ordersList;
@ManyToMany(cascade = {CascadeType.MERGE})
@LazyCollection(LazyCollectionOption.FALSE)
private List<Component> componentsList;
public Favor() {
componentsList = new ArrayList<>();
ordersList = new ArrayList<>();
}
public Favor(String favorName, Integer price) {
this.favorName = favorName;
this.price = price;
componentsList = new ArrayList<>();
ordersList = new ArrayList<>();
}
public Long getId() {
return id;
}
public String getFavorName() {
return favorName;
}
public void setFavorName(String favorName) {
this.favorName = favorName;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public List<Order> getOrders() {
return ordersList;
}
public List<Component> getComponents() {return componentsList;}
public void addOrder(Order order) {
if (ordersList == null)
ordersList = new ArrayList<>();
if (!ordersList.contains(order)){
ordersList.add(order);
}
if (!order.getFavorsList().contains(this)) {
order.addFavor(this);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Favor favor = (Favor) o;
return Objects.equals(id, favor.id);
}
public void addComponent(Component component){
if (componentsList == null)
componentsList = new ArrayList<>();
if (!componentsList.contains(component)){
componentsList.add(component);
}
if (!component.getFavors().contains(this)) {
component.addFavor(this);
}
}
public void deleteComponent(Component comp){
componentsList.remove(comp);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", productName='" + favorName + '\'' +
", price='" + price + '\'' +
'}';
}
public void deleteFavor(Order currentOrder) {
ordersList.remove(currentOrder);
}
}

View File

@ -0,0 +1,71 @@
package ru.ulstu.is.sbapp.repair.model;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "date")
private Date date;
@ManyToMany (fetch = FetchType.EAGER, mappedBy = "ordersList", cascade = {CascadeType.REFRESH})
private List<Favor> favorsList;
public Order(){
}
public Order(Date date) {
this.date = date;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Order order)) return false;
return Objects.equals(getId(), order.getId()) && Objects.equals(getDate(), order.getDate());
}
public List<Favor> getFavorsList() {
return favorsList;
}
public void addFavor(Favor favor){
if (favorsList == null)
favorsList = new ArrayList<>();
if (!favorsList.contains(favor)) {
favorsList.add(favor);
}
favor.addOrder(this);
}
@Override
public int hashCode() {
return Objects.hash(getId(), getDate());
}
public void deleteFavor(Favor favor) {favorsList.remove(favor);}
}

View File

@ -0,0 +1,62 @@
package ru.ulstu.is.sbapp.repair.model;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Objects;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, unique = true, length = 64)
@NotBlank
@Size(min = 3, max = 64)
private String login;
@Column(nullable = false, length = 64)
@NotBlank
@Size(min = 6, max = 64)
private String password;
private UserRole role;
public User() {
}
public User(String login, String password) {
this(login, password, UserRole.USER);
}
public User(String login, String password, UserRole role) {
this.login = login;
this.password = password;
this.role = role;
}
public Long getId() {
return id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserRole getRole() {
return role;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id) && Objects.equals(login, user.login);
}
@Override
public int hashCode() {
return Objects.hash(id, login);
}
}

View File

@ -0,0 +1,17 @@
package ru.ulstu.is.sbapp.repair.model;
import org.springframework.security.core.GrantedAuthority;
public enum UserRole implements GrantedAuthority {
ADMIN,
USER;
private static final String PREFIX = "ROLE_";
@Override
public String getAuthority() {
return PREFIX + this.name();
}
public static final class AsString {
public static final String ADMIN = PREFIX + "ADMIN";
public static final String USER = PREFIX + "USER";
}
}

View File

@ -0,0 +1,65 @@
package ru.ulstu.is.sbapp.repair.mvcController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.repair.dtos.ComponentDTO;
import ru.ulstu.is.sbapp.repair.service.ComponentService;
import javax.validation.Valid;
@Controller
@RequestMapping("/components")
public class ComponentMvcController {
private final ComponentService componentService;
public ComponentMvcController(ComponentService componentService){
this.componentService = componentService;
}
@GetMapping
public String getComponents(Model model) {
model.addAttribute("components",
componentService.findAllComponent().stream()
.map(ComponentDTO::new)
.toList());
return "components";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editComponent(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("componentDto", new ComponentDTO());
} else {
model.addAttribute("componentId", id);
model.addAttribute("componentDto", new ComponentDTO(componentService.findComponent(id)));
}
return "component-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveComponent(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ComponentDTO componentDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "component-edit";
}
if (id == null || id <= 0) {
componentService.addComponent( componentDTO.getComponentName(), componentDTO.getAmount());
} else {
componentService.updateComponent(id, componentDTO.getComponentName(), componentDTO.getAmount());
}
return "redirect:/components";
}
@PostMapping("/delete/{id}")
public String deleteComponent(@PathVariable Long id) {
componentService.deleteComponent(id);
return "redirect:/monitors";
}
}

View File

@ -0,0 +1,90 @@
package ru.ulstu.is.sbapp.repair.mvcController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.is.sbapp.repair.dtos.ComponentDTO;
import ru.ulstu.is.sbapp.repair.dtos.FavorDTO;
import ru.ulstu.is.sbapp.repair.model.Favor;
import ru.ulstu.is.sbapp.repair.service.ComponentService;
import ru.ulstu.is.sbapp.repair.service.FavorService;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Controller
@RequestMapping("/favors")
public class FavorMvcController {
private final FavorService favorService;
private final ComponentService componentService;
public FavorMvcController(FavorService favorService,
ComponentService componentService) {
this.favorService = favorService;
this.componentService = componentService;
}
@GetMapping
public String getFavors(Model model) {
model.addAttribute("favors",
favorService.findAllFavor().stream()
.map(FavorDTO::new)
.toList());
return "favors";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editFavor(@PathVariable(required = false) Long id,
Model model) {
FavorDTO favorDTO = new FavorDTO();
if (id == null || id <= 0) {
model.addAttribute("favorDto", new FavorDTO());
} else {
model.addAttribute("favorId", id);
favorDTO = new FavorDTO(favorService.findFavor(id));
model.addAttribute("favorDto", favorDTO);
model.addAttribute("componentsList", favorDTO.getComponentsDTOList());
}
model.addAttribute("allComponents",
componentService.findAllComponent().stream()
.map(ComponentDTO::new)
.toList());
return "favor-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveFavor(@PathVariable(required = false) Long id,
@ModelAttribute @Valid FavorDTO favorDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "favor-edit";
}
if (id == null || id <= 0) {
favorService.addFavor(favorDTO.getFavorName(), favorDTO.getPrice());
} else {
favorService.updateFavor(id, favorDTO.getFavorName(), favorDTO.getPrice());
}
return "redirect:/favors";
}
@PostMapping(value = "/{id}/component/{componentId}")
public String addFavorComponent(@PathVariable(value = "id") Long id,
@PathVariable(value = "componentId") Long componentId) {
favorService.addComponentToFavor(id, componentId);
return "redirect:/favors";
}
@PostMapping(value = "/{id}/componentDelete/{componentId}")
public String deleteFavorComponent(@PathVariable(value = "id") Long id,
@PathVariable(value = "componentId") Long componentId) {
favorService.deleteComponentfromFavor(id, componentId);
return "redirect:/favors";
}
@PostMapping("/delete/{id}")
public String deleteFavor(@PathVariable Long id) {
favorService.deleteFavor(id);
return "redirect:/favors";
}
}

View File

@ -0,0 +1,93 @@
package ru.ulstu.is.sbapp.repair.mvcController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.repair.dtos.ComponentDTO;
import ru.ulstu.is.sbapp.repair.dtos.FavorDTO;
import ru.ulstu.is.sbapp.repair.dtos.OrderDTO;
import ru.ulstu.is.sbapp.repair.service.ComponentService;
import ru.ulstu.is.sbapp.repair.service.FavorService;
import ru.ulstu.is.sbapp.repair.service.OrderService;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Controller
@RequestMapping("/orders")
public class OrderMvcController {
private final OrderService orderService;
private final FavorService favorService;
public OrderMvcController(OrderService orderService,
FavorService favorService) {
this.orderService = orderService;
this.favorService = favorService;
}
@GetMapping
public String getOrders(Model model) {
model.addAttribute("orders",
orderService.findAllOrders().stream()
.map(OrderDTO::new)
.toList());
return "orders";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editOrder(@PathVariable(required = false) Long id,
Model model) {
OrderDTO orderDTO = new OrderDTO();
if (id == null || id <= 0) {
model.addAttribute("orderDto", new OrderDTO());
} else {
model.addAttribute("orderId", id);
orderDTO = new OrderDTO(orderService.findOrder(id));
model.addAttribute("orderDto", orderDTO);
model.addAttribute("favorsList", orderDTO.getFavorsDTOList());
}
model.addAttribute("allFavors",
favorService.findAllFavor().stream()
.map(FavorDTO::new)
.toList());
return "order-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveOrder(@PathVariable(required = false) Long id,
@ModelAttribute @Valid OrderDTO orderDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "order-edit";
}
if (id == null || id <= 0) {
orderService.addOrder();
}
return "redirect:/orders";
}
@PostMapping(value = "/{id}/favor/{favorId}")
public String addOrderFavor(@PathVariable(value = "id") Long id,
@PathVariable(value = "favorId") Long favorId) {
orderService.addFavorToOrder(id, favorId);
return "redirect:/orders";
}
@PostMapping(value = "/{id}/favorDelete/{favorId}")
public String deleteOrderFavor(@PathVariable(value = "id") Long id,
@PathVariable(value = "favorId") Long favorId) {
orderService.deleteFavorfromOrder(id, favorId);
return "redirect:/orders";
}
@PostMapping("/delete/{id}")
public String deleteOrder(@PathVariable Long id) {
orderService.deleteOrder(id);
return "redirect:/orders";
}
}

View File

@ -0,0 +1,41 @@
package ru.ulstu.is.sbapp.repair.mvcController;
import org.springframework.data.domain.Page;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.is.sbapp.repair.dtos.UserDTO;
import ru.ulstu.is.sbapp.repair.model.UserRole;
import ru.ulstu.is.sbapp.repair.service.UserService;
import java.util.List;
import java.util.stream.IntStream;
@Controller
@RequestMapping("/users")
public class UserMvcController {
private final UserService userService;
public UserMvcController(UserService userService) {
this.userService = userService;
}
@GetMapping
@Secured({UserRole.AsString.ADMIN})
public String getUsers(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "5") int size,
Model model) {
final Page<UserDTO> users = userService.findAllPages(page, size)
.map(UserDTO::new);
model.addAttribute("users", users);
final int totalPages = users.getTotalPages();
final List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
.boxed()
.toList();
model.addAttribute("pages", pageNumbers);
model.addAttribute("totalPages", totalPages);
return "users";
}
}

View File

@ -0,0 +1,48 @@
package ru.ulstu.is.sbapp.repair.mvcController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.is.sbapp.repair.dtos.UserSignupDTO;
import ru.ulstu.is.sbapp.repair.model.User;
import ru.ulstu.is.sbapp.repair.service.UserService;
import ru.ulstu.is.sbapp.repair.util.validation.ValidationException;
import javax.validation.Valid;
@Controller
@RequestMapping(UserSignupMvcController.SIGNUP_URL)
public class UserSignupMvcController {
public static final String SIGNUP_URL = "/signup";
private final UserService userService;
public UserSignupMvcController(UserService userService) {
this.userService = userService;
}
@GetMapping
public String showSignupForm(Model model) {
model.addAttribute("userDto", new UserSignupDTO());
return "signup";
}
@PostMapping
public String signup(@ModelAttribute("userDto") @Valid UserSignupDTO userSignupDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "signup";
}
try {
final User user = userService.createUser(
userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
return "redirect:/login?created=" + user.getLogin();
} catch (ValidationException e) {
model.addAttribute("errors", e.getMessage());
return "signup";
}
}
}

View File

@ -0,0 +1,15 @@
package ru.ulstu.is.sbapp.repair.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.is.sbapp.repair.model.Component;
import java.util.List;
public interface ComponentRepository extends JpaRepository<Component, Long> {
@Query(value = "select s from Component s where (s.id = :id or :id is Null) and (s.amount = :amount or :amount = 0) and (s.componentName = :componentName or :componentName is Null)")
public List<Component> findFilteredComponents(@Param("id") Long id,
@Param("componentName") String componentName,
@Param("amount") Integer amount );
}

View File

@ -0,0 +1,22 @@
package ru.ulstu.is.sbapp.repair.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.is.sbapp.repair.model.Favor;
import java.util.List;
public interface FavorRepository extends JpaRepository<Favor, Long> {
@Query(value = "select s from Favor s where (s.id = :id or :id is Null) and (s.favorName = :favorName or :favorName is Null) and (s.price = :price or :price = 0)")
public List<Favor> findFilteredFavors(@Param("id") Long id,
@Param("favorName") String favorName,
@Param("price") int price);
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.repair.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.is.sbapp.repair.model.Order;
public interface OrderRepository extends JpaRepository<Order, Long> {
}

View File

@ -0,0 +1,8 @@
package ru.ulstu.is.sbapp.repair.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.is.sbapp.repair.model.User;
public interface UserRepository extends JpaRepository<User, Long> {
User findOneByLoginIgnoreCase(String login);
}

View File

@ -0,0 +1,83 @@
package ru.ulstu.is.sbapp.repair.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.repair.exception.ComponentNotFoundException;
import ru.ulstu.is.sbapp.repair.model.Component;
import ru.ulstu.is.sbapp.repair.repository.ComponentRepository;
import ru.ulstu.is.sbapp.repair.util.validation.ValidatorUtil;
import java.util.List;
import java.util.Optional;
@Service
public class ComponentService {
private final ComponentRepository componentRepository;
//@Autowired
private final ValidatorUtil validatorUtil;
public ComponentService(ComponentRepository componentRepository, ValidatorUtil validatorUtil) {
this.componentRepository = componentRepository;
this.validatorUtil = validatorUtil;
}
@Transactional
public Component addComponent(String componentName, Integer amount) {
if (!StringUtils.hasText(componentName)) {
throw new IllegalArgumentException("Component name is null or empty");
}
if (amount == null){
throw new IllegalArgumentException("Amount is null or empty");
}
final Component component = new Component(amount, componentName);
validatorUtil.validate(component);
return componentRepository.save(component);
}
@Transactional(readOnly = true)
public List<Component> findFilteredComponents(Long id, String componentName, Integer amount) {
return componentRepository.findFilteredComponents(id, componentName,Optional.ofNullable(amount).orElse(0));
}
@Transactional(readOnly = true)
public Component findComponent(Long id) {
final Optional <Component> component = componentRepository.findById(id);
return component.orElseThrow(() -> new ComponentNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Component> findAllComponent() {
return componentRepository.findAll();
}
@Transactional
public Component updateComponent(Long id, String componentName, Integer amount) {
if (!StringUtils.hasText(componentName)) {
throw new IllegalArgumentException("Component name is null or empty");
}
if (amount == null){
throw new IllegalArgumentException("Amount is null or empty");
}
final Component currentComponent = findComponent(id);
currentComponent.setComponentName(componentName);
currentComponent.setAmount(amount);
validatorUtil.validate(currentComponent);
return componentRepository.save(currentComponent);
}
@Transactional
public Component deleteComponent(Long id) {
final Component currentComponent = findComponent(id);
componentRepository.delete(currentComponent);
return currentComponent;
}
@Transactional
public void deleteAllComponent() {
componentRepository.deleteAll();
}
}

View File

@ -0,0 +1,108 @@
package ru.ulstu.is.sbapp.repair.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.repair.exception.FavorNotFoundException;
import ru.ulstu.is.sbapp.repair.model.Component;
import ru.ulstu.is.sbapp.repair.model.Favor;
import ru.ulstu.is.sbapp.repair.repository.FavorRepository;
import ru.ulstu.is.sbapp.repair.util.validation.ValidatorUtil;
import javax.persistence.criteria.CriteriaBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public class FavorService {
private final FavorRepository favorRepository;
private final ValidatorUtil validatorUtil;
private final ComponentService componentService;
public FavorService(FavorRepository favorRepository, ValidatorUtil validatorUtil, ComponentService componentService){
this.favorRepository = favorRepository;
this.validatorUtil = validatorUtil;
this.componentService = componentService;
}
@Transactional
public Favor addFavor(String favorName, Integer price) {
if (!StringUtils.hasText(favorName)) {
throw new IllegalArgumentException("Favor name is null or empty");
}
if (price == null){
throw new IllegalArgumentException("Price is null or empty");
}
final Favor favor = new Favor(favorName, price);
validatorUtil.validate(favor);
return favorRepository.save(favor);
}
@Transactional(readOnly = true)
public Favor findFavor(Long id) {
final Optional<Favor> favor = favorRepository.findById(id);
return favor.orElseThrow(() -> new FavorNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Favor> findAllFavor() {
return favorRepository.findAll();
}
@Transactional
public Favor updateFavor(Long id, String favorName, Integer price) {
if (!StringUtils.hasText(favorName)) {
throw new IllegalArgumentException("Favor name is null or empty");
}
if (price == null){
throw new IllegalArgumentException("Price is null or empty");
}
final Favor currentFavor = findFavor(id);
currentFavor.setFavorName(favorName);
currentFavor.setPrice(price);
validatorUtil.validate(currentFavor);
return favorRepository.save(currentFavor);
}
@Transactional
public Favor deleteFavor(Long id) {
final Favor currentFavor = findFavor(id);
favorRepository.delete(currentFavor);
return currentFavor;
}
@Transactional
public Favor deleteComponentfromFavor(Long id, Long compId){
final Favor currentFavor = findFavor(id);
final Component currentComponent = componentService.findComponent(compId);
currentFavor.deleteComponent(currentComponent);
return currentFavor;
}
@Transactional
public Favor addComponentToFavor(Long FavorId, Long ComponentID){
if ((Object)FavorId == null) {
throw new IllegalArgumentException("favor id is null or empty");
}
if ((Object)ComponentID == null) {
throw new IllegalArgumentException("component id is null or empty");
}
final Favor currentFavor = findFavor(FavorId);
final Component currentComponent = componentService.findComponent(ComponentID);
currentFavor.addComponent(currentComponent);
return currentFavor;
}
@Transactional
public void deleteAllFavor() {
favorRepository.deleteAll();
}
@Transactional(readOnly = true)
public List<Favor> findFilteredFavors(Long id, String favorName, Integer price) {
return favorRepository.findFilteredFavors(id, favorName, Optional.ofNullable(price).orElse(0));
}
}

View File

@ -0,0 +1,97 @@
package ru.ulstu.is.sbapp.repair.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.is.sbapp.repair.exception.OrderNotFoundException;
import ru.ulstu.is.sbapp.repair.model.Component;
import ru.ulstu.is.sbapp.repair.model.Favor;
import ru.ulstu.is.sbapp.repair.model.Order;
import ru.ulstu.is.sbapp.repair.repository.OrderRepository;
import ru.ulstu.is.sbapp.repair.util.validation.ValidatorUtil;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final ValidatorUtil validatorUtil;
private final FavorService favorService;
public OrderService(OrderRepository orderRepository, ValidatorUtil validatorUtil, FavorService favorService){
this.orderRepository = orderRepository;
this.validatorUtil = validatorUtil;
this.favorService = favorService;
}
@Transactional
public Order addOrder() {
Date today = new Date();
final Order order = new Order(today);
validatorUtil.validate(order);
return orderRepository.save(order);
}
public Date getDate(String date) {
SimpleDateFormat format = new SimpleDateFormat();
format.applyPattern("dd.MM.yyyy");
Date newDate;
try {
newDate = format.parse(date);
} catch (Exception exception) {
newDate = new Date();
}
return newDate;
}
@Transactional(readOnly = true)
public Order findOrder(Long id) {
final Optional<Order> order = orderRepository.findById(id);
return order.orElseThrow(() -> new OrderNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Order> findAllOrders() {
return orderRepository.findAll();
}
@Transactional
public Order updateOrder(Long id) {
final Order currentOrder = findOrder(id);
validatorUtil.validate(currentOrder);
return orderRepository.save(currentOrder);
}
@Transactional
public Order deleteOrder(Long id) {
final Order currentOrder = findOrder(id);
orderRepository.delete(currentOrder);
return currentOrder;
}
@Transactional
public Order addFavorToOrder(Long orderId, Long favorId){
final Order currentOrder = findOrder(orderId);
final Favor currentFavor = favorService.findFavor(favorId);
currentOrder.addFavor(currentFavor);
validatorUtil.validate(currentOrder);
orderRepository.save(currentOrder);
return currentOrder;
}
@Transactional
public void deleteAllOrder() {
orderRepository.deleteAll();
}
@Transactional
public Order deleteFavorfromOrder(Long id, Long favId){
final Order currentOrder = findOrder(id);
final Favor currentFavor = favorService.findFavor(favId);
currentFavor.deleteFavor(currentOrder);
currentOrder.deleteFavor(currentFavor);
return currentOrder;
}
}

View File

@ -0,0 +1,61 @@
package ru.ulstu.is.sbapp.repair.service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import ru.ulstu.is.sbapp.repair.model.User;
import ru.ulstu.is.sbapp.repair.model.UserRole;
import ru.ulstu.is.sbapp.repair.repository.UserRepository;
import ru.ulstu.is.sbapp.repair.util.validation.ValidationException;
import ru.ulstu.is.sbapp.repair.util.validation.ValidatorUtil;
import java.util.Collections;
import java.util.Objects;
@Service
public class UserService implements UserDetailsService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final ValidatorUtil validatorUtil;
public UserService(UserRepository userRepository,
PasswordEncoder passwordEncoder,
ValidatorUtil validatorUtil) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.validatorUtil = validatorUtil;
}
public Page<User> findAllPages(int page, int size) {
return userRepository.findAll(PageRequest.of(page - 1, size, Sort.by("id").ascending()));
}
public User findByLogin(String login) {
return userRepository.findOneByLoginIgnoreCase(login);
}
public User createUser(String login, String password, String passwordConfirm) {
return createUser(login, password, passwordConfirm, UserRole.USER);
}
public User createUser(String login, String password, String passwordConfirm, UserRole role) {
if (findByLogin(login) != null) {
throw new ValidationException(String.format("User '%s' already exists", login));
}
final User user = new User(login, passwordEncoder.encode(password), role);
validatorUtil.validate(user);
if (!Objects.equals(password, passwordConfirm)) {
throw new ValidationException("Passwords not equals");
}
return userRepository.save(user);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
final User userEntity = findByLogin(username);
if (userEntity == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(
userEntity.getLogin(), userEntity.getPassword(), Collections.singleton(userEntity.getRole()));
}
}

View File

@ -0,0 +1,42 @@
package ru.ulstu.is.sbapp.repair.util.error;
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 ru.ulstu.is.sbapp.repair.exception.ComponentNotFoundException;
import ru.ulstu.is.sbapp.repair.exception.FavorNotFoundException;
import ru.ulstu.is.sbapp.repair.exception.OrderNotFoundException;
import ru.ulstu.is.sbapp.repair.util.validation.ValidationException;
import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
@ExceptionHandler({
ValidationException.class,
ComponentNotFoundException.class,
FavorNotFoundException.class,
OrderNotFoundException.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,11 @@
package ru.ulstu.is.sbapp.repair.util.validation;
import java.util.Set;
public class ValidationException extends RuntimeException{
public <T> ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
public <T> ValidationException(String error) {
super(error);
}}

View File

@ -0,0 +1,30 @@
package ru.ulstu.is.sbapp.repair.util.validation;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
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

@ -0,0 +1,11 @@
spring.main.banner-mode=off
#server.port=8080
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false

View File

@ -0,0 +1,15 @@
.container-padding {
padding: 10px;
}
.margin-bottom {
margin-bottom: 10px;
}
.button-fixed {
min-width: 120px;
}
.button-sm {
padding: 1px;
}

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/components/{id}(id=${id})}" th:object="${componentDto}" method="post">
<div class="mb-3">
<label for="componentName" class="form-label">Название</label>
<input type="text" class="form-control" id="componentName" th:field="${componentDto.componentName}" required="true">
</div>
<div class="mb-3">
<label for="amount" class="form-label">Количество</label>
<input type="number" class="form-control" id="amount" th:field="${componentDto.amount}" 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="@{/components}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/components/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">Название</th>
<th scope="col">Количество</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="component, iterator: ${components}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${component.componentName}" style="width: 60%"/>
<td th:text="${component.amount}" style="width: 60%"/>
<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="@{/components/edit/{id}(id=${component.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-${component.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/components/delete/{id}(id=${component.id})}" method="post">
<button th:id="'remove-' + ${component.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
>
<head>
<meta charset="UTF-8">
<title>MVC App</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<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"/>
</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" sec:authorize="isAuthenticated()">
<ul class="navbar-nav" th:with="activeLink=${#request.requestURI}">
<a class="nav-link" href="/components"
th:classappend="${#strings.equals(activeLink, '/components')} ? 'active' : ''">Components</a>
<a class="nav-link" href="/favors"
th:classappend="${#strings.equals(activeLink, '/favors')} ? 'active' : ''">Favors</a>
<a class="nav-link" href="/orders"
th:classappend="${#strings.equals(activeLink, '/orders')} ? 'active' : ''">Orders</a>
<a class="nav-link" href="/users"
th:classappend="${#strings.equals(activeLink, '/users')} ? 'active' : ''">Пользователи</a>
</ul>
</div>
</div>
<a class="btn btn-danger button-fixed" href="/logout" sec:authorize="isAuthenticated()" style="margin-right: 5px">Выход</a>
</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

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

View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/favors/{id}(id=${id})}" th:object="${favorDto}" method="post">
<div class="mb-3">
<label for="favorName" class="form-label">Название</label>
<input type="text" class="form-control" id="favorName" th:field="${favorDto.favorName}" required="true">
</div>
<div class="mb-3">
<label for="price" class="form-label">Цена</label>
<input type="number" class="form-control" id="price" th:field="${favorDto.price}" required="true">
</div>
<div th:if="${id != null}" class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Название</th>
<th scope="col">Количество</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="component, iterator: ${componentsList}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${component.componentName}" style="width: 60%"/>
<td th:text="${component.amount}" style="width: 60%"/>
<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-${component.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/favors/{id}/componentDelete/{componentId}(id=${id}, componentId=${component.id})}" method="post">
<button th:id="'remove-' + ${component.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</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="@{/favors}">
Назад
</a>
</div>
</form>
<form th:if="${id != null}" th:action="@{/favors/{id}/component(id=${id})}" id="addComponentForm" method="post">
<div class="mb-3">
<label for="components" class="form-label">Добавить component </label>
<select class="form-select" id="components" required>
<option disabled value="">Выберите component</option>
<option th:each="component, iterator: ${allComponents}" th:text="${component.componentName}" th:value="${component.id}">
</select>
<button class="btn btn-outline-secondary" id="addComponentButton" th:attr="onclick=|document.getElementById('addComponentForm').action = document.getElementById('addComponentForm').action + '/' + document.getElementById('components').value ; document.getElementById('addComponentForm}').submit()|">Добавить</button>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
<title>Сайт</title>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/favors/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">Название </th>
<th scope="col">Цена </th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="favor, iterator: ${favors}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${favor.favorName}" style="width: 60%"/>
<td th:text="${favor.price}" style="width: 60%"/>
<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="@{/favors/edit/{id}(id=${favor.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-${favor.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/favors/delete/{id}(id=${favor.id})}" method="post">
<button th:id="'remove-' + ${favor.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container" layout:fragment="content">
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
Пользователь не найден или пароль указан не верно
</div>
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
Выход успешно произведен
</div>
<div th:if="${param.created}" class="alert alert-success margin-bottom">
Пользователь '<span th:text="${param.created}"></span>' успешно создан
</div>
<form th:action="@{/login}" method="post" class="container-padding">
<div class="mb-3">
<input type="text" name="username" id="username" class="form-control"
placeholder="Логин" required="true" autofocus="true"/>
</div>
<div class="mb-3">
<input type="password" name="password" id="password" class="form-control"
placeholder="Пароль" required="true"/>
</div>
<button type="submit" class="btn btn-success button-fixed">Войти</button>
<a class="btn btn-primary button-fixed" href="/signup">Регистрация</a>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/orders/{id}(id=${id})}" th:object="${orderDto}" method="post">
<div th:if="${id != null}" class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Название </th>
<th scope="col">Цена </th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="favor, iterator: ${favorsList}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${favor.favorName}" style="width: 60%"/>
<td th:text="${favor.price}" style="width: 60%"/>
<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-${favor.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/orders/{id}/favorDelete/{favorId}(id=${id}, favorId=${favor.id})}" method="post">
<button th:id="'remove-' + ${favor.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</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="@{/orders}">
Назад
</a>
</div>
</form>
<form th:if="${id != null}" th:action="@{/orders/{id}/favor(id=${id})}" id="addFavorForm" method="post">
<div class="mb-3">
<label for="favors" class="form-label">Добавить favor </label>
<select class="form-select" id="favors" required>
<option disabled value="">Выберите component</option>
<option th:each="favor, iterator: ${allFavors}" th:text="${favor.favorName}" th:value="${favor.id}">
</select>
<button class="btn btn-outline-secondary" id="addFavorButton" th:attr="onclick=|document.getElementById('addFavorForm').action = document.getElementById('addFavorForm').action + '/' + document.getElementById('favors').value ; document.getElementById('addFavorForm}').submit()|">Добавить</button>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
<title>Сайт</title>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/orders/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">Дата </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.date}" style="width: 60%"/>
<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="@{/orders/edit/{id}(id=${order.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container container-padding" layout:fragment="content">
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
<form action="#" th:action="@{/signup}" th:object="${userDto}" method="post">
<div class="mb-3">
<input type="text" class="form-control" th:field="${userDto.login}"
placeholder="Логин" required="true" autofocus="true" maxlength="64"/>
</div>
<div class="mb-3">
<input type="password" class="form-control" th:field="${userDto.password}"
placeholder="Пароль" required="true" minlength="6" maxlength="64"/>
</div>
<div class="mb-3">
<input type="password" class="form-control" th:field="${userDto.passwordConfirm}"
placeholder="Пароль (подтверждение)" required="true" minlength="6" maxlength="64"/>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-success button-fixed">Создать</button>
<a class="btn btn-primary button-fixed" href="/login">Назад</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container" layout:fragment="content">
<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="user, iterator: ${users}">
<th scope="row" th:text="${iterator.index} + 1"></th>
<td th:text="${user.id}"></td>
<td th:text="${user.login}" style="width: 60%"></td>
<td th:text="${user.role}" style="width: 20%"></td>
</tr>
</tbody>
</table>
</div>
<div th:if="${totalPages > 0}" class="pagination">
<span style="float: left; padding: 5px 5px;">Страницы:</span>
<a th:each="page : ${pages}"
th:href="@{/users(page=${page}, size=${users.size})}"
th:text="${page}"
th:class="${page == users.number + 1} ? active">
</a>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,65 @@
package ru.ulstu.is.sbapp;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.repair.model.*;
import ru.ulstu.is.sbapp.repair.service.*;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@SpringBootTest
class SbappApplicationTests {
// @Autowired
// private ComponentService componentService;
// @Autowired
// private FavorService favorService;
// @Autowired
// private OrderService orderService;
//
// @Test
// void testOrder(){
// componentService.deleteAllComponent();
// orderService.deleteAllOrder();
// favorService.deleteAllFavor();
//
// final Favor favor = favorService.addFavor("Favor1", 100);
//
// final Order order0 = orderService.addOrder("11.02.2023");
// final Order order1 = orderService.findOrder(order0.getId());
// final Component component1 = componentService.addComponent("comp", 10);
// favor.addComponent(component1);
// Assertions.assertEquals(order0, order1);
//
// orderService.addFavorToOrder(order0.getId(), favor);
// Assertions.assertEquals(favorService.findFavor(favor.getId()).getOrders().size(), 1);
// Assertions.assertEquals(orderService.findOrder(order0.getId()).getFavorsList().size(), 1);
//
// orderService.deleteOrder(order0.getId());
// Assertions.assertThrows(EntityNotFoundException.class, () -> orderService.findOrder(order0.getId()));
// }
//
// @Test
// void testFavor(){
// componentService.deleteAllComponent();
// orderService.deleteAllOrder();
// favorService.deleteAllFavor();
//
// final Component component = componentService.addComponent("Favor1", 100);
//
// final Favor favor0 = favorService.addFavor("fvr", 100);
// final Favor favor1 = favorService.findFavor(favor0.getId());
// Assertions.assertEquals(favor0, favor1);
//
//
// favorService.addComponentToFavor(favor0.getId(), component);
// Assertions.assertEquals(favorService.findFavor(favor0.getId()).getComponents().size(), 1);
// Assertions.assertEquals(componentService.findComponent(component.getId()).getFavors().size(), 1);
//
// favorService.deleteFavor(favor0.getId());
// Assertions.assertThrows(EntityNotFoundException.class, () -> favorService.findFavor(favor0.getId()));
//
// }
}