├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── khomsi │ │ └── site_project │ │ ├── WebStoreApplication.java │ │ ├── configuration │ │ ├── EncryptionConfig.java │ │ ├── WebConfig.java │ │ └── WebSecurityConfig.java │ │ ├── controller │ │ ├── AdminController.java │ │ ├── AdminTools.java │ │ ├── MainController.java │ │ ├── OrderController.java │ │ ├── ProductController.java │ │ ├── ShoppingCartRestController.java │ │ └── UserController.java │ │ ├── entity │ │ ├── Category.java │ │ ├── Delivery.java │ │ ├── DeliveryStatus.java │ │ ├── Order.java │ │ ├── OrderBasket.java │ │ ├── OrderType.java │ │ ├── Product.java │ │ ├── Role.java │ │ ├── User.java │ │ ├── UserInfo.java │ │ └── Vendor.java │ │ ├── exception │ │ ├── CategoryNotFoundException.java │ │ ├── OrderNotFoundException.java │ │ ├── ProductNotFoundException.java │ │ └── UserNotFoundException.java │ │ ├── repository │ │ ├── CategoryRepository.java │ │ ├── DeliveryRepository.java │ │ ├── OrderBasketRepository.java │ │ ├── OrderRepository.java │ │ ├── ProductRepository.java │ │ ├── UserInfoRepository.java │ │ ├── UserRepository.java │ │ └── VendorRepository.java │ │ └── service │ │ ├── CategoryPageInfo.java │ │ ├── CategoryService.java │ │ ├── ICategoryService.java │ │ ├── IOrderBasketService.java │ │ ├── IOrdersService.java │ │ ├── IProductService.java │ │ ├── IUserInfoService.java │ │ ├── IUserService.java │ │ ├── IVendorService.java │ │ ├── OrderBasketService.java │ │ ├── OrdersService.java │ │ ├── ProductService.java │ │ ├── UserInfoService.java │ │ ├── UserService.java │ │ └── VendorService.java └── resources │ ├── application.yml │ ├── messages.properties │ ├── messages_uk.properties │ ├── sql │ ├── WebShopDB.mwb │ └── triggers.txt │ ├── static │ ├── assets │ │ ├── email.gif │ │ ├── favicon.png │ │ └── logo.gif │ ├── category-images │ │ ├── Electronics.png │ │ ├── bathrobe.png │ │ ├── clothes.png │ │ ├── default.png │ │ ├── laptops.png │ │ ├── phonecase.png │ │ ├── phones.png │ │ ├── tv.png │ │ └── watch.png │ ├── css │ │ ├── mdb.css │ │ └── styles.css │ ├── img │ │ ├── ClothesBanner.png │ │ ├── ElectronicsBanner.png │ │ ├── PhonesBanner.png │ │ ├── samsungBanner.mp4 │ │ └── svg │ │ │ ├── arrow_left.svg │ │ │ └── arrow_right.svg │ ├── js │ │ ├── added_to_cart.js │ │ ├── formValidation.js │ │ ├── quantity_control.js │ │ └── shopping-cart.js │ ├── product-images │ │ ├── 05c6c1339.jpg │ │ ├── 05c6c1373.jpg │ │ ├── 143753339.jpg │ │ ├── 152740976.jpg │ │ ├── 153012611.jpg │ │ ├── 166805614.jpg │ │ ├── 175435404.jpg │ │ ├── 179665007.jpg │ │ ├── 181479242.jpg │ │ ├── 182225695.jpg │ │ ├── 18240829.jpg │ │ ├── 201644018.jpg │ │ ├── 215505081.jpg │ │ ├── 219511084.jpg │ │ ├── 221194930.jpg │ │ ├── 221208611.jpg │ │ ├── 221216157.jpg │ │ ├── 237286899.jpg │ │ ├── 237518825.jpg │ │ ├── 237518843.jpg │ │ ├── 237519282.jpg │ │ ├── 237519719.jpg │ │ ├── 240234430.jpg │ │ ├── 240679986.jpg │ │ ├── 241248608.jpg │ │ ├── 245951562.jpg │ │ ├── 246788854.png │ │ ├── 247191594.jpg │ │ ├── 248749664.jpg │ │ ├── 249006810.jpg │ │ ├── 249691847.jpg │ │ ├── 250964653.jpg │ │ ├── 252187527.jpg │ │ ├── 253280149.jpg │ │ ├── 253281547.jpg │ │ ├── 256314559.jpg │ │ ├── 259416221.jpg │ │ ├── 259453445.jpg │ │ ├── 262334763.jpg │ │ ├── 263940978.jpg │ │ ├── 263974548.jpg │ │ ├── 267604551.jpg │ │ ├── 267816864.jpg │ │ ├── 273584154.jpg │ │ ├── 274406559.jpg │ │ ├── 274646506.jpg │ │ ├── 275080610.jpg │ │ ├── 278076445.jpg │ │ ├── 278110854.jpg │ │ ├── 278357675.jpg │ │ ├── 278429510.jpg │ │ ├── 279813767.jpg │ │ ├── 279820947.jpg │ │ ├── 279865808.jpg │ │ ├── 279918555.jpg │ │ ├── 280040750.jpg │ │ ├── 280547595.jpg │ │ ├── 280562759.jpg │ │ ├── 280598520.jpg │ │ ├── 280612876.jpg │ │ ├── 280626933.jpg │ │ ├── 280630226.jpg │ │ ├── 280700402.jpg │ │ ├── 281372796.jpg │ │ ├── 281374487.jpg │ │ ├── 281374511.jpg │ │ ├── 282627868.jpg │ │ ├── 283515477.jpg │ │ ├── 283644375.jpg │ │ ├── 284920810.jpg │ │ ├── 284920851.jpg │ │ ├── 284924180.jpg │ │ ├── 285129119.jpg │ │ ├── 29115201.jpg │ │ ├── 30408872.jpg │ │ ├── 31528740.jpg │ │ ├── 37389483.jpg │ │ ├── 45692166.jpg │ │ ├── 4964O-99X-001-1-481447.jpg │ │ ├── 53638637.jpg │ │ ├── 53761557.jpg │ │ ├── 53777130.jpg │ │ ├── 5631N-50J-001-1-527331_1.jpg │ │ ├── 73896886.jpg │ │ ├── default.png │ │ ├── img_5018.jpg │ │ ├── img_5023.jpg │ │ ├── img_6285.jpg │ │ ├── img_6337.jpg │ │ ├── img_6409.jpg │ │ ├── iphone13_pro_max.png │ │ ├── photo_2020-11-08_07-22-10-768x1152.jpg │ │ ├── photo_2020-11-08_12-19-36.jpg │ │ ├── photo_2020-11-08_12-19-44.jpg │ │ ├── photo_2020-11-22_15-28-15.jpg │ │ ├── photo_2020-11-22_15-47-32.jpg │ │ ├── photo_2021-07-06_18-57-02.jpg │ │ ├── photo_2021-07-06_18-58-26.jpg │ │ ├── photo_2021-11-05_20-53-27.jpg │ │ ├── photo_2021-11-05_21-21-52.jpg │ │ ├── photo_2021-11-05_21-24-58.jpg │ │ ├── samsung_galaxy_m52.png │ │ ├── samsung_galaxy_s9.png │ │ └── tv.png │ └── richtext_editor │ │ ├── jquery.richtext.js │ │ ├── jquery.richtext.min.js │ │ ├── richtext.min.css │ │ └── richtext.scss │ └── templates │ ├── admin │ ├── admin-panel.html │ ├── category │ │ ├── categories.html │ │ └── category_form.html │ ├── order_basket │ │ └── order_baskets.html │ ├── orders │ │ ├── order_form.html │ │ └── orders.html │ ├── product │ │ ├── product_description.html │ │ ├── product_form.html │ │ ├── product_overview.html │ │ └── products.html │ ├── user │ │ ├── user_form.html │ │ └── users.html │ └── vendor │ │ ├── vendor_form.html │ │ └── vendors.html │ ├── blocks │ ├── breadcrumb.html │ ├── fragments.html │ └── login.html │ ├── category.html │ ├── checkout.html │ ├── error │ └── 404.html │ ├── index.html │ ├── product │ ├── product-page.html │ ├── product_fragment.html │ ├── products_by_category.html │ └── search_result.html │ ├── registration.html │ ├── shopping-cart.html │ └── user │ ├── orders.html │ ├── user-edit.html │ └── user-main.html └── test └── java └── com └── khomsi └── site_project ├── CategoryRepoTest.java ├── CategoryTest.java ├── OrderBasketTests.java ├── ProductRepositoryTest.java ├── ProductTest.java ├── UserTest.java └── WebStoreApplicationTests.java /.gitattributes: -------------------------------------------------------------------------------- 1 | *.css linguist-detectable=false 2 | *.html linguist-detectable=false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | /src/main/resources/sql/WebShopDB.mwb.bak 35 | /.mvn/ 36 | /.jpb/ 37 | src/main/java/com/khomsi/site_project/notesToFix.html 38 | 39 | /src/main/resources/sql/WebShop_old.mwb 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Samer Khomsi Kak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![icon](https://user-images.githubusercontent.com/71443826/190462552-83a4263b-f2d2-4814-a6c0-850dc89438d2.png)SENKO Web Store 2 | 3 | 4 | 5 | ![email](https://user-images.githubusercontent.com/71443826/190460590-41f6e112-8821-4115-8816-6704312854b2.gif) 6 | 7 | 8 | This E-commerce project built on Spring Boot.
9 | Look demo below. 10 | 11 | Login: admin
12 | Password: admin 13 | 14 | ## Used Technologies: 15 | 16 | * Spring (Boot, Data, Security, MVC etc) 17 | * JPA / Hibernate 18 | * MYSQL 19 | * Thymeleaf 20 | * Bootstrap, CSS, JS 21 | * Maven 22 | * Junit 23 | * Lombok 24 | * SQL Query 25 | 26 | ## About Project 27 | * User can register / log in. 28 | * User can navigate on the main pages browse products or select an item from the showcase, preview and categories with paginations. 29 | * User can search for the product according to the specified criteria. 30 | * User can add products to the shopping cart and delete products from the shopping cart. 31 | * User can order the products in the shopping cart. 32 | * User can change their password and view their orders. 33 | * User will receive email with order after it was finished successfully. 34 | * Admin can add or modify everything in DB (product, user, category, vendor, basket, delivery) 35 | ## Demo 36 | **Main page**: 37 | 38 | https://user-images.githubusercontent.com/71443826/190463648-28939833-30dd-4c46-9662-cf58b3bf2880.mp4 39 | 40 | **Main page adaptive**: 41 | 42 | https://user-images.githubusercontent.com/71443826/190474696-946531fd-a71b-4cd0-a3c0-09848b31af3e.mp4 43 | 44 | 45 | 46 | 47 | **Registration and authorization**: 48 | 49 | https://user-images.githubusercontent.com/71443826/190474763-8bd4bcab-d33b-4b7c-8569-4f838495c272.mp4 50 | 51 | 52 | 53 | **Shopping**: 54 | 55 | https://user-images.githubusercontent.com/71443826/190474806-dbbcda68-3c41-44f3-bb82-a4a168992311.mp4 56 | 57 | https://user-images.githubusercontent.com/71443826/190474886-5e36960a-a8b5-481d-bb11-b6d48a39c1e4.mp4 58 | 59 | **Admin**: 60 | 61 | https://user-images.githubusercontent.com/71443826/190474957-5db80a19-3875-4150-babf-d3d9949b5afb.mp4 62 | 63 | https://user-images.githubusercontent.com/71443826/190474975-ac66860e-3cc0-463e-af2c-3ea4d51f0140.mp4 64 | 65 | 66 | ## Screenshots 67 | 68 | Adaptive Category | Adaptive Product by Category 69 | 70 | ![categoryPage](https://user-images.githubusercontent.com/71443826/190475170-d33eca3a-a375-498c-970a-0fefec59bc4a.png) ![productByCategory](https://user-images.githubusercontent.com/71443826/190475343-0f4433f2-202f-4b4f-8562-a30ca2a790a4.png) 71 | 72 | 73 | Adaptive User's profile | Adaptive User's profile edit: 74 | 75 | ![profileAdaptive](https://user-images.githubusercontent.com/71443826/190475676-dc2f0e40-ad0d-4692-934f-57695e03fb0b.png) ![profileEditAdaptive](https://user-images.githubusercontent.com/71443826/190475741-f86cfa57-a87f-46c4-9209-8cc7b6b8eca9.png) 76 | 77 | 78 | Order Page: 79 | 80 | ![orderPage](https://user-images.githubusercontent.com/71443826/190475831-1738d27e-6c41-476f-81de-9dfe2d1b0a53.png) 81 | 82 | Admin Adaptive Product Page 83 | :------------------------: 84 | ![productAdmin](https://user-images.githubusercontent.com/71443826/190475969-4fcec221-9abe-46dc-b792-2ad62240618d.png) 85 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.2 9 | 10 | 11 | com.khomsi 12 | site_project 13 | 0.0.1-SNAPSHOT 14 | site_project 15 | Site project for Spring Boot 16 | 17 | 18 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-jpa 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-data-rest 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-security 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-thymeleaf 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-validation 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-web 44 | 45 | 46 | org.thymeleaf.extras 47 | thymeleaf-extras-springsecurity5 48 | 49 | 50 | mysql 51 | mysql-connector-java 52 | runtime 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-starter-mail 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-configuration-processor 61 | true 62 | 63 | 64 | org.projectlombok 65 | lombok 66 | true 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-starter-test 71 | test 72 | 73 | 74 | org.springframework.security 75 | spring-security-test 76 | test 77 | 78 | 79 | 80 | org.webjars.npm 81 | normalize.css 82 | 8.0.1 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-devtools 88 | 89 | 90 | 91 | org.webjars 92 | bootstrap 93 | 4.3.1 94 | 95 | 96 | 97 | org.webjars 98 | jquery 99 | 3.4.1 100 | 101 | 102 | org.webjars 103 | webjars-locator-core 104 | 105 | 106 | 107 | 108 | 109 | org.springframework.boot 110 | spring-boot-maven-plugin 111 | ${project.parent.version} 112 | 113 | 114 | 115 | org.projectlombok 116 | lombok 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/WebStoreApplication.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WebStoreApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(WebStoreApplication.class, args); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/configuration/EncryptionConfig.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.configuration; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | 8 | @Configuration 9 | public class EncryptionConfig { 10 | @Bean 11 | public PasswordEncoder encoder() { 12 | return new BCryptPasswordEncoder(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/configuration/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.configuration; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.LocaleResolver; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; 9 | import org.springframework.web.servlet.i18n.SessionLocaleResolver; 10 | 11 | import java.util.Locale; 12 | 13 | @Configuration 14 | public class WebConfig implements WebMvcConfigurer { 15 | 16 | //Declare default language 17 | @Bean 18 | public LocaleResolver localeResolver() { 19 | SessionLocaleResolver localeResolver = new SessionLocaleResolver(); 20 | localeResolver.setDefaultLocale(Locale.US); 21 | return localeResolver; 22 | } 23 | 24 | @Bean 25 | public LocaleChangeInterceptor localeChangeInterceptor() { 26 | LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); 27 | //When change to dif lang, we need to pass params by url 28 | localeChangeInterceptor.setParamName("lang"); 29 | return localeChangeInterceptor; 30 | } 31 | 32 | @Override 33 | public void addInterceptors(InterceptorRegistry registry) { 34 | registry.addInterceptor(localeChangeInterceptor()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/configuration/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.configuration; 2 | 3 | import com.khomsi.site_project.entity.Role; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 11 | import org.springframework.security.crypto.password.PasswordEncoder; 12 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 13 | 14 | import javax.sql.DataSource; 15 | 16 | @EnableWebSecurity 17 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 18 | @Autowired 19 | private DataSource dataSource; 20 | @Autowired 21 | private PasswordEncoder passwordEncoder; 22 | 23 | /* 24 | loginPage() – the custom login page 25 | loginProcessingUrl() – the URL to submit the username and password 26 | defaultSuccessUrl() – the landing page after a successful login 27 | failureUrl() – the landing page after an unsuccessful login 28 | */ 29 | // 30 | @Override 31 | protected void configure(HttpSecurity http) throws Exception { 32 | // http.csrf().disable().authorizeRequests() 33 | http.authorizeRequests().antMatchers("/admin/**").hasAuthority(Role.ADMIN.getAuthority()) 34 | .antMatchers("/js/**", "/css/**", "/**").permitAll() 35 | .anyRequest().authenticated() 36 | .and() 37 | .formLogin() 38 | .loginPage("/login") 39 | .loginProcessingUrl("/login") 40 | .defaultSuccessUrl("/", true) 41 | .permitAll() 42 | .and() 43 | .logout().logoutSuccessUrl("/") 44 | .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll().and().exceptionHandling() 45 | .accessDeniedPage("/error403"); 46 | } 47 | 48 | @Override 49 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 50 | auth.jdbcAuthentication().dataSource(dataSource) 51 | .passwordEncoder(passwordEncoder) 52 | .usersByUsernameQuery("select login, password, 'true' as enabled from user where login=?") 53 | .authoritiesByUsernameQuery("select login, role from user where login=?"); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/controller/MainController.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.controller; 2 | 3 | import com.khomsi.site_project.entity.*; 4 | import com.khomsi.site_project.exception.ProductNotFoundException; 5 | import com.khomsi.site_project.repository.CategoryRepository; 6 | import com.khomsi.site_project.service.ProductService; 7 | import com.khomsi.site_project.service.UserService; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.webjars.NotFoundException; 14 | 15 | import java.security.Principal; 16 | import java.util.List; 17 | 18 | @Controller 19 | public class MainController { 20 | @Autowired 21 | private UserService userService; 22 | 23 | @Autowired 24 | private CategoryRepository categoryRep; 25 | @Autowired 26 | private ProductService productService; 27 | 28 | @GetMapping("/") 29 | public String index(Model model) { 30 | model.addAttribute("listCategories", categoryRep.findAllEnabled()); 31 | try { 32 | model.addAttribute("listProducts", productService.getRandomAmountOfProducts()); 33 | } catch (ProductNotFoundException ex) { 34 | model.addAttribute("error", ex.getCause().getCause().getMessage()); 35 | return "/error/404"; 36 | } 37 | return "index"; 38 | } 39 | 40 | @GetMapping("/registration") 41 | public String registration(Model model) { 42 | model.addAttribute("user", new User()); 43 | model.addAttribute("userInfo", new UserInfo()); 44 | return "registration"; 45 | } 46 | 47 | @PostMapping("/registration") 48 | public String registration(User user, UserInfo userInfo) { 49 | user.setRole(Role.USER); 50 | user.setUserInfo(userInfo); 51 | userInfo.setUser(user); 52 | userService.saveUser(user); 53 | return "redirect:/"; 54 | } 55 | 56 | @GetMapping("/basket") 57 | public String showShoppingCard(Model model, 58 | Principal principal) { 59 | if (principal != null) { 60 | List orderBaskets = userService.getUserByLogin(principal.getName()).getOrderBaskets(); 61 | model.addAttribute("orderBaskets", orderBaskets); 62 | model.addAttribute("order", new Order()); 63 | } else { 64 | model.addAttribute("error", new NotFoundException("Order basket was not found")); 65 | return "/error/404"; 66 | } 67 | return "shopping-cart"; 68 | } 69 | 70 | @GetMapping("/category") 71 | public String showCategories(Model model) { 72 | List listEnabledCategories = categoryRep.findAllEnabled(); 73 | model.addAttribute("listCategories", listEnabledCategories); 74 | return "category"; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.controller; 2 | 3 | import com.khomsi.site_project.entity.Order; 4 | import com.khomsi.site_project.entity.OrderBasket; 5 | import com.khomsi.site_project.entity.OrderType; 6 | import com.khomsi.site_project.entity.User; 7 | import com.khomsi.site_project.service.OrdersService; 8 | import com.khomsi.site_project.service.UserService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.core.io.ClassPathResource; 11 | import org.springframework.mail.javamail.JavaMailSender; 12 | import org.springframework.mail.javamail.MimeMessageHelper; 13 | import org.springframework.orm.jpa.JpaSystemException; 14 | import org.springframework.stereotype.Controller; 15 | import org.springframework.ui.Model; 16 | import org.springframework.web.bind.annotation.GetMapping; 17 | import org.springframework.web.bind.annotation.PostMapping; 18 | import org.springframework.web.servlet.mvc.support.RedirectAttributes; 19 | import org.webjars.NotFoundException; 20 | 21 | import javax.mail.MessagingException; 22 | import javax.mail.internet.MimeMessage; 23 | import java.io.UnsupportedEncodingException; 24 | import java.security.Principal; 25 | import java.util.List; 26 | 27 | @Controller 28 | public class OrderController { 29 | 30 | @Autowired 31 | JavaMailSender javaMailSender; 32 | 33 | @Autowired 34 | private OrdersService ordersService; 35 | @Autowired 36 | private UserService userService; 37 | 38 | @GetMapping("/orders") 39 | public String showOrders(Model model, Principal principal) { 40 | if (principal != null) { 41 | User user = userService.getUserByLogin(principal.getName()); 42 | List orders = ordersService.getAllOrdersByUser(user); 43 | model.addAttribute("orders", orders); 44 | } else { 45 | model.addAttribute("error", new NotFoundException("Orders was not found")); 46 | return "/error/404"; 47 | } 48 | return "/user/orders"; 49 | } 50 | 51 | @GetMapping("/payment") 52 | public String createOrders(Model model, Principal principal) { 53 | if (principal != null) { 54 | User user = userService.getUserByLogin(principal.getName()); 55 | List orderBaskets = user.getOrderBaskets(); 56 | model.addAttribute("order", new Order()); 57 | model.addAttribute("user", user); 58 | model.addAttribute("orderBaskets", orderBaskets); 59 | model.addAttribute("waiting", OrderType.Ожидание); 60 | model.addAttribute("payed", OrderType.Оплачено); 61 | } else { 62 | model.addAttribute("error", new NotFoundException("Orders for payment was not found")); 63 | return "/error/404"; 64 | } 65 | return "checkout"; 66 | } 67 | 68 | @PostMapping("/payment") 69 | public String saveOrder(Order newOrder, Principal principal, 70 | Model model, RedirectAttributes attributes) { 71 | User user = userService.getUserByLogin(principal.getName()); 72 | List orderBaskets = user.getOrderBaskets(); 73 | newOrder.setUser(user); 74 | newOrder.setTotalPrice(ordersService.countSum(orderBaskets)); 75 | try { 76 | ordersService.saveOrder(newOrder); 77 | attributes.addFlashAttribute("message", "Order was completed! Check your email!"); 78 | sendVerificationEmail(newOrder); 79 | } catch (JpaSystemException | MessagingException | UnsupportedEncodingException ex) { 80 | model.addAttribute("error", ex.getCause().getCause().getMessage()); 81 | return "error/404"; 82 | } 83 | return "redirect:/orders"; 84 | } 85 | 86 | /* 87 | * Method that creates the email with orders that will be sent to user's email 88 | * */ 89 | private void sendVerificationEmail(Order order) 90 | throws MessagingException, UnsupportedEncodingException { 91 | 92 | String shipping = order.getShippingType() == 0 ? "Ukr poshta" : "Nova poshta"; 93 | 94 | String subject = "Thank you for ordering in SENKO"; 95 | String senderName = "Senko Store"; 96 | String mailContent = "

Order number: " + order.getId() + "

"; 97 | mailContent += "

Payment: " + order.getOrderStatus() + "

"; 98 | mailContent += "

Shipping: " + shipping + "

"; 99 | mailContent += "

City: " + order.getCity() + "

"; 100 | mailContent += "

Address: " + order.getAddress() + "

"; 101 | mailContent += "

Order total: " + order.getTotalPrice() + "

"; 102 | 103 | mailContent += "
"; 104 | 105 | MimeMessage message = javaMailSender.createMimeMessage(); 106 | MimeMessageHelper helper = new MimeMessageHelper(message, true); 107 | 108 | helper.setFrom("senkoShop@outlook.com", senderName); 109 | helper.setTo(order.getUser().getEmail()); 110 | helper.setSubject(subject); 111 | helper.setText(mailContent, true); 112 | 113 | ClassPathResource pathResource = new ClassPathResource("/static/assets/email.gif"); 114 | helper.addInline("logoImage", pathResource); 115 | javaMailSender.send(message); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/controller/ProductController.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.controller; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import com.khomsi.site_project.entity.Product; 5 | import com.khomsi.site_project.exception.CategoryNotFoundException; 6 | import com.khomsi.site_project.exception.ProductNotFoundException; 7 | import com.khomsi.site_project.service.CategoryService; 8 | import com.khomsi.site_project.service.ProductService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.domain.Page; 11 | import org.springframework.data.repository.query.Param; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.Model; 14 | import org.springframework.util.StringUtils; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.PathVariable; 17 | import org.springframework.web.bind.annotation.PostMapping; 18 | import org.springframework.web.bind.annotation.ResponseBody; 19 | 20 | import java.util.List; 21 | 22 | @Controller 23 | public class ProductController { 24 | @Autowired 25 | private ProductService productService; 26 | @Autowired 27 | private CategoryService categoryService; 28 | @Autowired 29 | private AdminTools adminTools; 30 | 31 | @GetMapping({"/category/{category_alias}"}) 32 | public String viewCategoryFirstPage(@PathVariable("category_alias") String alias, 33 | Model model) { 34 | return viewCategoryByPage(alias, model, 1); 35 | } 36 | 37 | @GetMapping("/category/{category_alias}/page/{pageNum}") 38 | public String viewCategoryByPage(@PathVariable("category_alias") String alias, 39 | Model model, @PathVariable("pageNum") int pageNum) { 40 | try { 41 | Category category = categoryService.getCategoryByAlias(alias); 42 | 43 | List listCategoryParents = categoryService.getCategoryParents(category); 44 | Page pageProduct = productService.listByCategory(pageNum, category.getId()); 45 | List listProducts = pageProduct.getContent(); 46 | long startCount = (pageNum - 1) * ProductService.PRODUCTS_PER_PAGE + 1; 47 | long endCount = startCount + ProductService.PRODUCTS_PER_PAGE - 1; 48 | 49 | adminTools.pageCountMethod(pageNum, model, pageProduct, startCount, endCount); 50 | 51 | model.addAttribute("pageTitle", category.getTitle()); 52 | model.addAttribute("listCategoryParents", listCategoryParents); 53 | model.addAttribute("listProducts", listProducts); 54 | 55 | 56 | model.addAttribute("category", category); 57 | return "product/products_by_category"; 58 | } catch (CategoryNotFoundException e) { 59 | model.addAttribute("error", e.getLocalizedMessage()); 60 | return "error/404"; 61 | } 62 | } 63 | 64 | @GetMapping("/product/{product_alias}") 65 | public String viewProductDetails(@PathVariable("product_alias") String alias, Model model) { 66 | try { 67 | Product product = productService.getProduct(alias); 68 | List listCategoryParents = categoryService.getCategoryParents(product.getCategory()); 69 | model.addAttribute("listCategoryParents", listCategoryParents); 70 | model.addAttribute("product", product); 71 | return "product/product-page"; 72 | } catch (ProductNotFoundException e) { 73 | model.addAttribute("error", e.getLocalizedMessage()); 74 | return "error/404"; 75 | } 76 | } 77 | 78 | @PostMapping("/products/check_unique") 79 | public @ResponseBody String checkUnique(@Param("id") Integer id, @Param("title") String title) { 80 | return productService.checkUnique(id, title); 81 | } 82 | 83 | @GetMapping("/search") 84 | public String searchFirstPage(@Param("keyword") String keyword, Model model) { 85 | return searchByPage(keyword, 1, model); 86 | } 87 | 88 | /* 89 | * We need param of page num, so i use pathVariable 90 | */ 91 | @GetMapping("/search/page/{pageNum}") 92 | public String searchByPage(@Param("keyword") String keyword, 93 | @PathVariable("pageNum") int pageNum, 94 | Model model) { 95 | Page productsPage = productService.search(keyword, pageNum); 96 | List resultList = productsPage.getContent(); 97 | 98 | long startCount = (pageNum - 1) * ProductService.SEARCH_RESULTS_PAGE + 1; 99 | long endCount = startCount + ProductService.SEARCH_RESULTS_PAGE - 1; 100 | adminTools.pageCountMethod(pageNum, model, productsPage, startCount, endCount); 101 | 102 | model.addAttribute("pageTitle", StringUtils.capitalize(keyword) + " - Search Result"); 103 | model.addAttribute("keyword", keyword); 104 | model.addAttribute("resultList", resultList); 105 | return "product/search_result"; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/controller/ShoppingCartRestController.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.controller; 2 | 3 | import com.khomsi.site_project.entity.User; 4 | import com.khomsi.site_project.service.OrderBasketService; 5 | import com.khomsi.site_project.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.security.Principal; 12 | 13 | @RestController 14 | public class ShoppingCartRestController { 15 | @Autowired 16 | private OrderBasketService orderBasketService; 17 | @Autowired 18 | private UserService userService; 19 | 20 | @PostMapping("/basket/add/{pid}/{qty}") 21 | public String addProductToBasket(@PathVariable("pid") Integer productId, 22 | @PathVariable("qty") Integer quantity, 23 | Principal principal) { 24 | if (principal == null) { 25 | return "You must login to add this product to your shopping basket"; 26 | } 27 | User user = userService.getUserByLogin(principal.getName()); 28 | 29 | if (user == null) return "You must login to add this product to your shopping basket"; 30 | 31 | Integer addedQuantity = orderBasketService.addProduct(productId, quantity, user); 32 | 33 | return addedQuantity > 1 ? addedQuantity + " items of this product were added to your shopping basket" 34 | : addedQuantity + " item of this product was added to your shopping basket"; 35 | } 36 | 37 | @PostMapping("/basket/update/{pid}/{qty}") 38 | public String updateQuantity(@PathVariable("pid") Integer productId, 39 | @PathVariable("qty") Integer quantity, 40 | Principal principal) { 41 | if (principal == null) { 42 | return "You must login to update quantity"; 43 | } 44 | User user = userService.getUserByLogin(principal.getName()); 45 | 46 | if (user == null) return "You must login to update quantity"; 47 | 48 | float subtotal = orderBasketService.updateQuantity(productId, quantity, user); 49 | 50 | return String.valueOf(subtotal); 51 | } 52 | 53 | @PostMapping("/basket/remove/{pid}") 54 | public String removeProductFromBasket(@PathVariable("pid") Integer productId, 55 | Principal principal) { 56 | if (principal == null) { 57 | return "You must login to remove product"; 58 | } 59 | User user = userService.getUserByLogin(principal.getName()); 60 | 61 | if (user == null) return "You must login to remove product"; 62 | 63 | orderBasketService.removeProduct(productId, user); 64 | 65 | return "The product has been removed from your shopping basket."; 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.controller; 2 | 3 | import com.khomsi.site_project.entity.User; 4 | import com.khomsi.site_project.entity.UserInfo; 5 | import com.khomsi.site_project.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.data.repository.query.Param; 8 | import org.springframework.security.crypto.password.PasswordEncoder; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.validation.BindingResult; 12 | import org.springframework.validation.ObjectError; 13 | import org.springframework.web.bind.annotation.GetMapping; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.ResponseBody; 17 | import org.webjars.NotFoundException; 18 | 19 | import java.security.Principal; 20 | 21 | @Controller 22 | @RequestMapping("/profile") 23 | public class UserController { 24 | @Autowired 25 | private UserService userService; 26 | @Autowired 27 | private PasswordEncoder passwordEncoder; 28 | 29 | @GetMapping({"/", ""}) 30 | public String getUserInfo(Principal principal, Model model) { 31 | if (principal != null) { 32 | User user = userService.getUserByLogin(principal.getName()); 33 | UserInfo userInfo = user.getUserInfo(); 34 | model.addAttribute("userDetails", userInfo); 35 | model.addAttribute("user", user); 36 | return "/user/user-main"; 37 | } else { 38 | model.addAttribute("error", new NotFoundException("User was not found")); 39 | return "error/404"; 40 | } 41 | } 42 | 43 | @GetMapping("/edit") 44 | public String showEditPage(Principal principal, Model model) { 45 | User user = userService.getUserByLogin(principal.getName()); 46 | UserInfo userInfo = user.getUserInfo(); 47 | model.addAttribute("userDetails", userInfo); 48 | model.addAttribute("user", user); 49 | 50 | return "/user/user-edit"; 51 | } 52 | 53 | @PostMapping("/edit") 54 | public String editUser(Principal principal, User user, BindingResult bindingResult) { 55 | User newUser = userService.getUserByLogin(principal.getName()); 56 | 57 | if (!user.getPassword().equals("")) { 58 | if (!passwordEncoder.matches(user.getPassword(), newUser.getPassword())) { 59 | newUser.setPassword(passwordEncoder.encode(user.getPassword())); 60 | } else { 61 | ObjectError error = new ObjectError("globalError", 62 | "The password must not be the same."); 63 | bindingResult.addError(error); 64 | System.err.println(bindingResult.hasErrors()); 65 | return "/user/user-edit"; 66 | } 67 | } 68 | newUser.getUserInfo().setName(user.getUserInfo().getName()); 69 | newUser.getUserInfo().setSurname(user.getUserInfo().getSurname()); 70 | newUser.getUserInfo().setPhone(user.getUserInfo().getPhone()); 71 | userService.saveUser(newUser); 72 | return "redirect:/profile"; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/Category.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | 8 | import javax.persistence.*; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | @NoArgsConstructor 14 | @Getter 15 | @Setter 16 | @Entity 17 | @Table(name = "category") 18 | public class Category { 19 | @Id 20 | @GeneratedValue(strategy = GenerationType.IDENTITY) 21 | @Column(name = "id", nullable = false) 22 | private Integer id; 23 | 24 | @Column(name = "title", nullable = false, length = 155) 25 | private String title; 26 | 27 | @Column(name = "alias") 28 | private String alias; 29 | 30 | @Column(name = "image") 31 | private String imageURL; 32 | 33 | @Column(name = "enabled", nullable = false) 34 | private Boolean enabled; 35 | 36 | //parent_id refers to category id or null if it's top-level category 37 | @ManyToOne 38 | @JoinColumn(name = "parent_id") 39 | private Category parent; 40 | 41 | @OneToMany(mappedBy = "parent") 42 | @OrderBy("title asc") 43 | @ToString.Exclude 44 | private Set children = new HashSet<>(); 45 | 46 | @OneToMany(mappedBy = "category", cascade = {CascadeType.ALL, CascadeType.PERSIST}) 47 | @ToString.Exclude 48 | private List products; 49 | 50 | @Column(name = "all_parent_ids", length = 255, nullable = true) 51 | @ToString.Exclude 52 | private String allParentsIDs; 53 | 54 | public static Category copyIdAndTitle(Category category) { 55 | Category copyCategory = new Category(); 56 | copyCategory.setId(category.getId()); 57 | copyCategory.setTitle(category.getTitle()); 58 | 59 | return copyCategory; 60 | } 61 | 62 | public static Category copyIdAndTitle(Integer id, String title) { 63 | Category copyCategory = new Category(); 64 | copyCategory.setId(id); 65 | copyCategory.setTitle(title); 66 | 67 | return copyCategory; 68 | } 69 | 70 | public static Category copyFull(Category category) { 71 | Category copyCategory = new Category(); 72 | copyCategory.setId(category.getId()); 73 | copyCategory.setTitle(category.getTitle()); 74 | copyCategory.setAlias(category.getAlias()); 75 | copyCategory.setImageURL(category.getImageURL()); 76 | copyCategory.setEnabled(category.getEnabled()); 77 | 78 | return copyCategory; 79 | } 80 | public static Category copyFull(Category category, String title) { 81 | Category copyCategory = Category.copyFull(category); 82 | copyCategory.setTitle(title); 83 | return copyCategory; 84 | } 85 | 86 | public Category(Integer id) { 87 | this.id = id; 88 | } 89 | 90 | public Category(String title, Category parent) { 91 | this(title); 92 | this.parent = parent; 93 | } 94 | 95 | public Category(String title) { 96 | this.title = title; 97 | this.alias = title; 98 | this.imageURL = "default.png"; 99 | } 100 | 101 | public Category(Integer id, String title, String alias, String imageURL, Boolean enabled, Category parent) { 102 | this.id = id; 103 | this.title = title; 104 | this.alias = alias; 105 | this.imageURL = imageURL; 106 | this.enabled = enabled; 107 | this.parent = parent; 108 | } 109 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/Delivery.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | import org.hibernate.annotations.OnDelete; 5 | import org.hibernate.annotations.OnDeleteAction; 6 | 7 | import javax.persistence.*; 8 | 9 | @AllArgsConstructor 10 | @NoArgsConstructor 11 | @Getter 12 | @Setter 13 | @ToString 14 | @Entity 15 | @Table(name = "delivery") 16 | public class Delivery { 17 | @Id 18 | @Column(name = "orders_id") 19 | private Integer id; 20 | 21 | @MapsId 22 | @OneToOne(fetch = FetchType.LAZY, optional = false) 23 | @OnDelete(action = OnDeleteAction.CASCADE) 24 | @JoinColumn(name = "orders_id") 25 | @ToString.Exclude 26 | private Order order; 27 | 28 | @Enumerated(EnumType.STRING) 29 | @Column(name = "status") 30 | private DeliveryStatus status; 31 | 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/DeliveryStatus.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | public enum DeliveryStatus { 4 | Обработка, 5 | Отправлено, 6 | Отмена, 7 | Доставлено, 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/Order.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.*; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | @Setter 11 | @ToString 12 | @Entity 13 | @Table(name = "orders") 14 | public class Order { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | @Column(name = "id") 18 | private int id; 19 | 20 | @Enumerated(EnumType.STRING) 21 | @Column(name = "order_status") 22 | private OrderType orderStatus; 23 | 24 | @ManyToOne(fetch = FetchType.LAZY, optional = false) 25 | @JoinColumn(name = "user_id") 26 | @ToString.Exclude 27 | private User user; 28 | 29 | @Column(name = "shipping_type") 30 | private int shippingType; 31 | 32 | @Column(name = "city") 33 | private String city; 34 | 35 | @Column(name = "address") 36 | private String address; 37 | 38 | @Column(name = "total_price") 39 | private Float totalPrice; 40 | 41 | @OneToOne(mappedBy = "order", cascade = CascadeType.ALL) 42 | @ToString.Exclude 43 | private Delivery delivery; 44 | 45 | 46 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/OrderBasket.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.*; 6 | import java.util.LinkedHashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Getter 13 | @Setter 14 | @ToString 15 | @Entity 16 | @Table(name = "order_basket") 17 | public class OrderBasket { 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | @Column(name = "id") 21 | private int id; 22 | 23 | @ManyToOne(fetch = FetchType.LAZY, optional = false) 24 | @JoinColumn(name = "product_id") 25 | @ToString.Exclude 26 | private Product product; 27 | 28 | @ManyToOne(fetch = FetchType.LAZY, optional = false) 29 | @JoinColumn(name = "user_id") 30 | @ToString.Exclude 31 | private User user; 32 | 33 | @Column(name = "quantity") 34 | private int quantity; 35 | 36 | //We use temporary field that is not in db for business logic(we don't need to save it in db) 37 | @Transient 38 | public float getSubtotal() { 39 | return this.product.getPrice() * quantity; 40 | } 41 | 42 | // @Transient 43 | // public float getTotal() { 44 | // float sum = 0; 45 | // for (OrderBasket orderBasket : this.product.getOrderBaskets()) { 46 | // sum += orderBasket.getSubtotal(); 47 | // } 48 | // return sum; 49 | // } 50 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/OrderType.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | public enum OrderType { 4 | Оплачено, 5 | Отмена, 6 | Ожидание, 7 | Обработка, 8 | Выполнен 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/Product.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | import org.hibernate.annotations.OnDelete; 5 | import org.hibernate.annotations.OnDeleteAction; 6 | 7 | import javax.persistence.*; 8 | import java.util.LinkedHashSet; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Getter 15 | @Setter 16 | @ToString 17 | @Entity 18 | @Table(name = "product") 19 | public class Product { 20 | @Id 21 | @GeneratedValue(strategy = GenerationType.IDENTITY) 22 | @Column(name = "id") 23 | private Integer id; 24 | 25 | @Column(name = "title") 26 | private String title; 27 | 28 | @Column(name = "alias") 29 | private String alias; 30 | 31 | @Column(name = "description") 32 | private String description; 33 | 34 | @Column(name = "price") 35 | private int price; 36 | 37 | @Column(name = "image") 38 | private String imageURL; 39 | @ManyToOne(fetch = FetchType.LAZY, optional = false) 40 | @OnDelete(action = OnDeleteAction.CASCADE) 41 | @JoinColumn(name = "vendor_id") 42 | @ToString.Exclude 43 | private Vendor vendor; 44 | 45 | @ManyToOne(fetch = FetchType.LAZY, optional = false) 46 | @OnDelete(action = OnDeleteAction.CASCADE) 47 | @JoinColumn(name = "category_id") 48 | @ToString.Exclude 49 | private Category category; 50 | 51 | @OneToMany(mappedBy = "product") 52 | @ToString.Exclude 53 | private List orderBaskets; 54 | 55 | @Transient 56 | public String getShortTitle() { 57 | if (title.length() > 40) { 58 | return title.substring(0, 40).concat("..."); 59 | } 60 | return title; 61 | } 62 | @Transient 63 | public String getShortAlias() { 64 | if (alias.length() > 40) { 65 | return alias.substring(0, 40).concat("..."); 66 | } 67 | return alias; 68 | } 69 | 70 | @Transient 71 | public String getShortDescription() { 72 | 73 | if (description != null && description.length() > 50) { 74 | return description.substring(0, 50).concat("..."); 75 | } 76 | return description; 77 | } 78 | 79 | 80 | //TODO add a new field in db discount if i need discount in future 81 | // @Transient 82 | // public float getDiscountPrice(){ 83 | // if (discountPercent > 0) 84 | // { 85 | // return price * ((100 - discountPercent) / 100); 86 | // } 87 | // return this.price; 88 | // } 89 | 90 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/Role.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | 5 | 6 | /* https://stackoverflow.com/questions/19525380/difference-between-role-and-grantedauthority-in-spring-security */ 7 | public enum Role implements GrantedAuthority { 8 | 9 | USER, ADMIN; 10 | 11 | @Override 12 | public String getAuthority() { 13 | return name(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.*; 6 | import javax.validation.constraints.NotBlank; 7 | import javax.validation.constraints.NotNull; 8 | import javax.validation.constraints.Size; 9 | import java.util.LinkedHashSet; 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @Getter 16 | @Setter 17 | @ToString 18 | @Entity 19 | @Table(name = "user") 20 | public class User { 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @Column(name = "id") 24 | private Integer id; 25 | 26 | @Column(name = "login") 27 | private String login; 28 | 29 | @Column(name = "password") 30 | private String password; 31 | 32 | @Column(name = "email") 33 | private String email; 34 | 35 | @Enumerated(EnumType.STRING) 36 | @Column(name = "role") 37 | private Role role; 38 | 39 | @OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL) 40 | @ToString.Exclude 41 | private UserInfo userInfo; 42 | 43 | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL, CascadeType.PERSIST}) 44 | @ToString.Exclude 45 | private List orderBaskets; 46 | 47 | @OneToMany(mappedBy = "user") 48 | @ToString.Exclude 49 | private List orders; 50 | 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | import org.hibernate.annotations.OnDelete; 5 | import org.hibernate.annotations.OnDeleteAction; 6 | 7 | import javax.persistence.*; 8 | 9 | @AllArgsConstructor 10 | @NoArgsConstructor 11 | @Getter 12 | @Setter 13 | @ToString 14 | @Entity 15 | @Table(name = "user_info") 16 | public class UserInfo { 17 | @Id 18 | @Column(name = "user_info_id", nullable = false) 19 | private int user_id; 20 | 21 | @MapsId 22 | @OneToOne(fetch = FetchType.LAZY, optional = false) 23 | @OnDelete(action = OnDeleteAction.CASCADE) 24 | @JoinColumn(name = "user_info_id") 25 | @ToString.Exclude 26 | private User user; 27 | 28 | @Column(name = "name") 29 | private String name; 30 | 31 | @Column(name = "surname") 32 | private String surname; 33 | 34 | @Column(name = "phone") 35 | private String phone; 36 | 37 | 38 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/entity/Vendor.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.entity; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.*; 6 | import java.util.LinkedHashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Getter 13 | @Setter 14 | @ToString 15 | @Entity 16 | @Table(name = "vendor") 17 | public class Vendor { 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | @Column(name = "id", nullable = false) 21 | private Integer id; 22 | 23 | @Column(name = "title", nullable = false) 24 | private String title; 25 | 26 | @OneToMany(mappedBy = "vendor") 27 | @ToString.Exclude 28 | private List products; 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/exception/CategoryNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.exception; 2 | 3 | public class CategoryNotFoundException extends Exception { 4 | public CategoryNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/exception/OrderNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.exception; 2 | 3 | public class OrderNotFoundException extends Exception { 4 | public OrderNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/exception/ProductNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.exception; 2 | 3 | public class ProductNotFoundException extends Exception { 4 | public ProductNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/exception/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.exception; 2 | 3 | public class UserNotFoundException extends Exception { 4 | public UserNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/CategoryRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.Query; 8 | import org.springframework.data.repository.query.Param; 9 | 10 | import java.util.List; 11 | 12 | public interface CategoryRepository extends JpaRepository { 13 | @Query("SELECT category FROM Category category WHERE category.enabled = true ORDER BY category.title ASC") 14 | public List findAllEnabled(); 15 | 16 | @Query("select category from Category category where category.enabled = true and category.alias = ?1") 17 | public Category findByAliasEnabled(String alias); 18 | 19 | public Category findByAlias(String alias); 20 | 21 | public Long countById(Integer id); 22 | 23 | @Query("SELECT c FROM Category c WHERE c.title = :title") 24 | public Category findByTitle(@Param("title") String title); 25 | 26 | //For categories that doesn't have parents, 27 | // so we avoid error when we choose for parent category parent's id 28 | @Query("SELECT c FROM Category c WHERE c.parent.id is NULL") 29 | public List findRootCategories(); 30 | 31 | @Query("SELECT c FROM Category c WHERE c.parent.id is NULL") 32 | public Page findRootCategories(Pageable pageable); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/DeliveryRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.Delivery; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface DeliveryRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/OrderBasketRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.OrderBasket; 4 | import com.khomsi.site_project.entity.Product; 5 | import com.khomsi.site_project.entity.User; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.Modifying; 8 | import org.springframework.data.jpa.repository.Query; 9 | 10 | import java.util.List; 11 | 12 | public interface OrderBasketRepository extends JpaRepository { 13 | public List findByUser(User user); 14 | 15 | public OrderBasket findByUserAndProduct(User user, Product product); 16 | 17 | //It's update/delete query so we use @modifying 18 | @Query("UPDATE OrderBasket orderBasket SET orderBasket.quantity = ?1 WHERE orderBasket.product.id = ?2 " + 19 | "AND orderBasket.user.id = ?3") 20 | @Modifying 21 | public void updateQuantity(Integer quantity, Integer productId, Integer userId); 22 | 23 | @Query("DELETE FROM OrderBasket orderBasket WHERE orderBasket.user.id = ?1 AND orderBasket.product.id = ?2") 24 | @Modifying 25 | public void deleteByUserAndProduct(Integer userId, Integer productId); 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.Order; 4 | import com.khomsi.site_project.entity.OrderBasket; 5 | import com.khomsi.site_project.entity.User; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | import java.util.List; 9 | 10 | public interface OrderRepository extends JpaRepository { 11 | Order findByUser(User user); 12 | 13 | List findOrdersByUser(User user); 14 | 15 | public Long countById(Integer id); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import com.khomsi.site_project.entity.Product; 5 | import org.springframework.data.domain.Page; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.data.jpa.repository.Query; 9 | 10 | import java.util.List; 11 | 12 | public interface ProductRepository extends JpaRepository { 13 | @Query("SELECT product FROM Product product WHERE (product.category.id = ?1 OR product.category.allParentsIDs LIKE %?2%)" 14 | + "ORDER BY product.title ASC") 15 | public Page listByCategory(Integer categoryId, Pageable pageable, String categoryIDMatch); 16 | 17 | @Query(value = "SELECT * FROM product WHERE MATCH(title, description) AGAINST (?1)", 18 | nativeQuery = true) 19 | public Page search(String keyword, Pageable pageable); 20 | 21 | public Product findByAlias(String alias); 22 | 23 | public Product findByTitle(String title); 24 | 25 | public List findAllByCategoryId(Integer category); 26 | 27 | public Long countById(Integer id); 28 | 29 | @Query("SELECT p FROM Product p WHERE p.title LIKE %?1% " 30 | + "OR p.description LIKE %?1% " 31 | + "OR p.vendor.title LIKE %?1% " 32 | + "OR p.category.title LIKE %?1%") 33 | public Page findAll(String keyword, Pageable pageable); 34 | 35 | @Query("SELECT p FROM Product p WHERE p.category.id = ?1 " + 36 | "OR p.category.allParentsIDs LIKE %?2%") 37 | public Page findAllInCategory(Integer categoryId, String categoryIdMatch, 38 | Pageable pageable); 39 | 40 | @Query("SELECT p FROM Product p WHERE (p.category.id = ?1 " + 41 | "OR p.category.allParentsIDs LIKE %?2%) AND " 42 | + "(p.title LIKE %?3% " 43 | + "OR p.description LIKE %?3% " 44 | + "OR p.vendor.title LIKE %?3% " 45 | + "OR p.category.title LIKE %?3%)") 46 | public Page searchInCategory(Integer categoryId, String categoryIdMatch, 47 | String keyword, Pageable pageable); 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/UserInfoRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.UserInfo; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface UserInfoRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | 10 | @Query("SELECT u FROM User u WHERE u.login = :login") 11 | public User findByLogin(@Param("login") String login); 12 | 13 | public Long countById(Integer id); 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/repository/VendorRepository.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.repository; 2 | 3 | import com.khomsi.site_project.entity.Vendor; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | public interface VendorRepository extends JpaRepository { 9 | public Long countById(Integer id); 10 | 11 | @Query("SELECT v FROM Vendor v WHERE v.title = :title") 12 | public Vendor findByTitle(@Param("title") String title); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/CategoryPageInfo.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | public class CategoryPageInfo { 4 | private int totalPages; 5 | private long totalElements; 6 | 7 | public int getTotalPages() { 8 | return totalPages; 9 | } 10 | 11 | public void setTotalPages(int totalPages) { 12 | this.totalPages = totalPages; 13 | } 14 | 15 | public long getTotalElements() { 16 | return totalElements; 17 | } 18 | 19 | public void setTotalElements(long totalElements) { 20 | this.totalElements = totalElements; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/ICategoryService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import com.khomsi.site_project.exception.CategoryNotFoundException; 5 | import org.springframework.data.domain.Page; 6 | 7 | import java.util.List; 8 | 9 | public interface ICategoryService { 10 | List listByPage(CategoryPageInfo pageInfo, int pageNum); 11 | 12 | public List listCategoriesUserInForm(); 13 | public Category saveCategory(Category category); 14 | 15 | public void deleteCategory(int id) throws CategoryNotFoundException; 16 | 17 | public Category getCategory(Integer id) throws CategoryNotFoundException; 18 | public Category getCategoryByAlias(String alias) throws CategoryNotFoundException; 19 | 20 | //list up parent of categories 21 | List getCategoryParents(Category child); 22 | 23 | 24 | String checkCategoryTitle(Integer id, String title, String alias); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/IOrderBasketService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.OrderBasket; 4 | import com.khomsi.site_project.entity.User; 5 | 6 | import java.util.List; 7 | 8 | public interface IOrderBasketService { 9 | List getAllOrderBaskets(); 10 | 11 | public List listOrderBasket(User user); 12 | 13 | public Integer addProduct(Integer productId, Integer quantity, User user); 14 | 15 | public float updateQuantity(Integer productId, Integer quantity, User user); 16 | 17 | public void removeProduct(Integer productId, User user); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/IOrdersService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.Order; 4 | import com.khomsi.site_project.entity.OrderBasket; 5 | import com.khomsi.site_project.entity.User; 6 | import com.khomsi.site_project.exception.OrderNotFoundException; 7 | import org.springframework.data.domain.Page; 8 | 9 | import java.util.List; 10 | 11 | public interface IOrdersService { 12 | public List getAllOrders(); 13 | 14 | List getAllOrdersByUser(User user); 15 | 16 | public void saveOrder(Order orders); 17 | 18 | public Order getOrder(int id); 19 | 20 | public Order getOrderByUser(User user) throws OrderNotFoundException; 21 | 22 | float countSum(List orderBaskets); 23 | 24 | public void deleteOrder(int id) throws OrderNotFoundException; 25 | 26 | 27 | Page listByPage(int pageNum); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/IProductService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.Product; 4 | import com.khomsi.site_project.exception.ProductNotFoundException; 5 | import org.springframework.data.domain.Page; 6 | 7 | import java.util.List; 8 | 9 | public interface IProductService { 10 | 11 | Page listByPage(int pageNum, String sortField, String sortDir, String keyword, 12 | Integer categoryId); 13 | 14 | public List getAllProducts() throws ProductNotFoundException; 15 | 16 | List getRandomAmountOfProducts() throws ProductNotFoundException; 17 | 18 | public Page listByCategory(int pageNum, Integer categoryId); 19 | 20 | public void saveProduct(Product product); 21 | 22 | Product getProduct(Integer id) throws ProductNotFoundException; 23 | 24 | Product getProduct(String alias) throws ProductNotFoundException; 25 | 26 | void deleteProduct(Integer id) throws ProductNotFoundException; 27 | 28 | 29 | String checkUnique(Integer id, String title); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/IUserInfoService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.UserInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface IUserInfoService { 8 | 9 | public List getAllUserDetails(); 10 | 11 | public void saveUserDetail(UserInfo userInfo); 12 | 13 | public UserInfo getUserDetail(int id); 14 | 15 | public void deleteUserDetail(int id); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.User; 4 | import com.khomsi.site_project.exception.UserNotFoundException; 5 | import org.springframework.data.domain.Page; 6 | 7 | import java.util.List; 8 | 9 | public interface IUserService { 10 | 11 | public List getAllUsers(); 12 | 13 | public void saveUser(User user); 14 | 15 | void encodePassword(User user); 16 | 17 | String isLoginUnique(Integer id, String login); 18 | 19 | boolean checkLoginRegistration(String login); 20 | 21 | public User getUser(int id) throws UserNotFoundException; 22 | 23 | public User getUserByLogin(String login); 24 | 25 | public void deleteUser(Integer id) throws UserNotFoundException; 26 | 27 | Page listByPage(int pageNum); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/IVendorService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.Vendor; 4 | import org.springframework.data.domain.Page; 5 | 6 | import java.util.List; 7 | 8 | public interface IVendorService { 9 | List getAllVendors(); 10 | 11 | void saveVendor(Vendor vendor); 12 | 13 | Vendor getVendor(int id); 14 | 15 | void deleteVendor(int id); 16 | 17 | Page listByPage(int pageNum); 18 | 19 | String checkVendorTitle(Integer id, String title); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/OrderBasketService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.OrderBasket; 4 | import com.khomsi.site_project.entity.Product; 5 | import com.khomsi.site_project.entity.User; 6 | import com.khomsi.site_project.repository.OrderBasketRepository; 7 | import com.khomsi.site_project.repository.ProductRepository; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.webjars.NotFoundException; 11 | 12 | import javax.transaction.Transactional; 13 | import java.util.List; 14 | 15 | @Service 16 | @Transactional 17 | public class OrderBasketService implements IOrderBasketService { 18 | @Autowired 19 | private OrderBasketRepository orderBasketRep; 20 | 21 | @Autowired 22 | private ProductRepository productRep; 23 | 24 | @Override 25 | public List getAllOrderBaskets() { 26 | List orderBasket = orderBasketRep.findAll(); 27 | if (orderBasket.isEmpty()) { 28 | throw new NotFoundException("Couldn't find any product in DB"); 29 | } 30 | return orderBasket; 31 | } 32 | 33 | @Override 34 | public List listOrderBasket(User user) { 35 | return orderBasketRep.findByUser(user); 36 | } 37 | 38 | 39 | @Override 40 | public Integer addProduct(Integer productId, Integer quantity, User user) { 41 | Integer addedQuantity = quantity; 42 | 43 | Product product = productRep.getReferenceById(productId); 44 | 45 | OrderBasket orderBasket = orderBasketRep.findByUserAndProduct(user, product); 46 | 47 | if (orderBasket != null) { 48 | addedQuantity = orderBasket.getQuantity() + quantity; 49 | orderBasket.setQuantity(addedQuantity); 50 | } 51 | //The product hasn't been added to the shopping card by this user 52 | else { 53 | orderBasket = new OrderBasket(); 54 | orderBasket.setQuantity(quantity); 55 | orderBasket.setUser(user); 56 | orderBasket.setProduct(product); 57 | } 58 | orderBasketRep.save(orderBasket); 59 | return addedQuantity; 60 | } 61 | 62 | @Override 63 | public float updateQuantity(Integer productId, Integer quantity, User user) { 64 | orderBasketRep.updateQuantity(quantity, productId, user.getId()); 65 | Product product = productRep.getReferenceById(productId); 66 | 67 | return product.getPrice() * quantity; 68 | } 69 | 70 | @Override 71 | public void removeProduct(Integer productId, User user) { 72 | orderBasketRep.deleteByUserAndProduct(user.getId(), productId); 73 | } 74 | 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/OrdersService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.*; 4 | import com.khomsi.site_project.exception.OrderNotFoundException; 5 | import com.khomsi.site_project.repository.OrderRepository; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.data.domain.Page; 8 | import org.springframework.data.domain.PageRequest; 9 | import org.springframework.data.domain.Pageable; 10 | import org.springframework.stereotype.Service; 11 | import org.webjars.NotFoundException; 12 | 13 | import java.util.List; 14 | import java.util.Optional; 15 | 16 | @Service 17 | public class OrdersService implements IOrdersService { 18 | @Autowired 19 | private OrderRepository orderRepository; 20 | 21 | public static final int ORDERS_PER_PAGE = 8; 22 | 23 | 24 | @Override 25 | public List getAllOrders() { 26 | return orderRepository.findAll(); 27 | } 28 | 29 | @Override 30 | public List getAllOrdersByUser(User user) { 31 | return orderRepository.findOrdersByUser(user); 32 | } 33 | 34 | @Override 35 | public void saveOrder(Order orders) { 36 | orderRepository.save(orders); 37 | } 38 | 39 | @Override 40 | public Order getOrder(int id) { 41 | Order orders = null; 42 | Optional optional = orderRepository.findById(id); 43 | if (optional.isPresent()) orders = optional.get(); 44 | return orders; 45 | } 46 | 47 | @Override 48 | public Order getOrderByUser(User user) throws OrderNotFoundException { 49 | Order order = orderRepository.findByUser(user); 50 | if (order == null) { 51 | throw new OrderNotFoundException("Couldn't find any orders with ID " + order.getId()); 52 | } 53 | return order; 54 | } 55 | 56 | @Override 57 | public float countSum(List orderBaskets) { 58 | float sum = 0; 59 | for (OrderBasket orderBasket : orderBaskets) { 60 | sum += orderBasket.getSubtotal(); 61 | } 62 | return sum; 63 | } 64 | 65 | @Override 66 | public void deleteOrder(int id) throws OrderNotFoundException { 67 | Long countById = orderRepository.countById(id); 68 | if (countById == null || countById == 0) { 69 | throw new OrderNotFoundException("Couldn't find any orders with id " + id); 70 | } 71 | orderRepository.deleteById(id); 72 | } 73 | 74 | @Override 75 | public Page listByPage(int pageNum) { 76 | Pageable pageable = PageRequest.of(pageNum - 1, ORDERS_PER_PAGE); 77 | return orderRepository.findAll(pageable); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.Product; 4 | import com.khomsi.site_project.exception.ProductNotFoundException; 5 | import com.khomsi.site_project.repository.ProductRepository; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.data.domain.Page; 8 | import org.springframework.data.domain.PageRequest; 9 | import org.springframework.data.domain.Pageable; 10 | import org.springframework.data.domain.Sort; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.Collections; 14 | import java.util.List; 15 | import java.util.NoSuchElementException; 16 | import java.util.Objects; 17 | 18 | @Service 19 | public class ProductService implements IProductService { 20 | @Autowired 21 | private ProductRepository productRepository; 22 | public static final int PRODUCTS_PER_PAGE = 10; 23 | public static final int SEARCH_RESULTS_PAGE = 10; 24 | 25 | public static final int PRODUCTS_PER_ADMIN_PAGE = 5; 26 | 27 | @Override 28 | public Page listByCategory(int pageNum, Integer categoryId) { 29 | String categoryIdMatch = "-" + String.valueOf(categoryId) + "-"; 30 | Pageable pageable = PageRequest.of(pageNum - 1, PRODUCTS_PER_PAGE); 31 | 32 | return productRepository.listByCategory(categoryId, pageable, categoryIdMatch); 33 | } 34 | 35 | @Override 36 | public Page listByPage(int pageNum, String sortField, String sortDir, String keyword, 37 | Integer categoryId) { 38 | Sort sort = Sort.by(sortField); 39 | sort = sortDir.equals("asc") ? sort.ascending() : sort.descending(); 40 | 41 | Pageable pageable = PageRequest.of(pageNum - 1, PRODUCTS_PER_ADMIN_PAGE, sort); 42 | 43 | if (keyword != null && !keyword.isEmpty()) { 44 | if (categoryId != null && categoryId > 0) { 45 | String categoryIdMatch = "-" + String.valueOf(categoryId) + "-"; 46 | return productRepository.searchInCategory(categoryId, categoryIdMatch, keyword, pageable); 47 | } 48 | return productRepository.findAll(keyword, pageable); 49 | } 50 | if (categoryId != null && categoryId > 0) { 51 | String categoryIdMatch = "-" + String.valueOf(categoryId) + "-"; 52 | return productRepository.findAllInCategory(categoryId, categoryIdMatch, pageable); 53 | } 54 | 55 | return productRepository.findAll(pageable); 56 | } 57 | 58 | @Override 59 | public List getAllProducts() throws ProductNotFoundException { 60 | List listProducts = productRepository.findAll(); 61 | if (listProducts.isEmpty()) { 62 | throw new ProductNotFoundException("Couldn't find any product in DB"); 63 | } 64 | return listProducts; 65 | } 66 | 67 | @Override 68 | public List getRandomAmountOfProducts() throws ProductNotFoundException { 69 | List productList = productRepository.findAllByCategoryId(4); 70 | if (productList.isEmpty()) { 71 | throw new ProductNotFoundException("Couldn't find any product in DB"); 72 | } 73 | Collections.shuffle(productList); 74 | int randomSeriesLength = 8; 75 | return productList.subList(0, randomSeriesLength); 76 | 77 | } 78 | 79 | @Override 80 | public void saveProduct(Product product) { 81 | if (product.getAlias() == null || product.getAlias().isEmpty()) { 82 | String defaultAlias = product.getTitle().toLowerCase(); 83 | product.setAlias((new CategoryService().convertCyrillic(defaultAlias).replaceAll(" ", "_"))); 84 | } else { 85 | product.setAlias(product.getAlias().replaceAll(" ", "_").toLowerCase()); 86 | } 87 | productRepository.save(product); 88 | } 89 | 90 | @Override 91 | public Product getProduct(Integer id) throws ProductNotFoundException { 92 | try { 93 | return productRepository.getReferenceById(id); 94 | } catch (NoSuchElementException e) { 95 | throw new ProductNotFoundException("Couldn't find any product with id " + id); 96 | } 97 | } 98 | 99 | @Override 100 | public Product getProduct(String alias) throws ProductNotFoundException { 101 | try { 102 | return productRepository.findByAlias(alias); 103 | } catch (NoSuchElementException e) { 104 | throw new ProductNotFoundException("Couldn't find any product with alias " + alias); 105 | } 106 | } 107 | 108 | @Override 109 | public void deleteProduct(Integer id) throws ProductNotFoundException { 110 | Long countById = productRepository.countById(id); 111 | if (countById == null || countById == 0) { 112 | throw new ProductNotFoundException("Couldn't find any product with ID " + id); 113 | } 114 | productRepository.deleteById(id); 115 | } 116 | 117 | @Override 118 | public String checkUnique(Integer id, String title) { 119 | boolean isCreatingNew = (id == null || id == 0); 120 | Product productByName = productRepository.findByTitle(title); 121 | if (isCreatingNew) { 122 | if (productByName != null) return "Duplicate"; 123 | } else { 124 | if (productByName != null && !Objects.equals(productByName.getId(), id)) { 125 | return "Duplicate"; 126 | } 127 | } 128 | return "OK"; 129 | } 130 | 131 | public Page search(String keyword, int pageNum) { 132 | Pageable pageable = PageRequest.of(pageNum - 1, SEARCH_RESULTS_PAGE); 133 | return productRepository.search(keyword, pageable); 134 | 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/UserInfoService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.UserInfo; 4 | import com.khomsi.site_project.repository.UserInfoRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | import java.util.Optional; 10 | @Service 11 | public class UserInfoService implements IUserInfoService { 12 | @Autowired 13 | private UserInfoRepository userInfoRepository; 14 | 15 | @Override 16 | public List getAllUserDetails() { 17 | return userInfoRepository.findAll(); 18 | } 19 | 20 | @Override 21 | public void saveUserDetail(UserInfo userInfo) { 22 | userInfoRepository.save(userInfo); 23 | } 24 | 25 | @Override 26 | public UserInfo getUserDetail(int id) { 27 | UserInfo userInfo = null; 28 | Optional optional = userInfoRepository.findById(id); 29 | if (optional.isPresent()) { 30 | userInfo = optional.get(); 31 | } 32 | return userInfo; 33 | } 34 | 35 | @Override 36 | public void deleteUserDetail(int id) { 37 | userInfoRepository.deleteById(id); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.User; 4 | import com.khomsi.site_project.exception.UserNotFoundException; 5 | import com.khomsi.site_project.repository.UserRepository; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.data.domain.Page; 8 | import org.springframework.data.domain.PageRequest; 9 | import org.springframework.data.domain.Pageable; 10 | import org.springframework.security.crypto.password.PasswordEncoder; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.List; 14 | import java.util.NoSuchElementException; 15 | import java.util.Objects; 16 | 17 | @Service 18 | public class UserService implements IUserService { 19 | 20 | @Autowired 21 | private UserRepository userRepository; 22 | @Autowired 23 | private PasswordEncoder passwordEncoder; 24 | 25 | public static final int USER_PER_PAGE = 4; 26 | 27 | @Override 28 | public List getAllUsers() { 29 | return userRepository.findAll(); 30 | } 31 | 32 | @Override 33 | public void saveUser(User user) { 34 | boolean isUpdatedUser = (user.getId() != null); 35 | if (isUpdatedUser) { 36 | User existingUser = userRepository.getReferenceById(user.getId()); 37 | 38 | if (user.getPassword().isEmpty()) { 39 | user.setPassword(existingUser.getPassword()); 40 | } else { 41 | encodePassword(user); 42 | } 43 | } else { 44 | encodePassword(user); 45 | } 46 | userRepository.save(user); 47 | } 48 | 49 | @Override 50 | public User getUser(int id) throws UserNotFoundException { 51 | try { 52 | return userRepository.getReferenceById(id); 53 | } catch (NoSuchElementException ex) { 54 | throw new UserNotFoundException("Couldn't find any user with id " + id); 55 | } 56 | } 57 | 58 | @Override 59 | public User getUserByLogin(String login) { 60 | return userRepository.findByLogin(login); 61 | } 62 | 63 | @Override 64 | public void deleteUser(Integer id) throws UserNotFoundException { 65 | Long countById = userRepository.countById(id); 66 | if (countById == null || countById == 0) { 67 | throw new UserNotFoundException("Couldn't find any user with id " + id); 68 | } 69 | userRepository.deleteById(id); 70 | } 71 | 72 | @Override 73 | public void encodePassword(User user) { 74 | String encodePass = passwordEncoder.encode(user.getPassword()); 75 | user.setPassword(encodePass); 76 | } 77 | 78 | @Override 79 | public String isLoginUnique(Integer id, String login) { 80 | User userByLogin = userRepository.findByLogin(login); 81 | boolean isCreatingNew = (id == null); 82 | 83 | if (isCreatingNew) { 84 | if (userByLogin != null) return "Duplicate"; 85 | } else { 86 | if (!Objects.equals(userByLogin.getId(), id)) { 87 | return "Duplicate"; 88 | } 89 | } 90 | return "OK"; 91 | } 92 | 93 | /* 94 | Added this method to check unique login for user while he's registration 95 | You can modify it to have more unique fields. 96 | (if you need unique fields in admin panel for user, change another methods like isLoginUnique) 97 | */ 98 | @Override 99 | public boolean checkLoginRegistration(String login) { 100 | User user = userRepository.findByLogin(login); 101 | 102 | return user == null; 103 | } 104 | 105 | @Override 106 | public Page listByPage(int pageNum) { 107 | Pageable pageable = PageRequest.of(pageNum - 1, USER_PER_PAGE); 108 | return userRepository.findAll(pageable); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/khomsi/site_project/service/VendorService.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project.service; 2 | 3 | import com.khomsi.site_project.entity.Vendor; 4 | import com.khomsi.site_project.repository.VendorRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.domain.Page; 7 | import org.springframework.data.domain.PageRequest; 8 | import org.springframework.data.domain.Pageable; 9 | import org.springframework.stereotype.Service; 10 | import org.webjars.NotFoundException; 11 | 12 | import java.util.List; 13 | import java.util.Objects; 14 | import java.util.Optional; 15 | 16 | @Service 17 | public class VendorService implements IVendorService { 18 | @Autowired 19 | private VendorRepository vendorRepository; 20 | 21 | public static final int VENDORS_PER_PAGE = 4; 22 | 23 | @Override 24 | public List getAllVendors() { 25 | return vendorRepository.findAll(); 26 | } 27 | 28 | @Override 29 | public void saveVendor(Vendor vendor) { 30 | vendorRepository.save(vendor); 31 | } 32 | 33 | @Override 34 | public Vendor getVendor(int id) { 35 | Vendor vendor = null; 36 | Optional optional = vendorRepository.findById(id); 37 | if (optional.isPresent()) { 38 | vendor = optional.get(); 39 | } 40 | return vendor; 41 | } 42 | 43 | @Override 44 | public void deleteVendor(int id) { 45 | Long countById = vendorRepository.countById(id); 46 | if (countById == null || countById == 0) { 47 | throw new NotFoundException("Couldn't find any vendor with id " + id); 48 | } 49 | vendorRepository.deleteById(id); 50 | } 51 | 52 | @Override 53 | public Page listByPage(int pageNum) { 54 | Pageable pageable = PageRequest.of(pageNum - 1, VENDORS_PER_PAGE); 55 | return vendorRepository.findAll(pageable); 56 | } 57 | 58 | @Override 59 | public String checkVendorTitle(Integer id, String title) { 60 | Vendor vendor = vendorRepository.findByTitle(title); 61 | boolean isCreatingNew = (id == null); 62 | 63 | if (isCreatingNew) { 64 | if (vendor != null) return "Duplicate"; 65 | } else { 66 | if (!Objects.equals(vendor.getId(), id)) { 67 | return "Duplicate"; 68 | } 69 | } 70 | return "OK"; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | username: spring 4 | url: jdbc:mysql://localhost:3306/web_store_test?useSSL=false 5 | password: spring 6 | mail: 7 | host: smtp-mail.outlook.com 8 | port: 587 9 | username: senkoShop@outlook.com 10 | password: Midostar10035 11 | properties: 12 | mail: 13 | smtp: 14 | auth: true 15 | starttls: 16 | enable: true 17 | 18 | server: 19 | port: 8084 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/sql/WebShopDB.mwb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/sql/WebShopDB.mwb -------------------------------------------------------------------------------- /src/main/resources/sql/triggers.txt: -------------------------------------------------------------------------------- 1 | DELIMITER // 2 | CREATE TRIGGER deleteFromUserInfo 3 | AFTER DELETE ON user 4 | FOR EACH ROW begin 5 | DELETE FROM user_info WHERE user_info_id = OLD.id; 6 | END// 7 | 8 | DELIMITER // 9 | CREATE TRIGGER insOrders 10 | AFTER INSERT 11 | ON `orders` 12 | FOR EACH ROW 13 | BEGIN 14 | DELETE FROM order_basket WHERE user_id = NEW.user_id; 15 | END // 16 | DELIMITER ; 17 | 18 | DELIMITER // 19 | CREATE TRIGGER afterUpdOrdersInsDel 20 | AFTER UPDATE on orders 21 | FOR EACH ROW 22 | BEGIN 23 | IF NEW.order_status = 'Оплачено' THEN 24 | INSERT INTO delivery(orders_id, status) values(OLD.id, 'Обработка'); 25 | END IF; 26 | END// 27 | DELIMITER ; 28 | 29 | 30 | DELIMITER // 31 | CREATE TRIGGER afterInsOrdersInsDel AFTER INSERT on orders 32 | FOR EACH ROW 33 | BEGIN 34 | IF NEW.order_status = 'Оплачено' THEN 35 | INSERT INTO delivery(orders_id, status) values(NEW.id, 'Обработка'); 36 | END IF; 37 | END// 38 | DELIMITER ; 39 | 40 | DELIMITER // 41 | CREATE TRIGGER deleteOrder_delivery 42 | BEFORE DELETE 43 | ON `orders` 44 | FOR EACH ROW 45 | BEGIN 46 | DELETE FROM delivery WHERE orders_id = OLD.id; 47 | END // 48 | DELIMITER ; -------------------------------------------------------------------------------- /src/main/resources/static/assets/email.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/assets/email.gif -------------------------------------------------------------------------------- /src/main/resources/static/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/assets/favicon.png -------------------------------------------------------------------------------- /src/main/resources/static/assets/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/assets/logo.gif -------------------------------------------------------------------------------- /src/main/resources/static/category-images/Electronics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/Electronics.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/bathrobe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/bathrobe.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/clothes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/clothes.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/default.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/laptops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/laptops.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/phonecase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/phonecase.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/phones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/phones.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/tv.png -------------------------------------------------------------------------------- /src/main/resources/static/category-images/watch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/category-images/watch.png -------------------------------------------------------------------------------- /src/main/resources/static/img/ClothesBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/img/ClothesBanner.png -------------------------------------------------------------------------------- /src/main/resources/static/img/ElectronicsBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/img/ElectronicsBanner.png -------------------------------------------------------------------------------- /src/main/resources/static/img/PhonesBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/img/PhonesBanner.png -------------------------------------------------------------------------------- /src/main/resources/static/img/samsungBanner.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/img/samsungBanner.mp4 -------------------------------------------------------------------------------- /src/main/resources/static/img/svg/arrow_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/static/img/svg/arrow_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/static/js/added_to_cart.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $("#addToCartBtn").on("click", function (e){ 3 | addToCart(); 4 | }) 5 | }); 6 | function addToCart(){ 7 | quantity = $("#quantity" + productId).val(); 8 | 9 | url = contextPath + "basket/add/" + productId + "/" + quantity; 10 | 11 | $.ajax({ 12 | type: "POST", 13 | url: url, 14 | beforeSend: function (xhr){ 15 | xhr.setRequestHeader(csrfHeaderName, csrfValue); 16 | } 17 | }).done(function (response){ 18 | $("#modalTitle").text("Shopping basket"); 19 | $("#modalBody").text(response); 20 | $("#myModal").modal(); 21 | }).fail(function (){ 22 | $("#modalTitle").text("Shopping basket"); 23 | $("#modalBody").text("Error while adding product to shopping basket."); 24 | $("#myModal").modal(); 25 | }); 26 | } -------------------------------------------------------------------------------- /src/main/resources/static/js/formValidation.js: -------------------------------------------------------------------------------- 1 | function emailCheck() { 2 | if ($("#email").val() == "") { 3 | $("#email").addClass('is-invalid'); 4 | return false; 5 | } else { 6 | var regMail = /^([_a-zA-Z0-9-]+)(\.[_a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,3})$/; 7 | if (regMail.test($("#email").val()) == false) { 8 | $("#email").addClass('is-invalid'); 9 | return false; 10 | } else { 11 | $("#email").removeClass('is-invalid'); 12 | $('#next-form').collapse('show'); 13 | } 14 | 15 | } 16 | } 17 | let password = document.getElementById('password'); 18 | let icon1 = document.getElementById('icon1'); 19 | icon1.addEventListener('click', () => { 20 | password.type = 21 | password.type == 'password' ? 'text' : 'password'; 22 | icon1.className = 23 | icon1.className == 'fas fa-eye' ? 'fas fa-eye-slash' : 'fas fa-eye'; 24 | }); -------------------------------------------------------------------------------- /src/main/resources/static/js/quantity_control.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $(".minusButton").on("click",function (evt){ 3 | evt.preventDefault(); 4 | productId = $(this).attr("pid"); 5 | qtyInput = $("#quantity" + productId); 6 | 7 | newQty = parseInt(qtyInput.val()) - 1; 8 | if (newQty > 0) qtyInput.val(newQty); 9 | }); 10 | $(".plusButton").on("click",function (evt){ 11 | evt.preventDefault(); 12 | productId = $(this).attr("pid"); 13 | qtyInput = $("#quantity" + productId); 14 | 15 | newQty = parseInt(qtyInput.val()) + 1; 16 | if (newQty <= 10) qtyInput.val(newQty); 17 | }); 18 | }); -------------------------------------------------------------------------------- /src/main/resources/static/js/shopping-cart.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $(".minusButton").on("click", function (evt) { 3 | evt.preventDefault(); 4 | decreaseQuantity($(this)); 5 | }); 6 | 7 | $(".plusButton").on("click", function (evt) { 8 | evt.preventDefault(); 9 | increaseQuantity($(this)); 10 | }); 11 | $(".link-remove").on("click", function (evt) { 12 | evt.preventDefault(); 13 | removeFromCart($(this)); 14 | }); 15 | updateTotal(); 16 | }); 17 | 18 | function removeFromCart(link) { 19 | url = link.attr("href"); 20 | 21 | $.ajax({ 22 | type: "POST", 23 | url: url, 24 | beforeSend: function (xhr) { 25 | xhr.setRequestHeader(csrfHeaderName, csrfValue); 26 | } 27 | }).done(function (response) { 28 | $("#modalTitle").text("Shopping basket"); 29 | if (response.includes("removed")) { 30 | $("#myModal").on("hide.bs.modal", function (e) { 31 | rowNumber = link.attr("rowNumber"); 32 | removeProduct(rowNumber); 33 | updateTotal(); 34 | }); 35 | } 36 | 37 | $("#modalBody").text(response); 38 | $("#myModal").modal(); 39 | }).fail(function () { 40 | $("#modalTitle").text("Shopping basket"); 41 | $("#modalBody").text("Error while removing product to shopping basket."); 42 | $("#myModal").modal(); 43 | }); 44 | } 45 | 46 | function removeProduct(rowNumber) { 47 | rowId = "row" + rowNumber; 48 | $("#" + rowId).remove(); 49 | } 50 | 51 | function increaseQuantity(link) { 52 | productId = link.attr("pid"); 53 | qtyInput = $("#quantity" + productId); 54 | 55 | newQty = parseInt(qtyInput.val()) + 1; 56 | if (newQty <= 10) { 57 | qtyInput.val(newQty); 58 | updateQuantity(productId, newQty); 59 | } 60 | } 61 | 62 | function decreaseQuantity(link) { 63 | productId = link.attr("pid"); 64 | qtyInput = $("#quantity" + productId); 65 | 66 | newQty = parseInt(qtyInput.val()) - 1; 67 | if (newQty > 0) { 68 | qtyInput.val(newQty); 69 | updateQuantity(productId, newQty); 70 | } 71 | } 72 | 73 | function updateQuantity(productId, quantity) { 74 | url = contextPath + "basket/update/" + productId + "/" + quantity; 75 | 76 | $.ajax({ 77 | type: "POST", 78 | url: url, 79 | beforeSend: function (xhr) { 80 | xhr.setRequestHeader(csrfHeaderName, csrfValue); 81 | } 82 | }).done(function (newSubtotal) { 83 | updateSubtotal(newSubtotal, productId); 84 | updateTotal(); 85 | }).fail(function () { 86 | $("#modalTitle").text("Shopping basket"); 87 | $("#modalBody").text("Error while updating product to shopping basket."); 88 | $("#myModal").modal(); 89 | }); 90 | } 91 | 92 | function updateSubtotal(newSubtotal, productId) { 93 | $("#subtotal" + productId).text(newSubtotal); 94 | } 95 | 96 | function updateTotal() { 97 | total = 0.0; 98 | $(".productSubtotal").each(function (index, element) { 99 | total = total + parseFloat(element.innerHTML); 100 | }); 101 | $("#totalAmount").text(total + "\u20B4"); 102 | } -------------------------------------------------------------------------------- /src/main/resources/static/product-images/05c6c1339.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/05c6c1339.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/05c6c1373.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/05c6c1373.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/143753339.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/143753339.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/152740976.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/152740976.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/153012611.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/153012611.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/166805614.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/166805614.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/175435404.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/175435404.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/179665007.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/179665007.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/181479242.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/181479242.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/182225695.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/182225695.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/18240829.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/18240829.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/201644018.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/201644018.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/215505081.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/215505081.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/219511084.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/219511084.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/221194930.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/221194930.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/221208611.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/221208611.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/221216157.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/221216157.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/237286899.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/237286899.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/237518825.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/237518825.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/237518843.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/237518843.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/237519282.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/237519282.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/237519719.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/237519719.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/240234430.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/240234430.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/240679986.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/240679986.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/241248608.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/241248608.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/245951562.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/245951562.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/246788854.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/246788854.png -------------------------------------------------------------------------------- /src/main/resources/static/product-images/247191594.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/247191594.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/248749664.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/248749664.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/249006810.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/249006810.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/249691847.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/249691847.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/250964653.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/250964653.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/252187527.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/252187527.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/253280149.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/253280149.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/253281547.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/253281547.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/256314559.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/256314559.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/259416221.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/259416221.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/259453445.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/259453445.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/262334763.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/262334763.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/263940978.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/263940978.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/263974548.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/263974548.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/267604551.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/267604551.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/267816864.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/267816864.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/273584154.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/273584154.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/274406559.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/274406559.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/274646506.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/274646506.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/275080610.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/275080610.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/278076445.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/278076445.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/278110854.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/278110854.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/278357675.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/278357675.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/278429510.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/278429510.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/279813767.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/279813767.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/279820947.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/279820947.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/279865808.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/279865808.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/279918555.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/279918555.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280040750.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280040750.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280547595.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280547595.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280562759.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280562759.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280598520.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280598520.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280612876.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280612876.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280626933.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280626933.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280630226.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280630226.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/280700402.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/280700402.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/281372796.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/281372796.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/281374487.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/281374487.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/281374511.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/281374511.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/282627868.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/282627868.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/283515477.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/283515477.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/283644375.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/283644375.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/284920810.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/284920810.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/284920851.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/284920851.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/284924180.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/284924180.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/285129119.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/285129119.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/29115201.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/29115201.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/30408872.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/30408872.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/31528740.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/31528740.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/37389483.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/37389483.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/45692166.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/45692166.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/4964O-99X-001-1-481447.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/4964O-99X-001-1-481447.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/53638637.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/53638637.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/53761557.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/53761557.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/53777130.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/53777130.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/5631N-50J-001-1-527331_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/5631N-50J-001-1-527331_1.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/73896886.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/73896886.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/default.png -------------------------------------------------------------------------------- /src/main/resources/static/product-images/img_5018.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/img_5018.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/img_5023.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/img_5023.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/img_6285.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/img_6285.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/img_6337.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/img_6337.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/img_6409.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/img_6409.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/iphone13_pro_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/iphone13_pro_max.png -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2020-11-08_07-22-10-768x1152.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2020-11-08_07-22-10-768x1152.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2020-11-08_12-19-36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2020-11-08_12-19-36.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2020-11-08_12-19-44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2020-11-08_12-19-44.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2020-11-22_15-28-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2020-11-22_15-28-15.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2020-11-22_15-47-32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2020-11-22_15-47-32.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2021-07-06_18-57-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2021-07-06_18-57-02.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2021-07-06_18-58-26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2021-07-06_18-58-26.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2021-11-05_20-53-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2021-11-05_20-53-27.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2021-11-05_21-21-52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2021-11-05_21-21-52.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/photo_2021-11-05_21-24-58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/photo_2021-11-05_21-24-58.jpg -------------------------------------------------------------------------------- /src/main/resources/static/product-images/samsung_galaxy_m52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/samsung_galaxy_m52.png -------------------------------------------------------------------------------- /src/main/resources/static/product-images/samsung_galaxy_s9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/samsung_galaxy_s9.png -------------------------------------------------------------------------------- /src/main/resources/static/product-images/tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SEM24/Ecommerce-Website-Spring-Boot/ff86de89a027ca29d990b48916321c4a0d815715/src/main/resources/static/product-images/tv.png -------------------------------------------------------------------------------- /src/main/resources/templates/admin/admin-panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 |
9 |
10 |

Welcome admin!
Use navbar to manage the DataBase!

11 |
12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/category/categories.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.categories.title}]]

9 | [[#{admin.categories.newCategory}]] 10 |
11 |
12 | [[${message}]] 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 38 | 39 |
[[#{admin.category.id}]][[#{admin.category.image}]][[#{admin.category.title}]][[#{admin.category.alias}]][[#{admin.category.enabled}]][[#{admin.managment}]]
30 | 36 |  
40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/category/category_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.categories.create.title}]]

9 |
10 |
12 | 13 |
14 |
15 | 16 |
17 | 19 |
20 |
21 |
22 | 23 |
24 | 27 |
28 |
29 |
30 | 31 |
32 | 34 |
35 |
36 |
37 | 38 |
39 | 45 |
46 |
47 |
48 | 49 |
50 | 53 |
54 |
55 |
56 | 59 | 62 |
63 |
64 |
65 |
66 |
67 |
68 | 73 | 121 | 122 |
123 | 124 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/order_basket/order_baskets.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.order_basket.title}]]

9 |
10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
[[#{admin.order_basket.id}]][[#{admin.order_basket.companyTitle}]][[#{admin.order_basket.login}]][[#{admin.order_basket.quantity}]]
26 |
27 |
28 |
29 |
30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/orders/order_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.orders.create.title}]]

9 |
10 |
12 | 13 | 14 |
15 |
16 | 17 |
18 | 19 | 23 | 24 |
25 |
26 |
27 | 28 |
29 | 31 | 32 | 34 | 35 |
36 |
37 |
38 | 39 |
40 | 42 |
43 |
44 |
45 | 46 |
47 | 49 |
50 |
51 |
52 | 53 |
54 | 56 |
57 |
58 |
59 | 62 | 65 |
66 |
67 |
68 |
69 |
70 |
71 | 72 | 79 | 80 |
81 | 82 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/orders/orders.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.orders.create.title}]]

9 |
10 |
11 | [[${message}]] 12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 |
[[#{admin.order.id}]][[#{admin.users.login}]][[#{admin.order.orderStatus}]][[#{admin.order.shipping}]][[#{admin.order.city}]][[#{admin.order.address}]][[#{admin.order.total}]][[#{admin.managment}]]
36 |  
40 |
41 | 42 | 43 |
44 |
45 |
46 |
47 | 48 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/product/product_description.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 9 |
10 |
11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/product/product_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 |
10 |
11 |

[[#{admin.products.create.title}]]

12 |
13 |
15 | 16 |
17 | 25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | 37 | 40 |
41 |
42 |
43 |
44 |
45 | 46 | 50 | 51 | 99 | 100 |
101 | 102 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/product/product_overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 |
8 | 10 |
11 |
12 |
13 | 14 |
15 | 18 |
19 |
20 |
21 | 22 |
23 | 28 |
29 |
30 |
31 | 32 |
33 | 35 |
36 |
37 |
38 | 39 |
40 | 45 |
46 |
47 |
48 | 49 |
50 | 52 |
53 |
54 |
55 | 56 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/user/user_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.users.create.title}]]

9 |
10 |
12 | 13 |
14 |
15 | 16 |
17 | 19 |
20 |
21 |
22 | 23 |
24 | 26 | 28 |
29 |
30 |
31 | 32 |
33 | 35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 | 44 |
45 |
46 |
47 | 48 |
49 | 51 |
52 |
53 |
54 | 55 |
56 | 58 |
59 |
60 |
61 |
62 | 63 |
64 | 65 | 69 | 70 |
71 |
72 |
73 | 75 | 77 |
78 |
79 |
80 |
81 |
82 |
83 | 84 | 129 | 130 |
131 | 132 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/user/users.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.users.title}]]

9 | 10 |
11 |
12 | [[${message}]] 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 43 | 44 |
[[#{admin.users.id}]][[#{admin.users.login}]][[#{admin.users.password}]][[#{admin.users.name}]][[#{admin.users.surname}]][[#{admin.users.phone}]][[#{admin.users.email}]][[#{admin.users.role}]][[#{admin.managment}]]
41 |  
45 |
46 | 47 |
48 |
49 |
50 |
51 | 52 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/vendor/vendor_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.vendor.create.title}]]

9 |
10 |
12 | 13 |
14 |
15 | 16 |
17 | 19 |
20 |
21 |
22 | 25 | 28 |
29 |
30 |
31 |
32 |
33 |
34 | 35 | 80 | 81 |
82 | 83 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/vendor/vendors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |

[[#{admin.vendors.title}]]

9 | [[#{admin.vendors.newVendor}]] 10 |
11 |
12 | [[${message}]] 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 29 | 30 |
[[#{admin.vendor.id}]][[#{admin.vendor.title}]][[#{admin.managment}]]
27 |  
31 |
32 | 33 |
34 |
35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /src/main/resources/templates/blocks/breadcrumb.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |
7 |
8 | 24 |
25 |
26 |
27 |
28 | 29 | -------------------------------------------------------------------------------- /src/main/resources/templates/blocks/login.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 |
8 |
9 | 44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/resources/templates/category.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 |
7 |
8 | 9 |
10 |
11 |

[[#{category.title}]]

12 |
13 | 25 |
26 | 27 |
28 | 29 | -------------------------------------------------------------------------------- /src/main/resources/templates/error/404.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 |
8 | 9 | 10 | 12 | 14 | 16 | 18 | 20 | 21 | 22 |
23 |

404

24 |
25 |

Page not found

26 |
27 |
28 | 31 |
32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 62 | 63 |
64 |
65 | 88 |
89 | 114 | 115 |
116 |
117 |
118 | 119 |
120 |
121 | 122 | -------------------------------------------------------------------------------- /src/main/resources/templates/product/product-page.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 |
8 | 9 | 10 |
11 |
12 |
13 | 14 |
15 | 16 |
17 | 18 |
19 | 20 | 21 | 22 |
23 | 24 | 25 |
26 |
27 |

[[${product.title}]]

28 |
29 |
30 | 31 | [[#{admin.product.category}]]: [[${product.category.title}]] 32 | 33 | [[#{admin.product.vendor}]]: [[${product.vendor.title}]] 34 |
35 |

36 |

[[#{admin.product.price}]]: [[${product.price}]] ₴

37 |

38 | 39 |

[[#{admin.product.shortDescription}]]:

40 | 41 |

42 | 43 |
44 |
46 |
47 |
48 | 52 |
53 |
54 | 55 | 56 |
57 | 58 | 59 |
60 | 61 | 62 |
63 | 64 | 65 |
66 |
67 | 68 | 69 | 70 |
71 | 75 | 76 | 77 | 78 | 79 |
80 | 81 |
82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/main/resources/templates/product/product_fragment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/templates/product/products_by_category.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 | 30 | 31 |
 
32 | 33 |
34 | 35 |
36 |
37 |
38 | 39 | 40 |
41 | 42 |
43 |
44 | 45 | -------------------------------------------------------------------------------- /src/main/resources/templates/product/search_result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |

Search Result for '[[${keyword}]]'

10 |
11 |
12 |

No match found

14 |


15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /src/main/resources/templates/registration.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 |
7 | 8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 | 17 |
18 | 20 |
21 |
22 | 24 |
25 |
26 |
27 |
28 | 30 | 33 |
34 |
35 | 37 | 40 |
41 |
42 |
43 | 44 | 47 |
48 |
49 | 50 | 53 |
54 |
55 | 56 | 59 |
60 |
61 |
62 | 65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | 112 | 113 |
114 | 115 | 116 | -------------------------------------------------------------------------------- /src/main/resources/templates/user/orders.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 |
7 | 8 |
9 |
10 |

[[#{orders.noOrders}]]

11 | 12 | 13 | 14 |
15 |
16 | [[${message}]] 17 |
18 |
19 |
20 |
21 |
22 |

[[#{orders.ordersTitle}]]

23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 |
42 | 43 |
44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 |
[[#{orders.number}]][[#{orders.payment}]][[#{orders.name}]][[#{orders.shipping}]][[#{orders.city}]][[#{orders.address}]][[#{label.total}]]
Nova poshtaUkr poshta[[${order.totalPrice}]] ₴
52 |
53 |
54 |

[[#{orders.deliveryTitle}]]

55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 74 | 78 | 79 | 80 |
[[#{orders.number}]][[#{orders.status}]][[#{orders.shippingMethod}]]
70 | 73 | 75 | 77 |
81 |
82 | 87 |
88 |
89 | 90 | 91 |
92 |
93 | 94 | -------------------------------------------------------------------------------- /src/main/resources/templates/user/user-edit.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 |
7 |
8 |
9 |
10 |
11 |

[[#{userEdit.edit}]] !

12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 |
32 | The password must not be the same as the old one. 33 |
34 | 39 | 44 | 49 | 54 | 59 | 60 | 61 |
[[#{userMain.login}]][[#{userMain.password}]][[#{userMain.name}]][[#{userMain.surname}]][[#{userMain.phone}]][[#{userMain.email}]]
27 | 30 | 35 | 38 | 40 | 43 | 45 | 48 | 50 | 53 | 55 | 58 |
62 | 63 |
64 |
65 |
66 |
67 | 68 | 69 | [[#{userEdit.returnBtn}]] 70 | 71 |
72 |
73 |
74 |
75 |
76 |
77 | 78 | -------------------------------------------------------------------------------- /src/main/resources/templates/user/user-main.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 |
7 |
8 |
9 |
10 |
11 |

[[#{label.welcome}]] !

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
[[#{userMain.login}]][[#{userMain.password}]][[#{userMain.name}]][[#{userMain.surname}]][[#{userMain.phone}]][[#{userMain.email}]]
******
34 |
35 |
36 | 44 |
45 |
46 |
47 |
48 |
49 | 50 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/CategoryRepoTest.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import com.khomsi.site_project.repository.CategoryRepository; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 8 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 9 | 10 | import java.util.List; 11 | 12 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 13 | 14 | @DataJpaTest 15 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 16 | public class CategoryRepoTest { 17 | @Autowired 18 | private CategoryRepository categoryRep; 19 | 20 | @Test 21 | void testListEnabledCategories() { 22 | List categories = categoryRep.findAllEnabled(); 23 | 24 | categories.forEach(category -> { 25 | System.out.println(category.getTitle() + " (" + category.getEnabled() + ")"); 26 | }); 27 | } 28 | 29 | @Test 30 | void categoryFindByAlias() { 31 | String alias = "protectors"; 32 | 33 | Category category = categoryRep.findByAliasEnabled(alias); 34 | 35 | assertThat(category).isNotNull(); 36 | 37 | } 38 | 39 | @Test 40 | void testListRootCategories(){ 41 | List categories = categoryRep.findRootCategories(); 42 | categories.forEach(category -> System.out.println(category.getTitle())); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/CategoryTest.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import com.khomsi.site_project.repository.CategoryRepository; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 8 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 9 | import org.springframework.test.annotation.Rollback; 10 | 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 15 | 16 | @DataJpaTest 17 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 18 | @Rollback(value = false) 19 | public class CategoryTest { 20 | @Autowired 21 | private CategoryRepository categoryRep; 22 | 23 | @Test 24 | void testCreateCategory() { 25 | 26 | Category testCategory = new Category(); 27 | Category parent = categoryRep.getReferenceById(1); 28 | testCategory.setTitle("Sensor phones"); 29 | testCategory.setAlias("sensor_phones"); 30 | testCategory.setImageURL("text.png"); 31 | testCategory.setEnabled(true); 32 | testCategory.setParent(parent); 33 | 34 | Category saveCategory = categoryRep.save(testCategory); 35 | assertThat(saveCategory).isNotNull(); 36 | assertThat(saveCategory.getId()).isPositive(); 37 | } 38 | 39 | @Test 40 | void testGetCategory() { 41 | Category category = categoryRep.getReferenceById(1); 42 | System.out.println(category.getTitle()); 43 | 44 | Set children = category.getChildren(); 45 | 46 | children.stream().map(Category::getTitle).forEach(System.out::println); 47 | assertThat(children.size()).isGreaterThan(0); 48 | } 49 | 50 | @Test 51 | void testShowHierarchicalCategories() { 52 | Iterable categories = categoryRep.findAll(); 53 | for (Category category : categories) { 54 | if (category.getParent() == null) { 55 | System.out.println(category.getTitle()); 56 | Set children = category.getChildren(); 57 | for (Category subCat : children) { 58 | System.out.println("--" + subCat.getTitle()); 59 | } 60 | } 61 | } 62 | } 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/OrderBasketTests.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import com.khomsi.site_project.entity.OrderBasket; 4 | import com.khomsi.site_project.entity.Product; 5 | import com.khomsi.site_project.entity.User; 6 | import com.khomsi.site_project.repository.OrderBasketRepository; 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 10 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 11 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; 12 | import org.springframework.test.annotation.Rollback; 13 | 14 | import java.util.List; 15 | 16 | import static org.junit.jupiter.api.Assertions.*; 17 | 18 | @DataJpaTest 19 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 20 | @Rollback(value = false) 21 | public class OrderBasketTests { 22 | @Autowired 23 | private OrderBasketRepository orderBasketRep; 24 | 25 | @Autowired 26 | private TestEntityManager entityManager; 27 | 28 | @Test 29 | public void testAddOneOrderBasketProduct() { 30 | Product product = entityManager.find(Product.class, 6); 31 | User user = entityManager.find(User.class, 8); 32 | 33 | OrderBasket newOrderBasket = new OrderBasket(); 34 | 35 | newOrderBasket.setUser(user); 36 | newOrderBasket.setProduct(product); 37 | newOrderBasket.setQuantity(1); 38 | 39 | 40 | OrderBasket saveOrderBasketProd = orderBasketRep.save(newOrderBasket); 41 | 42 | assertTrue(saveOrderBasketProd.getId() > 0); 43 | } 44 | 45 | @Test 46 | public void testGetOrderBasketProdByUser() { 47 | User user = new User(); 48 | user.setId(8); 49 | 50 | List orderBaskets = orderBasketRep.findByUser(user); 51 | 52 | assertEquals(1, orderBaskets.size()); 53 | 54 | } 55 | 56 | // @Test 57 | // public String getProductsFromBasketsToOrder(List orderBaskets) { 58 | // Product product = entityManager.find(Product.class, 6); 59 | // User user = entityManager.find(User.class, 1); 60 | // 61 | // OrderBasket newOrderBasket = new OrderBasket(); 62 | // 63 | // newOrderBasket.setUser(user); 64 | // newOrderBasket.setProduct(product); 65 | // newOrderBasket.setQuantity(1); 66 | // 67 | // String result = null; 68 | // if (!orderBaskets.isEmpty()) { 69 | // for (OrderBasket orderBasket : orderBaskets) { 70 | // result += String.valueOf(orderBasket.getProduct().getId()) + "/"; 71 | // } 72 | // } 73 | // return result; 74 | // } 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/ProductRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | 4 | import com.khomsi.site_project.entity.Product; 5 | import com.khomsi.site_project.repository.ProductRepository; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 9 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 10 | 11 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 12 | 13 | @DataJpaTest 14 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 15 | //@Rollback(value = false) 16 | public class ProductRepositoryTest { 17 | @Autowired 18 | ProductRepository productRepository; 19 | 20 | @Test 21 | public void testFindByAlias() { 22 | String alias = "samsung"; 23 | 24 | Product product = productRepository.findByAlias(alias); 25 | 26 | assertThat(product).isNotNull(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/ProductTest.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import com.khomsi.site_project.entity.Category; 4 | import com.khomsi.site_project.entity.Product; 5 | import com.khomsi.site_project.entity.Vendor; 6 | import com.khomsi.site_project.repository.ProductRepository; 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 10 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 11 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; 12 | import org.springframework.data.domain.Page; 13 | import org.springframework.data.domain.PageRequest; 14 | import org.springframework.data.domain.Pageable; 15 | 16 | import java.util.List; 17 | import java.util.Optional; 18 | 19 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 20 | 21 | @DataJpaTest 22 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 23 | //@Rollback(value = false) 24 | public class ProductTest { 25 | @Autowired 26 | private ProductRepository productRepo; 27 | 28 | @Autowired 29 | private TestEntityManager entityManager; 30 | 31 | @Test 32 | void testCreateProduct() { 33 | Category category = entityManager.find(Category.class, 1); 34 | Vendor vendor = entityManager.find(Vendor.class, 2); 35 | 36 | Product product = new Product(); 37 | product.setTitle("Samsung Galaxy S22 Ultra"); 38 | product.setAlias("samsung_galaxy_s22_ultra"); 39 | product.setDescription("Full hd screen, 512 gb, green, red, blue colors"); 40 | product.setPrice(36000); 41 | product.setImageURL("https://assets.mmsrg.com/isr/166325/c1/-/ASSET_MMS_91200147/fee_786_587_png"); 42 | product.setCategory(category); 43 | product.setVendor(vendor); 44 | 45 | Product saveProduct = productRepo.save(product); 46 | assertThat(saveProduct).isNotNull(); 47 | assertThat(saveProduct.getId()).isPositive(); 48 | } 49 | 50 | @Test 51 | void testListAllProducts() { 52 | Iterable iterableProd = productRepo.findAll(); 53 | iterableProd.forEach(System.out::println); 54 | } 55 | 56 | @Test 57 | void testGetProduct() { 58 | Integer id = 2; 59 | Product findById = productRepo.getReferenceById(id); 60 | System.out.println(findById); 61 | assertThat(findById).isNotNull(); 62 | } 63 | 64 | @Test 65 | void testUpdateProduct() { 66 | Integer id = 12; 67 | Product product = productRepo.getReferenceById(id); 68 | 69 | product.setPrice(39000); 70 | productRepo.save(product); 71 | Product updatedProduct = entityManager.find(Product.class, id); 72 | 73 | assertThat(updatedProduct.getPrice()).isEqualTo(39000); 74 | } 75 | 76 | @Test 77 | void testDeleteProduct() { 78 | Integer id = 12; 79 | productRepo.deleteById(id); 80 | Optional result = productRepo.findById(id); 81 | 82 | assertThat(result.isEmpty()); 83 | } 84 | 85 | @Test 86 | public void testSearchProduct(){ 87 | String keyword = "Apple"; 88 | int pageNum = 0; 89 | int pageSize = 4; 90 | Pageable pageable = PageRequest.of(pageNum, pageSize); 91 | Page page = productRepo.findAll(keyword, pageable); 92 | 93 | List productList = page.getContent(); 94 | 95 | productList.forEach(product -> System.out.println(product)); 96 | 97 | assertThat(productList.size()).isGreaterThan(0); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/UserTest.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import com.khomsi.site_project.entity.User; 4 | import com.khomsi.site_project.repository.UserRepository; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 8 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 9 | 10 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 11 | 12 | @DataJpaTest 13 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 14 | public class UserTest { 15 | 16 | @Autowired 17 | UserRepository userRepository; 18 | @Test 19 | public void testFindByLogin(){ 20 | String login = "admin"; 21 | User user = userRepository.findByLogin(login); 22 | 23 | assertThat(user).isNotNull(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/khomsi/site_project/WebStoreApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.khomsi.site_project; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class WebStoreApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------